gas/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 2 Feb 2003 19:37:20 +0000 (19:37 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sun, 2 Feb 2003 19:37:20 +0000 (19:37 +0000)
* config/tc-mips.c (enum small_ex_type): Remove.
(imm_unmatched_hi): Remove.
(md_assemble): Remove use of imm_unmatched_hi.  Remove the last
argument from calls to append_insn.
(append_insn): Remove unmatched_hi parameter; check reloc_type[0]
instead.
(macro_build): Update append_insn calls.
(mips16_macro_build, macro_build_lui): Likewise.
(mips_ip): Rework handling of small expressions.  Move explicit
relocation handling into my_getSmallExpression.  Assume that the
value of 'o' operands is zero if there is only one bracketed
expression left.
(percent_op): Make constant.  Record the BFD relocation code
associated with each operator.
(my_getSmallParser, my_getPercentOp): Remove.
(parse_relocation): New function.
(my_getSamllExpression): Rework.  Fill in relocations here
rather than in mips_ip.

gas/testsuite
* gas/mips/elf-rel8.[sd], gas/mips/elf-rel9.[sd],
gas/mips/elf-rel10.[sd], gas/mips/elf-rel11.[sd]: New tests.
* gas/mips/mips.exp: Run elf-rel8 and elf-rel9 for all elf
targets.  Run elf-rel10 and elf-rel11 for NewABI targets.

12 files changed:
gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/elf-rel10.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel10.s [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel11.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel11.s [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel8.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel8.s [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel9.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel9.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp

index e71d9653ac66f1ae145b871bc790de5058bc182e..e4383bb66bdd81d70f88f7f5d92ea0706dae308a 100644 (file)
@@ -1,3 +1,24 @@
+2003-02-02  Richard Sandiford  <rsandifo@redhat.com>
+
+       * config/tc-mips.c (enum small_ex_type): Remove.
+       (imm_unmatched_hi): Remove.
+       (md_assemble): Remove use of imm_unmatched_hi.  Remove the last
+       argument from calls to append_insn.
+       (append_insn): Remove unmatched_hi parameter; check reloc_type[0]
+       instead.
+       (macro_build): Update append_insn calls.
+       (mips16_macro_build, macro_build_lui): Likewise.
+       (mips_ip): Rework handling of small expressions.  Move explicit
+       relocation handling into my_getSmallExpression.  Assume that the
+       value of 'o' operands is zero if there is only one bracketed
+       expression left.
+       (percent_op): Make constant.  Record the BFD relocation code
+       associated with each operator.
+       (my_getSmallParser, my_getPercentOp): Remove.
+       (parse_relocation): New function.
+       (my_getSamllExpression): Rework.  Fill in relocations here
+       rather than in mips_ip.
+
 2003-01-29  Nick Clifton  <nickc@redhat.com>
 
        * config/tc-i386.c (line_comment_chars): Add '#'.  This makes the
index 446f95f4e6b34749a4517f95ff0c7af0dc5a2ffe..1d38d202d1502ce4424e0092e9b02b5fb4f6064b 100644 (file)
@@ -810,7 +810,7 @@ static void mips16_mark_labels
   PARAMS ((void));
 static void append_insn
   PARAMS ((char *place, struct mips_cl_insn * ip, expressionS * p,
-          bfd_reloc_code_real_type *r, bfd_boolean));
+          bfd_reloc_code_real_type *r));
 static void mips_no_prev_insn
   PARAMS ((int));
 static void mips_emit_delays
@@ -856,12 +856,10 @@ static void mips16_ip
 static void mips16_immed
   PARAMS ((char *, unsigned int, int, offsetT, bfd_boolean, bfd_boolean,
           bfd_boolean, unsigned long *, bfd_boolean *, unsigned short *));
-static int my_getPercentOp
-  PARAMS ((char **, unsigned int *, int *));
-static int my_getSmallParser
-  PARAMS ((char **, unsigned int *, int *));
-static int my_getSmallExpression
-  PARAMS ((expressionS *, char *));
+static bfd_boolean parse_relocation
+  PARAMS ((char **, bfd_reloc_code_real_type *));
+static size_t my_getSmallExpression
+  PARAMS ((expressionS *, bfd_reloc_code_real_type *, char *));
 static void my_getExpression
   PARAMS ((expressionS *, char *));
 #ifdef OBJ_ELF
@@ -946,32 +944,6 @@ static int mips_need_elf_addend_fixup
   PARAMS ((fixS *));
 #endif
 
-/* Return values of my_getSmallExpression().  */
-
-enum small_ex_type
-{
-  S_EX_NONE = 0,
-  S_EX_REGISTER,
-
-  /* Direct relocation creation by %percent_op().  */
-  S_EX_HALF,
-  S_EX_HI,
-  S_EX_LO,
-  S_EX_GP_REL,
-  S_EX_GOT,
-  S_EX_CALL16,
-  S_EX_GOT_DISP,
-  S_EX_GOT_PAGE,
-  S_EX_GOT_OFST,
-  S_EX_GOT_HI,
-  S_EX_GOT_LO,
-  S_EX_NEG,
-  S_EX_HIGHER,
-  S_EX_HIGHEST,
-  S_EX_CALL_HI,
-  S_EX_CALL_LO
-};
-
 /* Table and functions used to map between CPU/ISA names, and
    ISA levels, and CPU numbers.  */
 
@@ -1136,10 +1108,6 @@ static bfd_reloc_code_real_type imm_reloc[3]
 static bfd_reloc_code_real_type offset_reloc[3]
   = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
 
-/* This is set by mips_ip if imm_reloc is an unmatched HI16_S reloc.  */
-
-static bfd_boolean imm_unmatched_hi;
-
 /* These are set by mips16_ip if an explicit extension is used.  */
 
 static bfd_boolean mips16_small, mips16_ext;
@@ -1430,7 +1398,6 @@ md_assemble (str)
     = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
 
   imm_expr.X_op = O_absent;
-  imm_unmatched_hi = FALSE;
   offset_expr.X_op = O_absent;
   imm_reloc[0] = BFD_RELOC_UNUSED;
   imm_reloc[1] = BFD_RELOC_UNUSED;
@@ -1464,11 +1431,11 @@ md_assemble (str)
   else
     {
       if (imm_expr.X_op != O_absent)
-       append_insn (NULL, &insn, &imm_expr, imm_reloc, imm_unmatched_hi);
+       append_insn (NULL, &insn, &imm_expr, imm_reloc);
       else if (offset_expr.X_op != O_absent)
-       append_insn (NULL, &insn, &offset_expr, offset_reloc, FALSE);
+       append_insn (NULL, &insn, &offset_expr, offset_reloc);
       else
-       append_insn (NULL, &insn, NULL, unused_reloc, FALSE);
+       append_insn (NULL, &insn, NULL, unused_reloc);
     }
 }
 
@@ -1616,23 +1583,24 @@ mips16_mark_labels ()
    used with RELOC_TYPE.  */
 
 static void
-append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
+append_insn (place, ip, address_expr, reloc_type)
      char *place;
      struct mips_cl_insn *ip;
      expressionS *address_expr;
      bfd_reloc_code_real_type *reloc_type;
-     bfd_boolean unmatched_hi;
 {
   register unsigned long prev_pinfo, pinfo;
   char *f;
   fixS *fixp[3];
   int nops = 0;
+  bfd_boolean unmatched_reloc_p;
 
   /* Mark instruction labels in mips16 mode.  */
   mips16_mark_labels ();
 
   prev_pinfo = prev_insn.insn_mo->pinfo;
   pinfo = ip->insn_mo->pinfo;
+  unmatched_reloc_p = FALSE;
 
   if (place == NULL && (! mips_opts.noreorder || prev_nop_frag != NULL))
     {
@@ -2176,17 +2144,17 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
                   || *reloc_type == BFD_RELOC_MIPS_RELGOT))
                fixp[0]->fx_no_overflow = 1;
 
-             if (unmatched_hi)
+             if (reloc_type[0] == BFD_RELOC_HI16_S)
                {
                  struct mips_hi_fixup *hi_fixup;
 
-                 assert (*reloc_type == BFD_RELOC_HI16_S);
                  hi_fixup = ((struct mips_hi_fixup *)
                              xmalloc (sizeof (struct mips_hi_fixup)));
                  hi_fixup->fixp = fixp[0];
                  hi_fixup->seg = now_seg;
                  hi_fixup->next = mips_hi_fixup_list;
                  mips_hi_fixup_list = hi_fixup;
+                 unmatched_reloc_p = TRUE;
                }
 
              if (reloc_type[1] != BFD_RELOC_UNUSED)
@@ -2743,7 +2711,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
      reloc does not become a variant frag.  Otherwise, the
      rearrangement of %hi relocs in frob_file may confuse
      tc_gen_reloc.  */
-  if (unmatched_hi)
+  if (unmatched_reloc_p)
     {
       frag_wane (frag_now);
       frag_new (0);
@@ -3140,7 +3108,7 @@ macro_build (place, counter, ep, name, fmt, va_alist)
   va_end (args);
   assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
 
-  append_insn (place, &insn, ep, r, FALSE);
+  append_insn (place, &insn, ep, r);
 }
 
 static void
@@ -3266,7 +3234,7 @@ mips16_macro_build (place, counter, ep, name, fmt, args)
 
   assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
 
-  append_insn (place, &insn, ep, r, FALSE);
+  append_insn (place, &insn, ep, r);
 }
 
 /*
@@ -3356,10 +3324,10 @@ macro_build_lui (place, counter, ep, regnum)
   if (*r == BFD_RELOC_UNUSED)
     {
       insn.insn_opcode |= high_expr.X_add_number;
-      append_insn (place, &insn, NULL, r, FALSE);
+      append_insn (place, &insn, NULL, r);
     }
   else
-    append_insn (place, &insn, &high_expr, r, FALSE);
+    append_insn (place, &insn, &high_expr, r);
 }
 
 /* Generate a sequence of instructions to do a load or store from a constant
@@ -9065,122 +9033,70 @@ mips_ip (str, ip)
            case 'i':           /* 16 bit unsigned immediate */
            case 'j':           /* 16 bit signed immediate */
              *imm_reloc = BFD_RELOC_LO16;
-             c = my_getSmallExpression (&imm_expr, s);
-             if (c != S_EX_NONE)
-               {
-                 if (c != S_EX_LO)
-                   {
-                     if (c == S_EX_HI)
-                       {
-                         *imm_reloc = BFD_RELOC_HI16_S;
-                         imm_unmatched_hi = TRUE;
-                       }
-#ifdef OBJ_ELF
-                     else if (c == S_EX_HIGHEST)
-                       *imm_reloc = BFD_RELOC_MIPS_HIGHEST;
-                     else if (c == S_EX_HIGHER)
-                       *imm_reloc = BFD_RELOC_MIPS_HIGHER;
-                     else if (c == S_EX_GP_REL)
-                       {
-                         /* This occurs in NewABI only.  */
-                         c = my_getSmallExpression (&imm_expr, s);
-                         if (c != S_EX_NEG)
-                           as_bad (_("bad composition of relocations"));
-                         else
-                           {
-                             c = my_getSmallExpression (&imm_expr, s);
-                             if (c != S_EX_LO)
-                               as_bad (_("bad composition of relocations"));
-                             else
-                               {
-                                 imm_reloc[0] = BFD_RELOC_GPREL16;
-                                 imm_reloc[1] = BFD_RELOC_MIPS_SUB;
-                                 imm_reloc[2] = BFD_RELOC_LO16;
-                               }
-                           }
-                       }
-#endif
-                     else
-                       *imm_reloc = BFD_RELOC_HI16;
-                   }
-                 else if (imm_expr.X_op == O_constant)
-                   imm_expr.X_add_number &= 0xffff;
-               }
-             if (*args == 'i')
-               {
-                 if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
-                     || ((imm_expr.X_add_number < 0
-                          || imm_expr.X_add_number >= 0x10000)
-                         && imm_expr.X_op == O_constant))
-                   {
-                     if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
-                         !strcmp (insn->name, insn[1].name))
-                       break;
-                     if (imm_expr.X_op == O_constant
-                         || imm_expr.X_op == O_big)
-                       as_bad (_("16 bit expression not in range 0..65535"));
-                   }
-               }
-             else
+             if (my_getSmallExpression (&imm_expr, imm_reloc, s) == 0)
                {
                  int more;
-                 offsetT max;
-
-                 /* The upper bound should be 0x8000, but
-                    unfortunately the MIPS assembler accepts numbers
-                    from 0x8000 to 0xffff and sign extends them, and
-                    we want to be compatible.  We only permit this
-                    extended range for an instruction which does not
-                    provide any further alternates, since those
-                    alternates may handle other cases.  People should
-                    use the numbers they mean, rather than relying on
-                    a mysterious sign extension.  */
-                 more = (insn + 1 < &mips_opcodes[NUMOPCODES] &&
-                         strcmp (insn->name, insn[1].name) == 0);
-                 if (more)
-                   max = 0x8000;
+                 offsetT minval, maxval;
+
+                 more = (insn + 1 < &mips_opcodes[NUMOPCODES]
+                         && strcmp (insn->name, insn[1].name) == 0);
+
+                 /* If the expression was written as an unsigned number,
+                    only treat it as signed if there are no more
+                    alternatives.  */
+                 if (more
+                     && *args == 'j'
+                     && sizeof (imm_expr.X_add_number) <= 4
+                     && imm_expr.X_op == O_constant
+                     && imm_expr.X_add_number < 0
+                     && imm_expr.X_unsigned
+                     && HAVE_64BIT_GPRS)
+                   break;
+
+                 /* For compatibility with older assemblers, we accept
+                    0x8000-0xffff as signed 16-bit numbers when only
+                    signed numbers are allowed.  */
+                 if (*args == 'i')
+                   minval = 0, maxval = 0xffff;
+                 else if (more)
+                   minval = -0x8000, maxval = 0x7fff;
                  else
-                   max = 0x10000;
-                 if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
-                     || ((imm_expr.X_add_number < -0x8000
-                          || imm_expr.X_add_number >= max)
-                         && imm_expr.X_op == O_constant)
-                     || (more
-                         && imm_expr.X_add_number < 0
-                         && HAVE_64BIT_GPRS
-                         && imm_expr.X_unsigned
-                         && sizeof (imm_expr.X_add_number) <= 4))
+                   minval = -0x8000, maxval = 0xffff;
+
+                 if (imm_expr.X_op != O_constant
+                     || imm_expr.X_add_number < minval
+                     || imm_expr.X_add_number > maxval)
                    {
                      if (more)
                        break;
                      if (imm_expr.X_op == O_constant
                          || imm_expr.X_op == O_big)
-                       as_bad (_("16 bit expression not in range -32768..32767"));
+                       as_bad (_("expression out of range"));
                    }
                }
              s = expr_end;
              continue;
 
            case 'o':           /* 16 bit offset */
-             c = my_getSmallExpression (&offset_expr, s);
+             /* Check whether there is only a single bracketed expression
+                left.  If so, it must be the base register and the
+                constant must be zero.  */
+             if (*s == '(' && strchr (s + 1, '(') == 0)
+               {
+                 offset_expr.X_op = O_constant;
+                 offset_expr.X_add_number = 0;
+                 continue;
+               }
 
              /* If this value won't fit into a 16 bit offset, then go
                 find a macro that will generate the 32 bit offset
                 code pattern.  */
-             if (c == S_EX_NONE
+             if (my_getSmallExpression (&offset_expr, offset_reloc, s) == 0
                  && (offset_expr.X_op != O_constant
                      || offset_expr.X_add_number >= 0x8000
                      || offset_expr.X_add_number < -0x8000))
                break;
 
-             if (c == S_EX_HI)
-               {
-                 if (offset_expr.X_op != O_constant)
-                   break;
-                 offset_expr.X_add_number =
-                   (offset_expr.X_add_number >> 16) & 0xffff;
-               }
-             *offset_reloc = BFD_RELOC_LO16;
              s = expr_end;
              continue;
 
@@ -9191,49 +9107,10 @@ mips_ip (str, ip)
              continue;
 
            case 'u':           /* upper 16 bits */
-             c = my_getSmallExpression (&imm_expr, s);
-             *imm_reloc = BFD_RELOC_LO16;
-             if (c != S_EX_NONE)
-               {
-                 if (c != S_EX_LO)
-                   {
-                     if (c == S_EX_HI)
-                       {
-                         *imm_reloc = BFD_RELOC_HI16_S;
-                         imm_unmatched_hi = TRUE;
-                       }
-#ifdef OBJ_ELF
-                     else if (c == S_EX_HIGHEST)
-                       *imm_reloc = BFD_RELOC_MIPS_HIGHEST;
-                     else if (c == S_EX_GP_REL)
-                       {
-                         /* This occurs in NewABI only.  */
-                         c = my_getSmallExpression (&imm_expr, s);
-                         if (c != S_EX_NEG)
-                           as_bad (_("bad composition of relocations"));
-                         else
-                           {
-                             c = my_getSmallExpression (&imm_expr, s);
-                             if (c != S_EX_HI)
-                               as_bad (_("bad composition of relocations"));
-                             else
-                               {
-                                 imm_reloc[0] = BFD_RELOC_GPREL16;
-                                 imm_reloc[1] = BFD_RELOC_MIPS_SUB;
-                                 imm_reloc[2] = BFD_RELOC_HI16_S;
-                               }
-                           }
-                       }
-#endif
-                     else
-                       *imm_reloc = BFD_RELOC_HI16;
-                   }
-                 else if (imm_expr.X_op == O_constant)
-                   imm_expr.X_add_number &= 0xffff;
-               }
-             else if (imm_expr.X_op == O_constant
-                      && (imm_expr.X_add_number < 0
-                          || imm_expr.X_add_number >= 0x10000))
+             if (my_getSmallExpression (&imm_expr, imm_reloc, s) == 0
+                 && imm_expr.X_op == O_constant
+                 && (imm_expr.X_add_number < 0
+                     || imm_expr.X_add_number >= 0x10000))
                as_bad (_("lui expression not in range 0..65535"));
              s = expr_end;
              continue;
@@ -10070,222 +9947,118 @@ mips16_immed (file, line, type, val, warn, small, ext, insn, use_extend,
     }
 }
 \f
