| View previous topic :: View next topic |
| Author |
Message |
adsouzp Guest
|
Posted: Wed Aug 27, 2008 6:51 am Post subject: QUERY : ARM mode inline instructions in C Thumb mode file? |
|
|
hello:
one small question regarding use of ARM inline assembly code in a
C file that has been compiled for Thumb mode.
is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
how this is done is described on this page:
http://www.devrs.com/gba/files/asmc.txt
i have a C file that has been compiled for Thumb mode. in it, i am
using ARM inline assembly code. apparently, GCC issues no error
message but forcibly converts the ARM code into Thumb code.
i think that GCC requires an entire file to be in either Thumb mode
or ARM mode, but i am not sure. is that true?
the C code that is compiled into Thumb is:
void function_f( void )
{
asm volatile
(
".align \n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 }"
);
}
the C code is compiled with:
arm-elf-gcc -mlittle-endian -mcpu=arm7tdmi -march=armv4t \
-mthumb-interwork -mthumb -mno-tpcs-frame .....
here is the generated code:
00008194 <function_f>:
8194: b580 push {r7, lr}
8196: af02 add r7, sp, #8
8198: 0000 lsls r0, r0, #0
819a: e10f b.n 83bc <wrap+0x10>
819c: f000 e121 blx 4083e0 <_stack+0x3883e0>
81a0: 0001 lsls r1, r0, #0
81a2: e8bd 46bd ldmia.w sp!, {r0, r2, r3, r4, r5, r7, r9,
sl, lr}
81a6: b082 sub sp, #8
81a8: bc80 pop {r7}
81aa: bc01 pop {r0}
81ac: 4700 bx r0
in the inline assembly code, if i do not use ".arm", i get compiler
errors.
is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
Aaron
Makefile
--------
CC = arm-elf-gcc
TARGET_ARCH = -mlittle-endian -mcpu=arm7tdmi -march=armv4t
TARGET_ARCH += -mthumb -mno-tpcs-frame -mthumb-interwork
all: test
arm-elf-objdump -S -D test > test.lst
clean:
rm -f test test.o function.o
C CODE
------
void function_f( void )
{
asm volatile
(
".align \n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 }"
);
}
int main( void )
{
function_f();
return 0;
} |
|
| |
|
Back to top |
gdisirio Guest
|
Posted: Wed Aug 27, 2008 9:20 am Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
| Quote: | hello:
one small question regarding use of ARM inline assembly code in a
C file that has been compiled for Thumb mode.
is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
how this is done is described on this page:
http://www.devrs.com/gba/files/asmc.txt
i have a C file that has been compiled for Thumb mode. in it, i am
using ARM inline assembly code. apparently, GCC issues no error
message but forcibly converts the ARM code into Thumb code.
i think that GCC requires an entire file to be in either Thumb mode
or ARM mode, but i am not sure. is that true?
the C code that is compiled into Thumb is:
void function_f( void )
{
asm volatile
(
".align \n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 }"
);
}
the C code is compiled with:
arm-elf-gcc -mlittle-endian -mcpu=arm7tdmi -march=armv4t \
-mthumb-interwork -mthumb -mno-tpcs-frame .....
here is the generated code:
00008194 <function_f>:
8194: b580 push {r7, lr}
8196: af02 add r7, sp, #8
8198: 0000 lsls r0, r0, #0
819a: e10f b.n 83bc <wrap+0x10
819c: f000 e121 blx 4083e0 <_stack+0x3883e0
81a0: 0001 lsls r1, r0, #0
81a2: e8bd 46bd ldmia.w sp!, {r0, r2, r3, r4, r5, r7, r9,
sl, lr}
81a6: b082 sub sp, #8
81a8: bc80 pop {r7}
81aa: bc01 pop {r0}
81ac: 4700 bx r0
in the inline assembly code, if i do not use ".arm", i get compiler
errors.
is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
Aaron
Makefile
--------
CC = arm-elf-gcc
TARGET_ARCH = -mlittle-endian -mcpu=arm7tdmi -march=armv4t
TARGET_ARCH += -mthumb -mno-tpcs-frame -mthumb-interwork
all: test
arm-elf-objdump -S -D test > test.lst
clean:
rm -f test test.o function.o
C CODE
------
void function_f( void )
{
asm volatile
(
".align \n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 }"
);
}
int main( void )
{
function_f();
return 0;
}
|
Try this:
void function_f( void )
{
asm volatile
(
".code 32 \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
".code 16 \n\t"
"pop { r0 }"
);
}
It generates:
function_f:
.code 32
mrs r0, cpsr
msr cpsr_c, r0
.code 16
pop { r0 }
bx lr
You need to return to thumb mode after inserting the arm code or the
assembles will get confused.
BTW, that "pop r0" will crash the program.
regards,
Giovanni Di Sirio
---
ChibiOS/RT http://chibios.sourceforge.net |
|
| |
|
Back to top |
Wilco Dijkstra Guest
|
Posted: Wed Aug 27, 2008 2:44 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
"gdisirio" <herpes@ngi.it> wrote in message news:hKidnZFpiODXnCjVnZ2dnUVZ_uadnZ2d@giganews.com...
| Quote: | hello:
one small question regarding use of ARM inline assembly code in a
C file that has been compiled for Thumb mode.
is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
how this is done is described on this page:
http://www.devrs.com/gba/files/asmc.txt
i have a C file that has been compiled for Thumb mode. in it, i am
using ARM inline assembly code. apparently, GCC issues no error
message but forcibly converts the ARM code into Thumb code.
i think that GCC requires an entire file to be in either Thumb mode
or ARM mode, but i am not sure. is that true?
the C code that is compiled into Thumb is:
void function_f( void )
{
asm volatile
(
".align \n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 }"
);
}
the C code is compiled with:
arm-elf-gcc -mlittle-endian -mcpu=arm7tdmi -march=armv4t \
-mthumb-interwork -mthumb -mno-tpcs-frame .....
here is the generated code:
00008194 <function_f>:
8194: b580 push {r7, lr}
8196: af02 add r7, sp, #8
8198: 0000 lsls r0, r0, #0
819a: e10f b.n 83bc <wrap+0x10
819c: f000 e121 blx 4083e0 <_stack+0x3883e0
81a0: 0001 lsls r1, r0, #0
81a2: e8bd 46bd ldmia.w sp!, {r0, r2, r3, r4, r5, r7, r9,
sl, lr}
81a6: b082 sub sp, #8
81a8: bc80 pop {r7}
81aa: bc01 pop {r0}
81ac: 4700 bx r0
in the inline assembly code, if i do not use ".arm", i get compiler
errors.
is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
Aaron
Makefile
--------
CC = arm-elf-gcc
TARGET_ARCH = -mlittle-endian -mcpu=arm7tdmi -march=armv4t
TARGET_ARCH += -mthumb -mno-tpcs-frame -mthumb-interwork
all: test
arm-elf-objdump -S -D test > test.lst
clean:
rm -f test test.o function.o
C CODE
------
void function_f( void )
{
asm volatile
(
".align \n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 }"
);
}
int main( void )
{
function_f();
return 0;
}
Try this:
void function_f( void )
{
asm volatile
(
".code 32 \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
".code 16 \n\t"
"pop { r0 }"
);
}
It generates:
function_f:
.code 32
mrs r0, cpsr
msr cpsr_c, r0
.code 16
pop { r0 }
bx lr
|
That is still incorrect as it doesn't switch to ARM, nor switch back to Thumb...
You can't do this unless you:
A. Switch to ARM mode for the whole function - many compilers can switch
between ARM and Thumb on a per function basis. I don't know whether GCC
supports this yet. The key is that the function_f symbol is marked as ARM,
not Thumb, or it will be incorrectly called.
B. Use a Thumb function, like above, and explictly switch to ARM yourself,
do your ARM sequence and BX lr to switch back if needed.
You should use a naked assembler function to stop the compiler from
generating its own entry/exit sequences.
Btw why corrupt the stack using pop {r0}?
Wilco |
|
| |
|
Back to top |
Boudewijn Dijkstra Guest
|
Posted: Wed Aug 27, 2008 7:19 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
Op Wed, 27 Aug 2008 11:44:59 +0200 schreef Wilco Dijkstra
<Wilco.removethisDijkstra@ntlworld.com>:
| Quote: | "gdisirio" <herpes@ngi.it> wrote in message
news:hKidnZFpiODXnCjVnZ2dnUVZ_uadnZ2d@giganews.com...
A. Switch to ARM mode for the whole function - many compilers can switch
between ARM and Thumb on a per function basis. I don't know whether
GCC supports this yet.
|
No attribute or pragma exists for this in the documentation.
--
Gemaakt met Opera's revolutionaire e-mailprogramma:
http://www.opera.com/mail/ |
|
| |
|
Back to top |
gdisirio Guest
|
Posted: Wed Aug 27, 2008 7:33 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
The above example was only meant to make it compile correctly, I didn't
remove that "pop {r0}" either.
If you want to switch to arm mode and back to thumb mode then more
instructions are required:
void function_f( void )
{
asm volatile
(
".balign 4 \n\t"
"mov r0, pc \n\t"
"bx r0 \n\t"
".code 32 \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"add r0, pc, #1 \n\t"
"bx r0 \n\t"
".code 16 \n\t"
);
}
which generates:
function_f:
.balign 4
mov r0, pc // jumps into ARM mode
bx r0
.code 32
mrs r0, cpsr // ARM code starting here
msr cpsr_c, r0
add r0, pc, #1 // returns to thumb code
bx r0
.code 16
bx lr // thumb code continues here
This one should be complete.
regards,
Giovanni
---
ChibiOS/RT http://chibios.sourceforge.net |
|
| |
|
Back to top |
gdisirio Guest
|
Posted: Wed Aug 27, 2008 7:41 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
| Quote: | Op Wed, 27 Aug 2008 11:44:59 +0200 schreef Wilco Dijkstra
Wilco.removethisDijkstra@ntlworld.com>:
"gdisirio" <herpes@ngi.it> wrote in message
news:hKidnZFpiODXnCjVnZ2dnUVZ_uadnZ2d@giganews.com...
A. Switch to ARM mode for the whole function - many compilers can
switch
between ARM and Thumb on a per function basis. I don't know whether
GCC supports this yet.
No attribute or pragma exists for this in the documentation.
--
Gemaakt met Opera's revolutionaire e-mailprogramma:
http://www.opera.com/mail/
|
Yes, it is a big limit in the current implementation, they should really
add new function attributes for that. That would make writing mixed code
less painful.
---
ChibiOS/RT http://chibios.sourceforge.net |
|
| |
|
Back to top |
adsouzp Guest
|
Posted: Wed Aug 27, 2008 8:36 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
hello:
a few apologies.
in this example, i was focussing on the ".arm" directive and thought that
the assembler was not recognizing it. that's why the code is not
semantically correct. the extra r0 is an error here.
i should have written that i have not included the code to move from ARM
to Thumb mode and vice versa. that will require a bx r0, which i was
planning to use. before using r0, i was planning to save r0 on the stack.
that's why there is a pop r0.
i have also received a reply from Nick Clifton and will post his reply
also.
i will also post my complete code that works, and i could not find it
anywhere on the Internet. i wanted to simply add ARM mode inline assembly
code into a Thumb mode C file for enabling/disabling interrupts without
needing to call a function.
Aaron |
|
| |
|
Back to top |
adsouzp Guest
|
Posted: Wed Aug 27, 2008 8:48 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
hello ffolks:
here is a reply from Nick Clifton, which is really illuminating. pls read
it carefully. i will also post the complete working solution, if i can get
permission from my boss.
-------- Original Message --------
Subject : Re: RESEND : QUERY : ARM inline code in Thumb file?
Date : Wed 27 Aug 2008 10:37:23 +0100
From : Nick Clifton @ RedHat
To : Aaron P. D'Souza
Hi Aaron,
| Quote: | is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
|
Yes.
| Quote: | i have a C file that has been compiled for Thumb mode. in it, i am
using ARM inline assembly code. apparently, GCC issues no error
message but forcibly converts the ARM code into Thumb code.
|
Highly unlikely. What is more likely is that you need to be careful
about how you insert the ARM code.
| Quote: | the C code that is compiled into Thumb is:
void function_f( void )
{
asm volatile
(
".align \n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 }"
);
}
|
There are two problems with the above code:
1. You do not switch back to thumb mode at the end of the ARM code
fragment. Gcc passes the contents of the asm() directory on to the
assembler - it does not try to parse it and discover that you are
sneakily switching into ARM mode...
2. You have the .arm directive without a nearby label to hang it on.
The .arm (and .thumb) directives need a label because the changes
between instruction sets is encoded into attributes of the labels, thus
allowing the linker and disassembler to know when instruction sets have
changed.
ie. please try this:
void function_f( void )
{
asm volatile
(
".align \n"
"__f_into_arm:\n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 } \n"
"__f_from_arm:\n\t"
".thumb"
);
}
Cheers
Nick |
|
| |
|
Back to top |
adsouzp Guest
|
Posted: Wed Aug 27, 2008 9:20 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
Nick Clifton said:
| Quote: | There are two problems with the above code:
1. You do not switch back to thumb mode at the end of the ARM code
fragment. Gcc passes the contents of the asm() directory on to the
assembler - it does not try to parse it and discover that you are
sneakily switching into ARM mode...
2. You have the .arm directive without a nearby label to hang it on.
The .arm (and .thumb) directives need a label because the changes
between instruction sets is encoded into attributes of the labels, thus
allowing the linker and disassembler to know when instruction sets have
changed.
ie. please try this:
void function_f( void )
{
asm volatile
(
".align \n"
"__f_into_arm:\n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 } \n"
"__f_from_arm:\n\t"
".thumb"
);
}
|
i tried the above code but it still did not work! here is the code
generated.
00008194 <function_f>:
8194: b580 push {r7, lr}
8196: af02 add r7, sp, #8
00008198 <__f_into_arm>:
8198: 0000 lsls r0, r0, #0
819a: e10f b.n 83bc <wrap+0x10>
819c: f000 e121 blx 4083e0 <_stack+0x3883e0>
81a0: 0001 lsls r1, r0, #0
81a2: e8bd 46bd ldmia.w sp!, {r0, r2, r3, r4, r5, r7, r9, sl, lr}
000081a4 <__f_from_arm>:
81a4: b08246bd strlth r4, [r2], sp
81a8: bc01bc80 stclt 12, cr11, [r1], {128}
81ac: 00004700 andeq r4, r0, r0, lsl #14
Aaron |
|
| |
|
Back to top |
adsouzp Guest
|
Posted: Wed Aug 27, 2008 9:22 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
Nick Clifton said:
| Quote: | There are two problems with the above code:
1. You do not switch back to thumb mode at the end of the ARM code
fragment. Gcc passes the contents of the asm() directory on to the
assembler - it does not try to parse it and discover that you are
sneakily switching into ARM mode...
2. You have the .arm directive without a nearby label to hang it on.
The .arm (and .thumb) directives need a label because the changes
between instruction sets is encoded into attributes of the labels, thus
allowing the linker and disassembler to know when instruction sets have
changed.
ie. please try this:
void function_f( void )
{
asm volatile
(
".align \n"
"__f_into_arm:\n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 } \n"
"__f_from_arm:\n\t"
".thumb"
);
}
|
i tried the above code but it still did not work! here is the code
generated.
00008194 <function_f>:
8194: b580 push {r7, lr}
8196: af02 add r7, sp, #8
00008198 <__f_into_arm>:
8198: 0000 lsls r0, r0, #0
819a: e10f b.n 83bc <wrap+0x10>
819c: f000 e121 blx 4083e0 <_stack+0x3883e0>
81a0: 0001 lsls r1, r0, #0
81a2: e8bd 46bd ldmia.w sp!, {r0, r2, r3, r4, r5, r7, r9, sl, lr}
000081a4 <__f_from_arm>:
81a4: b08246bd strlth r4, [r2], sp
81a8: bc01bc80 stclt 12, cr11, [r1], {128}
81ac: 00004700 andeq r4, r0, r0, lsl #14
Aaron |
|
| |
|
Back to top |
adsouzp Guest
|
Posted: Wed Aug 27, 2008 10:22 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
hello:
i should have added a few important points:
- i tried Nick Clifton's solution and it did not work
- i tried Giovanni's solution and it did not work
- the entire C code is compiled to Thumb mode
- function function_f() is compiled to Thumb mode
- GNUARM gcc4.1.1 is being used
- the code is being checked in disassembled code generated
from the final .ELF executable file, disassembly being
done using arm-elf-objdump.
i hope that this information is helpful.
Aaron |
|
| |
|
Back to top |
Tauno Voipio Guest
|
Posted: Wed Aug 27, 2008 10:38 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
adsouzp wrote:
| Quote: | hello:
one small question regarding use of ARM inline assembly code in a
C file that has been compiled for Thumb mode.
is it possible to use ARM assembly code from within a C file that
has been compiled for Thumb and Thumb interworking?
|
Try this:
----------
#include <inttypes.h>
/* Change PSR - return old value */
uint32_t change_psr(uint32_t mask, uint32_t data) _attribute__((noinline));
uint32_t change_psr(uint32_t mask, uint32_t data)
{
uint32_t result;
asm volatile (
"adr r3,chg32\n\t" /* -> 32 bit code */
"bx r3\n\t" /* enter 32 bit mode */
".code 32\n"
"chg32:\n\t"
"mrs %[r],cpsr\n\t" /* get current PSR */
"bic r3,%[r],%[m]\n\t" /* clean up old PSR */
"orr r3,r3,%[d]\n\t" /* insert new bits */
"msr cpsr,r3\n\t" /* update current PSR */
"adr r3,chg16+1\n\t" /* -> 16 bit code */
"bx r3\n\t" /* return to 16 bit mode */
".code 16\n"
"chg16:"
: [r] "=&l" (result)
: [m] "r" (mask),
[d] "r" (mask & data)
: "r3");
return result;
}
----------
HTH
--
Tauno Voipio
tauno voipio (at) iki fi |
|
| |
|
Back to top |
David Brown Guest
|
Posted: Wed Aug 27, 2008 11:42 pm Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
gdisirio wrote:
| Quote: | Op Wed, 27 Aug 2008 11:44:59 +0200 schreef Wilco Dijkstra
Wilco.removethisDijkstra@ntlworld.com>:
"gdisirio" <herpes@ngi.it> wrote in message
news:hKidnZFpiODXnCjVnZ2dnUVZ_uadnZ2d@giganews.com...
A. Switch to ARM mode for the whole function - many compilers can
switch
between ARM and Thumb on a per function basis. I don't know whether
GCC supports this yet.
No attribute or pragma exists for this in the documentation.
Yes, it is a big limit in the current implementation, they should really
add new function attributes for that. That would make writing mixed code
less painful.
|
As far as I can see on the gcc website, gcc 4.4.0 supports changing
compiler options on a function-by-function basis (either as pragmas for
a block of code, or function attributes). However, this feature is
currently only enabled on the x86 target (according to the docs). But I
expect it will come soon on other targets. |
|
| |
|
Back to top |
Wilco Dijkstra Guest
|
Posted: Thu Aug 28, 2008 1:57 am Post subject: Re: QUERY : ARM mode inline instructions in C Thumb mode fil |
|
|
"adsouzp" <adsouzp@gmail.com> wrote in message news:APqdnc54RY_X4ijVnZ2dnUVZ_rHinZ2d@giganews.com...
| Quote: | Nick Clifton said:
There are two problems with the above code:
1. You do not switch back to thumb mode at the end of the ARM code
fragment. Gcc passes the contents of the asm() directory on to the
assembler - it does not try to parse it and discover that you are
sneakily switching into ARM mode...
2. You have the .arm directive without a nearby label to hang it on.
The .arm (and .thumb) directives need a label because the changes
between instruction sets is encoded into attributes of the labels, thus
allowing the linker and disassembler to know when instruction sets have
changed.
ie. please try this:
void function_f( void )
{
asm volatile
(
".align \n"
"__f_into_arm:\n\t"
".arm \n\t"
"mrs r0, cpsr \n\t"
"msr cpsr_c, r0 \n\t"
"pop { r0 } \n"
"__f_from_arm:\n\t"
".thumb"
);
}
i tried the above code but it still did not work! here is the code
generated.
00008194 <function_f>:
8194: b580 push {r7, lr}
8196: af02 add r7, sp, #8
00008198 <__f_into_arm>:
8198: 0000 lsls r0, r0, #0
819a: e10f b.n 83bc <wrap+0x10
819c: f000 e121 blx 4083e0 <_stack+0x3883e0
81a0: 0001 lsls r1, r0, #0
81a2: e8bd 46bd ldmia.w sp!, {r0, r2, r3, r4, r5, r7, r9, sl, lr}
000081a4 <__f_from_arm>:
81a4: b08246bd strlth r4, [r2], sp
81a8: bc01bc80 stclt 12, cr11, [r1], {128}
81ac: 00004700 andeq r4, r0, r0, lsl #14
|
That's because you need to first use .arm and then define the label.
The label uses the current instruction set, and doesn't look at whatever
comes afterwards. The disassembly is what I'd expect it to be.
Wilco |
|
| |
|
Back to top |
|