Patch to improve MIPS %hi/%lo matching

Richard Sandiford rsandifo@redhat.com
Sat Jul 3 10:49:00 GMT 2004


This patch follows on from the discussion with Maciej about code like:

        lui     $4,%hi(foo)
        lh      $4,%lo(foo+2)($4)

where the %hi() and %lo() have different offsets.  It's also related
to gcc PR 16310 (see <http://gcc.gnu.org/PR16310>).

The question is basically: is this legal assembly code, and if so,
what should we do with it?

The answer for RELA targets is easy.  Both the %hi() and %lo() expressions
can be accurately converted to relocations.  The code is legal assembly
(regardless of whether it does what the user wants at run time) and no
special action is needed.

The answer for REL targets is less clear.

In cases like these, the most natural follow-on question is often: what do
other MIPS assemblers do?  But that isn't much help here.  I think gas is
the only assembler to support explicit relocs on REL targets.

The next follow-on question might then be: can we produce sensible
output for this code?  And the answer to that is IMO "yes".  The code
only really makes sense if the user knows that adding 2 to "foo" will
not cause a carry from the low 16 bits to the high 16 bits.  It can
therefore be assembled as follows:

        lui     $4,0     (R_MIPS_HI16 foo)
        addiu   $4,$4,2  (R_MIPS_LO16 foo)

(with the relocations in that order).  This is strictly-conforming,
and no different from the code that we'd produce for "lh $4,foo+2",
or for:

        lui     $4,%hi(foo+2)
        lh      $4,%lo(foo+2)($4)

The same applies when relocations against "foo" are converted into
relocations against the section symbol.

So, if we can produce sensible output, can we do it _easily_?  Again, I
think we can.  See the attached patch.  Not only does it cope with this
sort of situation, but it also makes the code simpler, and means that
the inner loop only makes one pass over the relocs, as opposed to the
current two or three.  (That said, each of the existing passes has an
early exit, whereas the new one doesn't, so I can't claim it's a
clear-cut win.)

So the final question is: should we disallow it anyway?  And I don't
think we should.  Although an asm programmer would write "%hi(foo+2)",
the fact that gcc doesn't is not a bug.  gcc knows that, if you have:

        lui     $4,%hi(foo)

and "foo" is known to be N-byte aligned, then "$4 + %lo(foo + M)"
will address "foo + M" if 0 <= M < N.  It relies on this rule to
reuse %hi()s for expressions like:

        lui     $4,%hi(double_value)
        lw      $5,%lo(double_value)($4)
        lw      $6,%lo(double_value + 4)($4)

I don't think there's much disagreement that this code is legal.  But if,
after splitting the move into two lws, the compiler realises that $5 isn't
needed, it's perfectly free to delete the load.  The code should still be
legal IMO, and would certainly work on RELA targets.

-------------

So... onto the patch ;)  I hope the comments explain what's happening
well enough.

While working on this, I noticed that we were reordering relocations
on RELA targets.  That's unnecessary work, and likely to confuse anyone
looking at object dumps.  I'd therefore like to disable it.

The patch needs a few testsuite changes:

  - In elf{,el}-rel.d, we expect the relocation for the first %hi(foo)
    to match the relocation for the last %lo(foo).  After the patch,
    the first %hi(foo) will match the first %lo(foo).

    I wondered about changing the patch so that it preserves the
    existing behaviour, but it's easier to code the way it is, and I
    think the new order is more natural for anyone who has to read the
    relocation dumps.

  - We need Maciej's fix for elf-rel9.[sd].

  - elf-rel11.d was a case where we were reordering RELA relocations.

The patch also adds a testcase to cover cases like those discussed here.

Tested on:

   mips64-elf  mips64el-elf  mips-elf  mipsel-elf  mips-ecoff
   mips-linux-gnu  mipsel-linux-gnu mips64-linux-gnu  mips64el-linux-gnu

no regressions.  OK to install?

Richard


	* config/tc-mips.c (HAVE_IN_PLACE_ADDENDS): New macro.
	(reloc_needs_lo_p): Only return true if HAVE_IN_PLACE_ADDENDS.
	(mips_frob_file): Rework so that only a single pass through the
	relocs is needed.  Allow %lo()s to have higher offsets than their
	corresponding %hi()s or %got()s.

testsuite/
	* gas/mips/elf{,el}-rel.d: Adjust so that the earliest %hi() matches
	the earliest %lo().
	* gas/mips/elf-rel9.[sd]: Fix typo in %lo() expression.
	* gas/mips/elf-rel11.d: Don't expect the relocs to be reordered.
	* gas/mips/elf-rel20.[sd]: New test.
	* gas/mips/mips.exp: Run it.

Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.266
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.266 tc-mips.c
*** gas/config/tc-mips.c	15 Jun 2004 01:16:35 -0000	1.266
--- gas/config/tc-mips.c	3 Jul 2004 10:39:11 -0000
*************** #define HAVE_NEWABI (mips_abi == N32_ABI
*** 279,284 ****
--- 279,287 ----
  
  #define HAVE_64BIT_OBJECTS (mips_abi == N64_ABI)
  
+ /* True if relocations are stored in-place.  */
+ #define HAVE_IN_PLACE_ADDENDS (!HAVE_NEWABI)
+ 
  /* We can only have 64bit addresses if the object file format supports it.  */
  #define HAVE_32BIT_ADDRESSES                           \
     (HAVE_32BIT_GPRS                                    \
*************** md_assemble (char *str)
*** 1398,1405 ****
  static inline bfd_boolean
  reloc_needs_lo_p (bfd_reloc_code_real_type reloc)
  {
!   return (reloc == BFD_RELOC_HI16_S
! 	  || reloc == BFD_RELOC_MIPS_GOT16);
  }
  
  /* Return true if the given fixup is followed by a matching R_MIPS_LO16
--- 1401,1409 ----
  static inline bfd_boolean
  reloc_needs_lo_p (bfd_reloc_code_real_type reloc)
  {
!   return (HAVE_IN_PLACE_ADDENDS
! 	  && (reloc == BFD_RELOC_HI16_S
! 	      || reloc == BFD_RELOC_MIPS_GOT16));
  }
  
  /* Return true if the given fixup is followed by a matching R_MIPS_LO16
*************** mips_frob_file_before_adjust (void)
*** 10670,10679 ****
  #endif
  }
  
! /* Sort any unmatched HI16_S relocs so that they immediately precede
!    the corresponding LO reloc.  This is called before md_apply_fix3 and
!    tc_gen_reloc.  Unmatched HI16_S relocs can only be generated by
!    explicit use of the %hi modifier.  */
  
  void
  mips_frob_file (void)
--- 10674,10726 ----
  #endif
  }
  
! /* Sort any unmatched HI16 and GOT16 relocs so that they immediately precede
!    the corresponding LO16 reloc.  This is called before md_apply_fix3 and
!    tc_gen_reloc.  Unmatched relocs can only be generated by use of explicit
!    relocation operators.
! 
!    For our purposes, a %lo() expression matches a %got() or %hi()
!    expression if:
! 
!       (a) it refers to the same symbol; and
!       (b) the offset applied in the %lo() expression is no lower than
! 	  the offset applied in the %got() or %hi().
! 
!    (b) allows us to cope with code like:
! 
! 	lui	$4,%hi(foo)
! 	lh	$4,%lo(foo+2)($4)
! 
!    ...which is legal on RELA targets, and has a well-defined behaviour
!    if the user knows that adding 2 to "foo" will not induce a carry to
!    the high 16 bits.
! 
!    When several %lo()s match a particular %got() or %hi(), we use the
!    following rules to distinguish them:
! 
!      (1) %lo()s with smaller offsets are a better match than %lo()s with
!          higher offsets.
! 
!      (2) %lo()s with no matching %got() or %hi() are better than those
!          that already have a matching %got() or %hi().
! 
!      (3) later %lo()s are better than earlier %lo()s.
! 
!    These rules are applied in order.
! 
!    (1) means, among other things, that %lo()s with identical offsets are
!    chosen if they exist.
! 
!    (2) means that we won't associate several high-part relocations with
!    the same low-part relocation unless there's no alternative.  Having
!    several high parts for the same low part is a GNU extension; this rule
!    allows careful users to avoid it.
! 
!    (3) is purely cosmetic.  mips_hi_fixup_list is is in reverse order,
!    with the last high-part relocation being at the front of the list.
!    It therefore makes sense to choose the last matching low-part
!    relocation, all other things being equal.  It's also easier
!    to code that way.  */
  
  void
  mips_frob_file (void)
