https://sourceware.org/bugzilla/show_bug.cgi?id=20714
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 sourceforge.net Target Milestone: --- With gas-2.23 (and I presume, every other version), consider this code : ************************* bt/s call_handler mov.l p_orig, r2 call_handler: rts nop .BALIGN 4 p_orig: .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 bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils