* MIPS assembler branch relaxations @ 2002-09-14 4:49 Alexandre Oliva 2002-09-14 14:28 ` Daniel Jacobowitz ` (2 more replies) 0 siblings, 3 replies; 28+ messages in thread From: Alexandre Oliva @ 2002-09-14 4:49 UTC (permalink / raw) To: binutils, echristo [-- Attachment #1: Type: text/plain, Size: 258 bytes --] This patch arranges for the MIPS assembler to turn out-of-range branches into jumps. No regressions are introduced in the binutils testsuites for a mips-linux build. Details on how it is done are in comments in the beginning of the patch. Ok to install? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gas-mips-branch-relax.patch --] [-- Type: text/x-patch, Size: 30878 bytes --] Index: gas/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * config/tc-mips.h (mips_relax_frag): Take segment as argument. (md_relax_frag): Adjust macro. * config/tc-mips.c (RELAX_BRANCH_ENCODE, RELAX_BRANCH_P, RELAX_BRANCH_LIKELY, RELAX_BRANCH_LINK, RELAX_BRANCH_TOOBAR): New. (RELAX_MIPS16_P): Adjust. (append_insn): Emit branch to non-constant in a frag_var. (relaxed_branch_length): New function. (md_estimate_size_before_relax): Handle branch frags. (mips_relax_frag): Likewise. (md_convert_frag): Handle branch frags. Index: gas/testsuite/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * gas/mips/mips.exp: Don't xfail relax. * gas/mips/relax.s: Increase coverage. * gas/mips/relax.d: Add expected output. Index: gas/config/tc-mips.h =================================================================== RCS file: /cvs/src/src/gas/config/tc-mips.h,v retrieving revision 1.16 diff -u -p -r1.16 tc-mips.h --- gas/config/tc-mips.h 5 Sep 2002 00:01:18 -0000 1.16 +++ gas/config/tc-mips.h 14 Sep 2002 05:53:26 -0000 @@ -49,8 +49,9 @@ struct expressionS; relocation: */ #define MAX_GPREL_OFFSET (0x7FF0) -#define md_relax_frag(segment, fragp, stretch) mips_relax_frag(fragp, stretch) -extern int mips_relax_frag PARAMS ((struct frag *, long)); +#define md_relax_frag(segment, fragp, stretch) \ + mips_relax_frag(segment, fragp, stretch) +extern int mips_relax_frag PARAMS ((asection *, struct frag *, long)); #define md_undefined_symbol(name) (0) #define md_operand(x) Index: gas/config/tc-mips.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-mips.c,v retrieving revision 1.162 diff -u -p -r1.162 tc-mips.c --- gas/config/tc-mips.c 5 Sep 2002 00:01:18 -0000 1.162 +++ gas/config/tc-mips.c 14 Sep 2002 05:53:33 -0000 @@ -626,6 +626,88 @@ static const unsigned int mips16_to_32_r #define RELAX_RELOC3(i) (((i) >> 1) & 1) #define RELAX_WARN(i) ((i) & 1) +/* Branch without likely bit. If label is out of range, we turn: + + beq reg1, reg2, label + delay slot + + into + + bne reg1, reg2, 0f + nop + j label + 0: delay slot + + with the following opcode replacements: + + beq <-> bne + blez <-> bgtz + bltz <-> bgez + bc1f <-> bc1t + + bltzal <-> bgezal (with jal label instead of j label) + + Even though keeping the delay slot instruction in the delay slot of + the branch would be more efficient, it would be very tricky to do + correctly, because we'd have to introduce a variable frag *after* + the delay slot instruction, and expand that instead. Let's do it + the easy way for now, even if the branch-not-taken case now costs + one additional instruction. Out-of-range branches are not supposed + to be common, anyway. + + Branch likely. If label is out of range, we turn: + + beql reg1, reg2, label + delay slot (annulled if branch not taken) + + into + + beql reg1, reg2, 1f + nop + beqzl $0, 2f + nop + 1: j[al] label + delay slot (executed only if branch taken) + 2: + + It would be possible to generate a shorter sequence by losing the + likely bit, generating something like: + + bne reg1, reg2, 0f + nop + j[al] label + delay slot (executed only if branch taken) + 0: + + beql -> bne + bnel -> beq + blezl -> bgtz + bgtzl -> blez + bltzl -> bgez + bgezl -> bltz + bc1fl -> bc1t + bc1tl -> bc1f + + bltzall -> bgezal (with jal label instead of j label) + bgezall -> bltzal (ditto) + + + but it's not clear that it would actually improve performance. */ +#define RELAX_BRANCH_ENCODE(reloc_s2, uncond, likely, link, toofar) \ + ((relax_substateT) \ + (0xc0000000 \ + | ((toofar) ? 1 : 0) \ + | ((link) ? 2 : 0) \ + | ((likely) ? 4 : 0) \ + | ((uncond) ? 8 : 0) \ + | ((reloc_s2) ? 16 : 0))) +#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000) +#define RELAX_BRANCH_RELOC_S2(i) (((i) & 16) != 0) +#define RELAX_BRANCH_UNCOND(i) (((i) & 8) != 0) +#define RELAX_BRANCH_LIKELY(i) (((i) & 4) != 0) +#define RELAX_BRANCH_LINK(i) (((i) & 2) != 0) +#define RELAX_BRANCH_TOOFAR(i) (((i) & 1)) + /* For mips16 code, we use an entirely different form of relaxation. mips16 supports two versions of most instructions which take immediate values: a small one which takes some small value, and a @@ -653,7 +735,7 @@ static const unsigned int mips16_to_32_r | ((ext) ? 0x200 : 0) \ | ((dslot) ? 0x400 : 0) \ | ((jal_dslot) ? 0x800 : 0)) -#define RELAX_MIPS16_P(i) (((i) & 0x80000000) != 0) +#define RELAX_MIPS16_P(i) (((i) & 0xc0000000) == 0x80000000) #define RELAX_MIPS16_TYPE(i) ((i) & 0xff) #define RELAX_MIPS16_USER_SMALL(i) (((i) & 0x100) != 0) #define RELAX_MIPS16_USER_EXT(i) (((i) & 0x200) != 0) @@ -757,6 +839,7 @@ static void s_mips_weakext PARAMS ((int) static void s_mips_file PARAMS ((int)); static void s_mips_loc PARAMS ((int)); static int mips16_extended_frag PARAMS ((fragS *, asection *, long)); +static int relaxed_branch_length (fragS *, asection *, int); static int validate_mips_insn PARAMS ((const struct mips_opcode *)); static void show PARAMS ((FILE *, const char *, int *, int *)); #ifdef OBJ_ELF @@ -1766,7 +1849,32 @@ append_insn (place, ip, address_expr, re } } - if (*reloc_type > BFD_RELOC_UNUSED) + if (place == NULL + && address_expr + && ((*reloc_type == BFD_RELOC_16_PCREL + && address_expr->X_op != O_constant) + || *reloc_type == BFD_RELOC_16_PCREL_S2) + && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY + || pinfo & INSN_COND_BRANCH_LIKELY) + && !mips_opts.mips16) + { + f = frag_var (rs_machine_dependent, + relaxed_branch_length + (NULL, NULL, + (pinfo & INSN_UNCOND_BRANCH_DELAY) ? -1 + : (pinfo & INSN_COND_BRANCH_LIKELY) ? 1 : 0), 4, + RELAX_BRANCH_ENCODE + (*reloc_type == BFD_RELOC_16_PCREL_S2, + pinfo & INSN_UNCOND_BRANCH_DELAY, + pinfo & INSN_COND_BRANCH_LIKELY, + pinfo & INSN_WRITE_GPR_31, + 0), + address_expr->X_add_symbol, + address_expr->X_add_number, + 0); + *reloc_type = BFD_RELOC_UNUSED; + } + else if (*reloc_type > BFD_RELOC_UNUSED) { /* We need to set up a variant frag. */ assert (mips_opts.mips16 && address_expr != NULL); @@ -12428,6 +12536,74 @@ mips16_extended_frag (fragp, sec, stretc return 0; } +/* Compute the length of a branch sequence, and adjust the + RELAX_BRANCH_TOOFAR bit accordingly. If FRAGP is NULL, the + worst-case length is computed, with UPDATE being used to indicate + whether an unconditional (-1), branch-likely (+1) or regular (0) + branch is to be computed. */ +static int +relaxed_branch_length (fragp, sec, update) + fragS *fragp; + asection *sec; + int update; +{ + boolean toofar; + int length; + + if (fragp + && S_IS_DEFINED (fragp->fr_symbol) + && sec == S_GET_SEGMENT (fragp->fr_symbol)) + { + addressT addr; + offsetT val; + + val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset; + + addr = fragp->fr_address + fragp->fr_fix; + + val -= addr; + + toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2); + } + else if (fragp) + /* If the symbol is not defined or it's in a different segment, + assume the user knows what's going on and emit a short + branch. */ + toofar = false; + else + toofar = true; + + if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype)) + fragp->fr_subtype + = RELAX_BRANCH_ENCODE (RELAX_BRANCH_RELOC_S2 (fragp->fr_subtype), + RELAX_BRANCH_UNCOND (fragp->fr_subtype), + RELAX_BRANCH_LIKELY (fragp->fr_subtype), + RELAX_BRANCH_LINK (fragp->fr_subtype), + toofar); + + length = 4; + if (toofar) + { + if (fragp ? RELAX_BRANCH_LIKELY (fragp->fr_subtype) : (update > 0)) + length += 8; + + if (mips_pic != NO_PIC) + { + /* Additional space for PIC loading of target address. */ + length += 8; + if (mips_opts.isa == ISA_MIPS1) + /* Additional space for $at-stabilizing nop. */ + length += 4; + } + + /* If branch is conditional. */ + if (fragp ? !RELAX_BRANCH_UNCOND (fragp->fr_subtype) : (update >= 0)) + length += 8; + } + + return length; +} + /* Estimate the size of a frag before relaxing. Unless this is the mips16, we are not really relaxing here, and the final size is encoded in the subtype information. For the mips16, we have to @@ -12441,6 +12617,14 @@ md_estimate_size_before_relax (fragp, se int change = 0; boolean linkonce = false; + if (RELAX_BRANCH_P (fragp->fr_subtype)) + { + + fragp->fr_var = relaxed_branch_length (fragp, segtype, false); + + return fragp->fr_var; + } + if (RELAX_MIPS16_P (fragp->fr_subtype)) /* We don't want to modify the EXTENDED bit here; it might get us into infinite loops. We change it only in mips_relax_frag(). */ @@ -12797,10 +12981,20 @@ tc_gen_reloc (section, fixp) the current size of the frag should change. */ int -mips_relax_frag (fragp, stretch) +mips_relax_frag (sec, fragp, stretch) + asection *sec; fragS *fragp; long stretch; { + if (RELAX_BRANCH_P (fragp->fr_subtype)) + { + offsetT old_var = fragp->fr_var; + + fragp->fr_var = relaxed_branch_length (fragp, sec, true); + + return fragp->fr_var - old_var; + } + if (! RELAX_MIPS16_P (fragp->fr_subtype)) return 0; @@ -12832,6 +13026,213 @@ md_convert_frag (abfd, asec, fragp) { int old, new; char *fixptr; + + if (RELAX_BRANCH_P (fragp->fr_subtype)) + { + bfd_byte *buf; + unsigned long insn; + expressionS exp; + fixS *fixp; + + buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix; + + if (target_big_endian) + insn = bfd_getb32 (buf); + else + insn = bfd_getl32 (buf); + + if (!RELAX_BRANCH_TOOFAR (fragp->fr_subtype)) + { + /* We generate a fixup instead of applying it right now + because, if there are linker relaxations, we're going to + need the relocations. */ + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 1, + RELAX_BRANCH_RELOC_S2 (fragp->fr_subtype) + ? BFD_RELOC_16_PCREL_S2 + : BFD_RELOC_16_PCREL); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char *)buf, insn, 4); + buf += 4; + } + else + { + int i; + + if (RELAX_BRANCH_UNCOND (fragp->fr_subtype)) + goto uncond; + + if (!RELAX_BRANCH_LIKELY (fragp->fr_subtype)) + { + /* Reverse the branch. */ + switch ((insn >> 28) & 0xf) + { + case 4: + /* bc[0-3][tf]l? and bc1any[24][ft] instructions can + have the condition reversed by tweaking a single + bit, and their opcodes all have 0x4???????. */ + assert ((insn & 0xf1000000) == 0x41000000); + insn ^= 0x00010000; + break; + + case 0: + /* bltz 0x04000000 bgez 0x04010000 + bltzal 0x04100000 bgezal 0x04110000 */ + assert ((insn & 0xfc0e0000) == 0x04000000); + insn ^= 0x00010000; + break; + + case 1: + /* beq 0x10000000 bne 0x14000000 + blez 0x18000000 bgtz 0x1c000000 */ + insn ^= 0x04000000; + break; + + default: + abort (); + } + } + + if (RELAX_BRANCH_LINK (fragp->fr_subtype)) + { + /* Clear the and-link bit. */ + assert ((insn & 0xfc1c0000) == 0x04100000); + + /* bltzal 0x04100000 bgezal 0x04110000 + bltzall 0x04120000 bgezall 0x04130000 */ + insn &= ~0x00100000; + } + + /* Branch over the branch (if the branch was likely) or the + full jump (not likely case). Compute the offset from the + current instruction to branch to. */ + if (RELAX_BRANCH_LIKELY (fragp->fr_subtype)) + i = 16; + else + { + /* How many bytes in instructions we've already emitted? */ + i = buf - (bfd_byte *)fragp->fr_literal - fragp->fr_fix; + /* How many bytes in instructions from here to the end? */ + i = fragp->fr_var - i; + } + /* Convert to instruction count. */ + i >>= 2; + /* Branch counts from the next instruction. */ + i--; + insn |= i; + /* Branch over the jump. */ + md_number_to_chars ((char *)buf, insn, 4); + buf += 4; + + /* Nop */ + md_number_to_chars ((char*)buf, 0, 4); + buf += 4; + + if (RELAX_BRANCH_LIKELY (fragp->fr_subtype)) + { + /* beqzl $0, 2f */ + insn = 0x50000000; + /* Compute the PC offset from the current instruction to + the end of the variable frag. */ + /* How many bytes in instructions we've already emitted? */ + i = buf - (bfd_byte *)fragp->fr_literal - fragp->fr_fix; + /* How many bytes in instructions from here to the end? */ + i = fragp->fr_var - i; + /* Convert to instruction count. */ + i >>= 2; + /* Don't decrement i, because we want to branch over the + delay slot. */ + + insn |= i; + md_number_to_chars ((char *)buf, insn, 4); + buf += 4; + + md_number_to_chars ((char *)buf, 0, 4); + buf += 4; + } + + uncond: + if (mips_pic == NO_PIC) + { + /* j or jal. */ + insn = (RELAX_BRANCH_LINK (fragp->fr_subtype) + ? 0x0c000000 : 0x08000000); + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 0, BFD_RELOC_MIPS_JMP); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + } + else + { + /* lw/ld $at, <sym>($gp) R_MIPS_GOT16 */ + insn = HAVE_64BIT_ADDRESSES ? 0xdf810000 : 0x8f810000; + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + if (fragp->fr_offset) + { + exp.X_add_symbol = make_expr_symbol (&exp); + exp.X_add_number = 0; + } + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 0, BFD_RELOC_MIPS_GOT16); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + + if (mips_opts.isa == ISA_MIPS1) + { + /* nop */ + md_number_to_chars ((char*)buf, 0, 4); + buf += 4; + } + + /* d/addiu $at, $at, <sym> R_MIPS_LO16 */ + insn = HAVE_64BIT_ADDRESSES ? 0x64210000 : 0x24210000; + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 0, BFD_RELOC_LO16); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + + /* j(al)r $at. */ + if (RELAX_BRANCH_LINK (fragp->fr_subtype)) + insn = 0x0020f809; + else + insn = 0x00200008; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + } + } + + assert (buf == (bfd_byte *)fragp->fr_literal + + fragp->fr_fix + fragp->fr_var); + + fragp->fr_fix += fragp->fr_var; + + return; + } if (RELAX_MIPS16_P (fragp->fr_subtype)) { Index: gas/testsuite/gas/mips/mips.exp =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v retrieving revision 1.40 diff -u -p -r1.40 mips.exp --- gas/testsuite/gas/mips/mips.exp 12 Aug 2002 08:30:50 -0000 1.40 +++ gas/testsuite/gas/mips/mips.exp 14 Sep 2002 05:53:33 -0000 @@ -154,8 +154,6 @@ if { [istarget mips*-*-*] } then { run_dump_test "sb1-ext-mdmx" run_dump_test "sb1-ext-ps" - # It will always fail until someone fixes it. - setup_xfail "mips*-*-*" run_dump_test "relax" run_list_test "illegal" "" Index: gas/testsuite/gas/mips/relax.d =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/relax.d,v retrieving revision 1.1 diff -u -p -r1.1 relax.d --- gas/testsuite/gas/mips/relax.d 9 Jun 2001 06:25:55 -0000 1.1 +++ gas/testsuite/gas/mips/relax.d 14 Sep 2002 05:53:33 -0000 @@ -1,3 +1,4 @@ +#as: -KPIC -mips3 -32 #objdump: -dr --prefix-addresses -mmips:4000 #name: MIPS relax @@ -5,4 +6,389 @@ .*: +file format .*mips.* -Disassembly of section .text: +Disassembly of section \.text: +00000000 <foo> lw at,2\(gp\) + 0: R_MIPS_GOT16 \.text +00000004 <foo\+0x4> addiu at,at,592 + 4: R_MIPS_LO16 \.text +00000008 <foo\+0x8> jr at +0000000c <foo\+0xc> nop +00000010 <foo\+0x10> lw at,2\(gp\) + 10: R_MIPS_GOT16 \.text +00000014 <foo\+0x14> addiu at,at,592 + 14: R_MIPS_LO16 \.text +00000018 <foo\+0x18> jalr at +0000001c <foo\+0x1c> nop +00000020 <foo\+0x20> bne v0,v1,00000034 <foo\+0x34> +00000024 <foo\+0x24> nop +00000028 <foo\+0x28> lw at,2\(gp\) + 28: R_MIPS_GOT16 \.text +0000002c <foo\+0x2c> addiu at,at,592 + 2c: R_MIPS_LO16 \.text +00000030 <foo\+0x30> jr at +00000034 <foo\+0x34> nop +00000038 <foo\+0x38> beq a0,a1,0000004c <foo\+0x4c> +0000003c <foo\+0x3c> nop +00000040 <foo\+0x40> lw at,2\(gp\) + 40: R_MIPS_GOT16 \.text +00000044 <foo\+0x44> addiu at,at,592 + 44: R_MIPS_LO16 \.text +00000048 <foo\+0x48> jr at +0000004c <foo\+0x4c> nop +00000050 <foo\+0x50> bgtz v0,00000064 <foo\+0x64> +00000054 <foo\+0x54> nop +00000058 <foo\+0x58> lw at,2\(gp\) + 58: R_MIPS_GOT16 \.text +0000005c <foo\+0x5c> addiu at,at,592 + 5c: R_MIPS_LO16 \.text +00000060 <foo\+0x60> jr at +00000064 <foo\+0x64> nop +00000068 <foo\+0x68> blez v1,0000007c <foo\+0x7c> +0000006c <foo\+0x6c> nop +00000070 <foo\+0x70> lw at,2\(gp\) + 70: R_MIPS_GOT16 \.text +00000074 <foo\+0x74> addiu at,at,592 + 74: R_MIPS_LO16 \.text +00000078 <foo\+0x78> jr at +0000007c <foo\+0x7c> nop +00000080 <foo\+0x80> bgez a0,00000094 <foo\+0x94> +00000084 <foo\+0x84> nop +00000088 <foo\+0x88> lw at,2\(gp\) + 88: R_MIPS_GOT16 \.text +0000008c <foo\+0x8c> addiu at,at,592 + 8c: R_MIPS_LO16 \.text +00000090 <foo\+0x90> jr at +00000094 <foo\+0x94> nop +00000098 <foo\+0x98> bltz a1,000000ac <foo\+0xac> +0000009c <foo\+0x9c> nop +000000a0 <foo\+0xa0> lw at,2\(gp\) + a0: R_MIPS_GOT16 \.text +000000a4 <foo\+0xa4> addiu at,at,592 + a4: R_MIPS_LO16 \.text +000000a8 <foo\+0xa8> jr at +000000ac <foo\+0xac> nop +000000b0 <foo\+0xb0> bc1t 000000c4 <foo\+0xc4> +000000b4 <foo\+0xb4> nop +000000b8 <foo\+0xb8> lw at,2\(gp\) + b8: R_MIPS_GOT16 \.text +000000bc <foo\+0xbc> addiu at,at,592 + bc: R_MIPS_LO16 \.text +000000c0 <foo\+0xc0> jr at +000000c4 <foo\+0xc4> nop +000000c8 <foo\+0xc8> bc1f 000000dc <foo\+0xdc> +000000cc <foo\+0xcc> nop +000000d0 <foo\+0xd0> lw at,2\(gp\) + d0: R_MIPS_GOT16 \.text +000000d4 <foo\+0xd4> addiu at,at,592 + d4: R_MIPS_LO16 \.text +000000d8 <foo\+0xd8> jr at +000000dc <foo\+0xdc> nop +000000e0 <foo\+0xe0> bgez v0,000000f4 <foo\+0xf4> +000000e4 <foo\+0xe4> nop +000000e8 <foo\+0xe8> lw at,2\(gp\) + e8: R_MIPS_GOT16 \.text +000000ec <foo\+0xec> addiu at,at,592 + ec: R_MIPS_LO16 \.text +000000f0 <foo\+0xf0> jalr at +000000f4 <foo\+0xf4> nop +000000f8 <foo\+0xf8> bltz v1,0000010c <foo\+0x10c> +000000fc <foo\+0xfc> nop +00000100 <foo\+0x100> lw at,2\(gp\) + 100: R_MIPS_GOT16 \.text +00000104 <foo\+0x104> addiu at,at,592 + 104: R_MIPS_LO16 \.text +00000108 <foo\+0x108> jalr at +0000010c <foo\+0x10c> nop +00000110 <foo\+0x110> beql v0,v1,00000120 <foo\+0x120> +00000114 <foo\+0x114> nop +00000118 <foo\+0x118> beqzl zero,00000130 <foo\+0x130> +0000011c <foo\+0x11c> nop +00000120 <foo\+0x120> lw at,2\(gp\) + 120: R_MIPS_GOT16 \.text +00000124 <foo\+0x124> addiu at,at,592 + 124: R_MIPS_LO16 \.text +00000128 <foo\+0x128> jr at +0000012c <foo\+0x12c> nop +00000130 <foo\+0x130> bnel a0,a1,00000140 <foo\+0x140> +00000134 <foo\+0x134> nop +00000138 <foo\+0x138> beqzl zero,00000150 <foo\+0x150> +0000013c <foo\+0x13c> nop +00000140 <foo\+0x140> lw at,2\(gp\) + 140: R_MIPS_GOT16 \.text +00000144 <foo\+0x144> addiu at,at,592 + 144: R_MIPS_LO16 \.text +00000148 <foo\+0x148> jr at +0000014c <foo\+0x14c> nop +00000150 <foo\+0x150> blezl v0,00000160 <foo\+0x160> +00000154 <foo\+0x154> nop +00000158 <foo\+0x158> beqzl zero,00000170 <foo\+0x170> +0000015c <foo\+0x15c> nop +00000160 <foo\+0x160> lw at,2\(gp\) + 160: R_MIPS_GOT16 \.text +00000164 <foo\+0x164> addiu at,at,592 + 164: R_MIPS_LO16 \.text +00000168 <foo\+0x168> jr at +0000016c <foo\+0x16c> nop +00000170 <foo\+0x170> bgtzl v1,00000180 <foo\+0x180> +00000174 <foo\+0x174> nop +00000178 <foo\+0x178> beqzl zero,00000190 <foo\+0x190> +0000017c <foo\+0x17c> nop +00000180 <foo\+0x180> lw at,2\(gp\) + 180: R_MIPS_GOT16 \.text +00000184 <foo\+0x184> addiu at,at,592 + 184: R_MIPS_LO16 \.text +00000188 <foo\+0x188> jr at +0000018c <foo\+0x18c> nop +00000190 <foo\+0x190> bltzl a0,000001a0 <foo\+0x1a0> +00000194 <foo\+0x194> nop +00000198 <foo\+0x198> beqzl zero,000001b0 <foo\+0x1b0> +0000019c <foo\+0x19c> nop +000001a0 <foo\+0x1a0> lw at,2\(gp\) + 1a0: R_MIPS_GOT16 \.text +000001a4 <foo\+0x1a4> addiu at,at,592 + 1a4: R_MIPS_LO16 \.text +000001a8 <foo\+0x1a8> jr at +000001ac <foo\+0x1ac> nop +000001b0 <foo\+0x1b0> bgezl a1,000001c0 <foo\+0x1c0> +000001b4 <foo\+0x1b4> nop +000001b8 <foo\+0x1b8> beqzl zero,000001d0 <foo\+0x1d0> +000001bc <foo\+0x1bc> nop +000001c0 <foo\+0x1c0> lw at,2\(gp\) + 1c0: R_MIPS_GOT16 \.text +000001c4 <foo\+0x1c4> addiu at,at,592 + 1c4: R_MIPS_LO16 \.text +000001c8 <foo\+0x1c8> jr at +000001cc <foo\+0x1cc> nop +000001d0 <foo\+0x1d0> bc1fl 000001e0 <foo\+0x1e0> +000001d4 <foo\+0x1d4> nop +000001d8 <foo\+0x1d8> beqzl zero,000001f0 <foo\+0x1f0> +000001dc <foo\+0x1dc> nop +000001e0 <foo\+0x1e0> lw at,2\(gp\) + 1e0: R_MIPS_GOT16 \.text +000001e4 <foo\+0x1e4> addiu at,at,592 + 1e4: R_MIPS_LO16 \.text +000001e8 <foo\+0x1e8> jr at +000001ec <foo\+0x1ec> nop +000001f0 <foo\+0x1f0> bc1tl 00000200 <foo\+0x200> +000001f4 <foo\+0x1f4> nop +000001f8 <foo\+0x1f8> beqzl zero,00000210 <foo\+0x210> +000001fc <foo\+0x1fc> nop +00000200 <foo\+0x200> lw at,2\(gp\) + 200: R_MIPS_GOT16 \.text +00000204 <foo\+0x204> addiu at,at,592 + 204: R_MIPS_LO16 \.text +00000208 <foo\+0x208> jr at +0000020c <foo\+0x20c> nop +00000210 <foo\+0x210> bltzl v0,00000220 <foo\+0x220> +00000214 <foo\+0x214> nop +00000218 <foo\+0x218> beqzl zero,00000230 <foo\+0x230> +0000021c <foo\+0x21c> nop +00000220 <foo\+0x220> lw at,2\(gp\) + 220: R_MIPS_GOT16 \.text +00000224 <foo\+0x224> addiu at,at,592 + 224: R_MIPS_LO16 \.text +00000228 <foo\+0x228> jalr at +0000022c <foo\+0x22c> nop +00000230 <foo\+0x230> bgezl v1,00000240 <foo\+0x240> +00000234 <foo\+0x234> nop +00000238 <foo\+0x238> beqzl zero,00000250 <foo\+0x250> +0000023c <foo\+0x23c> nop +00000240 <foo\+0x240> lw at,2\(gp\) + 240: R_MIPS_GOT16 \.text +00000244 <foo\+0x244> addiu at,at,592 + 244: R_MIPS_LO16 \.text +00000248 <foo\+0x248> jalr at +0000024c <foo\+0x24c> nop + \.\.\. +00020250 <bar> lw at,0\(gp\) + 20250: R_MIPS_GOT16 \.text +00020254 <bar\+0x4> addiu at,at,0 + 20254: R_MIPS_LO16 \.text +00020258 <bar\+0x8> jr at +0002025c <bar\+0xc> nop +00020260 <bar\+0x10> lw at,0\(gp\) + 20260: R_MIPS_GOT16 \.text +00020264 <bar\+0x14> addiu at,at,0 + 20264: R_MIPS_LO16 \.text +00020268 <bar\+0x18> jalr at +0002026c <bar\+0x1c> nop +00020270 <bar\+0x20> bne v0,v1,00020284 <bar\+0x34> +00020274 <bar\+0x24> nop +00020278 <bar\+0x28> lw at,0\(gp\) + 20278: R_MIPS_GOT16 \.text +0002027c <bar\+0x2c> addiu at,at,0 + 2027c: R_MIPS_LO16 \.text +00020280 <bar\+0x30> jr at +00020284 <bar\+0x34> nop +00020288 <bar\+0x38> beq a0,a1,0002029c <bar\+0x4c> +0002028c <bar\+0x3c> nop +00020290 <bar\+0x40> lw at,0\(gp\) + 20290: R_MIPS_GOT16 \.text +00020294 <bar\+0x44> addiu at,at,0 + 20294: R_MIPS_LO16 \.text +00020298 <bar\+0x48> jr at +0002029c <bar\+0x4c> nop +000202a0 <bar\+0x50> bgtz v0,000202b4 <bar\+0x64> +000202a4 <bar\+0x54> nop +000202a8 <bar\+0x58> lw at,0\(gp\) + 202a8: R_MIPS_GOT16 \.text +000202ac <bar\+0x5c> addiu at,at,0 + 202ac: R_MIPS_LO16 \.text +000202b0 <bar\+0x60> jr at +000202b4 <bar\+0x64> nop +000202b8 <bar\+0x68> blez v1,000202cc <bar\+0x7c> +000202bc <bar\+0x6c> nop +000202c0 <bar\+0x70> lw at,0\(gp\) + 202c0: R_MIPS_GOT16 \.text +000202c4 <bar\+0x74> addiu at,at,0 + 202c4: R_MIPS_LO16 \.text +000202c8 <bar\+0x78> jr at +000202cc <bar\+0x7c> nop +000202d0 <bar\+0x80> bgez a0,000202e4 <bar\+0x94> +000202d4 <bar\+0x84> nop +000202d8 <bar\+0x88> lw at,0\(gp\) + 202d8: R_MIPS_GOT16 \.text +000202dc <bar\+0x8c> addiu at,at,0 + 202dc: R_MIPS_LO16 \.text +000202e0 <bar\+0x90> jr at +000202e4 <bar\+0x94> nop +000202e8 <bar\+0x98> bltz a1,000202fc <bar\+0xac> +000202ec <bar\+0x9c> nop +000202f0 <bar\+0xa0> lw at,0\(gp\) + 202f0: R_MIPS_GOT16 \.text +000202f4 <bar\+0xa4> addiu at,at,0 + 202f4: R_MIPS_LO16 \.text +000202f8 <bar\+0xa8> jr at +000202fc <bar\+0xac> nop +00020300 <bar\+0xb0> bc1t 00020314 <bar\+0xc4> +00020304 <bar\+0xb4> nop +00020308 <bar\+0xb8> lw at,0\(gp\) + 20308: R_MIPS_GOT16 \.text +0002030c <bar\+0xbc> addiu at,at,0 + 2030c: R_MIPS_LO16 \.text +00020310 <bar\+0xc0> jr at +00020314 <bar\+0xc4> nop +00020318 <bar\+0xc8> bc1f 0002032c <bar\+0xdc> +0002031c <bar\+0xcc> nop +00020320 <bar\+0xd0> lw at,0\(gp\) + 20320: R_MIPS_GOT16 \.text +00020324 <bar\+0xd4> addiu at,at,0 + 20324: R_MIPS_LO16 \.text +00020328 <bar\+0xd8> jr at +0002032c <bar\+0xdc> nop +00020330 <bar\+0xe0> bgez v0,00020344 <bar\+0xf4> +00020334 <bar\+0xe4> nop +00020338 <bar\+0xe8> lw at,0\(gp\) + 20338: R_MIPS_GOT16 \.text +0002033c <bar\+0xec> addiu at,at,0 + 2033c: R_MIPS_LO16 \.text +00020340 <bar\+0xf0> jalr at +00020344 <bar\+0xf4> nop +00020348 <bar\+0xf8> bltz v1,0002035c <bar\+0x10c> +0002034c <bar\+0xfc> nop +00020350 <bar\+0x100> lw at,0\(gp\) + 20350: R_MIPS_GOT16 \.text +00020354 <bar\+0x104> addiu at,at,0 + 20354: R_MIPS_LO16 \.text +00020358 <bar\+0x108> jalr at +0002035c <bar\+0x10c> nop +00020360 <bar\+0x110> beql v0,v1,00020370 <bar\+0x120> +00020364 <bar\+0x114> nop +00020368 <bar\+0x118> beqzl zero,00020380 <bar\+0x130> +0002036c <bar\+0x11c> nop +00020370 <bar\+0x120> lw at,0\(gp\) + 20370: R_MIPS_GOT16 \.text +00020374 <bar\+0x124> addiu at,at,0 + 20374: R_MIPS_LO16 \.text +00020378 <bar\+0x128> jr at +0002037c <bar\+0x12c> nop +00020380 <bar\+0x130> bnel a0,a1,00020390 <bar\+0x140> +00020384 <bar\+0x134> nop +00020388 <bar\+0x138> beqzl zero,000203a0 <bar\+0x150> +0002038c <bar\+0x13c> nop +00020390 <bar\+0x140> lw at,0\(gp\) + 20390: R_MIPS_GOT16 \.text +00020394 <bar\+0x144> addiu at,at,0 + 20394: R_MIPS_LO16 \.text +00020398 <bar\+0x148> jr at +0002039c <bar\+0x14c> nop +000203a0 <bar\+0x150> blezl v0,000203b0 <bar\+0x160> +000203a4 <bar\+0x154> nop +000203a8 <bar\+0x158> beqzl zero,000203c0 <bar\+0x170> +000203ac <bar\+0x15c> nop +000203b0 <bar\+0x160> lw at,0\(gp\) + 203b0: R_MIPS_GOT16 \.text +000203b4 <bar\+0x164> addiu at,at,0 + 203b4: R_MIPS_LO16 \.text +000203b8 <bar\+0x168> jr at +000203bc <bar\+0x16c> nop +000203c0 <bar\+0x170> bgtzl v1,000203d0 <bar\+0x180> +000203c4 <bar\+0x174> nop +000203c8 <bar\+0x178> beqzl zero,000203e0 <bar\+0x190> +000203cc <bar\+0x17c> nop +000203d0 <bar\+0x180> lw at,0\(gp\) + 203d0: R_MIPS_GOT16 \.text +000203d4 <bar\+0x184> addiu at,at,0 + 203d4: R_MIPS_LO16 \.text +000203d8 <bar\+0x188> jr at +000203dc <bar\+0x18c> nop +000203e0 <bar\+0x190> bltzl a0,000203f0 <bar\+0x1a0> +000203e4 <bar\+0x194> nop +000203e8 <bar\+0x198> beqzl zero,00020400 <bar\+0x1b0> +000203ec <bar\+0x19c> nop +000203f0 <bar\+0x1a0> lw at,0\(gp\) + 203f0: R_MIPS_GOT16 \.text +000203f4 <bar\+0x1a4> addiu at,at,0 + 203f4: R_MIPS_LO16 \.text +000203f8 <bar\+0x1a8> jr at +000203fc <bar\+0x1ac> nop +00020400 <bar\+0x1b0> bgezl a1,00020410 <bar\+0x1c0> +00020404 <bar\+0x1b4> nop +00020408 <bar\+0x1b8> beqzl zero,00020420 <bar\+0x1d0> +0002040c <bar\+0x1bc> nop +00020410 <bar\+0x1c0> lw at,0\(gp\) + 20410: R_MIPS_GOT16 \.text +00020414 <bar\+0x1c4> addiu at,at,0 + 20414: R_MIPS_LO16 \.text +00020418 <bar\+0x1c8> jr at +0002041c <bar\+0x1cc> nop +00020420 <bar\+0x1d0> bc1fl 00020430 <bar\+0x1e0> +00020424 <bar\+0x1d4> nop +00020428 <bar\+0x1d8> beqzl zero,00020440 <bar\+0x1f0> +0002042c <bar\+0x1dc> nop +00020430 <bar\+0x1e0> lw at,0\(gp\) + 20430: R_MIPS_GOT16 \.text +00020434 <bar\+0x1e4> addiu at,at,0 + 20434: R_MIPS_LO16 \.text +00020438 <bar\+0x1e8> jr at +0002043c <bar\+0x1ec> nop +00020440 <bar\+0x1f0> bc1tl 00020450 <bar\+0x200> +00020444 <bar\+0x1f4> nop +00020448 <bar\+0x1f8> beqzl zero,00020460 <bar\+0x210> +0002044c <bar\+0x1fc> nop +00020450 <bar\+0x200> lw at,0\(gp\) + 20450: R_MIPS_GOT16 \.text +00020454 <bar\+0x204> addiu at,at,0 + 20454: R_MIPS_LO16 \.text +00020458 <bar\+0x208> jr at +0002045c <bar\+0x20c> nop +00020460 <bar\+0x210> bltzl v0,00020470 <bar\+0x220> +00020464 <bar\+0x214> nop +00020468 <bar\+0x218> beqzl zero,00020480 <bar\+0x230> +0002046c <bar\+0x21c> nop +00020470 <bar\+0x220> lw at,0\(gp\) + 20470: R_MIPS_GOT16 \.text +00020474 <bar\+0x224> addiu at,at,0 + 20474: R_MIPS_LO16 \.text +00020478 <bar\+0x228> jalr at +0002047c <bar\+0x22c> nop +00020480 <bar\+0x230> bgezl v1,00020490 <bar\+0x240> +00020484 <bar\+0x234> nop +00020488 <bar\+0x238> beqzl zero,000204a0 <bar\+0x250> +0002048c <bar\+0x23c> nop +00020490 <bar\+0x240> lw at,0\(gp\) + 20490: R_MIPS_GOT16 \.text +00020494 <bar\+0x244> addiu at,at,0 + 20494: R_MIPS_LO16 \.text +00020498 <bar\+0x248> jalr at +0002049c <bar\+0x24c> nop Index: gas/testsuite/gas/mips/relax.s =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/relax.s,v retrieving revision 1.1 diff -u -p -r1.1 relax.s --- gas/testsuite/gas/mips/relax.s 9 Jun 2001 06:25:55 -0000 1.1 +++ gas/testsuite/gas/mips/relax.s 14 Sep 2002 05:53:33 -0000 @@ -2,6 +2,56 @@ .text foo: - move $2, $3 # just something + b bar + bal bar + beq $2, $3, bar + bne $4, $5, bar + blez $2, bar + bgtz $3, bar + bltz $4, bar + bgez $5, bar + bc1f bar + bc1t bar + + bltzal $2, bar + bgezal $3, bar + + beql $2, $3, bar + bnel $4, $5, bar + blezl $2, bar + bgtzl $3, bar + bltzl $4, bar + bgezl $5, bar + bc1fl bar + bc1tl bar + + bltzall $2, bar + bgezall $3, bar + .space 0x20000 # to make a 128kb loop body - beq $2, $3, foo +bar: + b foo + bal foo + beq $2, $3, foo + bne $4, $5, foo + blez $2, foo + bgtz $3, foo + bltz $4, foo + bgez $5, foo + bc1f foo + bc1t foo + + bltzal $2, foo + bgezal $3, foo + + beql $2, $3, foo + bnel $4, $5, foo + blezl $2, foo + bgtzl $3, foo + bltzl $4, foo + bgezl $5, foo + bc1fl foo + bc1tl foo + + bltzall $2, foo + bgezall $3, foo [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 4:49 MIPS assembler branch relaxations Alexandre Oliva @ 2002-09-14 14:28 ` Daniel Jacobowitz 2002-09-14 14:46 ` Eric Christopher ` (3 more replies) 2002-09-14 14:39 ` H. J. Lu 2002-09-15 1:00 ` Alexandre Oliva 2 siblings, 4 replies; 28+ messages in thread From: Daniel Jacobowitz @ 2002-09-14 14:28 UTC (permalink / raw) To: Alexandre Oliva; +Cc: binutils, echristo On Sat, Sep 14, 2002 at 02:59:45AM -0300, Alexandre Oliva wrote: > This patch arranges for the MIPS assembler to turn out-of-range > branches into jumps. No regressions are introduced in the binutils > testsuites for a mips-linux build. Details on how it is done are in > comments in the beginning of the patch. Ok to install? A couple of thoughts: + beql reg1, reg2, 1f + nop + beqzl $0, 2f + nop + 1: j[al] label + delay slot (executed only if branch taken) + 2: Why beqzl? Admittedly, I don't know much about MIPS hardware, but I'd think that just "b" would probably be faster, since that's the normal unconditional branch. + Even though keeping the delay slot instruction in the delay slot of + the branch would be more efficient, it would be very tricky to do + correctly, because we'd have to introduce a variable frag *after* + the delay slot instruction, and expand that instead. Let's do it + the easy way for now, even if the branch-not-taken case now costs + one additional instruction. Out-of-range branches are not supposed + to be common, anyway. If this goes in as-is, I doubt that it'll ever be done the right way. My cynicism speaking. The above aren't really objections, mind - I agree that performance of this isn't important. Just observations. More importantly, because the performance of this is not important or particularly good, it's important to avoid it. When will it trigger? Does it require -relax? [Not sure.] Does it happen inside .set nomacro? [I think so - should it? I'd say not!] I think there should be a command-line option to disable this, and/or warn about it. Most out-of-range branches represent bugs in GCC's calculations of instruction lengths. I know there are some in 3.2, because I've run into them. I don't know if they're fixed in HEAD, and if this goes in I may never find out. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 14:28 ` Daniel Jacobowitz @ 2002-09-14 14:46 ` Eric Christopher 2002-09-14 21:33 ` Daniel Jacobowitz 2002-09-14 15:00 ` Paul Koning ` (2 subsequent siblings) 3 siblings, 1 reply; 28+ messages in thread From: Eric Christopher @ 2002-09-14 14:46 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: Alexandre Oliva, binutils > + Even though keeping the delay slot instruction in the delay slot of > + the branch would be more efficient, it would be very tricky to do > + correctly, because we'd have to introduce a variable frag *after* > + the delay slot instruction, and expand that instead. Let's do it > + the easy way for now, even if the branch-not-taken case now costs > + one additional instruction. Out-of-range branches are not supposed > + to be common, anyway. > > > If this goes in as-is, I doubt that it'll ever be done the right way. > My cynicism speaking. > It's a good comment, however, a couple of other comments: 1) If this bites assembler programmers then they screwed themselves. 2) gcc is going towards .set nomacro, so, hopefully this is just temporary. > > The above aren't really objections, mind - I agree that performance of > this isn't important. Just observations. > > > More importantly, because the performance of this is not important or > particularly good, it's important to avoid it. When will it trigger? > Does it require -relax? [Not sure.] Does it happen inside .set > nomacro? [I think so - should it? I'd say not!] I think there should > be a command-line option to disable this, and/or warn about it. Most > out-of-range branches represent bugs in GCC's calculations of > instruction lengths. I know there are some in 3.2, because I've run > into them. I don't know if they're fixed in HEAD, and if this goes in > I may never find out. > 1) None of the other relaxations require a command line. 2) always. 3) no 4) shouldn't - good catch. 5) not always, macros are partially to blame. 6) you and i had a conversation about this very thing yesterday :) Anyhow, if 4 is I'm pretty happy with it going in. -eric -- Yuppies wear socks. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 14:46 ` Eric Christopher @ 2002-09-14 21:33 ` Daniel Jacobowitz 2002-09-14 21:33 ` Eric Christopher 0 siblings, 1 reply; 28+ messages in thread From: Daniel Jacobowitz @ 2002-09-14 21:33 UTC (permalink / raw) To: binutils On Sat, Sep 14, 2002 at 11:20:35AM -0700, Eric Christopher wrote: > > > + Even though keeping the delay slot instruction in the delay slot of > > + the branch would be more efficient, it would be very tricky to do > > + correctly, because we'd have to introduce a variable frag *after* > > + the delay slot instruction, and expand that instead. Let's do it > > + the easy way for now, even if the branch-not-taken case now costs > > + one additional instruction. Out-of-range branches are not supposed > > + to be common, anyway. > > > > > > If this goes in as-is, I doubt that it'll ever be done the right way. > > My cynicism speaking. > > > > It's a good comment, however, a couple of other comments: > > 1) If this bites assembler programmers then they screwed themselves. > 2) gcc is going towards .set nomacro, so, hopefully this is just > temporary. Fine. > > > > The above aren't really objections, mind - I agree that performance of > > this isn't important. Just observations. > > > > > > More importantly, because the performance of this is not important or > > particularly good, it's important to avoid it. When will it trigger? > > Does it require -relax? [Not sure.] Does it happen inside .set > > nomacro? [I think so - should it? I'd say not!] I think there should > > be a command-line option to disable this, and/or warn about it. Most > > out-of-range branches represent bugs in GCC's calculations of > > instruction lengths. I know there are some in 3.2, because I've run > > into them. I don't know if they're fixed in HEAD, and if this goes in > > I may never find out. > > > > 1) None of the other relaxations require a command line. > 2) always. > 3) no > 4) shouldn't - good catch. > 5) not always, macros are partially to blame. > 6) you and i had a conversation about this very thing yesterday :) > > Anyhow, if 4 is I'm pretty happy with it going in. Er... um... could I get that said again with more words? I have no idea what you just said. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 21:33 ` Daniel Jacobowitz @ 2002-09-14 21:33 ` Eric Christopher 0 siblings, 0 replies; 28+ messages in thread From: Eric Christopher @ 2002-09-14 21:33 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils > > > More importantly, because the performance of this is not important or > > > particularly good, it's important to avoid it. When will it trigger? > > > Does it require -relax? [Not sure.] Does it happen inside .set > > > nomacro? [I think so - should it? I'd say not!] I think there should > > > be a command-line option to disable this, and/or warn about it. Most > > > out-of-range branches represent bugs in GCC's calculations of > > > instruction lengths. I know there are some in 3.2, because I've run > > > into them. I don't know if they're fixed in HEAD, and if this goes in > > > I may never find out. > > > > > > > 1) None of the other relaxations require a command line. > > 2) always. > > 3) no > > 4) shouldn't - good catch. > > 5) not always, macros are partially to blame. > > 6) you and i had a conversation about this very thing yesterday :) > > > > Anyhow, if 4 is I'm pretty happy with it going in. > > Er... um... could I get that said again with more words? I have no > idea what you just said. > How about "if relaxation doesn't happen within set nomacro" i'm pretty happy with it going in. Or did you want all of them expanded? They were just answers to your questions. -eric -- Yuppies wear socks. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 14:28 ` Daniel Jacobowitz 2002-09-14 14:46 ` Eric Christopher @ 2002-09-14 15:00 ` Paul Koning 2002-09-14 16:35 ` Daniel Jacobowitz 2002-09-14 21:39 ` Thiemo Seufer 2002-09-15 0:49 ` Alexandre Oliva 3 siblings, 1 reply; 28+ messages in thread From: Paul Koning @ 2002-09-14 15:00 UTC (permalink / raw) To: drow; +Cc: aoliva, binutils, echristo >>>>> "Daniel" == Daniel Jacobowitz <drow@mvista.com> writes: Daniel> On Sat, Sep 14, 2002 at 02:59:45AM -0300, Alexandre Oliva Daniel> wrote: >> This patch arranges for the MIPS assembler to turn out-of-range >> branches into jumps. No regressions are introduced in the >> binutils testsuites for a mips-linux build. Details on how it is >> done are in comments in the beginning of the patch. Ok to >> install? Daniel> A couple of thoughts: Daniel> + beql reg1, reg2, 1f + nop + beqzl $0, 2f + nop + 1: j[al] Daniel> label + delay slot (executed only if branch taken) + 2: Daniel> Why beqzl? Admittedly, I don't know much about MIPS Daniel> hardware, but I'd think that just "b" would probably be Daniel> faster, since that's the normal unconditional branch. Not only that, but MIPS64 explicitly deprecates all flavors of "branch likely" which is why gcc has a way to avoid generating them. So the assembler should either have the same conditional stuff, or avoid them entirely. paul ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 15:00 ` Paul Koning @ 2002-09-14 16:35 ` Daniel Jacobowitz 2002-09-14 18:43 ` Paul Koning 0 siblings, 1 reply; 28+ messages in thread From: Daniel Jacobowitz @ 2002-09-14 16:35 UTC (permalink / raw) To: Paul Koning; +Cc: aoliva, binutils, echristo On Sat, Sep 14, 2002 at 05:21:32PM -0400, Paul Koning wrote: > >>>>> "Daniel" == Daniel Jacobowitz <drow@mvista.com> writes: > > Daniel> On Sat, Sep 14, 2002 at 02:59:45AM -0300, Alexandre Oliva > Daniel> wrote: > >> This patch arranges for the MIPS assembler to turn out-of-range > >> branches into jumps. No regressions are introduced in the > >> binutils testsuites for a mips-linux build. Details on how it is > >> done are in comments in the beginning of the patch. Ok to > >> install? > > Daniel> A couple of thoughts: > > Daniel> + beql reg1, reg2, 1f + nop + beqzl $0, 2f + nop + 1: j[al] > Daniel> label + delay slot (executed only if branch taken) + 2: > > Daniel> Why beqzl? Admittedly, I don't know much about MIPS > Daniel> hardware, but I'd think that just "b" would probably be > Daniel> faster, since that's the normal unconditional branch. > > Not only that, but MIPS64 explicitly deprecates all flavors of "branch > likely" which is why gcc has a way to avoid generating them. So the > assembler should either have the same conditional stuff, or avoid them > entirely. That's not a problem here - Alex's patch only generated branch-likely in response to existing branch-likely in the source. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 16:35 ` Daniel Jacobowitz @ 2002-09-14 18:43 ` Paul Koning 0 siblings, 0 replies; 28+ messages in thread From: Paul Koning @ 2002-09-14 18:43 UTC (permalink / raw) To: drow; +Cc: aoliva, binutils, echristo >>>>> "Daniel" == Daniel Jacobowitz <drow@mvista.com> writes: Daniel> Why beqzl? Admittedly, I don't know much about MIPS Daniel> hardware, but I'd think that just "b" would probably be Daniel> faster, since that's the normal unconditional branch. >> Not only that, but MIPS64 explicitly deprecates all flavors of >> "branch likely" which is why gcc has a way to avoid generating >> them. So the assembler should either have the same conditional >> stuff, or avoid them entirely. Daniel> That's not a problem here - Alex's patch only generated Daniel> branch-likely in response to existing branch-likely in the Daniel> source. Oh, right, I overlooked that. Agreed... paul ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 14:28 ` Daniel Jacobowitz 2002-09-14 14:46 ` Eric Christopher 2002-09-14 15:00 ` Paul Koning @ 2002-09-14 21:39 ` Thiemo Seufer 2002-09-14 22:18 ` Alexandre Oliva 2002-09-15 0:49 ` Alexandre Oliva 3 siblings, 1 reply; 28+ messages in thread From: Thiemo Seufer @ 2002-09-14 21:39 UTC (permalink / raw) To: binutils; +Cc: Alexandre Oliva, echristo Daniel Jacobowitz wrote: > On Sat, Sep 14, 2002 at 02:59:45AM -0300, Alexandre Oliva wrote: > > This patch arranges for the MIPS assembler to turn out-of-range > > branches into jumps. No regressions are introduced in the binutils > > testsuites for a mips-linux build. Details on how it is done are in > > comments in the beginning of the patch. Ok to install? > > A couple of thoughts: > > + beql reg1, reg2, 1f > + nop > + beqzl $0, 2f > + nop > + 1: j[al] label > + delay slot (executed only if branch taken) > + 2: > > Why beqzl? Admittedly, I don't know much about MIPS hardware, but I'd > think that just "b" would probably be faster, since that's the normal > unconditional branch. "b" isn't a valid opcode. :-) Btw, "beqzl" also isn't one. In this special case I'd prefer "beq". Thiemo ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 21:39 ` Thiemo Seufer @ 2002-09-14 22:18 ` Alexandre Oliva 2002-09-15 2:25 ` Thiemo Seufer 0 siblings, 1 reply; 28+ messages in thread From: Alexandre Oliva @ 2002-09-14 22:18 UTC (permalink / raw) To: Thiemo Seufer; +Cc: binutils, echristo On Sep 14, 2002, Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> wrote: >> Why beqzl? Admittedly, I don't know much about MIPS hardware, but I'd >> think that just "b" would probably be faster, since that's the normal >> unconditional branch. > "b" isn't a valid opcode. :-) Right. `b foo' is just a shorthand for `beq $0, $0, foo' > Btw, "beqzl" also isn't one. Huh? Please check your ISA manual again. It surely is there. > In this special case I'd prefer "beq". Then other branch prediction forms would kick in, and the branch would probably be considered unlikely for being a forward branch. I don't know whether mips has any such considerations, but indicating the branch is likely if there is a way to do so is an obvious improvement to me. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 22:18 ` Alexandre Oliva @ 2002-09-15 2:25 ` Thiemo Seufer 2002-09-15 3:38 ` Alexandre Oliva 0 siblings, 1 reply; 28+ messages in thread From: Thiemo Seufer @ 2002-09-15 2:25 UTC (permalink / raw) To: Alexandre Oliva; +Cc: binutils, echristo Alexandre Oliva wrote: > On Sep 14, 2002, Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> wrote: > > >> Why beqzl? Admittedly, I don't know much about MIPS hardware, but I'd > >> think that just "b" would probably be faster, since that's the normal > >> unconditional branch. > > > "b" isn't a valid opcode. :-) > > Right. `b foo' is just a shorthand for `beq $0, $0, foo' > > > Btw, "beqzl" also isn't one. > > Huh? Please check your ISA manual again. It surely is there. Definitly not for MIPS IV and earlier. Of course, "beql" is there, and with rt == $0 it equals "beqzl". (/opcodes/mips-opc.c provides "beqzl" this way.) It's a style issue, I like to use the official mnemnonic in such a case, but probably that's only me. > > In this special case I'd prefer "beq". > > Then other branch prediction forms would kick in, and the branch would > probably be considered unlikely for being a forward branch. I don't > know whether mips has any such considerations, but indicating the > branch is likely if there is a way to do so is an obvious improvement > to me. Ok, then it would be "beql". Thiemo ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-15 2:25 ` Thiemo Seufer @ 2002-09-15 3:38 ` Alexandre Oliva 0 siblings, 0 replies; 28+ messages in thread From: Alexandre Oliva @ 2002-09-15 3:38 UTC (permalink / raw) To: Thiemo Seufer; +Cc: binutils, echristo On Sep 15, 2002, Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> wrote: > Alexandre Oliva wrote: >> On Sep 14, 2002, Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> wrote: >> >> >> Why beqzl? Admittedly, I don't know much about MIPS hardware, but I'd >> >> think that just "b" would probably be faster, since that's the normal >> >> unconditional branch. >> >> > "b" isn't a valid opcode. :-) >> >> Right. `b foo' is just a shorthand for `beq $0, $0, foo' >> >> > Btw, "beqzl" also isn't one. >> >> Huh? Please check your ISA manual again. It surely is there. > Definitly not for MIPS IV and earlier. Eeek! I apologize. You're of course right. I don't know where I got this idea that beqzl existed but beql did not. I even wrote about beql myself, but apparently I did so in DMA mode :-) > Ok, then it would be "beql". Agreed, patch adjusted. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 14:28 ` Daniel Jacobowitz ` (2 preceding siblings ...) 2002-09-14 21:39 ` Thiemo Seufer @ 2002-09-15 0:49 ` Alexandre Oliva 2002-09-15 9:15 ` Daniel Jacobowitz 2002-09-16 11:56 ` Richard Henderson 3 siblings, 2 replies; 28+ messages in thread From: Alexandre Oliva @ 2002-09-15 0:49 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: binutils, echristo On Sep 14, 2002, Daniel Jacobowitz <drow@mvista.com> wrote: > If this goes in as-is, I doubt that it'll ever be done the right way. I agree. I doubt it's worth doing it the right way. It shouldn't strike often enough to motivate anyone to do it. > Does it happen inside .set nomacro? [I think so - should it? I'd > say not!] I don't see why not. It's not like we're expanding a macro. We're rather doing relaxation. Does the linker refrain from doing relaxations on machine code generated from opcodes assembled while .set nomacro was in effect? This is no different, except that the relaxation is being performed in the assembler rather than in the linker. > I think there should be a command-line option to disable this, > and/or warn about it. That would be a nice improvement. Just arrange for whatever option you come up with to disable this block: if (place == NULL && address_expr && ((*reloc_type == BFD_RELOC_16_PCREL && address_expr->X_op != O_constant) || *reloc_type == BFD_RELOC_16_PCREL_S2) && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_LIKELY) + && !whatever_option_you_come_up_with && !mips_opts.mips16) This will switch all the rest off. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-15 0:49 ` Alexandre Oliva @ 2002-09-15 9:15 ` Daniel Jacobowitz 2002-09-16 11:56 ` Richard Henderson 1 sibling, 0 replies; 28+ messages in thread From: Daniel Jacobowitz @ 2002-09-15 9:15 UTC (permalink / raw) To: Alexandre Oliva; +Cc: binutils, echristo On Sun, Sep 15, 2002 at 01:39:27AM -0300, Alexandre Oliva wrote: > On Sep 14, 2002, Daniel Jacobowitz <drow@mvista.com> wrote: > > > If this goes in as-is, I doubt that it'll ever be done the right way. > > I agree. I doubt it's worth doing it the right way. It shouldn't > strike often enough to motivate anyone to do it. > > > Does it happen inside .set nomacro? [I think so - should it? I'd > > say not!] > > I don't see why not. It's not like we're expanding a macro. We're > rather doing relaxation. Does the linker refrain from doing > relaxations on machine code generated from opcodes assembled while > .set nomacro was in effect? This is no different, except that the > relaxation is being performed in the assembler rather than in the > linker. I suppose. But, as I've been discussing with Eric, the eventual goal is for GCC to not emit macros; which will let it have much more precise control over the generated code. That'll make overlong branches significantly less likely, and more interesting to know about. I guess a warning would suffice. > > I think there should be a command-line option to disable this, > > and/or warn about it. > > That would be a nice improvement. Just arrange for whatever option > you come up with to disable this block: > > if (place == NULL > && address_expr > && ((*reloc_type == BFD_RELOC_16_PCREL > && address_expr->X_op != O_constant) > || *reloc_type == BFD_RELOC_16_PCREL_S2) > && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY > || pinfo & INSN_COND_BRANCH_LIKELY) > + && !whatever_option_you_come_up_with > && !mips_opts.mips16) > > This will switch all the rest off. Thanks. How about something as simple as -mno-relax-branch? (Or would it be -no-mrelax-branch? Gas is pretty inconsistent.) I suppose warning by default would be a little too harsh, too. With the option to not relax it would be as simple as running a GCC testsuite with unix/-Wa,-mno-relax-branch. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-15 0:49 ` Alexandre Oliva 2002-09-15 9:15 ` Daniel Jacobowitz @ 2002-09-16 11:56 ` Richard Henderson 2002-09-17 0:09 ` Alexandre Oliva 1 sibling, 1 reply; 28+ messages in thread From: Richard Henderson @ 2002-09-16 11:56 UTC (permalink / raw) To: Alexandre Oliva; +Cc: Daniel Jacobowitz, binutils, echristo On Sun, Sep 15, 2002 at 01:39:27AM -0300, Alexandre Oliva wrote: > > Does it happen inside .set nomacro? [I think so - should it? I'd > > say not!] > > I don't see why not. It's not like we're expanding a macro. We're > rather doing relaxation. Are we generating more than one instruction? Yes. Ergo it's a macro. > Does the linker refrain from doing relaxations on machine code > generated from opcodes assembled while .set nomacro was in effect? What linker relaxations? r~ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-16 11:56 ` Richard Henderson @ 2002-09-17 0:09 ` Alexandre Oliva 2002-09-17 0:26 ` Richard Henderson 2002-09-17 0:38 ` Thiemo Seufer 0 siblings, 2 replies; 28+ messages in thread From: Alexandre Oliva @ 2002-09-17 0:09 UTC (permalink / raw) To: Richard Henderson; +Cc: Daniel Jacobowitz, binutils, echristo On Sep 16, 2002, Richard Henderson <rth@redhat.com> wrote: >> Does the linker refrain from doing relaxations on machine code >> generated from opcodes assembled while .set nomacro was in effect? > What linker relaxations? coff-mips does them for embedded pic. I thought we did more of those, given the references to linker relaxations in comments in the assembler. Ok, I'm now convinced not doing such relaxations under certain conditions is the way to go. But what are the exact conditions? nomacro (as suggested), noat (to avoid clobbering $at in the expanded sequences) and no gp (to avoid depending on uninitialized values)? -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-17 0:09 ` Alexandre Oliva @ 2002-09-17 0:26 ` Richard Henderson 2002-09-17 0:38 ` Thiemo Seufer 1 sibling, 0 replies; 28+ messages in thread From: Richard Henderson @ 2002-09-17 0:26 UTC (permalink / raw) To: Alexandre Oliva; +Cc: Daniel Jacobowitz, binutils, echristo On Tue, Sep 17, 2002 at 02:25:31AM -0300, Alexandre Oliva wrote: > Ok, I'm now convinced not doing such relaxations under certain > conditions is the way to go. But what are the exact conditions? > nomacro (as suggested), noat (to avoid clobbering $at in the expanded > sequences) and no gp (to avoid depending on uninitialized values)? Dunno what current behaviour is like for the mips assembler, but for the alpha assembler the behaviour would be that only nomacro would prevent the expansion, but if noat is present you get an assembler error if it's needed. r~ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-17 0:09 ` Alexandre Oliva 2002-09-17 0:26 ` Richard Henderson @ 2002-09-17 0:38 ` Thiemo Seufer 2002-10-09 16:51 ` Alexandre Oliva 1 sibling, 1 reply; 28+ messages in thread From: Thiemo Seufer @ 2002-09-17 0:38 UTC (permalink / raw) To: Alexandre Oliva; +Cc: Richard Henderson, Daniel Jacobowitz, binutils, echristo Alexandre Oliva wrote: > On Sep 16, 2002, Richard Henderson <rth@redhat.com> wrote: > > >> Does the linker refrain from doing relaxations on machine code > >> generated from opcodes assembled while .set nomacro was in effect? > > > What linker relaxations? > > coff-mips does them for embedded pic. I thought we did more of those, > given the references to linker relaxations in comments in the > assembler. > > Ok, I'm now convinced not doing such relaxations under certain > conditions is the way to go. But what are the exact conditions? > nomacro (as suggested), Always, as it should prevent expansions. > noat (to avoid clobbering $at in the expanded > sequences) Only if $at is actually used. AFAICS this is the PIC case. > and no gp (to avoid depending on uninitialized values)? AFAICS $gp is only used for PIC, where it must be defined anyway. Btw, your patch uses explicit binary patterns to create insns, is it actually impossible to use mips_ip()/append_insn() instead? Thiemo ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-17 0:38 ` Thiemo Seufer @ 2002-10-09 16:51 ` Alexandre Oliva 2002-10-09 16:54 ` Alexandre Oliva 2002-10-11 13:08 ` Eric Christopher 0 siblings, 2 replies; 28+ messages in thread From: Alexandre Oliva @ 2002-10-09 16:51 UTC (permalink / raw) To: Thiemo Seufer; +Cc: Richard Henderson, Daniel Jacobowitz, binutils, echristo [-- Attachment #1: Type: text/plain, Size: 1483 bytes --] On Sep 17, 2002, Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> wrote: > Alexandre Oliva wrote: >> Ok, I'm now convinced not doing such relaxations under certain >> conditions is the way to go. But what are the exact conditions? >> nomacro (as suggested), > Always, as it should prevent expansions. >> noat (to avoid clobbering $at in the expanded >> sequences) > Only if $at is actually used. AFAICS this is the PIC case. Below you'll find a revised patch that prevents us from attempting to do branch relaxation in the two cases above, and that introduces the -relax-branch and -no-relax-branch options. -no-relax-branch is in effect by default, because I found out the assembler generates worse code for: la $3,l2-l3 # -30 in gas/testsuite/gas/mips/empic.s, because by the time it computes the offset between l3 and l2, it's already committed to a longer expansion of `la', instead of the single-instruction it uses currently. This could probably be overcome using generic relaxation tables, but that's too much work for now. > Btw, your patch uses explicit binary patterns to create insns, is it > actually impossible to use mips_ip()/append_insn() instead? I haven't really tried to do it, out of fear of running into corner cases such as the conversion of `j' to `b' in EMBEDDED_PIC. I agree it would be desirable, but I preferred not to take the risk, since it's essential to know in advance exactly which instructions we're going to emit. Ok to install? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: gas-mips-branch-relax.patch --] [-- Type: text/x-patch, Size: 36995 bytes --] Index: gas/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * config/tc-mips.h (mips_relax_frag): Take segment as argument. (md_relax_frag): Adjust macro. * config/tc-mips.c (mips_relax_branch): New variable. (RELAX_BRANCH_ENCODE, RELAX_BRANCH_P, RELAX_BRANCH_LIKELY, RELAX_BRANCH_LINK, RELAX_BRANCH_TOOBAR): New. (RELAX_MIPS16_P): Adjust. (append_insn): Emit branch to non-constant in a frag_var if branch-relaxation is desirable and possible. (OPTION_RELAX_BRANCH, OPTION_NO_RELAX_BRANCH): New options. (OPTION_ELF_BASE): Adjust. (md_parse_option): Handle new options. (md_apply_fix3): Update comment on EMBEDDED_PIC conditional branch relaxation. (relaxed_branch_length): New function. (md_estimate_size_before_relax): Handle branch frags. (mips_relax_frag): Likewise. (md_convert_frag): Handle branch frags. Warn if branch is relaxed. Index: gas/testsuite/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * gas/mips/mips.exp: Don't xfail relax. * gas/mips/relax.s: Increase coverage. * gas/mips/relax.d: Add expected output. Use relax.l for as stderr. * gas/mips/relax.l: New file. Index: gas/config/tc-mips.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-mips.c,v retrieving revision 1.171 diff -u -p -r1.171 tc-mips.c --- gas/config/tc-mips.c 30 Sep 2002 12:04:51 -0000 1.171 +++ gas/config/tc-mips.c 9 Oct 2002 23:33:34 -0000 @@ -563,6 +563,13 @@ static const unsigned int mips16_to_32_r }; static int mips_fix_4122_bugs; + +/* We don't relax branches by default, since this causes us to expand + `la .l2 - .l1' if there's a branch between .l1 and .l2, because we + fail to compute the offset before expanding the macro to the most + efficient expansion. */ + +static int mips_relax_branch; \f /* Since the MIPS does not have multiple forms of PC relative instructions, we do not have to do relaxing as is done on other @@ -640,6 +647,88 @@ static int mips_fix_4122_bugs; #define RELAX_RELOC3(i) (((i) >> 1) & 1) #define RELAX_WARN(i) ((i) & 1) +/* Branch without likely bit. If label is out of range, we turn: + + beq reg1, reg2, label + delay slot + + into + + bne reg1, reg2, 0f + nop + j label + 0: delay slot + + with the following opcode replacements: + + beq <-> bne + blez <-> bgtz + bltz <-> bgez + bc1f <-> bc1t + + bltzal <-> bgezal (with jal label instead of j label) + + Even though keeping the delay slot instruction in the delay slot of + the branch would be more efficient, it would be very tricky to do + correctly, because we'd have to introduce a variable frag *after* + the delay slot instruction, and expand that instead. Let's do it + the easy way for now, even if the branch-not-taken case now costs + one additional instruction. Out-of-range branches are not supposed + to be common, anyway. + + Branch likely. If label is out of range, we turn: + + beql reg1, reg2, label + delay slot (annulled if branch not taken) + + into + + beql reg1, reg2, 1f + nop + beql $0, $0, 2f + nop + 1: j[al] label + delay slot (executed only if branch taken) + 2: + + It would be possible to generate a shorter sequence by losing the + likely bit, generating something like: + + bne reg1, reg2, 0f + nop + j[al] label + delay slot (executed only if branch taken) + 0: + + beql -> bne + bnel -> beq + blezl -> bgtz + bgtzl -> blez + bltzl -> bgez + bgezl -> bltz + bc1fl -> bc1t + bc1tl -> bc1f + + bltzall -> bgezal (with jal label instead of j label) + bgezall -> bltzal (ditto) + + + but it's not clear that it would actually improve performance. */ +#define RELAX_BRANCH_ENCODE(reloc_s2, uncond, likely, link, toofar) \ + ((relax_substateT) \ + (0xc0000000 \ + | ((toofar) ? 1 : 0) \ + | ((link) ? 2 : 0) \ + | ((likely) ? 4 : 0) \ + | ((uncond) ? 8 : 0) \ + | ((reloc_s2) ? 16 : 0))) +#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000) +#define RELAX_BRANCH_RELOC_S2(i) (((i) & 16) != 0) +#define RELAX_BRANCH_UNCOND(i) (((i) & 8) != 0) +#define RELAX_BRANCH_LIKELY(i) (((i) & 4) != 0) +#define RELAX_BRANCH_LINK(i) (((i) & 2) != 0) +#define RELAX_BRANCH_TOOFAR(i) (((i) & 1)) + /* For mips16 code, we use an entirely different form of relaxation. mips16 supports two versions of most instructions which take immediate values: a small one which takes some small value, and a @@ -667,7 +756,7 @@ static int mips_fix_4122_bugs; | ((ext) ? 0x200 : 0) \ | ((dslot) ? 0x400 : 0) \ | ((jal_dslot) ? 0x800 : 0)) -#define RELAX_MIPS16_P(i) (((i) & 0x80000000) != 0) +#define RELAX_MIPS16_P(i) (((i) & 0xc0000000) == 0x80000000) #define RELAX_MIPS16_TYPE(i) ((i) & 0xff) #define RELAX_MIPS16_USER_SMALL(i) (((i) & 0x100) != 0) #define RELAX_MIPS16_USER_EXT(i) (((i) & 0x200) != 0) @@ -785,6 +874,7 @@ static void s_mips_weakext PARAMS ((int) static void s_mips_file PARAMS ((int)); static void s_mips_loc PARAMS ((int)); static int mips16_extended_frag PARAMS ((fragS *, asection *, long)); +static int relaxed_branch_length (fragS *, asection *, int); static int validate_mips_insn PARAMS ((const struct mips_opcode *)); static void show PARAMS ((FILE *, const char *, int *, int *)); #ifdef OBJ_ELF @@ -1840,7 +1930,38 @@ append_insn (place, ip, address_expr, re } } - if (*reloc_type > BFD_RELOC_UNUSED) + if (place == NULL + && address_expr + && ((*reloc_type == BFD_RELOC_16_PCREL + && address_expr->X_op != O_constant) + || *reloc_type == BFD_RELOC_16_PCREL_S2) + && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY + || pinfo & INSN_COND_BRANCH_LIKELY) + && mips_relax_branch + /* Don't try branch relaxation within .set nomacro, or within + .set noat if we use $at for PIC computations. If it turns + out that the branch was out-of-range, we'll get an error. */ + && !mips_opts.warn_about_macros + && !(mips_opts.noat && mips_pic != NO_PIC) + && !mips_opts.mips16) + { + f = frag_var (rs_machine_dependent, + relaxed_branch_length + (NULL, NULL, + (pinfo & INSN_UNCOND_BRANCH_DELAY) ? -1 + : (pinfo & INSN_COND_BRANCH_LIKELY) ? 1 : 0), 4, + RELAX_BRANCH_ENCODE + (*reloc_type == BFD_RELOC_16_PCREL_S2, + pinfo & INSN_UNCOND_BRANCH_DELAY, + pinfo & INSN_COND_BRANCH_LIKELY, + pinfo & INSN_WRITE_GPR_31, + 0), + address_expr->X_add_symbol, + address_expr->X_add_number, + 0); + *reloc_type = BFD_RELOC_UNUSED; + } + else if (*reloc_type > BFD_RELOC_UNUSED) { /* We need to set up a variant frag. */ assert (mips_opts.mips16 && address_expr != NULL); @@ -10125,8 +10246,12 @@ struct option md_longopts[] = #define OPTION_NO_FIX_VR4122 (OPTION_MD_BASE + 38) {"mfix-vr4122-bugs", no_argument, NULL, OPTION_FIX_VR4122}, {"no-mfix-vr4122-bugs", no_argument, NULL, OPTION_NO_FIX_VR4122}, +#define OPTION_RELAX_BRANCH (OPTION_MD_BASE + 39) +#define OPTION_NO_RELAX_BRANCH (OPTION_MD_BASE + 40) + {"relax-branch", no_argument, NULL, OPTION_RELAX_BRANCH}, + {"no-relax-branch", no_argument, NULL, OPTION_NO_RELAX_BRANCH}, #ifdef OBJ_ELF -#define OPTION_ELF_BASE (OPTION_MD_BASE + 39) +#define OPTION_ELF_BASE (OPTION_MD_BASE + 41) #define OPTION_CALL_SHARED (OPTION_ELF_BASE + 0) {"KPIC", no_argument, NULL, OPTION_CALL_SHARED}, {"call_shared", no_argument, NULL, OPTION_CALL_SHARED}, @@ -10335,6 +10460,14 @@ md_parse_option (c, arg) mips_fix_4122_bugs = 0; break; + case OPTION_RELAX_BRANCH: + mips_relax_branch = 1; + break; + + case OPTION_NO_RELAX_BRANCH: + mips_relax_branch = 0; + break; + #ifdef OBJ_ELF /* When generating ELF code, we permit -KPIC and -call_shared to select SVR4_PIC, and -non_shared to select no PIC. This is @@ -11186,13 +11319,9 @@ md_apply_fix3 (fixP, valP, seg) } else { - /* FIXME. It would be possible in principle to handle - conditional branches which overflow. They could be - transformed into a branch around a jump. This would - require setting up variant frags for each different - branch type. The native MIPS assembler attempts to - handle these cases, but it appears to do it - incorrectly. */ + /* If we got here, we have branch-relaxation disabled, + and there's nothing we can do to fix this instruction + without turning it into a longer sequence. */ as_bad_where (fixP->fx_file, fixP->fx_line, _("Branch out of range")); } @@ -12662,6 +12791,74 @@ mips16_extended_frag (fragp, sec, stretc return 0; } +/* Compute the length of a branch sequence, and adjust the + RELAX_BRANCH_TOOFAR bit accordingly. If FRAGP is NULL, the + worst-case length is computed, with UPDATE being used to indicate + whether an unconditional (-1), branch-likely (+1) or regular (0) + branch is to be computed. */ +static int +relaxed_branch_length (fragp, sec, update) + fragS *fragp; + asection *sec; + int update; +{ + boolean toofar; + int length; + + if (fragp + && S_IS_DEFINED (fragp->fr_symbol) + && sec == S_GET_SEGMENT (fragp->fr_symbol)) + { + addressT addr; + offsetT val; + + val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset; + + addr = fragp->fr_address + fragp->fr_fix + 4; + + val -= addr; + + toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2); + } + else if (fragp) + /* If the symbol is not defined or it's in a different segment, + assume the user knows what's going on and emit a short + branch. */ + toofar = false; + else + toofar = true; + + if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype)) + fragp->fr_subtype + = RELAX_BRANCH_ENCODE (RELAX_BRANCH_RELOC_S2 (fragp->fr_subtype), + RELAX_BRANCH_UNCOND (fragp->fr_subtype), + RELAX_BRANCH_LIKELY (fragp->fr_subtype), + RELAX_BRANCH_LINK (fragp->fr_subtype), + toofar); + + length = 4; + if (toofar) + { + if (fragp ? RELAX_BRANCH_LIKELY (fragp->fr_subtype) : (update > 0)) + length += 8; + + if (mips_pic != NO_PIC) + { + /* Additional space for PIC loading of target address. */ + length += 8; + if (mips_opts.isa == ISA_MIPS1) + /* Additional space for $at-stabilizing nop. */ + length += 4; + } + + /* If branch is conditional. */ + if (fragp ? !RELAX_BRANCH_UNCOND (fragp->fr_subtype) : (update >= 0)) + length += 8; + } + + return length; +} + /* Estimate the size of a frag before relaxing. Unless this is the mips16, we are not really relaxing here, and the final size is encoded in the subtype information. For the mips16, we have to @@ -12675,6 +12872,14 @@ md_estimate_size_before_relax (fragp, se int change = 0; boolean linkonce = false; + if (RELAX_BRANCH_P (fragp->fr_subtype)) + { + + fragp->fr_var = relaxed_branch_length (fragp, segtype, false); + + return fragp->fr_var; + } + if (RELAX_MIPS16_P (fragp->fr_subtype)) /* We don't want to modify the EXTENDED bit here; it might get us into infinite loops. We change it only in mips_relax_frag(). */ @@ -13049,10 +13254,20 @@ tc_gen_reloc (section, fixp) the current size of the frag should change. */ int -mips_relax_frag (fragp, stretch) +mips_relax_frag (sec, fragp, stretch) + asection *sec; fragS *fragp; long stretch; { + if (RELAX_BRANCH_P (fragp->fr_subtype)) + { + offsetT old_var = fragp->fr_var; + + fragp->fr_var = relaxed_branch_length (fragp, sec, true); + + return fragp->fr_var - old_var; + } + if (! RELAX_MIPS16_P (fragp->fr_subtype)) return 0; @@ -13084,6 +13299,216 @@ md_convert_frag (abfd, asec, fragp) { int old, new; char *fixptr; + + if (RELAX_BRANCH_P (fragp->fr_subtype)) + { + bfd_byte *buf; + unsigned long insn; + expressionS exp; + fixS *fixp; + + buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix; + + if (target_big_endian) + insn = bfd_getb32 (buf); + else + insn = bfd_getl32 (buf); + + if (!RELAX_BRANCH_TOOFAR (fragp->fr_subtype)) + { + /* We generate a fixup instead of applying it right now + because, if there are linker relaxations, we're going to + need the relocations. */ + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 1, + RELAX_BRANCH_RELOC_S2 (fragp->fr_subtype) + ? BFD_RELOC_16_PCREL_S2 + : BFD_RELOC_16_PCREL); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char *)buf, insn, 4); + buf += 4; + } + else + { + int i; + + as_warn_where (fragp->fr_file, fragp->fr_line, + _("relaxed out-of-range branch into a jump")); + + if (RELAX_BRANCH_UNCOND (fragp->fr_subtype)) + goto uncond; + + if (!RELAX_BRANCH_LIKELY (fragp->fr_subtype)) + { + /* Reverse the branch. */ + switch ((insn >> 28) & 0xf) + { + case 4: + /* bc[0-3][tf]l? and bc1any[24][ft] instructions can + have the condition reversed by tweaking a single + bit, and their opcodes all have 0x4???????. */ + assert ((insn & 0xf1000000) == 0x41000000); + insn ^= 0x00010000; + break; + + case 0: + /* bltz 0x04000000 bgez 0x04010000 + bltzal 0x04100000 bgezal 0x04110000 */ + assert ((insn & 0xfc0e0000) == 0x04000000); + insn ^= 0x00010000; + break; + + case 1: + /* beq 0x10000000 bne 0x14000000 + blez 0x18000000 bgtz 0x1c000000 */ + insn ^= 0x04000000; + break; + + default: + abort (); + } + } + + if (RELAX_BRANCH_LINK (fragp->fr_subtype)) + { + /* Clear the and-link bit. */ + assert ((insn & 0xfc1c0000) == 0x04100000); + + /* bltzal 0x04100000 bgezal 0x04110000 + bltzall 0x04120000 bgezall 0x04130000 */ + insn &= ~0x00100000; + } + + /* Branch over the branch (if the branch was likely) or the + full jump (not likely case). Compute the offset from the + current instruction to branch to. */ + if (RELAX_BRANCH_LIKELY (fragp->fr_subtype)) + i = 16; + else + { + /* How many bytes in instructions we've already emitted? */ + i = buf - (bfd_byte *)fragp->fr_literal - fragp->fr_fix; + /* How many bytes in instructions from here to the end? */ + i = fragp->fr_var - i; + } + /* Convert to instruction count. */ + i >>= 2; + /* Branch counts from the next instruction. */ + i--; + insn |= i; + /* Branch over the jump. */ + md_number_to_chars ((char *)buf, insn, 4); + buf += 4; + + /* Nop */ + md_number_to_chars ((char*)buf, 0, 4); + buf += 4; + + if (RELAX_BRANCH_LIKELY (fragp->fr_subtype)) + { + /* beql $0, $0, 2f */ + insn = 0x50000000; + /* Compute the PC offset from the current instruction to + the end of the variable frag. */ + /* How many bytes in instructions we've already emitted? */ + i = buf - (bfd_byte *)fragp->fr_literal - fragp->fr_fix; + /* How many bytes in instructions from here to the end? */ + i = fragp->fr_var - i; + /* Convert to instruction count. */ + i >>= 2; + /* Don't decrement i, because we want to branch over the + delay slot. */ + + insn |= i; + md_number_to_chars ((char *)buf, insn, 4); + buf += 4; + + md_number_to_chars ((char *)buf, 0, 4); + buf += 4; + } + + uncond: + if (mips_pic == NO_PIC) + { + /* j or jal. */ + insn = (RELAX_BRANCH_LINK (fragp->fr_subtype) + ? 0x0c000000 : 0x08000000); + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 0, BFD_RELOC_MIPS_JMP); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + } + else + { + /* lw/ld $at, <sym>($gp) R_MIPS_GOT16 */ + insn = HAVE_64BIT_ADDRESSES ? 0xdf810000 : 0x8f810000; + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + if (fragp->fr_offset) + { + exp.X_add_symbol = make_expr_symbol (&exp); + exp.X_add_number = 0; + } + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 0, BFD_RELOC_MIPS_GOT16); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + + if (mips_opts.isa == ISA_MIPS1) + { + /* nop */ + md_number_to_chars ((char*)buf, 0, 4); + buf += 4; + } + + /* d/addiu $at, $at, <sym> R_MIPS_LO16 */ + insn = HAVE_64BIT_ADDRESSES ? 0x64210000 : 0x24210000; + + fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + 4, &exp, 0, BFD_RELOC_LO16); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + + /* j(al)r $at. */ + if (RELAX_BRANCH_LINK (fragp->fr_subtype)) + insn = 0x0020f809; + else + insn = 0x00200008; + + md_number_to_chars ((char*)buf, insn, 4); + buf += 4; + } + } + + assert (buf == (bfd_byte *)fragp->fr_literal + + fragp->fr_fix + fragp->fr_var); + + fragp->fr_fix += fragp->fr_var; + + return; + } if (RELAX_MIPS16_P (fragp->fr_subtype)) { Index: gas/config/tc-mips.h =================================================================== RCS file: /cvs/src/src/gas/config/tc-mips.h,v retrieving revision 1.17 diff -u -p -r1.17 tc-mips.h --- gas/config/tc-mips.h 1 Oct 2002 06:15:33 -0000 1.17 +++ gas/config/tc-mips.h 9 Oct 2002 23:33:34 -0000 @@ -49,8 +49,9 @@ struct expressionS; relocation: */ #define MAX_GPREL_OFFSET (0x7FF0) -#define md_relax_frag(segment, fragp, stretch) mips_relax_frag(fragp, stretch) -extern int mips_relax_frag PARAMS ((struct frag *, long)); +#define md_relax_frag(segment, fragp, stretch) \ + mips_relax_frag(segment, fragp, stretch) +extern int mips_relax_frag PARAMS ((asection *, struct frag *, long)); #define md_undefined_symbol(name) (0) #define md_operand(x) Index: gas/testsuite/gas/mips/mips.exp =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v retrieving revision 1.48 diff -u -p -r1.48 mips.exp --- gas/testsuite/gas/mips/mips.exp 1 Oct 2002 04:37:47 -0000 1.48 +++ gas/testsuite/gas/mips/mips.exp 9 Oct 2002 23:33:35 -0000 @@ -168,8 +168,6 @@ if { [istarget mips*-*-*] } then { run_dump_test "sb1-ext-mdmx" run_dump_test "sb1-ext-ps" - # It will always fail until someone fixes it. - setup_xfail "mips*-*-*" run_dump_test "relax" run_list_test "illegal" "" Index: gas/testsuite/gas/mips/relax.d =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/relax.d,v retrieving revision 1.1 diff -u -p -r1.1 relax.d --- gas/testsuite/gas/mips/relax.d 9 Jun 2001 06:25:55 -0000 1.1 +++ gas/testsuite/gas/mips/relax.d 9 Oct 2002 23:33:35 -0000 @@ -1,8 +1,395 @@ +#as: -KPIC -mips3 -32 -relax-branch #objdump: -dr --prefix-addresses -mmips:4000 #name: MIPS relax +#stderr: relax.l # Test relaxation. .*: +file format .*mips.* -Disassembly of section .text: +Disassembly of section \.text: +00000000 <foo> lw at,2\(gp\) + 0: R_MIPS_GOT16 \.text +00000004 <foo\+0x4> addiu at,at,592 + 4: R_MIPS_LO16 \.text +00000008 <foo\+0x8> jr at +0000000c <foo\+0xc> nop +00000010 <foo\+0x10> lw at,2\(gp\) + 10: R_MIPS_GOT16 \.text +00000014 <foo\+0x14> addiu at,at,592 + 14: R_MIPS_LO16 \.text +00000018 <foo\+0x18> jalr at +0000001c <foo\+0x1c> nop +00000020 <foo\+0x20> bne v0,v1,00000034 <foo\+0x34> +00000024 <foo\+0x24> nop +00000028 <foo\+0x28> lw at,2\(gp\) + 28: R_MIPS_GOT16 \.text +0000002c <foo\+0x2c> addiu at,at,592 + 2c: R_MIPS_LO16 \.text +00000030 <foo\+0x30> jr at +00000034 <foo\+0x34> nop +00000038 <foo\+0x38> beq a0,a1,0000004c <foo\+0x4c> +0000003c <foo\+0x3c> nop +00000040 <foo\+0x40> lw at,2\(gp\) + 40: R_MIPS_GOT16 \.text +00000044 <foo\+0x44> addiu at,at,592 + 44: R_MIPS_LO16 \.text +00000048 <foo\+0x48> jr at +0000004c <foo\+0x4c> nop +00000050 <foo\+0x50> bgtz v0,00000064 <foo\+0x64> +00000054 <foo\+0x54> nop +00000058 <foo\+0x58> lw at,2\(gp\) + 58: R_MIPS_GOT16 \.text +0000005c <foo\+0x5c> addiu at,at,592 + 5c: R_MIPS_LO16 \.text +00000060 <foo\+0x60> jr at +00000064 <foo\+0x64> nop +00000068 <foo\+0x68> blez v1,0000007c <foo\+0x7c> +0000006c <foo\+0x6c> nop +00000070 <foo\+0x70> lw at,2\(gp\) + 70: R_MIPS_GOT16 \.text +00000074 <foo\+0x74> addiu at,at,592 + 74: R_MIPS_LO16 \.text +00000078 <foo\+0x78> jr at +0000007c <foo\+0x7c> nop +00000080 <foo\+0x80> bgez a0,00000094 <foo\+0x94> +00000084 <foo\+0x84> nop +00000088 <foo\+0x88> lw at,2\(gp\) + 88: R_MIPS_GOT16 \.text +0000008c <foo\+0x8c> addiu at,at,592 + 8c: R_MIPS_LO16 \.text +00000090 <foo\+0x90> jr at +00000094 <foo\+0x94> nop +00000098 <foo\+0x98> bltz a1,000000ac <foo\+0xac> +0000009c <foo\+0x9c> nop +000000a0 <foo\+0xa0> lw at,2\(gp\) + a0: R_MIPS_GOT16 \.text +000000a4 <foo\+0xa4> addiu at,at,592 + a4: R_MIPS_LO16 \.text +000000a8 <foo\+0xa8> jr at +000000ac <foo\+0xac> nop +000000b0 <foo\+0xb0> bc1t 000000c4 <foo\+0xc4> +000000b4 <foo\+0xb4> nop +000000b8 <foo\+0xb8> lw at,2\(gp\) + b8: R_MIPS_GOT16 \.text +000000bc <foo\+0xbc> addiu at,at,592 + bc: R_MIPS_LO16 \.text +000000c0 <foo\+0xc0> jr at +000000c4 <foo\+0xc4> nop +000000c8 <foo\+0xc8> bc1f 000000dc <foo\+0xdc> +000000cc <foo\+0xcc> nop +000000d0 <foo\+0xd0> lw at,2\(gp\) + d0: R_MIPS_GOT16 \.text +000000d4 <foo\+0xd4> addiu at,at,592 + d4: R_MIPS_LO16 \.text +000000d8 <foo\+0xd8> jr at +000000dc <foo\+0xdc> nop +000000e0 <foo\+0xe0> bgez v0,000000f4 <foo\+0xf4> +000000e4 <foo\+0xe4> nop +000000e8 <foo\+0xe8> lw at,2\(gp\) + e8: R_MIPS_GOT16 \.text +000000ec <foo\+0xec> addiu at,at,592 + ec: R_MIPS_LO16 \.text +000000f0 <foo\+0xf0> jalr at +000000f4 <foo\+0xf4> nop +000000f8 <foo\+0xf8> bltz v1,0000010c <foo\+0x10c> +000000fc <foo\+0xfc> nop +00000100 <foo\+0x100> lw at,2\(gp\) + 100: R_MIPS_GOT16 \.text +00000104 <foo\+0x104> addiu at,at,592 + 104: R_MIPS_LO16 \.text +00000108 <foo\+0x108> jalr at +0000010c <foo\+0x10c> nop +00000110 <foo\+0x110> beql v0,v1,00000120 <foo\+0x120> +00000114 <foo\+0x114> nop +00000118 <foo\+0x118> beqzl zero,00000130 <foo\+0x130> +0000011c <foo\+0x11c> nop +00000120 <foo\+0x120> lw at,2\(gp\) + 120: R_MIPS_GOT16 \.text +00000124 <foo\+0x124> addiu at,at,592 + 124: R_MIPS_LO16 \.text +00000128 <foo\+0x128> jr at +0000012c <foo\+0x12c> nop +00000130 <foo\+0x130> bnel a0,a1,00000140 <foo\+0x140> +00000134 <foo\+0x134> nop +00000138 <foo\+0x138> beqzl zero,00000150 <foo\+0x150> +0000013c <foo\+0x13c> nop +00000140 <foo\+0x140> lw at,2\(gp\) + 140: R_MIPS_GOT16 \.text +00000144 <foo\+0x144> addiu at,at,592 + 144: R_MIPS_LO16 \.text +00000148 <foo\+0x148> jr at +0000014c <foo\+0x14c> nop +00000150 <foo\+0x150> blezl v0,00000160 <foo\+0x160> +00000154 <foo\+0x154> nop +00000158 <foo\+0x158> beqzl zero,00000170 <foo\+0x170> +0000015c <foo\+0x15c> nop +00000160 <foo\+0x160> lw at,2\(gp\) + 160: R_MIPS_GOT16 \.text +00000164 <foo\+0x164> addiu at,at,592 + 164: R_MIPS_LO16 \.text +00000168 <foo\+0x168> jr at +0000016c <foo\+0x16c> nop +00000170 <foo\+0x170> bgtzl v1,00000180 <foo\+0x180> +00000174 <foo\+0x174> nop +00000178 <foo\+0x178> beqzl zero,00000190 <foo\+0x190> +0000017c <foo\+0x17c> nop +00000180 <foo\+0x180> lw at,2\(gp\) + 180: R_MIPS_GOT16 \.text +00000184 <foo\+0x184> addiu at,at,592 + 184: R_MIPS_LO16 \.text +00000188 <foo\+0x188> jr at +0000018c <foo\+0x18c> nop +00000190 <foo\+0x190> bltzl a0,000001a0 <foo\+0x1a0> +00000194 <foo\+0x194> nop +00000198 <foo\+0x198> beqzl zero,000001b0 <foo\+0x1b0> +0000019c <foo\+0x19c> nop +000001a0 <foo\+0x1a0> lw at,2\(gp\) + 1a0: R_MIPS_GOT16 \.text +000001a4 <foo\+0x1a4> addiu at,at,592 + 1a4: R_MIPS_LO16 \.text +000001a8 <foo\+0x1a8> jr at +000001ac <foo\+0x1ac> nop +000001b0 <foo\+0x1b0> bgezl a1,000001c0 <foo\+0x1c0> +000001b4 <foo\+0x1b4> nop +000001b8 <foo\+0x1b8> beqzl zero,000001d0 <foo\+0x1d0> +000001bc <foo\+0x1bc> nop +000001c0 <foo\+0x1c0> lw at,2\(gp\) + 1c0: R_MIPS_GOT16 \.text +000001c4 <foo\+0x1c4> addiu at,at,592 + 1c4: R_MIPS_LO16 \.text +000001c8 <foo\+0x1c8> jr at +000001cc <foo\+0x1cc> nop +000001d0 <foo\+0x1d0> bc1fl 000001e0 <foo\+0x1e0> +000001d4 <foo\+0x1d4> nop +000001d8 <foo\+0x1d8> beqzl zero,000001f0 <foo\+0x1f0> +000001dc <foo\+0x1dc> nop +000001e0 <foo\+0x1e0> lw at,2\(gp\) + 1e0: R_MIPS_GOT16 \.text +000001e4 <foo\+0x1e4> addiu at,at,592 + 1e4: R_MIPS_LO16 \.text +000001e8 <foo\+0x1e8> jr at +000001ec <foo\+0x1ec> nop +000001f0 <foo\+0x1f0> bc1tl 00000200 <foo\+0x200> +000001f4 <foo\+0x1f4> nop +000001f8 <foo\+0x1f8> beqzl zero,00000210 <foo\+0x210> +000001fc <foo\+0x1fc> nop +00000200 <foo\+0x200> lw at,2\(gp\) + 200: R_MIPS_GOT16 \.text +00000204 <foo\+0x204> addiu at,at,592 + 204: R_MIPS_LO16 \.text +00000208 <foo\+0x208> jr at +0000020c <foo\+0x20c> nop +00000210 <foo\+0x210> bltzl v0,00000220 <foo\+0x220> +00000214 <foo\+0x214> nop +00000218 <foo\+0x218> beqzl zero,00000230 <foo\+0x230> +0000021c <foo\+0x21c> nop +00000220 <foo\+0x220> lw at,2\(gp\) + 220: R_MIPS_GOT16 \.text +00000224 <foo\+0x224> addiu at,at,592 + 224: R_MIPS_LO16 \.text +00000228 <foo\+0x228> jalr at +0000022c <foo\+0x22c> nop +00000230 <foo\+0x230> bgezl v1,00000240 <foo\+0x240> +00000234 <foo\+0x234> nop +00000238 <foo\+0x238> beqzl zero,00000250 <foo\+0x250> +0000023c <foo\+0x23c> nop +00000240 <foo\+0x240> lw at,2\(gp\) + 240: R_MIPS_GOT16 \.text +00000244 <foo\+0x244> addiu at,at,592 + 244: R_MIPS_LO16 \.text +00000248 <foo\+0x248> jalr at +0000024c <foo\+0x24c> nop + \.\.\. +00020250 <bar> lw at,0\(gp\) + 20250: R_MIPS_GOT16 \.text +00020254 <bar\+0x4> addiu at,at,0 + 20254: R_MIPS_LO16 \.text +00020258 <bar\+0x8> jr at +0002025c <bar\+0xc> nop +00020260 <bar\+0x10> lw at,0\(gp\) + 20260: R_MIPS_GOT16 \.text +00020264 <bar\+0x14> addiu at,at,0 + 20264: R_MIPS_LO16 \.text +00020268 <bar\+0x18> jalr at +0002026c <bar\+0x1c> nop +00020270 <bar\+0x20> bne v0,v1,00020284 <bar\+0x34> +00020274 <bar\+0x24> nop +00020278 <bar\+0x28> lw at,0\(gp\) + 20278: R_MIPS_GOT16 \.text +0002027c <bar\+0x2c> addiu at,at,0 + 2027c: R_MIPS_LO16 \.text +00020280 <bar\+0x30> jr at +00020284 <bar\+0x34> nop +00020288 <bar\+0x38> beq a0,a1,0002029c <bar\+0x4c> +0002028c <bar\+0x3c> nop +00020290 <bar\+0x40> lw at,0\(gp\) + 20290: R_MIPS_GOT16 \.text +00020294 <bar\+0x44> addiu at,at,0 + 20294: R_MIPS_LO16 \.text +00020298 <bar\+0x48> jr at +0002029c <bar\+0x4c> nop +000202a0 <bar\+0x50> bgtz v0,000202b4 <bar\+0x64> +000202a4 <bar\+0x54> nop +000202a8 <bar\+0x58> lw at,0\(gp\) + 202a8: R_MIPS_GOT16 \.text +000202ac <bar\+0x5c> addiu at,at,0 + 202ac: R_MIPS_LO16 \.text +000202b0 <bar\+0x60> jr at +000202b4 <bar\+0x64> nop +000202b8 <bar\+0x68> blez v1,000202cc <bar\+0x7c> +000202bc <bar\+0x6c> nop +000202c0 <bar\+0x70> lw at,0\(gp\) + 202c0: R_MIPS_GOT16 \.text +000202c4 <bar\+0x74> addiu at,at,0 + 202c4: R_MIPS_LO16 \.text +000202c8 <bar\+0x78> jr at +000202cc <bar\+0x7c> nop +000202d0 <bar\+0x80> bgez a0,000202e4 <bar\+0x94> +000202d4 <bar\+0x84> nop +000202d8 <bar\+0x88> lw at,0\(gp\) + 202d8: R_MIPS_GOT16 \.text +000202dc <bar\+0x8c> addiu at,at,0 + 202dc: R_MIPS_LO16 \.text +000202e0 <bar\+0x90> jr at +000202e4 <bar\+0x94> nop +000202e8 <bar\+0x98> bltz a1,000202fc <bar\+0xac> +000202ec <bar\+0x9c> nop +000202f0 <bar\+0xa0> lw at,0\(gp\) + 202f0: R_MIPS_GOT16 \.text +000202f4 <bar\+0xa4> addiu at,at,0 + 202f4: R_MIPS_LO16 \.text +000202f8 <bar\+0xa8> jr at +000202fc <bar\+0xac> nop +00020300 <bar\+0xb0> bc1t 00020314 <bar\+0xc4> +00020304 <bar\+0xb4> nop +00020308 <bar\+0xb8> lw at,0\(gp\) + 20308: R_MIPS_GOT16 \.text +0002030c <bar\+0xbc> addiu at,at,0 + 2030c: R_MIPS_LO16 \.text +00020310 <bar\+0xc0> jr at +00020314 <bar\+0xc4> nop +00020318 <bar\+0xc8> bc1f 0002032c <bar\+0xdc> +0002031c <bar\+0xcc> nop +00020320 <bar\+0xd0> lw at,0\(gp\) + 20320: R_MIPS_GOT16 \.text +00020324 <bar\+0xd4> addiu at,at,0 + 20324: R_MIPS_LO16 \.text +00020328 <bar\+0xd8> jr at +0002032c <bar\+0xdc> nop +00020330 <bar\+0xe0> bgez v0,00020344 <bar\+0xf4> +00020334 <bar\+0xe4> nop +00020338 <bar\+0xe8> lw at,0\(gp\) + 20338: R_MIPS_GOT16 \.text +0002033c <bar\+0xec> addiu at,at,0 + 2033c: R_MIPS_LO16 \.text +00020340 <bar\+0xf0> jalr at +00020344 <bar\+0xf4> nop +00020348 <bar\+0xf8> bltz v1,0002035c <bar\+0x10c> +0002034c <bar\+0xfc> nop +00020350 <bar\+0x100> lw at,0\(gp\) + 20350: R_MIPS_GOT16 \.text +00020354 <bar\+0x104> addiu at,at,0 + 20354: R_MIPS_LO16 \.text +00020358 <bar\+0x108> jalr at +0002035c <bar\+0x10c> nop +00020360 <bar\+0x110> beql v0,v1,00020370 <bar\+0x120> +00020364 <bar\+0x114> nop +00020368 <bar\+0x118> beqzl zero,00020380 <bar\+0x130> +0002036c <bar\+0x11c> nop +00020370 <bar\+0x120> lw at,0\(gp\) + 20370: R_MIPS_GOT16 \.text +00020374 <bar\+0x124> addiu at,at,0 + 20374: R_MIPS_LO16 \.text +00020378 <bar\+0x128> jr at +0002037c <bar\+0x12c> nop +00020380 <bar\+0x130> bnel a0,a1,00020390 <bar\+0x140> +00020384 <bar\+0x134> nop +00020388 <bar\+0x138> beqzl zero,000203a0 <bar\+0x150> +0002038c <bar\+0x13c> nop +00020390 <bar\+0x140> lw at,0\(gp\) + 20390: R_MIPS_GOT16 \.text +00020394 <bar\+0x144> addiu at,at,0 + 20394: R_MIPS_LO16 \.text +00020398 <bar\+0x148> jr at +0002039c <bar\+0x14c> nop +000203a0 <bar\+0x150> blezl v0,000203b0 <bar\+0x160> +000203a4 <bar\+0x154> nop +000203a8 <bar\+0x158> beqzl zero,000203c0 <bar\+0x170> +000203ac <bar\+0x15c> nop +000203b0 <bar\+0x160> lw at,0\(gp\) + 203b0: R_MIPS_GOT16 \.text +000203b4 <bar\+0x164> addiu at,at,0 + 203b4: R_MIPS_LO16 \.text +000203b8 <bar\+0x168> jr at +000203bc <bar\+0x16c> nop +000203c0 <bar\+0x170> bgtzl v1,000203d0 <bar\+0x180> +000203c4 <bar\+0x174> nop +000203c8 <bar\+0x178> beqzl zero,000203e0 <bar\+0x190> +000203cc <bar\+0x17c> nop +000203d0 <bar\+0x180> lw at,0\(gp\) + 203d0: R_MIPS_GOT16 \.text +000203d4 <bar\+0x184> addiu at,at,0 + 203d4: R_MIPS_LO16 \.text +000203d8 <bar\+0x188> jr at +000203dc <bar\+0x18c> nop +000203e0 <bar\+0x190> bltzl a0,000203f0 <bar\+0x1a0> +000203e4 <bar\+0x194> nop +000203e8 <bar\+0x198> beqzl zero,00020400 <bar\+0x1b0> +000203ec <bar\+0x19c> nop +000203f0 <bar\+0x1a0> lw at,0\(gp\) + 203f0: R_MIPS_GOT16 \.text +000203f4 <bar\+0x1a4> addiu at,at,0 + 203f4: R_MIPS_LO16 \.text +000203f8 <bar\+0x1a8> jr at +000203fc <bar\+0x1ac> nop +00020400 <bar\+0x1b0> bgezl a1,00020410 <bar\+0x1c0> +00020404 <bar\+0x1b4> nop +00020408 <bar\+0x1b8> beqzl zero,00020420 <bar\+0x1d0> +0002040c <bar\+0x1bc> nop +00020410 <bar\+0x1c0> lw at,0\(gp\) + 20410: R_MIPS_GOT16 \.text +00020414 <bar\+0x1c4> addiu at,at,0 + 20414: R_MIPS_LO16 \.text +00020418 <bar\+0x1c8> jr at +0002041c <bar\+0x1cc> nop +00020420 <bar\+0x1d0> bc1fl 00020430 <bar\+0x1e0> +00020424 <bar\+0x1d4> nop +00020428 <bar\+0x1d8> beqzl zero,00020440 <bar\+0x1f0> +0002042c <bar\+0x1dc> nop +00020430 <bar\+0x1e0> lw at,0\(gp\) + 20430: R_MIPS_GOT16 \.text +00020434 <bar\+0x1e4> addiu at,at,0 + 20434: R_MIPS_LO16 \.text +00020438 <bar\+0x1e8> jr at +0002043c <bar\+0x1ec> nop +00020440 <bar\+0x1f0> bc1tl 00020450 <bar\+0x200> +00020444 <bar\+0x1f4> nop +00020448 <bar\+0x1f8> beqzl zero,00020460 <bar\+0x210> +0002044c <bar\+0x1fc> nop +00020450 <bar\+0x200> lw at,0\(gp\) + 20450: R_MIPS_GOT16 \.text +00020454 <bar\+0x204> addiu at,at,0 + 20454: R_MIPS_LO16 \.text +00020458 <bar\+0x208> jr at +0002045c <bar\+0x20c> nop +00020460 <bar\+0x210> bltzl v0,00020470 <bar\+0x220> +00020464 <bar\+0x214> nop +00020468 <bar\+0x218> beqzl zero,00020480 <bar\+0x230> +0002046c <bar\+0x21c> nop +00020470 <bar\+0x220> lw at,0\(gp\) + 20470: R_MIPS_GOT16 \.text +00020474 <bar\+0x224> addiu at,at,0 + 20474: R_MIPS_LO16 \.text +00020478 <bar\+0x228> jalr at +0002047c <bar\+0x22c> nop +00020480 <bar\+0x230> bgezl v1,00020490 <bar\+0x240> +00020484 <bar\+0x234> nop +00020488 <bar\+0x238> beqzl zero,000204a0 <bar\+0x250> +0002048c <bar\+0x23c> nop +00020490 <bar\+0x240> lw at,0\(gp\) + 20490: R_MIPS_GOT16 \.text +00020494 <bar\+0x244> addiu at,at,0 + 20494: R_MIPS_LO16 \.text +00020498 <bar\+0x248> jalr at +0002049c <bar\+0x24c> nop Index: gas/testsuite/gas/mips/relax.l =================================================================== RCS file: gas/testsuite/gas/mips/relax.l diff -N gas/testsuite/gas/mips/relax.l --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gas/testsuite/gas/mips/relax.l 9 Oct 2002 23:33:35 -0000 @@ -0,0 +1,45 @@ +.*: Assembler messages: +.*:5: Warning: relaxed out-of-range branch into a jump +.*:6: Warning: relaxed out-of-range branch into a jump +.*:7: Warning: relaxed out-of-range branch into a jump +.*:8: Warning: relaxed out-of-range branch into a jump +.*:9: Warning: relaxed out-of-range branch into a jump +.*:10: Warning: relaxed out-of-range branch into a jump +.*:11: Warning: relaxed out-of-range branch into a jump +.*:12: Warning: relaxed out-of-range branch into a jump +.*:13: Warning: relaxed out-of-range branch into a jump +.*:14: Warning: relaxed out-of-range branch into a jump +.*:16: Warning: relaxed out-of-range branch into a jump +.*:17: Warning: relaxed out-of-range branch into a jump +.*:19: Warning: relaxed out-of-range branch into a jump +.*:20: Warning: relaxed out-of-range branch into a jump +.*:21: Warning: relaxed out-of-range branch into a jump +.*:22: Warning: relaxed out-of-range branch into a jump +.*:23: Warning: relaxed out-of-range branch into a jump +.*:24: Warning: relaxed out-of-range branch into a jump +.*:25: Warning: relaxed out-of-range branch into a jump +.*:26: Warning: relaxed out-of-range branch into a jump +.*:28: Warning: relaxed out-of-range branch into a jump +.*:29: Warning: relaxed out-of-range branch into a jump +.*:33: Warning: relaxed out-of-range branch into a jump +.*:34: Warning: relaxed out-of-range branch into a jump +.*:35: Warning: relaxed out-of-range branch into a jump +.*:36: Warning: relaxed out-of-range branch into a jump +.*:37: Warning: relaxed out-of-range branch into a jump +.*:38: Warning: relaxed out-of-range branch into a jump +.*:39: Warning: relaxed out-of-range branch into a jump +.*:40: Warning: relaxed out-of-range branch into a jump +.*:41: Warning: relaxed out-of-range branch into a jump +.*:42: Warning: relaxed out-of-range branch into a jump +.*:44: Warning: relaxed out-of-range branch into a jump +.*:45: Warning: relaxed out-of-range branch into a jump +.*:47: Warning: relaxed out-of-range branch into a jump +.*:48: Warning: relaxed out-of-range branch into a jump +.*:49: Warning: relaxed out-of-range branch into a jump +.*:50: Warning: relaxed out-of-range branch into a jump +.*:51: Warning: relaxed out-of-range branch into a jump +.*:52: Warning: relaxed out-of-range branch into a jump +.*:53: Warning: relaxed out-of-range branch into a jump +.*:54: Warning: relaxed out-of-range branch into a jump +.*:56: Warning: relaxed out-of-range branch into a jump +.*:57: Warning: relaxed out-of-range branch into a jump Index: gas/testsuite/gas/mips/relax.s =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/relax.s,v retrieving revision 1.1 diff -u -p -r1.1 relax.s --- gas/testsuite/gas/mips/relax.s 9 Jun 2001 06:25:55 -0000 1.1 +++ gas/testsuite/gas/mips/relax.s 9 Oct 2002 23:33:35 -0000 @@ -2,6 +2,56 @@ .text foo: - move $2, $3 # just something + b bar + bal bar + beq $2, $3, bar + bne $4, $5, bar + blez $2, bar + bgtz $3, bar + bltz $4, bar + bgez $5, bar + bc1f bar + bc1t bar + + bltzal $2, bar + bgezal $3, bar + + beql $2, $3, bar + bnel $4, $5, bar + blezl $2, bar + bgtzl $3, bar + bltzl $4, bar + bgezl $5, bar + bc1fl bar + bc1tl bar + + bltzall $2, bar + bgezall $3, bar + .space 0x20000 # to make a 128kb loop body - beq $2, $3, foo +bar: + b foo + bal foo + beq $2, $3, foo + bne $4, $5, foo + blez $2, foo + bgtz $3, foo + bltz $4, foo + bgez $5, foo + bc1f foo + bc1t foo + + bltzal $2, foo + bgezal $3, foo + + beql $2, $3, foo + bnel $4, $5, foo + blezl $2, foo + bgtzl $3, foo + bltzl $4, foo + bgezl $5, foo + bc1fl foo + bc1tl foo + + bltzall $2, foo + bgezall $3, foo [-- Attachment #3: Type: text/plain, Size: 289 bytes --] -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-10-09 16:51 ` Alexandre Oliva @ 2002-10-09 16:54 ` Alexandre Oliva 2002-10-09 17:17 ` H. J. Lu 2002-10-11 13:08 ` Eric Christopher 1 sibling, 1 reply; 28+ messages in thread From: Alexandre Oliva @ 2002-10-09 16:54 UTC (permalink / raw) To: Thiemo Seufer; +Cc: Richard Henderson, Daniel Jacobowitz, binutils, echristo On Oct 9, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > Ok to install? I forgot to mention this introduced no regressions in a athlon-pc-linux-gnu-hosted mips64-linux testsuite run. I.e., MIPS branch-misc-2 was broken before, and remains broken after the patch. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-10-09 16:54 ` Alexandre Oliva @ 2002-10-09 17:17 ` H. J. Lu 0 siblings, 0 replies; 28+ messages in thread From: H. J. Lu @ 2002-10-09 17:17 UTC (permalink / raw) To: Alexandre Oliva Cc: Thiemo Seufer, Richard Henderson, Daniel Jacobowitz, binutils, echristo On Wed, Oct 09, 2002 at 08:53:38PM -0300, Alexandre Oliva wrote: > On Oct 9, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > > > Ok to install? > > I forgot to mention this introduced no regressions in a > athlon-pc-linux-gnu-hosted mips64-linux testsuite run. I.e., MIPS > branch-misc-2 was broken before, and remains broken after the patch. FYI, branch-misc-2 has been fixed in my Linux binutils. H.J. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-10-09 16:51 ` Alexandre Oliva 2002-10-09 16:54 ` Alexandre Oliva @ 2002-10-11 13:08 ` Eric Christopher 1 sibling, 0 replies; 28+ messages in thread From: Eric Christopher @ 2002-10-11 13:08 UTC (permalink / raw) To: Alexandre Oliva Cc: Thiemo Seufer, Richard Henderson, Daniel Jacobowitz, binutils > > Ok to install? > OK. I really wish we could use the generic tables, but this is a start. -eric -- Yeah, I used to play basketball... ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 4:49 MIPS assembler branch relaxations Alexandre Oliva 2002-09-14 14:28 ` Daniel Jacobowitz @ 2002-09-14 14:39 ` H. J. Lu 2002-09-14 23:12 ` Alexandre Oliva 2002-09-15 1:00 ` Alexandre Oliva 2 siblings, 1 reply; 28+ messages in thread From: H. J. Lu @ 2002-09-14 14:39 UTC (permalink / raw) To: Alexandre Oliva; +Cc: binutils, echristo On Sat, Sep 14, 2002 at 02:59:45AM -0300, Alexandre Oliva wrote: > This patch arranges for the MIPS assembler to turn out-of-range > branches into jumps. No regressions are introduced in the binutils > testsuites for a mips-linux build. Details on how it is done are in > comments in the beginning of the patch. Ok to install? > Have you checked it against g++.dg/opt/longbranch1.C in gcc 3.2 on Linux/mips? It should pass now. H.J. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 14:39 ` H. J. Lu @ 2002-09-14 23:12 ` Alexandre Oliva 2002-09-15 9:13 ` H. J. Lu 0 siblings, 1 reply; 28+ messages in thread From: Alexandre Oliva @ 2002-09-14 23:12 UTC (permalink / raw) To: H. J. Lu; +Cc: binutils, echristo On Sep 14, 2002, "H. J. Lu" <hjl@lucon.org> wrote: > Have you checked it against g++.dg/opt/longbranch1.C in gcc 3.2 on > Linux/mips? It should pass now. Nope. I'm still struggling to get a stable kernel for mips-linux development, on which I'd be able to bootstrap gcc and test it. -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 23:12 ` Alexandre Oliva @ 2002-09-15 9:13 ` H. J. Lu 2002-09-15 15:32 ` Eric Christopher 0 siblings, 1 reply; 28+ messages in thread From: H. J. Lu @ 2002-09-15 9:13 UTC (permalink / raw) To: Alexandre Oliva; +Cc: binutils, echristo On Sun, Sep 15, 2002 at 01:33:15AM -0300, Alexandre Oliva wrote: > On Sep 14, 2002, "H. J. Lu" <hjl@lucon.org> wrote: > > > Have you checked it against g++.dg/opt/longbranch1.C in gcc 3.2 on > > Linux/mips? It should pass now. > > Nope. I'm still struggling to get a stable kernel for mips-linux 2.4 kernel from oss.sgi.com has been extremely stable for me on Malta. > development, on which I'd be able to bootstrap gcc and test it. > How about gas/mips/relax.s? I added it and marked it xfail, hoping one day someone would fix it :-). H.J. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-15 9:13 ` H. J. Lu @ 2002-09-15 15:32 ` Eric Christopher 2002-09-15 16:53 ` H. J. Lu 0 siblings, 1 reply; 28+ messages in thread From: Eric Christopher @ 2002-09-15 15:32 UTC (permalink / raw) To: H. J. Lu; +Cc: Alexandre Oliva, binutils > > development, on which I'd be able to bootstrap gcc and test it. > > > > How about gas/mips/relax.s? I added it and marked it xfail, hoping > one day someone would fix it :-). I thought the patch he posted had changes to mips.exp about relax.s :) -eric -- Yuppies wear socks. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-15 15:32 ` Eric Christopher @ 2002-09-15 16:53 ` H. J. Lu 0 siblings, 0 replies; 28+ messages in thread From: H. J. Lu @ 2002-09-15 16:53 UTC (permalink / raw) To: Eric Christopher; +Cc: Alexandre Oliva, binutils On Sun, Sep 15, 2002 at 10:58:32AM -0700, Eric Christopher wrote: > > > > development, on which I'd be able to bootstrap gcc and test it. > > > > > > > How about gas/mips/relax.s? I added it and marked it xfail, hoping > > one day someone would fix it :-). > > I thought the patch he posted had changes to mips.exp about relax.s :) Great. H.J. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: MIPS assembler branch relaxations 2002-09-14 4:49 MIPS assembler branch relaxations Alexandre Oliva 2002-09-14 14:28 ` Daniel Jacobowitz 2002-09-14 14:39 ` H. J. Lu @ 2002-09-15 1:00 ` Alexandre Oliva 2 siblings, 0 replies; 28+ messages in thread From: Alexandre Oliva @ 2002-09-15 1:00 UTC (permalink / raw) To: binutils; +Cc: echristo On Sep 14, 2002, Alexandre Oliva <aoliva@redhat.com> wrote: > + val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset; > + > + addr = fragp->fr_address + fragp->fr_fix; > + > + val -= addr; > + > + toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2); I just realized this test is off by 4. The base address added to the branch offset is the address of the instruction in the delay slot, not that of the branch instruction. I'm amending the patch as follows: addr = fragp->fr_address + fragp->fr_fix + 4; -- Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/ Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org} CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org} Free Software Evangelist Professional serial bug killer ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2002-10-11 20:08 UTC | newest] Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-09-14 4:49 MIPS assembler branch relaxations Alexandre Oliva 2002-09-14 14:28 ` Daniel Jacobowitz 2002-09-14 14:46 ` Eric Christopher 2002-09-14 21:33 ` Daniel Jacobowitz 2002-09-14 21:33 ` Eric Christopher 2002-09-14 15:00 ` Paul Koning 2002-09-14 16:35 ` Daniel Jacobowitz 2002-09-14 18:43 ` Paul Koning 2002-09-14 21:39 ` Thiemo Seufer 2002-09-14 22:18 ` Alexandre Oliva 2002-09-15 2:25 ` Thiemo Seufer 2002-09-15 3:38 ` Alexandre Oliva 2002-09-15 0:49 ` Alexandre Oliva 2002-09-15 9:15 ` Daniel Jacobowitz 2002-09-16 11:56 ` Richard Henderson 2002-09-17 0:09 ` Alexandre Oliva 2002-09-17 0:26 ` Richard Henderson 2002-09-17 0:38 ` Thiemo Seufer 2002-10-09 16:51 ` Alexandre Oliva 2002-10-09 16:54 ` Alexandre Oliva 2002-10-09 17:17 ` H. J. Lu 2002-10-11 13:08 ` Eric Christopher 2002-09-14 14:39 ` H. J. Lu 2002-09-14 23:12 ` Alexandre Oliva 2002-09-15 9:13 ` H. J. Lu 2002-09-15 15:32 ` Eric Christopher 2002-09-15 16:53 ` H. J. Lu 2002-09-15 1:00 ` Alexandre Oliva
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).