*************** mips_frob_file (void)
*** 10683,10689 ****
    for (l = mips_hi_fixup_list; l != NULL; l = l->next)
      {
        segment_info_type *seginfo;
!       int pass;
  
        assert (reloc_needs_lo_p (l->fixp->fx_r_type));
  
--- 10730,10737 ----
    for (l = mips_hi_fixup_list; l != NULL; l = l->next)
      {
        segment_info_type *seginfo;
!       bfd_boolean matched_lo_p;
!       fixS **hi_pos, **lo_pos, **pos;
  
        assert (reloc_needs_lo_p (l->fixp->fx_r_type));
  
*************** mips_frob_file (void)
*** 10697,10755 ****
        if (fixup_has_matching_lo_p (l->fixp))
  	continue;
  
-       /* Look through the fixups for this segment for a matching %lo.
-          When we find one, move the %hi just in front of it.  We do
-          this in two passes.  In the first pass, we try to find a
-          unique %lo.  In the second pass, we permit multiple %hi
-          relocs for a single %lo (this is a GNU extension).  */
        seginfo = seg_info (l->seg);
-       for (pass = 0; pass < 2; pass++)
- 	{
- 	  fixS *f, *prev;
  
! 	  prev = NULL;
! 	  for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
! 	    {
! 	      /* Check whether this is a %lo fixup which matches l->fixp.  */
! 	      if (f->fx_r_type == BFD_RELOC_LO16
! 		  && f->fx_addsy == l->fixp->fx_addsy
! 		  && f->fx_offset == l->fixp->fx_offset
! 		  && (pass == 1
! 		      || prev == NULL
! 		      || !reloc_needs_lo_p (prev->fx_r_type)
! 		      || !fixup_has_matching_lo_p (prev)))
! 		{
! 		  fixS **pf;
! 
! 		  /* Move l->fixp before f.  */
! 		  for (pf = &seginfo->fix_root;
! 		       *pf != l->fixp;
! 		       pf = &(*pf)->fx_next)
! 		    assert (*pf != NULL);
! 
! 		  *pf = l->fixp->fx_next;
! 
! 		  l->fixp->fx_next = f;
! 		  if (prev == NULL)
! 		    seginfo->fix_root = l->fixp;
! 		  else
! 		    prev->fx_next = l->fixp;
! 
! 		  break;
! 		}
! 
! 	      prev = f;
  	    }
- 
- 	  if (f != NULL)
- 	    break;
- 
- #if 0 /* GCC code motion plus incomplete dead code elimination
- 	 can leave a %hi without a %lo.  */
- 	  if (pass == 1)
- 	    as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
- 			   _("Unmatched %%hi reloc"));
- #endif
  	}
      }
  }
--- 10745,10795 ----
        if (fixup_has_matching_lo_p (l->fixp))
  	continue;
  
        seginfo = seg_info (l->seg);
  
