c - Inline asm with sideeffects -
i want use inline asm armv7 clang 3.4, in order write low level code accesses cpus control registers. test, wrote program reads register, conditionally fiddles bits, , writes new value.
however, when @ produced machine code entire bit-fiddling has been optimized away. apparently have not used right asm constraints tell clang result of writing register depends on being written. (i used simple "volatile" modifier).
how should write inline asm code clang generates correct asm? here code test.c
typedef unsigned int uint32_t; // code reads , writes id_pfr1 register uint32_t read_id_pfr1() { uint32_t a; asm volatile ("mrc p15, 0, %0, c0, c1, 1" : : "r"(a) : ); return a; } void write_id_pfr1(uint32_t a) { asm volatile ("mcr p15, 0, %0, c0, c1, 1" :"=r"(a) : : ); } // regular c code modifies register uint32_t foo(uint32_t b) { uint32_t a; = read_id_pfr1(); write_id_pfr1(b); return a+b; } void bit_fiddle() { uint32_t a; = read_id_pfr1(); if ((a & 0x3) == 1) { |= 1<<2; } |= 1<<3; write_id_pfr1(a); }
i compiled
clang-3.4 -target armv7a-none-eabi test.c -o test -o3
this resulting machine code
$ arm-linux-gnueabi-objdump -s test test: file format elf32-littlearm disassembly of section .text: 00000000 <read_id_pfr1>: 0: ee100f31 mrc 15, 0, r0, cr0, cr1, {1} 4: e12fff1e bx lr 00000008 <write_id_pfr1>: 8: ee000f31 mcr 15, 0, r0, cr0, cr1, {1} c: e12fff1e bx lr 00000010 <foo>: 10: ee100f31 mrc 15, 0, r0, cr0, cr1, {1} 14: ee000f31 mcr 15, 0, r0, cr0, cr1, {1} 18: e12fff1e bx lr 0000001c <bit_fiddle>: 1c: ee100f31 mrc 15, 0, r0, cr0, cr1, {1} 20: ee000f31 mcr 15, 0, r0, cr0, cr1, {1} 24: e12fff1e bx lr
as can see in <bit_fiddle>
, nothing left between mrc
, mcr
instructions. , see how foo
fails add a+b
in produced machine code.
you close "="
: means operand write-only:
while using constraints, more precise control on effects of constraints, gcc provides constraint modifiers. used constraint modifiers are
"=" : means operand write-only instruction; previous value discarded , replaced output data. "&" : means operand earlyclobber operand, modified before instruction finished using input operands. therefore, operand may not lie in register used input operand or part of memory address. input operand can tied earlyclobber operand if use input occurs before result written.
the input , output determined order in list separated :
asm ( assembler template : output operands /* optional */ : input operands /* optional */ : list of clobbered registers /* optional */ );
Comments
Post a Comment