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;
}