-static struct percent_op_match
+static const struct percent_op_match
 {
-   const char *str;
-   const enum small_ex_type type;
+  const char *str;
+  bfd_reloc_code_real_type reloc;
 } percent_op[] =
 {
-  {"%lo", S_EX_LO},
+  {"%lo", BFD_RELOC_LO16},
 #ifdef OBJ_ELF
-  {"%call_hi", S_EX_CALL_HI},
-  {"%call_lo", S_EX_CALL_LO},
-  {"%call16", S_EX_CALL16},
-  {"%got_disp", S_EX_GOT_DISP},
-  {"%got_page", S_EX_GOT_PAGE},
-  {"%got_ofst", S_EX_GOT_OFST},
-  {"%got_hi", S_EX_GOT_HI},
-  {"%got_lo", S_EX_GOT_LO},
-  {"%got", S_EX_GOT},
-  {"%gp_rel", S_EX_GP_REL},
-  {"%half", S_EX_HALF},
-  {"%highest", S_EX_HIGHEST},
-  {"%higher", S_EX_HIGHER},
-  {"%neg", S_EX_NEG},
+  {"%call_hi", BFD_RELOC_MIPS_CALL_HI16},
+  {"%call_lo", BFD_RELOC_MIPS_CALL_LO16},
+  {"%call16", BFD_RELOC_MIPS_CALL16},
+  {"%got_disp", BFD_RELOC_MIPS_GOT_DISP},
+  {"%got_page", BFD_RELOC_MIPS_GOT_PAGE},
+  {"%got_ofst", BFD_RELOC_MIPS_GOT_OFST},
+  {"%got_hi", BFD_RELOC_MIPS_GOT_HI16},
+  {"%got_lo", BFD_RELOC_MIPS_GOT_LO16},
+  {"%got", BFD_RELOC_MIPS_GOT16},
+  {"%gp_rel", BFD_RELOC_GPREL16},
+  {"%half", BFD_RELOC_16},
+  {"%highest", BFD_RELOC_MIPS_HIGHEST},
+  {"%higher", BFD_RELOC_MIPS_HIGHER},
+  {"%neg", BFD_RELOC_MIPS_SUB},
 #endif
-  {"%hi", S_EX_HI}
+  {"%hi", BFD_RELOC_HI16_S}
 };
 
-/* Parse small expression input.  STR gets adjusted to eat up whitespace.
-   It detects valid "%percent_op(...)" and "($reg)" strings.  Percent_op's
-   can be nested, this is handled by blanking the innermost, parsing the
-   rest by subsequent calls.  */
 
-static int
-my_getSmallParser (str, len, nestlevel)
+/* Return true if *STR points to a relocation operator.  When returning true,
+   move *STR over the operator and store its relocation code in *RELOC.
+   Leave both *STR and *RELOC alone when returning false.  */
+
+static bfd_boolean
+parse_relocation (str, reloc)
      char **str;
-     unsigned int *len;
-     int *nestlevel;
+     bfd_reloc_code_real_type *reloc;
 {
-  *len = 0;
-  *str += strspn (*str, " \t");
-  /* Check for expression in parentheses.  */
-  if (**str == '(')
-    {
-      char *b = *str + 1 + strspn (*str + 1, " \t");
-      char *e;
-
-      /* Check for base register.  */
-      if (b[0] == '$')
-       {
-         if (strchr (b, ')')
-             && (e = b + strcspn (b, ") \t"))
-             && e - b > 1 && e - b < 4)
-           {
-             if ((e - b == 3
-                  && ((b[1] == 'f' && b[2] == 'p')
-                      || (b[1] == 's' && b[2] == 'p')
-                      || (b[1] == 'g' && b[2] == 'p')
-                      || (b[1] == 'a' && b[2] == 't')
-                      || (ISDIGIT (b[1])
-                          && ISDIGIT (b[2]))))
-                 || (ISDIGIT (b[1])))
-               {
-                 *len = strcspn (*str, ")") + 1;
-                 return S_EX_REGISTER;
-               }
-           }
-       }
-      /* Check for percent_op (in parentheses).  */
-      else if (b[0] == '%')
-       {
-         *str = b;
-         return my_getPercentOp (str, len, nestlevel);
-       }
+  size_t i;
 
-      /* Some other expression in the parentheses, which can contain
-        parentheses itself. Attempt to find the matching one.  */
+  for (i = 0; i < ARRAY_SIZE (percent_op); i++)
+    if (strncasecmp (*str, percent_op[i].str, strlen (percent_op[i].str)) == 0)
       {
-       int pcnt = 1;
-       char *s;
+       *str += strlen (percent_op[i].str);
+       *reloc = percent_op[i].reloc;
 
-       *len = 1;
-       for (s = *str + 1; *s && pcnt; s++, (*len)++)
+       /* Check whether the output BFD supports this relocation.
+          If not, issue an error and fall back on something safe.  */
+       if (!bfd_reloc_type_lookup (stdoutput, percent_op[i].reloc))
          {
-           if (*s == '(')
-             ++pcnt;
-           else if (*s == ')')
-             --pcnt;
+           as_bad ("relocation %s isn't supported by the current ABI",
+                   percent_op[i].str);
+           *reloc = BFD_RELOC_LO16;
          }
+       return TRUE;
       }
-    }
-  /* Check for percent_op (outside of parentheses).  */
-  else if (*str[0] == '%')
-    return my_getPercentOp (str, len, nestlevel);
-
-  /* Any other expression.  */
-  return S_EX_NONE;
+  return FALSE;
 }
 
