On Sunday, 14 June 2015 06:49:37 UTC+2, Robert Willy wrote:
>
> I want to write ARM asm code with GCC toolchain. Previously, I use TI CGT, 
> whose asm syntax is different from GCC.
>

The assembler is actually part of "Binutils", not of GCC itself. You can 
find its manual at: https://sourceware.org/binutils/docs/as/


For example, the last line has an error with GCC toolchain (bad instruction 
> type). 
>
> gvar_a .field gvar, 32
>

The main issue is the lack of colon after the label gvar_a. This makes the 
assembler think it is some (unknown) instruction. Also, I've never seen the 
".field" directive. You probably want ".long gvar" here.

An even easier solution is using a literal load, i.e. "ldr r1, =gvar".

Also, I should note that "mov pc, lr" is a deprecated way to return from a 
function, "bx lr" should be used instead.


One way to see how to write "proper" assembler is by having GCC produce 
some for you (although you may need to weed through some redundant 
directives and unreadable randomly-generated labels). For example, if I 
understand your intention correctly, your code aims to do the equivalent of:

extern int gvar;
void asmfunc( int arg ) {
        gvar += arg;
}


If I put that in a file "foo.c" and compile it with 
"arm-linux-gnueabihf-gcc -Og -S -o- foo.c" then several things can be 
noticed about the output:
1. the ".syntax unified" directive, to select UAL syntax (which is the 
syntax currently used by the ARM Architecture Reference Manual, so 
selecting it is highly recommended)
2. some declarations of the target architecture, with many finer points 
defined in rather poorly readable "eabi attributes"
3. the use of Thumb mode by default, which I'd agree with: since ARMv7 
there's really little reason not to.
4. the use of movw+movt to produce the address of gvar, instead of loading 
it from some location.

It is interesting to note that if I compile with "clang -target 
arm-linux-gnueabihf -O -S -o- foo.c" then it will generate code essentially 
identical to yours, however the directives at the top show it is being 
conservative and targeting arm1136jf-s. If I add "-march=armv7-a" or 
"-mcpu=cortex-a8" to the commandline options then clang will also use 
movw+movt, so apparently this really is preferred (and considering the 
effects on separate L1 instruction and data caches, I can imagine why). 
Also, clang conveniently includes some comments on what all those 
eabi-attributes mean.


BTW, you haven't mentioned what your motivation is to write in assembly, 
but note that GCC has powerful functionality for including inline assembly 
into C/C++ source code. For example, if you want to use the "rbit" 
instruction (for which no intrinsic is available I think) you can easily 
wrap it in a function:

__attribute__((const))
static inline unsigned bitreverse( unsigned x ) {
        unsigned result;
        asm( "rbit %0, %1" : "=r"( result ) : "r"( x ) );
        return result;
}


(The "const" attribute indicates that the function is free of side-effects 
and doesn't depend on global memory, giving the optimizer a lot of liberty 
to move the instruction around.)

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to