Michael Walle wrote: > Hi, > > That was quick :) > >> Your asm has no output operands and no side effects, with more >> aggressive optimization the whole ask would disappear. > Sorry, that was just a small test file, the original code has output operands. > > The new test code: > static int inline f1(int arg) > { > register int ret asm("r1"); > register int a1 asm("r8") = 10; > register int a2 asm("r1") = arg; > > asm volatile ("scall" : "=r"(ret) : "r"(a1), "r"(a2) : "memory"); > > return ret; > } > > int f2(int arg1, int arg2) > { > return f1(arg1 >> 10); > } > > translates to the same assembly: > f2: > addi sp, sp, -4 > sw (sp+4), ra > addi r2, r0, 10 > calli __ashrsi3 > scall > lw ra, (sp+4) > addi sp, sp, 4 > b ra > > PS. R1 is the return register in the target architecture ABI.
I'd guess you ran into http://gcc.gnu.org/onlinedocs/gcc/Local-Reg-Vars.html#Local-Reg-Vars A common pitfall is to initialize multiple call-clobbered registers with arbitrary expressions, where a function call or library call for an arithmetic operator will overwrite a register value from a previous assignment, for example r0 below: register int *p1 asm ("r0") = ...; register int *p2 asm ("r1") = ...; In those cases, a solution is to use a temporary variable for each arbitrary expression. So I'd try to rewrite it as static int inline f1 (int arg0) { int arg = arg0; register int ret asm("r1"); register int a1 asm("r8") = 10; register int a2 asm("r1") = arg; asm volatile ("scall" : "=r"(ret) : "r"(a1), "r"(a2) : "memory"); return ret; } and if that does not help the rather hackish static int inline f1 (int arg0) { int arg = arg0; register int ret asm("r1"); register int a1 asm("r8"); register int a2 asm("r1"); asm ("" : "+r" (arg)); a1 = 10; a2 = arg; asm volatile ("scall" : "=r"(ret) : "r"(a1), "r"(a2) : "memory"); return ret; }