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.

MSP430FR5969: PUSHX.A imm20 fails?

Part Number: MSP430FR5969

Tool/software:

I was trying something out when I noticed something odd. First, the GCC utility msp430-elf-objdump showed a 20 bit immediate value as 16 bits.

    441c:       80 18 70 12     pushx.a #-21846 ;#0xaaaa
    4420:       aa aa 

The extension word (0x1880) clearly has bit 7 set so the value should be 0x1aaaa.

Worse, when I execute this instruction on a FR5969, the upper word on the stack is zero instead of one. If I load the immediate value into a register before pushing the register I get the expected 20 bit value.

I double checked the documentation and it does say you can use a 20 bit immediate value with pushx. The assembler accepts it without so much as a warning. But the disassembler and CPU ignore the bits in the extension word.

  • Hi David,

    Dose it happen with TI compiler? Like v21.6.1.LTS? 

    Could you help to share a simple project to me to reproduce this issue? I can try it on myside.

  • I have never used and do not have any other compiler. The instruction encoding matches what I expect from the documentation with the A/L and B/W bits correct for 20 bits. One other oddity I found with the GNU assembler is that it put bits into the extension word even for pushx.w

    I have never used it with the MSP430 but I dusted off the AS assembler and it produced identical encodings. Although it does complain about overflow if the operand is too big for pushx.w.

    I don't have a source file to share as this turned up using an asm() statement. The  strange disassembly prompted me to try executing it using an eForth system. Since this doesn't turn up in C compiler output much. Or at all.

    But I cobbled up a simple example. Compile, set a breakpoint at the NOP, examine the stack.

    #include <msp430.h>
    
    
    main(void)
    {
       WDTCTL = WDTPW | WDTHOLD;
       asm(" pushx.a #0xf1234\n");
       asm(" nop\n");
    
    
       while(1)
         LPM3;
    }
    

    Interestingly, mspdebug displays the instruction as "PUSHX.?":

    04412: 80 1f 70 12 34 12 PUSHX.? #0x1234

    The stack of course shows 32 bits pushed but the upper 16 are zeros:

    (mspdebug) md 0x23fa
    023fa: 34 12 00 00 0c 44 ff 3f ff 3f ff 3f ff 3f ff 3f |4....D.?.?.?.?.?|

  • I think you are right, it seems some thing wrong with the GUN compiler, below is my test with 

    GUN v9.3.0.31 

    But when I changed to TI v21.6.1.LTS compiler, it will woks as expected 

    I will change this thread to our compiler team to see if any comments there.

  • I suspect that this confusion is the result of bad documentation. The formats shown for single operand instructions at Figure 4-31 (slau367) do not show a version for a source operand. The lower 4 bits of the extension word are always shown as a destination. Nor does pushx.a appear in the format exceptions.

    Leaving the general form of the extension word shown at Figure 6-26 for guidance.

**Attention** This is a public forum