public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Modify Xtensa instruction relaxation
@ 2023-07-31 19:20 daniel
  2023-07-31 19:41 ` Max Filippov
  0 siblings, 1 reply; 6+ messages in thread
From: daniel @ 2023-07-31 19:20 UTC (permalink / raw)
  To: gcc-help

Hi everybody,

I would like to modify the relaxation behavior of Xtensa assembly. 
Furthermore, I only want to modify the last relaxation of a call8 
instruction.

So my question is: how do I know which is the last relaxation in a 
function?

I already know that one of the last relaxations is done in 
convert_frag_immed() in tc-xtensa.c. Can I somehow tell from the segment 
pointer or fragment pointer if I'm at the end of a function?

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modify Xtensa instruction relaxation
  2023-07-31 19:20 Modify Xtensa instruction relaxation daniel
@ 2023-07-31 19:41 ` Max Filippov
  2023-07-31 19:57   ` daniel
  0 siblings, 1 reply; 6+ messages in thread
From: Max Filippov @ 2023-07-31 19:41 UTC (permalink / raw)
  To: daniel; +Cc: gcc-help

Hi Daniel,

On Mon, Jul 31, 2023 at 12:21 PM <daniel@wegemer.com> wrote:
> I would like to modify the relaxation behavior of Xtensa assembly.
> Furthermore, I only want to modify the last relaxation of a call8
> instruction.
>
> So my question is: how do I know which is the last relaxation in a
> function?

Could you elaborate a bit on the "last" part. Last in what sense?

> I already know that one of the last relaxations is done in
> convert_frag_immed() in tc-xtensa.c. Can I somehow tell from the segment
> pointer or fragment pointer if I'm at the end of a function?

I don't think so. On the other hand windowed functions always begin
with the entry instruction and end with either retw or retw.n instruction.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modify Xtensa instruction relaxation
  2023-07-31 19:41 ` Max Filippov
@ 2023-07-31 19:57   ` daniel
  2023-07-31 20:20     ` Max Filippov
  0 siblings, 1 reply; 6+ messages in thread
From: daniel @ 2023-07-31 19:57 UTC (permalink / raw)
  To: Max Filippov; +Cc: gcc-help

On 2023-07-31 21:41, Max Filippov wrote:
> Hi Daniel,
> 
> On Mon, Jul 31, 2023 at 12:21 PM <daniel@wegemer.com> wrote:
>> I would like to modify the relaxation behavior of Xtensa assembly.
>> Furthermore, I only want to modify the last relaxation of a call8
>> instruction.
>> 
>> So my question is: how do I know which is the last relaxation in a
>> function?
> 
> Could you elaborate a bit on the "last" part. Last in what sense?
In case a function calls multiple other functions I would like to be 
able to modify the relaxation of the "last" call8 instruction happening 
in this function.
BTW: I'm compiling with -mlongcalls.

> I don't think so. On the other hand windowed functions always begin
> with the entry instruction and end with either retw or retw.n 
> instruction.
For this I would need to be able to look into the "future". Can I 
traverse fragP->fr_next for that? Does fr_opcode contain the opcode of 
"retw" instructions as well?

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modify Xtensa instruction relaxation
  2023-07-31 19:57   ` daniel
@ 2023-07-31 20:20     ` Max Filippov
  2023-08-03 13:04       ` daniel
  0 siblings, 1 reply; 6+ messages in thread
From: Max Filippov @ 2023-07-31 20:20 UTC (permalink / raw)
  To: daniel; +Cc: gcc-help

On Mon, Jul 31, 2023 at 12:57 PM <daniel@wegemer.com> wrote:
> On 2023-07-31 21:41, Max Filippov wrote:
> > I don't think so. On the other hand windowed functions always begin
> > with the entry instruction and end with either retw or retw.n
> > instruction.
> For this I would need to be able to look into the "future".

It could be done in reverse: keep track of the most recent call instruction
and take an action once retw is seen?

> Can I
> traverse fragP->fr_next for that? Does fr_opcode contain the opcode of
> "retw" instructions as well?

Take a look at the xtensa_mark_narrow_branches, it does this kind
of traversal.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modify Xtensa instruction relaxation
  2023-07-31 20:20     ` Max Filippov
@ 2023-08-03 13:04       ` daniel
  2023-08-03 19:21         ` Max Filippov
  0 siblings, 1 reply; 6+ messages in thread