-static int
-my_getPercentOp (str, len, nestlevel)
-     char **str;
-     unsigned int *len;
-     int *nestlevel;
-{
-  char *tmp = *str + 1;
-  unsigned int i = 0;
 
-  while (ISALPHA (*tmp) || *tmp == '_')
-    {
-      *tmp = TOLOWER (*tmp);
-      tmp++;
-    }
-  while (i < (sizeof (percent_op) / sizeof (struct percent_op_match)))
-    {
-      if (strncmp (*str, percent_op[i].str, strlen (percent_op[i].str)))
-       i++;
-      else
-       {
-         int type = percent_op[i].type;
+/* Parse string STR as a 16-bit relocatable operand.  Store the
+   expression in *EP and the relocations in the array starting
+   at RELOC.  Return the number of relocation operators used.
 
-         /* Only %hi and %lo are allowed for OldABI.  */
-         if (! HAVE_NEWABI && type != S_EX_HI && type != S_EX_LO)
-           return S_EX_NONE;
+   On exit, EXPR_END points to the first character after the expression.
+   If no relocation operators are used, RELOC[0] is set to BFD_RELOC_LO16.  */
 
-         *len = strlen (percent_op[i].str);
-         ++(*nestlevel);
-         return type;
-       }
-    }
-  return S_EX_NONE;
-}
-
-static int
-my_getSmallExpression (ep, str)
+static size_t
+my_getSmallExpression (ep, reloc, str)
      expressionS *ep;
+     bfd_reloc_code_real_type *reloc;
      char *str;
 {
-  static char *oldstr = NULL;
-  int c = S_EX_NONE;
-  int oldc;
-  int nestlevel = -1;
-  unsigned int len;
+  bfd_reloc_code_real_type reversed_reloc[3];
+  size_t reloc_index, i;
+  int bracket_depth;
 
-  /* Don't update oldstr if the last call had nested percent_op's. We need
-     it to parse the outer ones later.  */
-  if (! oldstr)
-    oldstr = str;
+  reloc_index = 0;
+  bracket_depth = 0;
 
-  do
+  /* Search for the start of the main expression, recoding relocations
+     in REVERSED_RELOC.  */
+  for (;;)
     {
-      oldc = c;
-      c = my_getSmallParser (&str, &len, &nestlevel);
-      if (c != S_EX_NONE && c != S_EX_REGISTER)
-       str += len;
+      if (*str == '(')
+       bracket_depth++, str++;
+      else if (*str == ' ' || *str == '\t')
+       str++;
+      else if (*str == '%'
+              && reloc_index < (HAVE_NEWABI ? 3 : 1)
+              && parse_relocation (&str, &reversed_reloc[reloc_index]))
+       reloc_index++;
+      else
+       break;
     }
-  while (c != S_EX_NONE && c != S_EX_REGISTER);
 
-  if (nestlevel >= 0)
-    {
-      /* A percent_op was encountered.  Don't try to get an expression if
-        it is already blanked out.  */
-      if (*(str + strspn (str + 1, " )")) != ')')
-       {
-         char save;
-
-         /* Let my_getExpression() stop at the closing parenthesis.  */
-         save = *(str + len);
-         *(str + len) = '\0';
-         my_getExpression (ep, str);
-         *(str + len) = save;
-       }
-      if (nestlevel > 0)
-       {
-         /* Blank out including the % sign and the proper matching
-            parenthesis.  */
-         int pcnt = 1;
-         char *s = strrchr (oldstr, '%');
-         char *end;
+  my_getExpression (ep, str);
+  str = expr_end;
 
-         for (end = strchr (s, '(') + 1; *end && pcnt; end++)
-           {
-             if (*end == '(')
-               ++pcnt;
-             else if (*end == ')')
-               --pcnt;
-           }
+  /* Match every open bracket.  */
+  while (bracket_depth > 0 && (*str == ')' || *str == ' ' || *str == '\t'))
+    if (*str++ == ')')
+      bracket_depth--;
 
-         memset (s, ' ', end - s);
-         str = oldstr;
-       }
-      else
-       expr_end = str + len;
+  if (bracket_depth > 0)
+    as_bad ("unclosed '('");
 
-      c = oldc;
-    }
-  else if (c == S_EX_NONE)
-    {
-      my_getExpression (ep, str);
-    }
-  else if (c == S_EX_REGISTER)
-    {
-      ep->X_op = O_constant;
-      expr_end = str;
-      ep->X_add_symbol = NULL;
-      ep->X_op_symbol = NULL;
-      ep->X_add_number = 0;
-    }
-  else
-    {
-      as_fatal (_("internal error"));
-    }
+  expr_end = str;
 
-  if (nestlevel <= 0)
-    /* All percent_op's have been handled.  */
-    oldstr = NULL;
+  reloc[0] = BFD_RELOC_LO16;
+  for (i = 0; i < reloc_index; i++)
+    reloc[i] = reversed_reloc[reloc_index - 1 - i];
 
-  return c;
+  return reloc_index;
 }
 
 static void
index d4dacdf2aae66a909ec55d73c7e0e8ce8aa3bc68..7729161f89bcfacc99d7532dc743ac7c38a4bbce 100644 (file)
@@ -1,3 +1,10 @@
+2003-02-02  Richard Sandiford  <rsandifo@redhat.com>
+
+       * gas/mips/elf-rel8.[sd], gas/mips/elf-rel9.[sd],
+       gas/mips/elf-rel10.[sd], gas/mips/elf-rel11.[sd]: New tests.
+       * gas/mips/mips.exp: Run elf-rel8 and elf-rel9 for all elf
+       targets.  Run elf-rel10 and elf-rel11 for NewABI targets.
+
 2003-01-27  Alexandre Oliva  <aoliva@redhat.com>
 
        * gas/mips/n32-consec.d: New.
