kvnsk
kvnsk

Reputation: 3

IAR 7.40 compiler generating invalid assembly

I have a inline assembly code for arm cortex-R5

#include <stdio.h>

#define mtcpsr(v)   __asm volatile(\
              "msr  cpsr,%0\n"\
              : : "r" (v)\
            )

int mfcpsr (void)
{
    int rval;
    asm("mrs %0, cpsr" : "=r"(rval));
    return rval;
}


void main(void)
{

    /*
     * Enable interrupts in the ARM
     */

    mtcpsr(mfcpsr() & ~ ((0x80U) & (0x40U | 0x80U)));
}

This when compiled with IAR 7.40 compiler in Thumb mode by setting --cpu_mode=thumb as compiler flag, is generating assembly as

                `.text6`:
                mfcpsr:
  0xfffc040c: 0xf3ef 0x8000  MRS     R0, APSR
  0xfffc0410: 0x4770         BX      LR
  0xfffc0412: 0x0000         MOVS    R0, R0
                main:
  0xfffc0414: 0xb580         PUSH    {R7, LR}
  0xfffc0416: 0xf7ff 0xfff9  BL      mfcpsr                 ; 0xfffc040c
  0xfffc041a: 0xf020 0x0080  BIC.W   R0, R0, #128           ; 0x80
  0xfffc041e: 0xf380 0x8000  MSR     ??-0-0, R0
  0xfffc0422: 0xbd01         POP     {R0, PC}

MSR ??-0-0, R0 is the invalid assembly. I am expecting it as MSR CPSR_fc, R0 (which i got this without thumb option). Can you guys help me locate the problem.

Upvotes: 0

Views: 414

Answers (1)

Johan
Johan

Reputation: 3881

The syntax of the MSR instruction in your code is not correct. The MSR instruction requires that the name of the status register, CPSR in your case, should be suffixed by the fields that should be updated. So if you change the mtcpsr macro to the following you get the expected output

#define mtcpsr(v)   __asm volatile(\
          "msr  CPSR_cxsf,%0\n"\
          : : "r" (v)\
        )

I can only guess why the compiler behaves differently in arm and thumb mode or why it doesn't issue a warning but it is probably a bug.

As a side note, if you only want to enable interrupts you can use the CPSIE if instruction or the __enable_interrupts() intrinsic function.

Upvotes: 2

Related Questions