From: daniel @ 2023-08-03 13:04 UTC (permalink / raw)
  To: Max Filippov; +Cc: gcc-help

Thanks for the pointer! I got it working. I'm currently iterating over 
all FragS pointers in md_convert_frag() to find the one just before 
retw.

But now I'm hitting an assertion in write.c: "Internal error in 
cvt_frag_to_fill"

I checked, its this part of the code:
     gas_assert (fragP->fr_next == NULL || (fragP->fr_next->fr_address - 
fragP->fr_address == fragP->fr_fix));

fr_next seems to be ok, but the difference between fr_address seems to 
be off by 3, fr_fix seems to be 3 higher then the difference of 
fr_address in the current and the next fragP.

Any idea how that can be the case?

All I'm doing is adding an additional instruction in case I'm on the 
last fragment and the current opcode is a call8 and the previous opcode 
was a ldr32. So only the stuff in the if-clause is additional:

static bool
xg_build_to_stack (IStack *istack, TInsn *insn, BuildInstr *bi)
{
     BuildInstr *prev_bi = NULL;

     for (; bi != NULL; bi = bi->next)
     {
        printf("adding new instruction!\n");
        if(bi->opcode == 0x3a && prev_bi->opcode == 0x86 && bi->next == 
NULL) {
             if(istack->is_last_fragment == 1) {
                 TInsn *new_ins = (TInsn *) malloc(sizeof(TInsn));
                 tinsn_init (new_ins);
                 build_wsr_litbase_insn(new_ins);
                 new_ins->debug_line = insn->debug_line;
                 new_ins->loc_directive_seen = insn->loc_directive_seen;
                 istack_push(istack, new_ins);
             }
         }

         TInsn *next_insn = istack_push_space (istack);

         if (!xg_build_to_insn (next_insn, insn, bi))
             return false;

         prev_bi = bi;
     }
     return true;
}

Strangely, if I leave the check for is_last_fragment away, it works.

Thanks.

On 2023-07-31 22:20, Max Filippov wrote:
> On Mon, Jul 31, 2023 at 12:57 PM <daniel@wegemer.com> wrote:
>> On 2023-07-31 21:41, Max Filippov wrote:
>> > I don't think so. On the other hand windowed functions always begin
>> > with the entry instruction and end with either retw or retw.n
>> > instruction.
>> For this I would need to be able to look into the "future".
> 
> It could be done in reverse: keep track of the most recent call 
> instruction
> and take an action once retw is seen?
> 
>> Can I
>> traverse fragP->fr_next for that? Does fr_opcode contain the opcode of
>> "retw" instructions as well?
> 
> Take a look at the xtensa_mark_narrow_branches, it does this kind
> of traversal.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modify Xtensa instruction relaxation
  2023-08-03 13:04       ` daniel
@ 2023-08-03 19:21         ` Max Filippov
  0 siblings, 0 replies; 6+ messages in thread
From: Max Filippov @ 2023-08-03 19:21 UTC (permalink / raw)
  To: daniel; +Cc: gcc-help

On Thu, Aug 3, 2023 at 6:04 AM <daniel@wegemer.com> wrote:
> But now I'm hitting an assertion in write.c: "Internal error in
> cvt_frag_to_fill"
>
> I checked, its this part of the code:
>      gas_assert (fragP->fr_next == NULL || (fragP->fr_next->fr_address -
> fragP->fr_address == fragP->fr_fix));
>
> fr_next seems to be ok, but the difference between fr_address seems to
> be off by 3, fr_fix seems to be 3 higher then the difference of
> fr_address in the current and the next fragP.
>
> Any idea how that can be the case?

If you change the frags too late in the process their addresses
may have been used by that time to make decisions like where
to put a literal so it's reachable or whether a trampoline is needed
for a jump.

> Strangely, if I leave the check for is_last_fragment away, it works.

It may fail later in opcode conversion to binary form if new offsets
won't fit, or it may generate code that references wrong addresses.
E.g. try to have a jump around the code that is modified by your
change and see whether the disassembly still looks correct.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-08-03 19:22 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-31 19:20 Modify Xtensa instruction relaxation daniel
2023-07-31 19:41 ` Max Filippov
2023-07-31 19:57   ` daniel
2023-07-31 20:20     ` Max Filippov
2023-08-03 13:04       ` daniel
2023-08-03 19:21         ` Max Filippov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).