Am 17.07.24 um 17:55 schrieb Jeff Law:
On 7/17/24 9:26 AM, Georg-Johann Lay wrote:
It looks fine for the trunk.  Out of curiosity, does the avr port implement linker relaxing for this case?  That would seem to be

No. avr-ld performs relaxing, but only the two cases of

- JMP/CALL to RJMP/RCALL provided the offset fits.
- [R]CALL+RET to [R]JMP provided there's no label between.
Yea, the first could be comparable to other targets.  The second is probably not all that common since the compiler should be doing that tail call elimination.

It should.  But there are cases where gcc doesn't optimize, like

float add (float a, float b)
{
    return a + b;
}

Then there are the calls that are not visible to the compiler, like

long mul (long a, long b)
{
    return b * a;
}

so that the linker relaxations still have something to do.

I had a look at ld relaxing some time ago, and I must admit that
I don't understand completely what they are doing.  Not much comments
and explanations there, basically a copy+paste from some other target
from decades ago...
Can't speak for the avr implementation, but in general, yes, odds are it was copied from some other target eons ago with minimal documentation.

The basics are straightforward.  The devil is in all the details.  It's been years since I've done any linker relaxing, but I've been immersed in it in the past.  I tried to comment my implementation, both in terms of the code sequences for the target and the interactions with the BFD data structures.

One job for Binutils could be optimizing fixed registers like in

char mul3 (char a, char b, char c)
{
    return a * b * c;
}

mul3:
        mul r22,r20      ;  21  [c=12 l=3]  *mulqi3_enh
        mov r22,r0
        clr r1
        mul r22,r24      ;  22  [c=12 l=3]  *mulqi3_enh
        mov r24,r0
        clr r1
        ret              ;  25  [c=0 l=1]  return

The first "clr r1" is void due to the following mul.
Just like GCC PR20296, the only feasible solution is by letting Binutils
do the job.  But I have no idea how to adjust branches without labels
like RJMP .+20 that cross an instruction that's optimized out.

Johann

Linker relaxing would be ADD.lo8 + ADC.hi8 => ADD.hi8 which affects
condition code.
In which case it'd only be safe if you knew that CC died before being used.

jeff

Reply via email to