ARM: Forcing halfword operation for (short *)?

Toralf Lund toralf@procaptura.com
Tue Nov 9 15:55:00 GMT 2004


Bill Gatliff wrote:

> Toralf:
>
>
> One word: __asm__.  :^)

Yeah. Or completely skip the C code and write the whole thing in 
assembler...

>
>
> Although, seriously, this specific example has me scratching my head a 
> bit too.  What happens if you turn the optimizer on?

Same result. Or maybe there are fewer instructions, but I definitely 
still get two "strb" operations instead of one "strh"... But I found out 
a bit more about this just after I asked (I read the same doc before I 
posted the question, without noticing this. Seriously...)

The description of *-malignment-traps* in the manual page explains it 
all, really. Not that I'm using this option, but it tells me something I 
didn't know about the ARM architecture: Apparently, old revisions didn't 
have "half-word" instructions. Also, it seems like a pretty basic 
version of the ARM is assumed if no "-mcpu" option is passed, so I guess 
the compiler simply won't output any "strh" instructions at all.

So "-mcpu=arm9" solves the problem. Maybe I should have used this option 
all along, but I guess I've assumed that a fairly new architecture 
revision would be the default, and I haven't thought a lot about getting 
the most out of the processor, since the application is more than 
efficient enough anyway (it was written for a 12Mhz M68K, so obviously 
performance is not an issue with a modern ARM-based CPU.) *


*

> Toralf Lund wrote:

>
>> Sigh... Another problem with my ARM setup, after trying to access 
>> some additional hardware... Seems like I still have a lot to learn 
>> about the fine level of control over I/O-operations...
>>
>> Anyhow, the problem this time is the access size of a specific write 
>> operation. Consider the following function, which is a simplified 
>> version of one actually appearing in my application:
>>
>> int eraseTest()
>> {
>>  volatile unsigned short *sector=(unsigned short *)0x10000000;
>>
>>  *sector=(unsigned short )0x0030;
>> }
>>
>> The code generated for this is (from 'objdump -d' output):
>>
>> 0801c938 <_eraseTest>:
>> 801c938:    e1a0c00d     mov    ip, sp
>> 801c93c:    e92dd800     stmdb    sp!, {fp, ip, lr, pc}
>> 801c940:    e24cb004     sub    fp, ip, #4    ; 0x4
>> 801c944:    e24dd004     sub    sp, sp, #4    ; 0x4
>> 801c948:    e3a03201     mov    r3, #268435456    ; 0x10000000
>> 801c94c:    e50b3010     str    r3, [fp, -#16]
>> 801c950:    e51b3010     ldr    r3, [fp, -#16]
>> 801c954:    e3a02000     mov    r2, #0    ; 0x0
>> 801c958:    e3a01030     mov    r1, #48    ; 0x30
>> 801c95c:    e5c32000     strb    r2, [r3]
>> 801c960:    e5c31001     strb    r1, [r3, #1]
>> 801c964:    e91ba800     ldmdb    fp, {fp, sp, pc}
>>
>> This simply won't do. The problem? The data is stored via two strb 
>> operations, and it is absolutely essential that there is only one bus 
>> access. More generally, I need to have some more control over the 
>> actual access commands generated throughout my application.
>>
>> So, why do I get two byte-accesses in this case? Why not one halfword 
>> operation? And is there any way to make sure "strh" is used instead?
>>
>> - Toralf
>>
>>
>> ------
>> Want more information?  See the CrossGCC FAQ, 
>> http://www.objsw.com/CrossGCC/
>> Want to unsubscribe? Send a note to 
>> crossgcc-unsubscribe@sources.redhat.com
>>
>
>
- Toralf

------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com



More information about the crossgcc mailing list