!       /* Set HI_POS to the position of this relocation in the chain.
! 	 Set LO_POS to the position of the chosen low-part relocation.
! 	 MATCHED_LO_P is true on entry to the loop if *POS is a low-part
! 	 relocation that matches an immediately-preceding high-part
! 	 relocation.  */
!       hi_pos = NULL;
!       lo_pos = NULL;
!       matched_lo_p = FALSE;
!       for (pos = &seginfo->fix_root; *pos != NULL; pos = &(*pos)->fx_next)
! 	{
! 	  if (*pos == l->fixp)
! 	    hi_pos = pos;
! 
! 	  if ((*pos)->fx_r_type == BFD_RELOC_LO16
! 	      && (*pos)->fx_addsy == l->fixp->fx_addsy
! 	      && (*pos)->fx_offset >= l->fixp->fx_offset
! 	      && (lo_pos == NULL
! 		  || (*pos)->fx_offset < (*lo_pos)->fx_offset
! 		  || (!matched_lo_p
! 		      && (*pos)->fx_offset == (*lo_pos)->fx_offset)))
! 	    lo_pos = pos;
! 
! 	  matched_lo_p = (reloc_needs_lo_p ((*pos)->fx_r_type)
! 			  && fixup_has_matching_lo_p (*pos));
! 	}
! 
!       /* If we found a match, remove the high-part relocation from its
! 	 current position and insert it before the low-part relocation.
! 	 Make the offsets match so that fixup_has_matching_lo_p()
! 	 will return true.
! 
! 	 We don't warn about unmatched high-part relocations since some
! 	 versions of gcc have been known to emit dead "lui ...%hi(...)"
! 	 instructions.  */
!       if (lo_pos != NULL)
! 	{
! 	  l->fixp->fx_offset = (*lo_pos)->fx_offset;
! 	  if (l->fixp->fx_next != *lo_pos)
! 	    {
! 	      *hi_pos = l->fixp->fx_next;
! 	      l->fixp->fx_next = *lo_pos;
! 	      *lo_pos = l->fixp;
  	    }
  	}
      }
  }
Index: gas/testsuite/gas/mips/elf-rel.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/elf-rel.d,v
retrieving revision 1.7
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.7 elf-rel.d
*** gas/testsuite/gas/mips/elf-rel.d	7 May 2003 05:08:20 -0000	1.7
--- gas/testsuite/gas/mips/elf-rel.d	3 Jul 2004 10:39:11 -0000
*************** 0+0000010 R_MIPS_HI16       \.text
*** 22,48 ****
  0+000002c R_MIPS_LO16       \.text
  0+0000030 R_MIPS_HI16       \.text
  0+0000048 R_MIPS_LO16       \.text
! 0+0000064 R_MIPS_HI16       \.text
  0+000004c R_MIPS_LO16       \.text
! 0+0000068 R_MIPS_HI16       \.text
  0+0000050 R_MIPS_LO16       \.text
! 0+000006c R_MIPS_HI16       \.text
  0+0000054 R_MIPS_LO16       \.text
! 0+0000074 R_MIPS_HI16       \.text
  0+0000058 R_MIPS_LO16       \.text
! 0+0000070 R_MIPS_HI16       \.text
  0+000005c R_MIPS_LO16       \.text
  0+0000060 R_MIPS_HI16       \.text
  0+0000078 R_MIPS_LO16       \.text
! 0+0000034 R_MIPS_HI16       \.text
  0+000007c R_MIPS_LO16       \.text
! 0+0000038 R_MIPS_HI16       \.text
  0+0000080 R_MIPS_LO16       \.text
! 0+000003c R_MIPS_HI16       \.text
  0+0000084 R_MIPS_LO16       \.text
! 0+0000044 R_MIPS_HI16       \.text
  0+0000088 R_MIPS_LO16       \.text
! 0+0000040 R_MIPS_HI16       \.text
  0+000008c R_MIPS_LO16       \.text
  
  
--- 22,48 ----
  0+000002c R_MIPS_LO16       \.text
  0+0000030 R_MIPS_HI16       \.text
  0+0000048 R_MIPS_LO16       \.text
! 0+0000034 R_MIPS_HI16       \.text
  0+000004c R_MIPS_LO16       \.text
! 0+0000038 R_MIPS_HI16       \.text
  0+0000050 R_MIPS_LO16       \.text
