* elf32-mips.c (_bfd_mips_elf_lo16_reloc): Simplify, and perform
authorAlan Modra <amodra@gmail.com>
Sat, 5 Jan 2002 12:36:18 +0000 (12:36 +0000)
committerAlan Modra <amodra@gmail.com>
Sat, 5 Jan 2002 12:36:18 +0000 (12:36 +0000)
sign extension adjustments without conditionals.

bfd/ChangeLog
bfd/elf32-mips.c

index 4695b89..37614e4 100644 (file)
@@ -1,3 +1,8 @@
+2002-01-05  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf32-mips.c (_bfd_mips_elf_lo16_reloc): Simplify, and perform
+       sign extension adjustments without conditionals.
+
 2002-01-04  Jakub Jelinek  <jakub@redhat.com>
 
        * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Don't crash if
index 0c44c4e..63e6e02 100644 (file)
@@ -1,5 +1,5 @@
 /* MIPS-specific support for 32-bit ELF
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
@@ -1786,23 +1786,23 @@ _bfd_mips_elf_lo16_reloc (abfd,
             to know anything about the LO16 itself, except where to
             find the low 16 bits of the addend needed by the LO16.  */
          insn = bfd_get_32 (abfd, l->addr);
-         vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
-                  & 0xffff);
+         vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+         /* The low order 16 bits are always treated as a signed
+            value.  */
+         vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
          val = ((insn & 0xffff) << 16) + vallo;
          val += l->addend;
 
-         /* The low order 16 bits are always treated as a signed
-            value.  Therefore, a negative value in the low order bits
-            requires an adjustment in the high order bits.  We need
-            to make this adjustment in two ways: once for the bits we
-            took from the data, and once for the bits we are putting
-            back in to the data.  */
-         if ((vallo & 0x8000) != 0)
-           val -= 0x10000;
-         if ((val & 0x8000) != 0)
-           val += 0x10000;
-
-         insn = (insn &~ (bfd_vma) 0xffff) | ((val >> 16) & 0xffff);
+         /* At this point, "val" has the value of the combined HI/LO
+            pair.  If the low order 16 bits (which will be used for
+            the LO16 insn) are negative, then we will need an
+            adjustment for the high order 16 bits.  */
+         val += 0x8000;
+         val = (val >> 16) & 0xffff;
+
+         insn &= ~ (bfd_vma) 0xffff;
+         insn |= val;
          bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
 
          if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)