On Fri, 1 Oct 2021, Nelson Ribeiro via Gcc wrote:
> Hello.
>
> Firstly I want to apologize for this long post, but in a way this post also
> is meant for documenting the work that I have done hunting down this issue.
> Secondly I must say that I do not have much insights on the GCC internals,
> only the basic stuff. I know what a function prologue and epilogue is, but
> I am not able to read GIMPLE or RTL for instance...
>
> So I have a C function that basically starts this way (after CPP
> pre-processing):
>
> void e_printf( const charptr ctrl1, ...){
>     int long_flag;
>     int dot_flag;
>     int skip_switch;
>     params_t par;
>     char ch;
>     va_list argp;
>     charptr ctrl = ctrl1;
>     __builtin_va_start(argp,ctrl1);
>     for ( ; *ctrl; ctrl++) {
>     (....)
>
> This C code function when compiled with the GCC version currently in git
> trunk, compiled for target lm32-elf, generates the following assembly code:
> (...)
>  .global e_printf
> .type e_printf, @function
> e_printf:
> addi     sp, sp, -116
> sw       (sp+56), r11
> sw       (sp+52), r12
> sw       (sp+48), r13
> sw       (sp+44), r14
> sw       (sp+40), r15
> sw       (sp+36), r16
> sw       (sp+32), r17
> sw       (sp+28), r18
> sw       (sp+24), r19
> sw       (sp+20), r20
> sw       (sp+16), r21
> sw       (sp+12), r22
> sw       (sp+8), r23
> sw       (sp+4), ra
> lw       r9, (sp+88)
> sw       (sp+92), r2
> sw       (sp+88), r1
> lbu      r1, (r9+0)
> sw       (sp+96), r3
> sw       (sp+100), r4
> sw       (sp+104), r5
> sw       (sp+108), r6
> sw       (sp+112), r7
> sw       (sp+116), r8
> sw       (sp+60), r9
> be     r1,r0,.L1
> (...)
>
> Now this code in part is suboptimal because all 'pushed registers' from r2
> to r8 to the stack are never "poped" back but that is not the issue I am
> referring.
> Assuming that the "const charptr ctrl1" is passed to the function in
> register r1, the following sequence is obviously wrong (the "sw
> (sp+88), r1" instruction should appear first in this small sequence of
> instructions for this snip of code to be correct):
> lw       r9, (sp+88)
> sw       (sp+92), r2
> sw       (sp+88), r1
> lbu      r1, (r9+0)
>
> Something went horrible wrong in this reordering instructions in the stack.

If I were you, I'd look into setting proper alias sets for the
MEMs through which frame and varargs values are stored for lm32.
Grep for set_mem_alias_set in the
prologue/epilogue/varargs-handling expansions of other ports and
perform archeology on the related commits and email-list
traffic.

Then again, that's more or less just a wild hunch.

brgds, H-P

Reply via email to