! 0+000003c R_MIPS_HI16       \.text
  0+0000054 R_MIPS_LO16       \.text
! 0+0000044 R_MIPS_HI16       \.text
  0+0000058 R_MIPS_LO16       \.text
! 0+0000040 R_MIPS_HI16       \.text
  0+000005c R_MIPS_LO16       \.text
  0+0000060 R_MIPS_HI16       \.text
  0+0000078 R_MIPS_LO16       \.text
! 0+0000064 R_MIPS_HI16       \.text
  0+000007c R_MIPS_LO16       \.text
! 0+0000068 R_MIPS_HI16       \.text
  0+0000080 R_MIPS_LO16       \.text
! 0+000006c R_MIPS_HI16       \.text
  0+0000084 R_MIPS_LO16       \.text
! 0+0000074 R_MIPS_HI16       \.text
  0+0000088 R_MIPS_LO16       \.text
! 0+0000070 R_MIPS_HI16       \.text
  0+000008c R_MIPS_LO16       \.text
  
  
Index: gas/testsuite/gas/mips/elf-rel11.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/elf-rel11.d,v
retrieving revision 1.1
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.1 elf-rel11.d
*** gas/testsuite/gas/mips/elf-rel11.d	2 Feb 2003 19:37:20 -0000	1.1
--- gas/testsuite/gas/mips/elf-rel11.d	3 Jul 2004 10:39:11 -0000
*************** Relocation section '\.rela\.text' at off
*** 7,16 ****
  0+0000 * 0+..0000001d * R_MIPS_HIGHEST * 0+0000 * bar \+ 0
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+0008 * 0+..0000001c * R_MIPS_HIGHER * 0+0000 * bar \+ 0
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+0004 * 0+..00000005 * R_MIPS_HI16 * 0+0000 * bar \+ 0
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
  0+000c * 0+..00000006 * R_MIPS_LO16 * 0+0000 * bar \+ 0
--- 7,16 ----
  0+0000 * 0+..0000001d * R_MIPS_HIGHEST * 0+0000 * bar \+ 0
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+0004 * 0+..00000005 * R_MIPS_HI16 * 0+0000 * bar \+ 0
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+0008 * 0+..0000001c * R_MIPS_HIGHER * 0+0000 * bar \+ 0
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
  0+000c * 0+..00000006 * R_MIPS_LO16 * 0+0000 * bar \+ 0
*************** 0+000c * 0+..00000006 * R_MIPS_LO16 * 0+
*** 19,28 ****
  0+0018 * 0+..0000001d * R_MIPS_HIGHEST * 0+0000 * bar \+ 12345678
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+0020 * 0+..0000001c * R_MIPS_HIGHER * 0+0000 * bar \+ 12345678
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+001c * 0+..00000005 * R_MIPS_HI16 * 0+0000 * bar \+ 12345678
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
  0+0024 * 0+..00000006 * R_MIPS_LO16 * 0+0000 * bar \+ 12345678
--- 19,28 ----
  0+0018 * 0+..0000001d * R_MIPS_HIGHEST * 0+0000 * bar \+ 12345678
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+001c * 0+..00000005 * R_MIPS_HI16 * 0+0000 * bar \+ 12345678
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
! 0+0020 * 0+..0000001c * R_MIPS_HIGHER * 0+0000 * bar \+ 12345678
   * Type2: R_MIPS_NONE *
   * Type3: R_MIPS_NONE *
  0+0024 * 0+..00000006 * R_MIPS_LO16 * 0+0000 * bar \+ 12345678
Index: gas/testsuite/gas/mips/elf-rel9.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/elf-rel9.d,v
retrieving revision 1.1
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.1 elf-rel9.d
*** gas/testsuite/gas/mips/elf-rel9.d	2 Feb 2003 19:37:20 -0000	1.1
--- gas/testsuite/gas/mips/elf-rel9.d	3 Jul 2004 10:39:11 -0000
*************** 0+00 <foo>:
*** 45,51 ****
  			44: R_MIPS_LO16	\.data
    48:	8f840002 	lw	\$4,2\(\$28\)
  			48: R_MIPS_GOT16	\.data
