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 */        ); 
  1. read gcc inline assembly howto.
  2. copy content of c variable register (gcc)

Comments

Popular posts from this blog

html - Sizing a high-res image (~8MB) to display entirely in a small div (circular, diameter 100px) -

java - IntelliJ - No such instance method -

identifier - Is it possible for an html5 document to have two ids? -