This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more information.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ARM: Forcing halfword operation for (short *)?


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]