Reputation: 3
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
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