| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#11
|
| adsouzp wrote: > 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 /* 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 |
|
#12
|
| gdisirio wrote: >> Op Wed, 27 Aug 2008 11:44:59 +0200 schreef Wilco Dijkstra >> >>> "gdisirio" >>> news:hKidnZFpiODXnCjVnZ2dnUVZ_uadnZ2d-at-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. |
|
#13
|
| "adsouzp" > 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 > 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 > 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 |
![]() |
| Thread Tools | |
| Display Modes | |