Take-away:

In the existing msp430-as, there is NO BEHAVIORAL DIFFERENCE between these
two statements:

  mov &extern, r15
  mov extern, r15

And that is flat out wrong.  If you have assembly code that depends on
these being equivalent, it will break with the next release of mspgcc.  An
ampersand will be required to produce absolute offsets.

The details:

While reviewing the binutils port, I've found a frighteningly large number
of bugs in assembly and disassembly, especially in the 430X instructions
and in addressing modes not normally produced by gcc.  Ten of them were bad
enough to be reported on the
tracker<https://sourceforge.net/tracker/?group_id=42303&atid=432701>.
 The suite of bugs affecting symbolic addressing mode are what I'm afraid
of: correcting them will break currently working, but incorrect, assembly
code.

Here's the situation: MSP430 supports two addressing modes that involve
constant offsets: "symbolic" is PC-relative, and "absolute" is, well,
absolute.  Symbolic is implemented by adding an offset to the value of r0
(=pc); absolute by adding an offset to r2 (=cg1 configured to read as zero).

In assembly code the instruction:

  mov &0x1000, r15

loads the word at address 0x1000 into r15.  This is absolute mode.

The similar instruction:

  mov 0x1000, r15

is in symbolic mode.  If the opcode for mov is at address 0x2000, then the
word at address 0x3002 (i.e., 0x2002+0x1000) will be loaded into r15.  (The
extra 2 is because pc was incremented after reading the opcode.)

So: LTS-20110716, which has essentially the same binutils that's been in
mspgcc for years, converts this:

.global extern
       mov     &0x1000, r15
       mov     0x1000, r15
       mov     &extern, r15
       mov     extern, r15

into this:

00000000 <test>:
  0:   1f 42 00 10     mov     &0x1000,r15
  4:   1f 40 fa 0f     mov     0x0ffa, r15     ;PC rel. 0x01002
  8:   1f 42 00 00     mov     &0x0000,r15
                       a: R_MSP430_16  extern
  c:   1f 40 00 00     mov     0x0000, r15     ;PC rel. 0x00010
                       e: R_MSP430_16_PCREL_BYTE       extern

Absolute addressing mode is fine at this point, but symbolic mode has a
couple flaws.  First, the specified value 0x1000 was improperly adjusted
based on an assumption that the value would be stored at offset 6 (which it
is at this point).  The result is that the address that would actually be
read is 0x1000, rather than 0x1000+r0 which is what the instruction should
have meant.  This subverts the intent of symbolic addressing mode by making
it effectively the same as absolute addressing mode.  It's also wrong,
because at this point the code is still relocatable and final address
hasn't been determined: it probably won't be 6.  (Note the "PC rel" comment
suggests the address that would be read is 0x1002; it's not, because of bug
3487360<https://sourceforge.net/tracker/?func=detail&aid=3487360&group_id=42303&atid=432701>.
 Does your head hurt yet?  Mine does.)

Now, if you take that relocatable code and pass it through the linker with
extern defined as 0x1000 and the text section starting at 0x6000, you get:

   6000:       1f 42 00 10     mov     &0x1000,r15
   6004:       1f 40 fa 0f     mov     0x0ffa, r15     ;PC rel. 0x07002
   6008:       1f 42 00 10     mov     &0x1000,r15
   600c:       1f 40 f2 af     mov     0xaff2, r15     ;PC rel. 0x01002

Again, absolute mode is correct, and symbolic mode has made another attempt
to convert the offset so that an absolute address is read.  Ignore the
decoding error in the comment, because in practice the last two
instructions would both read a word from offset 0x1000.

These errors will not be fixed in LTS-20110716.

However, unless somebody can convince me this analysis is wrong (which is
part of why I'm posting this), in the next development release of mspgcc
the original code will produce:

   6000:       1f 42 00 10     mov     &0x1000,r15
   6004:       1f 40 00 10     mov     0x1000, r15     ;PC rel. 0x07006
   6008:       1f 42 00 10     mov     &0x1000,r15
   600c:       1f 40 00 10     mov     0x1000, r15     ;PC rel. 0x0700e

For the most part, the gcc port does not emit code that uses symbolic mode,
so these bugs haven't been affecting it.  There are a couple cases where it
does, and those will have to be fixed too.  But it's assembly-language
coders who will have to fix their code if they've been using symbolic mode
where they should have been using absolute mode.

Peter
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to