public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* 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

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).