!   4c:	2484f100 	addiu	\$4,\$4,-3840
  			4c: R_MIPS_LO16	\.data
    50:	8f840003 	lw	\$4,3\(\$28\)
  			50: R_MIPS_GOT16	\.data
--- 45,51 ----
  			44: R_MIPS_LO16	\.data
    48:	8f840002 	lw	\$4,2\(\$28\)
  			48: R_MIPS_GOT16	\.data
!   4c:	24840000 	addiu	\$4,\$4,0
  			4c: R_MIPS_LO16	\.data
    50:	8f840003 	lw	\$4,3\(\$28\)
  			50: R_MIPS_GOT16	\.data
Index: gas/testsuite/gas/mips/elf-rel9.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/elf-rel9.s,v
retrieving revision 1.1
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.1 elf-rel9.s
*** gas/testsuite/gas/mips/elf-rel9.s	2 Feb 2003 19:37:20 -0000	1.1
--- gas/testsuite/gas/mips/elf-rel9.s	3 Jul 2004 10:39:11 -0000
*************** foo:
*** 28,34 ****
  	addiu	$4,$4,%lo(l2 + 0xfff)
  
  	lw	$4,%got(l2 + 0x1000)($28)
! 	addiu	$4,$4,%lo(l2 + 0x100)
  
  	lw	$4,%got(l2 + 0x12345)($28)
  	addiu	$4,$4,%lo(l2 + 0x12345)
--- 28,34 ----
  	addiu	$4,$4,%lo(l2 + 0xfff)
  
  	lw	$4,%got(l2 + 0x1000)($28)
! 	addiu	$4,$4,%lo(l2 + 0x1000)
  
  	lw	$4,%got(l2 + 0x12345)($28)
  	addiu	$4,$4,%lo(l2 + 0x12345)
Index: gas/testsuite/gas/mips/elfel-rel.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/elfel-rel.d,v
retrieving revision 1.6
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.6 elfel-rel.d
*** gas/testsuite/gas/mips/elfel-rel.d	19 Sep 2003 23:34:16 -0000	1.6
--- gas/testsuite/gas/mips/elfel-rel.d	3 Jul 2004 10:39:11 -0000
*************** 0+0000010 R_MIPS_HI16       \.text
*** 23,49 ****
  0+000002c R_MIPS_LO16       \.text
  0+0000030 R_MIPS_HI16       \.text
  0+0000048 R_MIPS_LO16       \.text
! 0+0000064 R_MIPS_HI16       \.text
  0+000004c R_MIPS_LO16       \.text
! 0+0000068 R_MIPS_HI16       \.text
  0+0000050 R_MIPS_LO16       \.text
! 0+000006c R_MIPS_HI16       \.text
  0+0000054 R_MIPS_LO16       \.text
! 0+0000074 R_MIPS_HI16       \.text
  0+0000058 R_MIPS_LO16       \.text
! 0+0000070 R_MIPS_HI16       \.text
  0+000005c R_MIPS_LO16       \.text
  0+0000060 R_MIPS_HI16       \.text
  0+0000078 R_MIPS_LO16       \.text
! 0+0000034 R_MIPS_HI16       \.text
  0+000007c R_MIPS_LO16       \.text
! 0+0000038 R_MIPS_HI16       \.text
  0+0000080 R_MIPS_LO16       \.text
! 0+000003c R_MIPS_HI16       \.text
  0+0000084 R_MIPS_LO16       \.text
! 0+0000044 R_MIPS_HI16       \.text
  0+0000088 R_MIPS_LO16       \.text
! 0+0000040 R_MIPS_HI16       \.text
  0+000008c R_MIPS_LO16       \.text
  
  
--- 23,49 ----
  0+000002c R_MIPS_LO16       \.text
  0+0000030 R_MIPS_HI16       \.text
  0+0000048 R_MIPS_LO16       \.text