diff --git a/gas/testsuite/gas/mips/elf-rel10.d b/gas/testsuite/gas/mips/elf-rel10.d
new file mode 100644 (file)
index 0000000..eb12f13
--- /dev/null
@@ -0,0 +1,29 @@
+#as: -march=mips3 -mabi=n32 -KPIC
+#readelf: --relocs
+#name: MIPS ELF reloc 10
+
+Relocation section '\.rela\.text' at offset .* contains 22 entries:
+ *Offset * Info * Type * Sym\.Value * Sym\. Name \+ Addend
+0+0000 * 0+..07 * R_MIPS_GPREL16 * 0+0000 * foo \+ 0
+0+0000 * 0+0018 * R_MIPS_SUB * 0+0000
+0+0000 * 0+0005 * R_MIPS_HI16 * 0+0000
+0+0004 * 0+..07 * R_MIPS_GPREL16 * 0+0000 * foo \+ 0
+0+0004 * 0+0018 * R_MIPS_SUB * 0+0000
+0+0004 * 0+0006 * R_MIPS_LO16 * 0+0000
+0+000c * 0+..07 * R_MIPS_GPREL16 * 0+0000 * \.text \+ c
+0+000c * 0+0018 * R_MIPS_SUB * 0+0000
+0+000c * 0+0005 * R_MIPS_HI16 * 0+0000
+0+0010 * 0+..07 * R_MIPS_GPREL16 * 0+0000 * \.text \+ c
+0+0010 * 0+0018 * R_MIPS_SUB * 0+0000
+0+0010 * 0+0006 * R_MIPS_LO16 * 0+0000
+0+0018 * 0+..14 * R_MIPS_GOT_PAGE * 0+0000 * foo \+ 0
+0+001c * 0+..15 * R_MIPS_GOT_OFST * 0+0000 * foo \+ 0
+0+0020 * 0+..14 * R_MIPS_GOT_PAGE * 0+0000 * foo \+ 1234
+0+0024 * 0+..15 * R_MIPS_GOT_OFST * 0+0000 * foo \+ 1234
+0+0028 * 0+..14 * R_MIPS_GOT_PAGE * 0+0000 * \.text \+ c
+0+002c * 0+..15 * R_MIPS_GOT_OFST * 0+0000 * \.text \+ c
+0+0030 * 0+..14 * R_MIPS_GOT_PAGE * 0+0000 * \.text \+ 33221d
+0+0034 * 0+..15 * R_MIPS_GOT_OFST * 0+0000 * \.text \+ 33221d
+0+0038 * 0+..14 * R_MIPS_GOT_PAGE * 0+0000 * frob \+ 0
+0+003c * 0+..15 * R_MIPS_GOT_OFST * 0+0000 * frob \+ 0
+#pass
diff --git a/gas/testsuite/gas/mips/elf-rel10.s b/gas/testsuite/gas/mips/elf-rel10.s
new file mode 100644 (file)
index 0000000..cda73de
--- /dev/null
@@ -0,0 +1,31 @@
+       .globl  foo
+       .ent    foo
+foo:
+       lui     $gp,%hi(%neg(%gp_rel(foo)))
+       addiu   $gp,$gp,%lo(%neg(%gp_rel(foo)))
+       daddu   $gp,$gp,$25
+       .end    foo
+
+       .ent    bar
+bar:
+       lui     $gp,%hi(%neg(%gp_rel(bar)))
+       addiu   $gp,$gp,%lo(%neg(%gp_rel(bar)))
+       daddu   $gp,$gp,$25
+       .end    bar
+
+       .ent    frob
+       lw      $4,%got_page(foo)($gp)
+       addiu   $4,$4,%got_ofst(foo)
+
+       lw      $4,%got_page(foo + 0x1234)($gp)
+       addiu   $4,$4,%got_ofst(foo + 0x1234)
+
+       lw      $4,%got_page(bar)($gp)
+       addiu   $4,$4,%got_ofst(bar)
+
+       lw      $4,%got_page(bar + 0x332211)($gp)
+       addiu   $4,$4,%got_ofst(bar + 0x332211)
+
+       lw      $4,%got_page(frob)($gp)
+       addiu   $4,$4,%got_ofst(frob)
+       .end    frob
diff --git a/gas/testsuite/gas/mips/elf-rel11.d b/gas/testsuite/gas/mips/elf-rel11.d
new file mode 100644 (file)
index 0000000..408795d
--- /dev/null
@@ -0,0 +1,43 @@
+#as: -march=mips3 -mabi=64
+#readelf: --relocs
+#name: MIPS ELF reloc 11
+
+Relocation section '\.rela\.text' at offset .* contains 12 entries:
+ *Offset * Info * Type * Sym\. Value * Sym\. Name \+ Addend
+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
+ * Type2: R_MIPS_NONE *
+ * Type3: R_MIPS_NONE *
+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
+ * Type2: R_MIPS_NONE *
+ * Type3: R_MIPS_NONE *
+0+0030 * 0+..0000001d * R_MIPS_HIGHEST * 0+0000 * \.data \+ 10
+ * Type2: R_MIPS_NONE *
+ * Type3: R_MIPS_NONE *
+0+0034 * 0+..0000001c * R_MIPS_HIGHER * 0+0000 * \.data \+ 10
+ * Type2: R_MIPS_NONE *
+ * Type3: R_MIPS_NONE *
+0+003c * 0+..00000005 * R_MIPS_HI16 * 0+0000 * \.data \+ 10
+ * Type2: R_MIPS_NONE *
+ * Type3: R_MIPS_NONE *
+0+0044 * 0+..00000006 * R_MIPS_LO16 * 0+0000 * \.data \+ 10
+ * Type2: R_MIPS_NONE *
+ * Type3: R_MIPS_NONE *
+#pass
diff --git a/gas/testsuite/gas/mips/elf-rel11.s b/gas/testsuite/gas/mips/elf-rel11.s
new file mode 100644 (file)
index 0000000..e8f5378
--- /dev/null
@@ -0,0 +1,27 @@
+       .ent    foo
+foo:
+       lui     $4,%highest(bar)
+       lui     $5,%hi(bar)
+       daddiu  $4,$4,%higher(bar)
+       daddiu  $5,$5,%lo(bar)
+       dsll32  $4,$4,0
+       daddu   $4,$4,$5
+
+       lui     $4,%highest(bar + 0x12345678)
+       lui     $5,%hi(bar + 0x12345678)
+       daddiu  $4,$4,%higher(bar + 0x12345678)
+       daddiu  $5,$5,%lo(bar + 0x12345678)
+       dsll32  $4,$4,0
+       daddu   $4,$4,$5
+
+       lui     $4,%highest(l1)
+       daddiu  $4,$4,%higher(l1)
+       dsll    $4,$4,16
+       daddiu  $4,$4,%hi(l1)
+       dsll    $4,$4,16
+       lw      $4,%lo(l1)($4)
+       .end    foo
+
+       .data
+       .word   1,2,3,4
+l1:    .word   4,5
diff --git a/gas/testsuite/gas/mips/elf-rel8.d b/gas/testsuite/gas/mips/elf-rel8.d
new file mode 100644 (file)
index 0000000..270533b
--- /dev/null
@@ -0,0 +1,57 @@
+#as: -march=mips2 -mabi=32
+#objdump: -M gpr-names=numeric -dr
+#name: MIPS ELF reloc 8
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+00 <foo>:
+   0:  3c040000        lui     \$4,0x0
+                       0: R_MIPS_HI16  gvar
+   4:  24840000        addiu   \$4,\$4,0
+                       4: R_MIPS_LO16  gvar
+   8:  8ca40000        lw      \$4,0\(\$5\)
+                       8: R_MIPS_LO16  gvar
+   c:  8fc40002        lw      \$4,2\(\$30\)
+  10:  3c040000        lui     \$4,0x0
+                       10: R_MIPS_CALL_HI16    gfunc
+  14:  009c2021        addu    \$4,\$4,\$28
+  18:  8c990000        lw      \$25,0\(\$4\)
+                       18: R_MIPS_CALL_LO16    gfunc
+  1c:  3c040000        lui     \$4,0x0
+                       1c: R_MIPS_GOT_HI16     gvar
+  20:  009c2021        addu    \$4,\$4,\$28
+  24:  8c850000        lw      \$5,0\(\$4\)
+                       24: R_MIPS_GOT_LO16     gvar
+  28:  8f840000        lw      \$4,0\(\$28\)
+                       28: R_MIPS_GOT16        \.data
+  2c:  a0850000        sb      \$5,0\(\$4\)
+                       2c: R_MIPS_LO16 \.data
+  30:  3c040000        lui     \$4,0x0
+                       30: R_MIPS_CALL_HI16    gfunc
+  34:  24840000        addiu   \$4,\$4,0
+                       34: R_MIPS_CALL_LO16    gfunc
+  38:  3c040000        lui     \$4,0x0
+                       38: R_MIPS_GOT_HI16     gvar
+  3c:  24840000        addiu   \$4,\$4,0
+                       3c: R_MIPS_GOT_LO16     gvar
+  40:  8f840000        lw      \$4,0\(\$28\)
+                       40: R_MIPS_GOT16        \.data
+  44:  24840000        addiu   \$4,\$4,0
+                       44: R_MIPS_LO16 \.data
+  48:  8f990000        lw      \$25,0\(\$28\)
+                       48: R_MIPS_CALL16       gfunc
+  4c:  27840000        addiu   \$4,\$28,0
+                       4c: R_MIPS_CALL16       gfunc
+  50:  8f840000        lw      \$4,0\(\$28\)
+                       50: R_MIPS_GOT_DISP     gvar
+  54:  27840000        addiu   \$4,\$28,0
+                       54: R_MIPS_GOT_DISP     gvar
+  58:  8f840000        lw      \$4,0\(\$28\)
+                       58: R_MIPS_GPREL16      gvar
+  5c:  af840000        sw      \$4,0\(\$28\)
+                       5c: R_MIPS_GPREL16      gvar
+  60:  27840000        addiu   \$4,\$28,0
+                       60: R_MIPS_GPREL16      gvar
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/elf-rel8.s b/gas/testsuite/gas/mips/elf-rel8.s
new file mode 100644 (file)
index 0000000..b3f5dab
--- /dev/null
@@ -0,0 +1,53 @@
+       .equ    $fprel, 2
+
+       .ent    foo
+foo:
+       # Test various forms of relocation syntax.
+
+       lui     $4,(%hi gvar)
+       addiu   $4,$4,(%lo (gvar))
+       lw      $4,%lo gvar($5)
+
+       # Check that registers aren't confused with $ identifiers.
+
+       lw      $4,($fprel)($fp)
+
+       # Check various forms of paired relocations.
+
+       lui     $4,%call_hi(gfunc)
+       addu    $4,$4,$gp
+       lw      $25,%call_lo(gfunc)($4)
+
+       lui     $4,%got_hi(gvar)
+       addu    $4,$4,$gp
+       lw      $5,%got_lo(gvar)($4)
+
+       lw      $4,%got(lvar)($28)
+       sb      $5,%lo(lvar)($4)
+
+       lui     $4,%call_hi(gfunc)
+       addiu   $4,$4,%call_lo(gfunc)
+
+       lui     $4,%got_hi(gvar)
+       addiu   $4,$4,%got_lo(gvar)
+
+       lw      $4,%got(lvar)($28)
+       addiu   $4,$4,%lo(lvar)
+
+       # Check individual relocations.
+
+       lw      $25,%call16(gfunc)($28)
+       addiu   $4,$28,%call16(gfunc)
+
+       lw      $4,%got_disp(gvar)($28)
+       addiu   $4,$28,%got_disp(gvar)
+
+       lw      $4,%gp_rel(gvar)($28)
+       sw      $4,%gp_rel(gvar)($28)
+       addiu   $4,$28,%gp_rel(gvar)
+
+       .space  64
+       .end    foo
+
+       .data
+lvar:  .word   1,2
diff --git a/gas/testsuite/gas/mips/elf-rel9.d b/gas/testsuite/gas/mips/elf-rel9.d
new file mode 100644 (file)
index 0000000..c78a4bf
--- /dev/null
@@ -0,0 +1,68 @@
+#as: -march=mips2 -mabi=32
+#objdump: -M gpr-names=numeric -dr
+#name: MIPS ELF reloc 9
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+00 <foo>:
+   0:  8f840000        lw      \$4,0\(\$28\)
+                       0: R_MIPS_GOT16 \.data
+   4:  24840010        addiu   \$4,\$4,16
+                       4: R_MIPS_LO16  \.data
+   8:  8f840000        lw      \$4,0\(\$28\)
+                       8: R_MIPS_GOT16 \.data
+   c:  24840020        addiu   \$4,\$4,32
+                       c: R_MIPS_LO16  \.data
+  10:  8f840000        lw      \$4,0\(\$28\)
+                       10: R_MIPS_GOT16        \.data
+  14:  24847ffc        addiu   \$4,\$4,32764
+                       14: R_MIPS_LO16 \.data
+  18:  8f840001        lw      \$4,1\(\$28\)
+                       18: R_MIPS_GOT16        \.data
+  1c:  24848000        addiu   \$4,\$4,-32768
+                       1c: R_MIPS_LO16 \.data
+  20:  8f840001        lw      \$4,1\(\$28\)
+                       20: R_MIPS_GOT16        \.data
+  24:  2484fffc        addiu   \$4,\$4,-4
+                       24: R_MIPS_LO16 \.data
+  28:  8f840001        lw      \$4,1\(\$28\)
+                       28: R_MIPS_GOT16        \.data
+  2c:  24840000        addiu   \$4,\$4,0
+                       2c: R_MIPS_LO16 \.data
+  30:  8f840002        lw      \$4,2\(\$28\)
+                       30: R_MIPS_GOT16        \.data
+  34:  24848010        addiu   \$4,\$4,-32752
+                       34: R_MIPS_LO16 \.data
+  38:  8f840002        lw      \$4,2\(\$28\)
+                       38: R_MIPS_GOT16        \.data
+  3c:  2484f000        addiu   \$4,\$4,-4096
+                       3c: R_MIPS_LO16 \.data
+  40:  8f840002        lw      \$4,2\(\$28\)
+                       40: R_MIPS_GOT16        \.data
+  44:  2484ffff        addiu   \$4,\$4,-1
+                       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
+  54:  24841345        addiu   \$4,\$4,4933
+                       54: R_MIPS_LO16 \.data
+  58:  8f84c000        lw      \$4,-16384\(\$28\)
+                       58: R_MIPS_GPREL16      \.sdata\+0x4000
+  5c:  8f84c004        lw      \$4,-16380\(\$28\)
+                       5c: R_MIPS_GPREL16      \.sdata\+0x4000
+  60:  8f84c004        lw      \$4,-16380\(\$28\)
+                       60: R_MIPS_GPREL16      \.sdata\+0x4000
+  64:  8f84c008        lw      \$4,-16376\(\$28\)
+                       64: R_MIPS_GPREL16      \.sdata\+0x4000
+  68:  8f84c00c        lw      \$4,-16372\(\$28\)
+                       68: R_MIPS_GPREL16      \.sdata\+0x4000
+  6c:  8f84c014        lw      \$4,-16364\(\$28\)
+                       6c: R_MIPS_GPREL16      \.sdata\+0x4000
+  70:  8f84c018        lw      \$4,-16360\(\$28\)
+                       70: R_MIPS_GPREL16      \.sdata\+0x4000
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/elf-rel9.s b/gas/testsuite/gas/mips/elf-rel9.s
new file mode 100644 (file)
index 0000000..4768c24
--- /dev/null
@@ -0,0 +1,57 @@
+       .ent    foo
+foo:
+       lw      $4,%got(l1)($28)
+       addiu   $4,$4,%lo(l1)
+
+       lw      $4,%got(l1 + 16)($28)
+       addiu   $4,$4,%lo(l1 + 16)
+
+       lw      $4,%got(l1 + 0x7fec)($28)
+       addiu   $4,$4,%lo(l1 + 0x7fec)
+
+       lw      $4,%got(l1 + 0x7ff0)($28)
+       addiu   $4,$4,%lo(l1 + 0x7ff0)
+
+       lw      $4,%got(l1 + 0xffec)($28)
+       addiu   $4,$4,%lo(l1 + 0xffec)
+
+       lw      $4,%got(l1 + 0xfff0)($28)
+       addiu   $4,$4,%lo(l1 + 0xfff0)
+
+       lw      $4,%got(l1 + 0x18000)($28)
+       addiu   $4,$4,%lo(l1 + 0x18000)
+
+       lw      $4,%got(l2)($28)
+       addiu   $4,$4,%lo(l2)
+
+       lw      $4,%got(l2 + 0xfff)($28)
+       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)
+
+       lw      $4,%gp_rel(l3)($28)
+       lw      $4,%gp_rel(l3 + 4)($28)
+       lw      $4,%gp_rel(l4)($28)
+       lw      $4,%gp_rel(l4 + 4)($28)
+       lw      $4,%gp_rel(l5)($28)
+       lw      $4,%gp_rel(l5 + 8)($28)
+       lw      $4,%gp_rel(l5 + 12)($28)
+
+       .space  64
+       .end    foo
+
+       .data
+       .word   1,2,3,4
+l1:    .word   4,5
+       .space  0x1f000 - 24
+l2:    .word   7,8
+
+       .sdata
+l3:    .word   1
+l4:    .word   2
+       .word   3
+l5:    .word   4
index 046a33f5282fa606f4c8fddf9a0b7601bc1f31f5..43b21939932f08655f44219ee23f717617344618 100644 (file)
@@ -376,7 +376,7 @@ if { [istarget mips*-*-*] } then {
     set ilocks [istarget mipstx39*-*-*]
     set gpr_ilocks [expr [istarget mipstx39*-*-*]]
     set addr32 [expr [istarget mipstx39*-*-*]]
-    set hasn32 [expr [istarget *-*-irix6*] || [istarget mips64*-*-linux*]]
+    set has_newabi [expr [istarget *-*-irix6*] || [istarget mips64*-*-linux*]]
 
     if { [istarget "mips*-*-*linux*"] } then {
        set tmips "t"
@@ -602,6 +602,12 @@ if { [istarget mips*-*-*] } then {
        run_dump_test "elf-rel5"
        run_dump_test "elf-rel6"
        run_dump_test "elf-rel7"
+       run_dump_test "elf-rel8"
+       run_dump_test "elf-rel9"
+       if $has_newabi {
+           run_dump_test "elf-rel10"
+           run_dump_test "elf-rel11"
+       }
        run_dump_test "${tmips}${el}empic"
        run_dump_test "empic2"
        run_dump_test "empic3_e"
@@ -614,7 +620,7 @@ if { [istarget mips*-*-*] } then {
        run_dump_test "elf-consthilo"
     }
 
-    if $hasn32 {
+    if $has_newabi {
        run_dump_test "n32-consec"
     }