Hi all,
Compiling the following example (with cl55 -O[123]):
extern long f(long);
long t(long i)
{
f(i);
return i;
}
will generate the following assembler:
AADD #-3, SP
MOV AC0, dbl(*SP(#0)) ; |3|
MOV dbl(*SP(#0)), AC0 ; |3|
///Why ?
CALL #_f ; |4|
MOV dbl(*SP(#0)), AC0 ; |4|
AADD #3, SP
RET
Which has a useless statement in moving the stack back to AC0. It just moved it from there. How can AC0 be different from the stack? Or am I missing something?
I noticed the compiler does this for a lot of stack based variables, this example shows it for pointers as well.
Compile using cl55 -O3 -k -ml -v5502 main.c (-ml is vital here, because otherwise pointer size = 16 bit and very different code is generated)
extern int* f0();
extern void f1(int*);
void t(void)
{
int* i0 = f0();
int* i1 = f0();
int* i2 = f0();
int* i3 = f0(); //First pointer that is saved on stack instead of register
i0=i0+10; f1(i0+10);
i1=i1+10; f1(i1+10);
i2=i2+10; f1(i2+10);
i3=i3+10; f1(i3+10);
}
the assembler:
MOV dbl(*SP(#0)), XAR3
MOV XAR3, dbl(*SP(#0))
|| AADD #10, AR3 ; |13|
MOV dbl(*SP(#0)), XAR0 // why is this? We have it already in XAR3.
AADD #10, AR0 ; |13|
CALL #_f1 ; |13|
Why is it first moving from stack to XAR3, then back to stack and then rereading it from stack to XAR0? It still is there in XAR3!
The basic problem seems that for variables that are on stack it moves to a register, do the requested operation, and stores it again to stack. So far so good
But if the same variable is now needed for a new operation it will again read it from stack, while it is already in a register.