! 0+0000034 R_MIPS_HI16       \.text
  0+000004c R_MIPS_LO16       \.text
! 0+0000038 R_MIPS_HI16       \.text
  0+0000050 R_MIPS_LO16       \.text
! 0+000003c R_MIPS_HI16       \.text
  0+0000054 R_MIPS_LO16       \.text
! 0+0000044 R_MIPS_HI16       \.text
  0+0000058 R_MIPS_LO16       \.text
! 0+0000040 R_MIPS_HI16       \.text
  0+000005c R_MIPS_LO16       \.text
  0+0000060 R_MIPS_HI16       \.text
  0+0000078 R_MIPS_LO16       \.text
! 0+0000064 R_MIPS_HI16       \.text
  0+000007c R_MIPS_LO16       \.text
! 0+0000068 R_MIPS_HI16       \.text
  0+0000080 R_MIPS_LO16       \.text
! 0+000006c R_MIPS_HI16       \.text
  0+0000084 R_MIPS_LO16       \.text
! 0+0000074 R_MIPS_HI16       \.text
  0+0000088 R_MIPS_LO16       \.text
! 0+0000070 R_MIPS_HI16       \.text
  0+000008c R_MIPS_LO16       \.text
  
  
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.91
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.91 mips.exp
*** gas/testsuite/gas/mips/mips.exp	12 May 2004 03:06:10 -0000	1.91
--- gas/testsuite/gas/mips/mips.exp	3 Jul 2004 10:39:12 -0000
*************** if { [istarget mips*-*-*] } then {
*** 660,665 ****
--- 660,666 ----
  	    run_dump_test "elf-rel18"
  	}
  	run_dump_test "elf-rel19"
+ 	run_dump_test "elf-rel20"
  
  	if { !$no_mips16 } {
  	    run_dump_test "${tmips}mips${el}16-e"
*** /dev/null	Fri Apr 23 00:21:55 2004
--- gas/testsuite/gas/mips/elf-rel20.d	Fri Jul  2 16:34:03 2004
***************
*** 0 ****
--- 1,15 ----
+ #as: -march=mips2 -mabi=32 -KPIC
+ #readelf: --relocs
+ #name: MIPS ELF reloc 20
+ 
+ Relocation section '\.rel\.text' at offset .* contains 8 entries:
+  *Offset * Info * Type * Sym\.Value * Sym\. Name
+ 0+0000 * 0+..05 * R_MIPS_HI16 * 0+0000 * foo
+ 0+0010 * 0+..06 * R_MIPS_LO16 * 0+0000 * foo
+ 0+0004 * 0+..05 * R_MIPS_HI16 * 0+0000 * foo
+ 0+0014 * 0+..06 * R_MIPS_LO16 * 0+0000 * foo
+ 0+000c * 0+..05 * R_MIPS_HI16 * 0+0000 * \.bss
+ 0+0018 * 0+..06 * R_MIPS_LO16 * 0+0000 * \.bss
+ 0+0008 * 0+..05 * R_MIPS_HI16 * 0+0000 * \.bss
+ 0+001c * 0+..06 * R_MIPS_LO16 * 0+0000 * \.bss
+ #pass
*** /dev/null	Fri Apr 23 00:21:55 2004
--- gas/testsuite/gas/mips/elf-rel20.s	Fri Jul  2 16:29:45 2004
***************
*** 0 ****
--- 1,11 ----
+ 	lui	$4,%hi(foo)
+ 	lui	$5,%hi(foo + 0x80000)
+ 	lui	$7,%hi(bar + 0x80000)
+ 	lui	$6,%hi(bar)
+ 	addiu	$4,$4,%lo(foo + 2)
+ 	addiu	$5,$5,%lo(foo + 0x80004)
+ 	addiu	$6,$6,%lo(bar + 2)
+ 	addiu	$7,$7,%lo(bar + 0x80004)
+ 	.section .bss
+ bar:
+ 	.space	0x80010



More information about the Binutils mailing list