|
|
|
|
|
|
Re: Assembly code error with Cygwin toolchain [message #1721172 is a reply to message #1721160] |
Mon, 25 January 2016 13:07 |
Tauno Voipio Messages: 742 Registered: August 2014 |
Senior Member |
|
|
This compiles, and has been in use for as long as there has been Atmel ARMs:
/* Interrupt disable (kernel internal - for speed) */
#define PS_I (1 << 7) /* interrupt disable */
#define PS_F (1 << 6) /* fast interrupt disable */
static NOINLINE NAKED void disable_int(void)
{
uint32_t tmp;
__asm__ volatile (
"adr %[t],1f\n\t" /* -> 32 bit code */
"bx %[t]\n\t" /* enter 32 bit mode */
".align 2\n\t"
".code 32\n"
"1:\n\t"
"mrs %[t],cpsr\n\t" /* get current PSR */
"orr %[t],%[t],%[ps_i]\n\t" /* insert interrupt disable bit */
"msr cpsr,%[t]\n\t" /* update current PSR */
"bx lr\n\t" /* return in 16 bit mode */
: [t] "=l" (tmp)
: [ps_i] "i" (PS_I)
);
}
The code is for Thumb mode, drop the adr, .code32 and first bx lines for ARM. You can change the ps_i argument to PS_I|PS_F for full disable.
I doubt that the assembler complains about the low registers in your above code, but please take the semicolons out and terminate the statements with a '\n'.
If you create a separate function like mine, you can let the compiler to select the most suitable temporary register instead of casting r4 in concrete. The ARM code generator prefers to use the registers r0 to r3 for temporary use if they are not occupied as function arguments. The compiler is smart enough to inline the function when it is advantageous, and some level of optimization is selected (I prefer -Os).
--
Tauno Voipio
|
|
|
Powered by
FUDForum. Page generated in 0.02792 seconds