This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
MIPS assembler branch relaxations
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: binutils at sources dot redhat dot com, echristo at redhat dot com
- Date: 14 Sep 2002 02:59:45 -0300
- Subject: MIPS assembler branch relaxations
- Organization: GCC Team, Red Hat
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?
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
--
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