From ce8ad8721313d288a05a95b62d95ca43db584ebb Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 27 Apr 2017 00:47:15 +0100 Subject: [PATCH] MIPS/GAS: Fix `.option picX' handling with relaxation Correct the handling of `.option pic0' and `.option pic2' GAS pseudo-ops in relaxation and use the setting of `mips_pic' (which these directives control) as at the time a relaxed frag has been created rather than the final `mips_pic' setting at the end of the source file processed. To do so record whether `mips_pic' is NO_PIC or not in the frag itself and use this information throughout relaxation instead of `mips_pic' to decide which of NO_PIC or SVR4_PIC to produce machine code for, fixing code generation and removing a possible fatal failure reproducible with: $ as -32 --relax-branch -o option-pic-relax-3.o option-pic-relax-3.s option-pic-relax-3.s: Assembler messages: option-pic-relax-3.s:7: Warning: relaxed out-of-range branch into a jump option-pic-relax-3.s: Internal error in cvt_frag_to_fill at .../gas/write.c:490. Please report this bug. $ using the test source included, due to a buffer overrun in filling the variable part of a frag. Likewise use the `fx_tcbit2' flag of a BFD_RELOC_16_PCREL_S2 fixup to handle the simple case of substituting an out of range unconditional branch with an equivalent absolute jump in NO_PIC code. Retain the current way of VXWORKS_PIC use, which commit 41a1578ed17c ("MIPS/GAS: Sanitize `.option picX' pseudo-op") has forbidden the use of `.option picX' with. gas/ * config/tc-mips.c (RELAX_ENCODE): Add `PIC' flag. (RELAX_PIC): New macro. (RELAX_USE_SECOND, RELAX_SECOND_LONGER, RELAX_NOMACRO) (RELAX_DELAY_SLOT, RELAX_DELAY_SLOT_16BIT) (RELAX_DELAY_SLOT_SIZE_FIRST, RELAX_DELAY_SLOT_SIZE_SECOND): Shift bits. (RELAX_BRANCH_ENCODE): Add `pic' flag. (RELAX_BRANCH_UNCOND, RELAX_BRANCH_LIKELY, RELAX_BRANCH_LINK) (RELAX_BRANCH_TOOFAR): Shift bits. (RELAX_BRANCH_PIC): New macro. (RELAX_MICROMIPS_ENCODE): Add `pic' flag. (RELAX_MICROMIPS_PIC): New macro. (RELAX_MICROMIPS_UNCOND, RELAX_MICROMIPS_COMPACT) (RELAX_MICROMIPS_LINK, RELAX_MICROMIPS_NODS) (RELAX_MICROMIPS_RELAX32): Shift bits. (relax_close_frag): Pass `mips_pic' setting to RELAX_ENCODE. (append_insn): Pass `mips_pic' setting to RELAX_BRANCH_ENCODE and RELAX_MICROMIPS_ENCODE, and record it in `fx_tcbit2' of the first fixup created. (md_apply_fix) : Use `fx_tcbit2' of the fixup processed rather than `mips_pic' in choosing to relax an out of range branch to a jump. (relaxed_branch_length): Use the `pic' flag of the relaxed frag rather than `mips_pic'. (relaxed_micromips_32bit_branch_length): Likewise. (md_estimate_size_before_relax): Likewise. (md_convert_frag): Likewise. * testsuite/gas/mips/option-pic-relax-0.d: New test. * testsuite/gas/mips/option-pic-relax-1.d: New test. * testsuite/gas/mips/option-pic-relax-2.d: New test. * testsuite/gas/mips/option-pic-relax-3.d: New test. * testsuite/gas/mips/option-pic-relax-3a.d: New test. * testsuite/gas/mips/option-pic-relax-4.d: New test. * testsuite/gas/mips/option-pic-relax-5.d: New test. * testsuite/gas/mips/option-pic-relax-2.l: New stderr output. * testsuite/gas/mips/option-pic-relax-3.l: New stderr output. * testsuite/gas/mips/option-pic-relax-4.l: New stderr output. * testsuite/gas/mips/option-pic-relax-5.l: New stderr output. * testsuite/gas/mips/option-pic-relax-0.s: New test source. * testsuite/gas/mips/option-pic-relax-1.s: New test source. * testsuite/gas/mips/option-pic-relax-2.s: New test source. * testsuite/gas/mips/option-pic-relax-3.s: New test source. * testsuite/gas/mips/option-pic-relax-4.s: New test source. * testsuite/gas/mips/option-pic-relax-5.s: New test source. * testsuite/gas/mips/mips.exp: Run the new tests. --- gas/ChangeLog | 49 ++++++++ gas/config/tc-mips.c | 120 +++++++++++-------- gas/testsuite/gas/mips/mips.exp | 7 ++ gas/testsuite/gas/mips/option-pic-relax-0.d | 21 ++++ gas/testsuite/gas/mips/option-pic-relax-0.s | 15 +++ gas/testsuite/gas/mips/option-pic-relax-1.d | 18 +++ gas/testsuite/gas/mips/option-pic-relax-1.s | 12 ++ gas/testsuite/gas/mips/option-pic-relax-2.d | 28 +++++ gas/testsuite/gas/mips/option-pic-relax-2.l | 2 + gas/testsuite/gas/mips/option-pic-relax-2.s | 19 +++ gas/testsuite/gas/mips/option-pic-relax-3.d | 20 ++++ gas/testsuite/gas/mips/option-pic-relax-3.l | 2 + gas/testsuite/gas/mips/option-pic-relax-3.s | 16 +++ gas/testsuite/gas/mips/option-pic-relax-3a.d | 9 ++ gas/testsuite/gas/mips/option-pic-relax-4.d | 28 +++++ gas/testsuite/gas/mips/option-pic-relax-4.l | 2 + gas/testsuite/gas/mips/option-pic-relax-4.s | 20 ++++ gas/testsuite/gas/mips/option-pic-relax-5.d | 20 ++++ gas/testsuite/gas/mips/option-pic-relax-5.l | 2 + gas/testsuite/gas/mips/option-pic-relax-5.s | 17 +++ 20 files changed, 375 insertions(+), 52 deletions(-) create mode 100644 gas/testsuite/gas/mips/option-pic-relax-0.d create mode 100644 gas/testsuite/gas/mips/option-pic-relax-0.s create mode 100644 gas/testsuite/gas/mips/option-pic-relax-1.d create mode 100644 gas/testsuite/gas/mips/option-pic-relax-1.s create mode 100644 gas/testsuite/gas/mips/option-pic-relax-2.d create mode 100644 gas/testsuite/gas/mips/option-pic-relax-2.l create mode 100644 gas/testsuite/gas/mips/option-pic-relax-2.s create mode 100644 gas/testsuite/gas/mips/option-pic-relax-3.d create mode 100644 gas/testsuite/gas/mips/option-pic-relax-3.l create mode 100644 gas/testsuite/gas/mips/option-pic-relax-3.s create mode 100644 gas/testsuite/gas/mips/option-pic-relax-3a.d create mode 100644 gas/testsuite/gas/mips/option-pic-relax-4.d create mode 100644 gas/testsuite/gas/mips/option-pic-relax-4.l create mode 100644 gas/testsuite/gas/mips/option-pic-relax-4.s create mode 100644 gas/testsuite/gas/mips/option-pic-relax-5.d create mode 100644 gas/testsuite/gas/mips/option-pic-relax-5.l create mode 100644 gas/testsuite/gas/mips/option-pic-relax-5.s diff --git a/gas/ChangeLog b/gas/ChangeLog index ded300db80f..6156e1e4296 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,52 @@ +2017-04-26 Maciej W. Rozycki + + * config/tc-mips.c (RELAX_ENCODE): Add `PIC' flag. + (RELAX_PIC): New macro. + (RELAX_USE_SECOND, RELAX_SECOND_LONGER, RELAX_NOMACRO) + (RELAX_DELAY_SLOT, RELAX_DELAY_SLOT_16BIT) + (RELAX_DELAY_SLOT_SIZE_FIRST, RELAX_DELAY_SLOT_SIZE_SECOND): + Shift bits. + (RELAX_BRANCH_ENCODE): Add `pic' flag. + (RELAX_BRANCH_UNCOND, RELAX_BRANCH_LIKELY, RELAX_BRANCH_LINK) + (RELAX_BRANCH_TOOFAR): Shift bits. + (RELAX_BRANCH_PIC): New macro. + (RELAX_MICROMIPS_ENCODE): Add `pic' flag. + (RELAX_MICROMIPS_PIC): New macro. + (RELAX_MICROMIPS_UNCOND, RELAX_MICROMIPS_COMPACT) + (RELAX_MICROMIPS_LINK, RELAX_MICROMIPS_NODS) + (RELAX_MICROMIPS_RELAX32): Shift bits. + (relax_close_frag): Pass `mips_pic' setting to RELAX_ENCODE. + (append_insn): Pass `mips_pic' setting to RELAX_BRANCH_ENCODE + and RELAX_MICROMIPS_ENCODE, and record it in `fx_tcbit2' of the + first fixup created. + (md_apply_fix) : Use `fx_tcbit2' of the + fixup processed rather than `mips_pic' in choosing to relax an + out of range branch to a jump. + (relaxed_branch_length): Use the `pic' flag of the relaxed frag + rather than `mips_pic'. + (relaxed_micromips_32bit_branch_length): Likewise. + (md_estimate_size_before_relax): Likewise. + (md_convert_frag): Likewise. + + * testsuite/gas/mips/option-pic-relax-0.d: New test. + * testsuite/gas/mips/option-pic-relax-1.d: New test. + * testsuite/gas/mips/option-pic-relax-2.d: New test. + * testsuite/gas/mips/option-pic-relax-3.d: New test. + * testsuite/gas/mips/option-pic-relax-3a.d: New test. + * testsuite/gas/mips/option-pic-relax-4.d: New test. + * testsuite/gas/mips/option-pic-relax-5.d: New test. + * testsuite/gas/mips/option-pic-relax-2.l: New stderr output. + * testsuite/gas/mips/option-pic-relax-3.l: New stderr output. + * testsuite/gas/mips/option-pic-relax-4.l: New stderr output. + * testsuite/gas/mips/option-pic-relax-5.l: New stderr output. + * testsuite/gas/mips/option-pic-relax-0.s: New test source. + * testsuite/gas/mips/option-pic-relax-1.s: New test source. + * testsuite/gas/mips/option-pic-relax-2.s: New test source. + * testsuite/gas/mips/option-pic-relax-3.s: New test source. + * testsuite/gas/mips/option-pic-relax-4.s: New test source. + * testsuite/gas/mips/option-pic-relax-5.s: New test source. + * testsuite/gas/mips/mips.exp: Run the new tests. + 2017-04-25 Claudiu Zissulescu * testsuite/gas/arc/leave_enter.d: Update test. diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index da8e9ab2718..1df1f86ebea 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -967,6 +967,9 @@ static bfd_boolean mips_ignore_branch_isa; can be extracted using RELAX_FIRST() and RELAX_SECOND(). In addition, the subtype has the following flags: + RELAX_PIC + Set if generating PIC code. + RELAX_USE_SECOND Set if it has been decided that we should use the second sequence instead of the first. @@ -1008,17 +1011,19 @@ static bfd_boolean mips_ignore_branch_isa; The code and fixups for the unwanted alternative are discarded by md_convert_frag. */ -#define RELAX_ENCODE(FIRST, SECOND) (((FIRST) << 8) | (SECOND)) +#define RELAX_ENCODE(FIRST, SECOND, PIC) \ + (((FIRST) << 8) | (SECOND) | ((PIC) ? 0x10000 : 0)) #define RELAX_FIRST(X) (((X) >> 8) & 0xff) #define RELAX_SECOND(X) ((X) & 0xff) -#define RELAX_USE_SECOND 0x10000 -#define RELAX_SECOND_LONGER 0x20000 -#define RELAX_NOMACRO 0x40000 -#define RELAX_DELAY_SLOT 0x80000 -#define RELAX_DELAY_SLOT_16BIT 0x100000 -#define RELAX_DELAY_SLOT_SIZE_FIRST 0x200000 -#define RELAX_DELAY_SLOT_SIZE_SECOND 0x400000 +#define RELAX_PIC(X) (((X) & 0x10000) != 0) +#define RELAX_USE_SECOND 0x20000 +#define RELAX_SECOND_LONGER 0x40000 +#define RELAX_NOMACRO 0x80000 +#define RELAX_DELAY_SLOT 0x100000 +#define RELAX_DELAY_SLOT_16BIT 0x200000 +#define RELAX_DELAY_SLOT_SIZE_FIRST 0x400000 +#define RELAX_DELAY_SLOT_SIZE_SECOND 0x800000 /* Branch without likely bit. If label is out of range, we turn: @@ -1087,19 +1092,22 @@ static bfd_boolean mips_ignore_branch_isa; but it's not clear that it would actually improve performance. */ -#define RELAX_BRANCH_ENCODE(at, uncond, likely, link, toofar) \ +#define RELAX_BRANCH_ENCODE(at, pic, \ + uncond, likely, link, toofar) \ ((relax_substateT) \ (0xc0000000 \ | ((at) & 0x1f) \ - | ((toofar) ? 0x20 : 0) \ - | ((link) ? 0x40 : 0) \ - | ((likely) ? 0x80 : 0) \ - | ((uncond) ? 0x100 : 0))) + | ((pic) ? 0x20 : 0) \ + | ((toofar) ? 0x40 : 0) \ + | ((link) ? 0x80 : 0) \ + | ((likely) ? 0x100 : 0) \ + | ((uncond) ? 0x200 : 0))) #define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000) -#define RELAX_BRANCH_UNCOND(i) (((i) & 0x100) != 0) -#define RELAX_BRANCH_LIKELY(i) (((i) & 0x80) != 0) -#define RELAX_BRANCH_LINK(i) (((i) & 0x40) != 0) -#define RELAX_BRANCH_TOOFAR(i) (((i) & 0x20) != 0) +#define RELAX_BRANCH_UNCOND(i) (((i) & 0x200) != 0) +#define RELAX_BRANCH_LIKELY(i) (((i) & 0x100) != 0) +#define RELAX_BRANCH_LINK(i) (((i) & 0x80) != 0) +#define RELAX_BRANCH_TOOFAR(i) (((i) & 0x40) != 0) +#define RELAX_BRANCH_PIC(i) (((i) & 0x20) != 0) #define RELAX_BRANCH_AT(i) ((i) & 0x1f) /* For mips16 code, we use an entirely different form of relaxation. @@ -1164,36 +1172,38 @@ static bfd_boolean mips_ignore_branch_isa; instructions is enabled, and whether the displacement of a branch is too large to fit as an immediate argument of a 16-bit and a 32-bit branch, respectively. */ -#define RELAX_MICROMIPS_ENCODE(type, at, insn32, \ +#define RELAX_MICROMIPS_ENCODE(type, at, insn32, pic, \ uncond, compact, link, nods, \ relax32, toofar16, toofar32) \ (0x40000000 \ | ((type) & 0xff) \ | (((at) & 0x1f) << 8) \ | ((insn32) ? 0x2000 : 0) \ - | ((uncond) ? 0x4000 : 0) \ - | ((compact) ? 0x8000 : 0) \ - | ((link) ? 0x10000 : 0) \ - | ((nods) ? 0x20000 : 0) \ - | ((relax32) ? 0x40000 : 0) \ - | ((toofar16) ? 0x80000 : 0) \ - | ((toofar32) ? 0x100000 : 0)) + | ((pic) ? 0x4000 : 0) \ + | ((uncond) ? 0x8000 : 0) \ + | ((compact) ? 0x10000 : 0) \ + | ((link) ? 0x20000 : 0) \ + | ((nods) ? 0x40000 : 0) \ + | ((relax32) ? 0x80000 : 0) \ + | ((toofar16) ? 0x100000 : 0) \ + | ((toofar32) ? 0x200000 : 0)) #define RELAX_MICROMIPS_P(i) (((i) & 0xc0000000) == 0x40000000) #define RELAX_MICROMIPS_TYPE(i) ((i) & 0xff) #define RELAX_MICROMIPS_AT(i) (((i) >> 8) & 0x1f) #define RELAX_MICROMIPS_INSN32(i) (((i) & 0x2000) != 0) -#define RELAX_MICROMIPS_UNCOND(i) (((i) & 0x4000) != 0) -#define RELAX_MICROMIPS_COMPACT(i) (((i) & 0x8000) != 0) -#define RELAX_MICROMIPS_LINK(i) (((i) & 0x10000) != 0) -#define RELAX_MICROMIPS_NODS(i) (((i) & 0x20000) != 0) -#define RELAX_MICROMIPS_RELAX32(i) (((i) & 0x40000) != 0) - -#define RELAX_MICROMIPS_TOOFAR16(i) (((i) & 0x80000) != 0) -#define RELAX_MICROMIPS_MARK_TOOFAR16(i) ((i) | 0x80000) -#define RELAX_MICROMIPS_CLEAR_TOOFAR16(i) ((i) & ~0x80000) -#define RELAX_MICROMIPS_TOOFAR32(i) (((i) & 0x100000) != 0) -#define RELAX_MICROMIPS_MARK_TOOFAR32(i) ((i) | 0x100000) -#define RELAX_MICROMIPS_CLEAR_TOOFAR32(i) ((i) & ~0x100000) +#define RELAX_MICROMIPS_PIC(i) (((i) & 0x4000) != 0) +#define RELAX_MICROMIPS_UNCOND(i) (((i) & 0x8000) != 0) +#define RELAX_MICROMIPS_COMPACT(i) (((i) & 0x10000) != 0) +#define RELAX_MICROMIPS_LINK(i) (((i) & 0x20000) != 0) +#define RELAX_MICROMIPS_NODS(i) (((i) & 0x40000) != 0) +#define RELAX_MICROMIPS_RELAX32(i) (((i) & 0x80000) != 0) + +#define RELAX_MICROMIPS_TOOFAR16(i) (((i) & 0x100000) != 0) +#define RELAX_MICROMIPS_MARK_TOOFAR16(i) ((i) | 0x100000) +#define RELAX_MICROMIPS_CLEAR_TOOFAR16(i) ((i) & ~0x100000) +#define RELAX_MICROMIPS_TOOFAR32(i) (((i) & 0x200000) != 0) +#define RELAX_MICROMIPS_MARK_TOOFAR32(i) ((i) | 0x200000) +#define RELAX_MICROMIPS_CLEAR_TOOFAR32(i) ((i) & ~0x200000) /* Sign-extend 16-bit value X. */ #define SEXT_16BIT(X) ((((X) + 0x8000) & 0xffff) - 0x8000) @@ -4345,7 +4355,8 @@ relax_close_frag (void) { mips_macro_warning.first_frag = frag_now; frag_var (rs_machine_dependent, 0, 0, - RELAX_ENCODE (mips_relax.sizes[0], mips_relax.sizes[1]), + RELAX_ENCODE (mips_relax.sizes[0], mips_relax.sizes[1], + mips_pic != NO_PIC), mips_relax.symbol, 0, (char *) mips_relax.first_fixup); memset (&mips_relax.sizes, 0, sizeof (mips_relax.sizes)); @@ -7332,7 +7343,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr, : branch_likely_p (ip) ? 1 : 0)), 4, RELAX_BRANCH_ENCODE - (AT, + (AT, mips_pic != NO_PIC, uncond_branch_p (ip), branch_likely_p (ip), pinfo & INSN_WRITE_GPR_31, @@ -7369,6 +7380,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr, length32 = relaxed_micromips_32bit_branch_length (NULL, NULL, uncond); add_relaxed_insn (ip, length32, relax16 ? 2 : 4, RELAX_MICROMIPS_ENCODE (type, AT, mips_opts.insn32, + mips_pic != NO_PIC, uncond, compact, al, nods, relax32, 0, 0), address_expr->X_add_symbol, @@ -7490,6 +7502,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr, address_expr, howto0 && howto0->pc_relative, final_type[0]); + /* Record non-PIC mode in `fx_tcbit2' for `md_apply_fix'. */ + ip->fixp[0]->fx_tcbit2 = mips_pic == NO_PIC; /* Tag symbols that have a R_MIPS16_26 relocation against them. */ if (final_type[0] == BFD_RELOC_MIPS16_JMP && ip->fixp[0]->fx_addsy) @@ -15582,7 +15596,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) insn |= (*valP >> 2) & 0xffff; write_insn (buf, insn); } - else if (mips_pic == NO_PIC + else if (fixP->fx_tcbit2 && fixP->fx_done && fixP->fx_frag->fr_address >= text_section->vma && (fixP->fx_frag->fr_address @@ -17339,6 +17353,7 @@ relaxed_branch_length (fragS *fragp, asection *sec, int update) if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype)) fragp->fr_subtype = RELAX_BRANCH_ENCODE (RELAX_BRANCH_AT (fragp->fr_subtype), + RELAX_BRANCH_PIC (fragp->fr_subtype), RELAX_BRANCH_UNCOND (fragp->fr_subtype), RELAX_BRANCH_LIKELY (fragp->fr_subtype), RELAX_BRANCH_LINK (fragp->fr_subtype), @@ -17350,7 +17365,7 @@ relaxed_branch_length (fragS *fragp, asection *sec, int update) if (fragp ? RELAX_BRANCH_LIKELY (fragp->fr_subtype) : (update > 0)) length += 8; - if (mips_pic != NO_PIC) + if (!fragp || RELAX_BRANCH_PIC (fragp->fr_subtype)) { /* Additional space for PIC loading of target address. */ length += 8; @@ -17393,6 +17408,7 @@ relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update) { bfd_boolean insn32 = TRUE; bfd_boolean nods = TRUE; + bfd_boolean pic = TRUE; bfd_boolean al = TRUE; int short_insn_size; bfd_boolean toofar; @@ -17402,6 +17418,7 @@ relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update) { insn32 = RELAX_MICROMIPS_INSN32 (fragp->fr_subtype); nods = RELAX_MICROMIPS_NODS (fragp->fr_subtype); + pic = RELAX_MICROMIPS_PIC (fragp->fr_subtype); al = RELAX_MICROMIPS_LINK (fragp->fr_subtype); } short_insn_size = insn32 ? 4 : 2; @@ -17464,7 +17481,7 @@ relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update) # compact && (!PIC || insn32) 0: */ - if ((mips_pic == NO_PIC || insn32) && (!compact_known || compact)) + if ((!pic || insn32) && (!compact_known || compact)) length += short_insn_size; /* If assembling PIC code, we further turn: @@ -17477,12 +17494,12 @@ relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update) d/addiu at, %lo(label) # 4 bytes jr/c at # 2/4 bytes */ - if (mips_pic != NO_PIC) + if (pic) length += 4 + short_insn_size; /* Add an extra nop if the jump has no compact form and we need to fill the delay slot. */ - if ((mips_pic == NO_PIC || al) && nods) + if ((!pic || al) && nods) length += (fragp ? frag_branch_delay_slot_size (fragp, al, short_insn_size) : short_insn_size); @@ -17597,15 +17614,13 @@ md_estimate_size_before_relax (fragS *fragp, asection *segtype) return length; } - if (mips_pic == NO_PIC) - change = nopic_need_relax (fragp->fr_symbol, 0); - else if (mips_pic == SVR4_PIC) - change = pic_need_relax (fragp->fr_symbol); - else if (mips_pic == VXWORKS_PIC) + if (mips_pic == VXWORKS_PIC) /* For vxworks, GOT16 relocations never have a corresponding LO16. */ change = 0; + else if (RELAX_PIC (fragp->fr_subtype)) + change = pic_need_relax (fragp->fr_symbol); else - abort (); + change = nopic_need_relax (fragp->fr_symbol, 0); if (change) { @@ -17988,7 +18003,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp) } uncond: - if (mips_pic == NO_PIC) + if (!RELAX_BRANCH_PIC (fragp->fr_subtype)) { /* j or jal. */ insn = (RELAX_BRANCH_LINK (fragp->fr_subtype) @@ -18066,6 +18081,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp) bfd_boolean compact = RELAX_MICROMIPS_COMPACT (fragp->fr_subtype); bfd_boolean insn32 = RELAX_MICROMIPS_INSN32 (fragp->fr_subtype); bfd_boolean nods = RELAX_MICROMIPS_NODS (fragp->fr_subtype); + bfd_boolean pic = RELAX_MICROMIPS_PIC (fragp->fr_subtype); bfd_boolean al = RELAX_MICROMIPS_LINK (fragp->fr_subtype); int type = RELAX_MICROMIPS_TYPE (fragp->fr_subtype); bfd_boolean short_ds; @@ -18241,7 +18257,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp) } } - if (mips_pic == NO_PIC) + if (!pic) { unsigned long jal = (short_ds || nods ? 0x74000000 : 0xf4000000); /* jal/s */ diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index 31a4075fade..30e2342a977 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -1800,6 +1800,13 @@ if { [istarget mips*-*-vxworks*] } { "MIPS invalid PIC option in VxWorks PIC" run_list_test "option-pic-vxworks-2" "-mvxworks-pic" \ "MIPS invalid switch to SVR4 PIC from VxWorks PIC" + run_dump_test "option-pic-relax-0" + run_dump_test "option-pic-relax-1" + run_dump_test "option-pic-relax-2" + run_dump_test "option-pic-relax-3" + run_dump_test "option-pic-relax-3a" + run_dump_test "option-pic-relax-4" + run_dump_test "option-pic-relax-5" run_dump_test_arches "isa-override-1" "" [mips_arch_list_matching mips1] run_list_test_arches "isa-override-2" "-32" [mips_arch_list_matching mips1] diff --git a/gas/testsuite/gas/mips/option-pic-relax-0.d b/gas/testsuite/gas/mips/option-pic-relax-0.d new file mode 100644 index 00000000000..141cc5dc8ee --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-0.d @@ -0,0 +1,21 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS `.option picX' with relaxation 0 +#as: -32 + +# Verify that relaxation is done according to the `.option picX' setting +# at the time the relevant instruction was assembled rather than at +# relaxation time. + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 3c1c0000 lui gp,0x0 +[ ]*[0-9a-f]+: R_MIPS_HI16 _gp_disp +[0-9a-f]+ <[^>]*> 279c0000 addiu gp,gp,0 +[ ]*[0-9a-f]+: R_MIPS_LO16 _gp_disp +[0-9a-f]+ <[^>]*> 0399e021 addu gp,gp,t9 +[0-9a-f]+ <[^>]*> 8f820000 lw v0,0\(gp\) +[ ]*[0-9a-f]+: R_MIPS_GOT16 bar +[0-9a-f]+ <[^>]*> 03e00008 jr ra +[0-9a-f]+ <[^>]*> 00000000 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/option-pic-relax-0.s b/gas/testsuite/gas/mips/option-pic-relax-0.s new file mode 100644 index 00000000000..65864020245 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-0.s @@ -0,0 +1,15 @@ + .text + .ent foo + .option pic2 +foo: + .set noreorder + .cpload $25 + .set reorder + la $2, bar + jr $31 + .option pic0 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/gas/testsuite/gas/mips/option-pic-relax-1.d b/gas/testsuite/gas/mips/option-pic-relax-1.d new file mode 100644 index 00000000000..dd68fc8c96b --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-1.d @@ -0,0 +1,18 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS `.option picX' with relaxation 1 +#as: -32 + +# Verify that relaxation is done according to the `.option picX' setting +# at the time the relevant instruction was assembled rather than at +# relaxation time. + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 3c020000 lui v0,0x0 +[ ]*[0-9a-f]+: R_MIPS_HI16 bar +[0-9a-f]+ <[^>]*> 24420000 addiu v0,v0,0 +[ ]*[0-9a-f]+: R_MIPS_LO16 bar +[0-9a-f]+ <[^>]*> 03e00008 jr ra +[0-9a-f]+ <[^>]*> 00000000 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/option-pic-relax-1.s b/gas/testsuite/gas/mips/option-pic-relax-1.s new file mode 100644 index 00000000000..dda5e569f91 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-1.s @@ -0,0 +1,12 @@ + .text + .ent foo + .option pic0 +foo: + la $2, bar + jr $31 + .option pic2 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/gas/testsuite/gas/mips/option-pic-relax-2.d b/gas/testsuite/gas/mips/option-pic-relax-2.d new file mode 100644 index 00000000000..6c2d9f4d299 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-2.d @@ -0,0 +1,28 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS `.option picX' with relaxation 2 +#as: -32 -mips2 --relax-branch +#stderr: option-pic-relax-2.l + +# Verify that relaxation is done according to the `.option picX' setting +# at the time the relevant instruction was assembled rather than at +# relaxation time. + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 3c1c0000 lui gp,0x0 +[ ]*[0-9a-f]+: R_MIPS_HI16 _gp_disp +[0-9a-f]+ <[^>]*> 279c0000 addiu gp,gp,0 +[ ]*[0-9a-f]+: R_MIPS_LO16 _gp_disp +[0-9a-f]+ <[^>]*> 0399e021 addu gp,gp,t9 +[0-9a-f]+ <[^>]*> 00801025 move v0,a0 +[0-9a-f]+ <[^>]*> 8f810002 lw at,2\(gp\) +[ ]*[0-9a-f]+: R_MIPS_GOT16 \.text +[0-9a-f]+ <[^>]*> 2421001c addiu at,at,28 +[ ]*[0-9a-f]+: R_MIPS_LO16 \.text +[0-9a-f]+ <[^>]*> 00200008 jr at +[0-9a-f]+ <[^>]*> 00a01825 move v1,a1 + \.\.\. +[0-9a-f]+ <[^>]*> 03e00008 jr ra +[0-9a-f]+ <[^>]*> 00000000 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/option-pic-relax-2.l b/gas/testsuite/gas/mips/option-pic-relax-2.l new file mode 100644 index 00000000000..570a78339b7 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-2.l @@ -0,0 +1,2 @@ +.*: Assembler messages: +.*:10: Warning: relaxed out-of-range branch into a jump diff --git a/gas/testsuite/gas/mips/option-pic-relax-2.s b/gas/testsuite/gas/mips/option-pic-relax-2.s new file mode 100644 index 00000000000..41cf65eadcd --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-2.s @@ -0,0 +1,19 @@ + .text + .ent foo + .option pic2 +foo: + .set noreorder + .cpload $25 + .set reorder + move $2, $4 + move $3, $5 + b bar + .space 0x7fff << 2 +bar: + jr $31 + .option pic0 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/gas/testsuite/gas/mips/option-pic-relax-3.d b/gas/testsuite/gas/mips/option-pic-relax-3.d new file mode 100644 index 00000000000..46f90a642a3 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-3.d @@ -0,0 +1,20 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS `.option picX' with relaxation 3 +#as: -32 --relax-branch +#stderr: option-pic-relax-3.l + +# Verify that relaxation is done according to the `.option picX' setting +# at the time the relevant instruction was assembled rather than at +# relaxation time. + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 00801025 move v0,a0 +[0-9a-f]+ <[^>]*> 08008002 j 00020008 <.*> +[ ]*[0-9a-f]+: R_MIPS_26 \.text +[0-9a-f]+ <[^>]*> 00a01825 move v1,a1 + \.\.\. +[0-9a-f]+ <[^>]*> 03e00008 jr ra +[0-9a-f]+ <[^>]*> 00000000 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/option-pic-relax-3.l b/gas/testsuite/gas/mips/option-pic-relax-3.l new file mode 100644 index 00000000000..22a671d60b6 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-3.l @@ -0,0 +1,2 @@ +.*: Assembler messages: +.*:7: Warning: relaxed out-of-range branch into a jump diff --git a/gas/testsuite/gas/mips/option-pic-relax-3.s b/gas/testsuite/gas/mips/option-pic-relax-3.s new file mode 100644 index 00000000000..7aa052d9b19 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-3.s @@ -0,0 +1,16 @@ + .text + .ent foo + .option pic0 +foo: + move $2, $4 + move $3, $5 + b bar + .space 0x7fff << 2 +bar: + jr $31 + .option pic2 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/gas/testsuite/gas/mips/option-pic-relax-3a.d b/gas/testsuite/gas/mips/option-pic-relax-3a.d new file mode 100644 index 00000000000..d6d4088d791 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-3a.d @@ -0,0 +1,9 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS `.option picX' with relaxation 3a +#as: -32 +#source: option-pic-relax-3.s +#dump: option-pic-relax-3.d + +# Verify that relaxation is done according to the `.option picX' setting +# at the time the relevant instruction was assembled rather than at +# relaxation time. diff --git a/gas/testsuite/gas/mips/option-pic-relax-4.d b/gas/testsuite/gas/mips/option-pic-relax-4.d new file mode 100644 index 00000000000..c46f42e79d6 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-4.d @@ -0,0 +1,28 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS `.option picX' with relaxation 4 +#as: -32 -mmicromips --relax-branch +#stderr: option-pic-relax-4.l + +# Verify that relaxation is done according to the `.option picX' setting +# at the time the relevant instruction was assembled rather than at +# relaxation time. + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 41bc 0000 lui gp,0x0 +[ ]*[0-9a-f]+: R_MICROMIPS_HI16 _gp_disp +[0-9a-f]+ <[^>]*> 339c 0000 addiu gp,gp,0 +[ ]*[0-9a-f]+: R_MICROMIPS_LO16 _gp_disp +[0-9a-f]+ <[^>]*> 033c e150 addu gp,gp,t9 +[0-9a-f]+ <[^>]*> 0c44 move v0,a0 +[0-9a-f]+ <[^>]*> fc3c 0001 lw at,1\(gp\) +[ ]*[0-9a-f]+: R_MICROMIPS_GOT16 \.text +[0-9a-f]+ <[^>]*> 3021 0019 addiu at,at,25 +[ ]*[0-9a-f]+: R_MICROMIPS_LO16 \.text +[0-9a-f]+ <[^>]*> 4581 jr at +[0-9a-f]+ <[^>]*> 0c65 move v1,a1 +[0-9a-f]+ <[^>]*> 0c00 nop + \.\.\. +[0-9a-f]+ <[^>]*> 45bf jrc ra + \.\.\. diff --git a/gas/testsuite/gas/mips/option-pic-relax-4.l b/gas/testsuite/gas/mips/option-pic-relax-4.l new file mode 100644 index 00000000000..570a78339b7 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-4.l @@ -0,0 +1,2 @@ +.*: Assembler messages: +.*:10: Warning: relaxed out-of-range branch into a jump diff --git a/gas/testsuite/gas/mips/option-pic-relax-4.s b/gas/testsuite/gas/mips/option-pic-relax-4.s new file mode 100644 index 00000000000..b988d53fef3 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-4.s @@ -0,0 +1,20 @@ + .text + .ent foo + .option pic2 +foo: + .set noreorder + .cpload $25 + .set reorder + move $2, $4 + move $3, $5 + b bar + nop + .space 0x7ffe << 1 +bar: + jr $31 + .option pic0 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/gas/testsuite/gas/mips/option-pic-relax-5.d b/gas/testsuite/gas/mips/option-pic-relax-5.d new file mode 100644 index 00000000000..43e57960228 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-5.d @@ -0,0 +1,20 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS `.option picX' with relaxation 5 +#as: -32 -mmicromips --relax-branch +#stderr: option-pic-relax-5.l + +# Verify that relaxation is done according to the `.option picX' setting +# at the time the relevant instruction was assembled rather than at +# relaxation time. + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 0c44 move v0,a0 +[0-9a-f]+ <[^>]*> d400 0000 j 00000000 +[ ]*[0-9a-f]+: R_MICROMIPS_26_S1 bar +[0-9a-f]+ <[^>]*> 0c65 move v1,a1 +[0-9a-f]+ <[^>]*> 0c00 nop + \.\.\. +[0-9a-f]+ <[^>]*> 45bf jrc ra + \.\.\. diff --git a/gas/testsuite/gas/mips/option-pic-relax-5.l b/gas/testsuite/gas/mips/option-pic-relax-5.l new file mode 100644 index 00000000000..22a671d60b6 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-5.l @@ -0,0 +1,2 @@ +.*: Assembler messages: +.*:7: Warning: relaxed out-of-range branch into a jump diff --git a/gas/testsuite/gas/mips/option-pic-relax-5.s b/gas/testsuite/gas/mips/option-pic-relax-5.s new file mode 100644 index 00000000000..1ab46fa2179 --- /dev/null +++ b/gas/testsuite/gas/mips/option-pic-relax-5.s @@ -0,0 +1,17 @@ + .text + .ent foo + .option pic0 +foo: + move $2, $4 + move $3, $5 + b bar + nop + .space 0x7ffe << 1 +bar: + jr $31 + .option pic2 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 -- 2.30.2