Bug ID: 20714
           Summary: [SH] bad @(disp, PC) form in delay slot
           Product: binutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gas
          Assignee: unassigned at sourceware dot org
          Reporter: fenugrec at users dot
  Target Milestone: ---

With gas-2.23 (and I presume, every other version), consider this code :

        bt/s    call_handler
        mov.l   p_orig, r2


        .long 0x13BEC

The expected result is of course to have the assembler magically replace that
mov.l with the appropriate "mov.l @(disp, PC), Rn" form.

The problem is that, being in the delay slot, any opcode with the @(disp, PC)
offset actually does the access with the value PC = PC_of_branch_target + 2.

This is documented in the SH docs, and there's even an example:
(from REJ09B0316-0200 SH-2E software manual)

100A      BRA NEXT ;Delayed branch instruction
100C      MOV.L @(4,PC),R3 ;R3 = H’12345678

1012 NEXT JMP @R3 ;Branch destination of the BRA instruction
1014      CMP/EQ #0,R0 ;← PC location used for address calculation for the
                     ;MOV.L instruction
          .align 4 ;
1018      .data.l H'12345678 ;

To summarize :
1- the main problem is that the usually helpful syntax "mov.l   <label>, rX"
does not work as expected if placed in a delay slot !

2- further : if the branch opcode is a {braf, bsrf, jmp, jsr, rts, rte}, then
writing "mov.l    <label>, rX"  in their delay slot is asking for trouble,
since usually gas will have no way of knowing the value of PC after the branch.

Workaround for the first sample: manually calculating the displacement will
work, like this:
        mov.l   @(p_orig - call_handler + 2, PC), r2
But ugly.

You are receiving this mail because:
You are on the CC list for the bug.
bug-binutils mailing list

Reply via email to