This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5529: PUSHX.W instruction not working properly

Part Number: MSP430F5529

Hi everybody,

I would like to report an issue that I've discovered working with my MSP430 launchpad kit. I've noticed how the CPU doesn't correctly recognize the PUSHX.W instructions using absolute mode with a 20-bit address. Specifically, using the instruction "PUSHX[.W] &0x10000", or any other value above "0xFFFF", will simply let the CPU push the value at the address given by the specified one with its most important bit dropped. The CPU drops the most important bit, which is correctly encoded in the extension word, and simply ignores it.  "PUSHX[.W] &0x10000" will become "PUSHX[.W] &0x0000", "PUSHX[.W] &0x10010" will become "PUSHX[.W] &0x0010" and "PUSHX[.W] &0x20333" will become "PUSHX[.W] &0x0333".

It's worth noting that the compiler correctly distinguishes between "PUSHX[.W] &0x10000" and "PUSHX[.W] &0x0000" since it uses the extension word to encode the extra bit and creates a binary code with different instructions, but the CPU does not make any distinction between these two instructions. 

If anybody has a solution to this problem I would appreciate any feedback!

  • I am working with 20-bit instruction / regs in assembler, and didn't found any problem.

    PUSHX.B will put byte on stack, PUSHX.W will put 16-bit word on stack. PUSHX.A will put 20-bit word on stack.

  • Hi,

    Why you want to push a value large than 20 bit to stack?

    MSP430 can't recognize that address large than 20 bit.

    Eason

  • The replies appear to be missing the point. This appears to be exactly the same as the example in the CPUX guide for PUSHX:

    Save the byte at the 20-bit address &EDE on the stack
    PUSHX.B &EDE ; Save byte at address EDE

    He is saying that instead of using the 20 bit address &EDE to fetch the argument, the CPU is ignoring the upper 4 bits of the address. The size of what gets pushed onto the stack is not at issue.

    I attempted to build a simple test case for this using gas but it didn't work very well. While I wrote "pushx.w    &0x10000", objdump rendered that as:

      36:   c0 18 12 12     pushx.w &0x0000         ;
      3a:   00 00 

    That does appear to have the extra address bits in the extension word. (0x18c0)

  • Hi David,

    Thank you for pointing out my mistake. I think Bruce is right. Here is the description on UG. PUSHX.B only can be used to push 8-,16-bit source to stack.

    Eason

  • Exactly, I'm pointing out the problem in the address used as a pointer rather than the actual value that gets pushed. Glad to know that it's not only my problem. Hope there is a way to fix it although I doubt it. 

  • I did some more testing and the problem extends beyond PUSHX. objdump exhibits the same failure for all of the Format II instructions (single argument). It also happens with the Format I (dual argument) instruction tstx.w &EDE. (Which is actually the compare instruction but uses the constant generator to get a zero.)

    I did  a really simple test with "rrcx.w &0x10202" which changed PAOUT instead. (At 0x0202). So it appears that objdump is defective only in the sense that it doesn't match the documentation or stated extension word encoding. It does agree with the hardware.

        442e:       c0 18 12 10     rrcx.w  &0x0202         ;
        4432:       02 02 

    It seems kind of strange that such a serious flaw would have escaped attention till now. I can only assume that no C compiler uses these instructions with this addressing mode.

**Attention** This is a public forum