[ gas/ChangeLog ]
authorChris Demetriou <cgd@google.com>
Wed, 18 Sep 2002 21:33:07 +0000 (21:33 +0000)
committerChris Demetriou <cgd@google.com>
Wed, 18 Sep 2002 21:33:07 +0000 (21:33 +0000)
2002-09-18  Chris Demetriou  <cgd@broadcom.com>

        * config/tc-mips.c (IS_SEXT_32BIT_NUM): Move closer to top of file.
        (IS_SEXT_16BIT_NUM): New macro.
        (macro_build_ldst_constoffset): New function, to build a set of
        instructions to do a load or store from a constant offset relative
        to a given register.
        (macro, s_cprestore): Use macro_build_ldst_constoffset to implement
        .cprestore pseudo-op.

[ gas/testsuite/ChangeLog ]
2002-09-18  Chris Demetriou  <cgd@broadcom.com>

        * gas/mips/mips-abi32-pic2.s: New file.
        * gas/mips/mips-abi32-pic2.d: New file.
        * gas/mips/mips.exp: Run new test.

[ plus, fixed date on prev. gas/testsuite/ChangeLog entry. ]

gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/mips-abi32-pic2.d [new file with mode: 0644]
gas/testsuite/gas/mips/mips-abi32-pic2.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp

index a959777820f3ad34183bc15fe17d2fb649694692..7c9871a7e97865e468ebe4c8e0bc76fd2e87139b 100644 (file)
@@ -1,3 +1,13 @@
+2002-09-18  Chris Demetriou  <cgd@broadcom.com>
+
+       * config/tc-mips.c (IS_SEXT_32BIT_NUM): Move closer to top of file.
+       (IS_SEXT_16BIT_NUM): New macro.
+       (macro_build_ldst_constoffset): New function, to build a set of
+       instructions to do a load or store from a constant offset relative
+       to a given register.
+       (macro, s_cprestore): Use macro_build_ldst_constoffset to implement
+       .cprestore pseudo-op.
+
 2002-09-18  Chris Demetriou  <cgd@broadcom.com>
 
        * config/tc-mips.c (md_apply_fix3): Just return for BFD_RELOC_8.
index c1026751cb32e4d2dccdce5aedeae72c053cb8c8..ba803d215885785bee07685f92c05affbb7c601f 100644 (file)
@@ -665,6 +665,17 @@ static const unsigned int mips16_to_32_reg_map[] =
 #define RELAX_MIPS16_LONG_BRANCH(i) (((i) & 0x2000) != 0)
 #define RELAX_MIPS16_MARK_LONG_BRANCH(i) ((i) | 0x2000)
 #define RELAX_MIPS16_CLEAR_LONG_BRANCH(i) ((i) &~ 0x2000)
+
+/* Is the given value a sign-extended 32-bit value?  */
+#define IS_SEXT_32BIT_NUM(x)                                           \
+  (((x) &~ (offsetT) 0x7fffffff) == 0                                  \
+   || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
+
+/* Is the given value a sign-extended 16-bit value?  */
+#define IS_SEXT_16BIT_NUM(x)                                           \
+  (((x) &~ (offsetT) 0x7fff) == 0                                      \
+   || (((x) &~ (offsetT) 0x7fff) == ~ (offsetT) 0x7fff))
+
 \f
 /* Prototypes for static functions.  */
 
@@ -701,6 +712,9 @@ static void mips16_macro_build PARAMS ((char *, int *, expressionS *,
 static void macro_build_jalr PARAMS ((int, expressionS *));
 static void macro_build_lui PARAMS ((char *place, int *counter,
                                     expressionS * ep, int regnum));
+static void macro_build_ldst_constoffset PARAMS ((char *place, int *counter,
+                                                 expressionS * ep, const char *op,
+                                                 int valreg, int breg));
 static void set_at PARAMS ((int *counter, int reg, int unsignedp));
 static void check_absolute_expr PARAMS ((struct mips_cl_insn * ip,
                                         expressionS *));
@@ -3082,6 +3096,52 @@ macro_build_lui (place, counter, ep, regnum)
     append_insn (place, &insn, &high_expr, r, false);
 }
 
+/* Generate a sequence of instructions to do a load or store from a constant
+   offset off of a base register (breg) into/from a target register (treg),
+   using AT if necessary.  */
+static void
+macro_build_ldst_constoffset (place, counter, ep, op, treg, breg)
+     char *place;
+     int *counter;
+     expressionS *ep;
+     const char *op;
+     int treg, breg;
+{
+  assert (ep->X_op == O_constant);
+
+  /* Right now, this routine can only handle signed 32-bit contants.  */
+  if (! IS_SEXT_32BIT_NUM(ep->X_add_number))
+    as_warn (_("operand overflow"));
+
+  if (IS_SEXT_16BIT_NUM(ep->X_add_number))
+    {
+      /* Signed 16-bit offset will fit in the op.  Easy!  */
+      macro_build (place, counter, ep, op, "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, breg);
+    }
+  else
+    {
+      /* 32-bit offset, need multiple instructions and AT, like:
+          lui      $tempreg,const_hi       (BFD_RELOC_HI16_S)
+          addu     $tempreg,$tempreg,$breg
+           <op>     $treg,const_lo($tempreg)   (BFD_RELOC_LO16)
+         to handle the complete offset.  */
+      macro_build_lui (place, counter, ep, AT);
+      if (place != NULL)
+       place += 4;
+      macro_build (place, counter, (expressionS *) NULL,
+                  HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
+                  "d,v,t", AT, AT, breg);
+      if (place != NULL)
+       place += 4;
+      macro_build (place, counter, ep, op, "t,o(b)", treg,
+                  (int) BFD_RELOC_LO16, AT);
+
+      if (mips_opts.noat)
+       as_warn (_("Macro used $at after \".set noat\""));
+    }
+}
+
 /*                     set_at()
  * Generates code to set the $at register to true (one)
  * if reg is less than the immediate expression.
@@ -3196,11 +3256,6 @@ check_absolute_expr (ip, ex)
            ? 1                          \
            : 0)
 
-/* Is the given value a sign-extended 32-bit value?  */
-#define IS_SEXT_32BIT_NUM(x)                                           \
-  (((x) &~ (offsetT) 0x7fffffff) == 0                                  \
-   || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
-
 /*                     load_register()
  *  This routine generates the least number of instructions neccessary to load
  *  an absolute expression value into a register.
@@ -5063,10 +5118,9 @@ macro (ip)
                      mips_cprestore_valid = 1;
                    }
                  expr1.X_add_number = mips_cprestore_offset;
-                 macro_build ((char *) NULL, &icnt, &expr1,
-                              HAVE_32BIT_ADDRESSES ? "lw" : "ld", "t,o(b)",
-                              mips_gp_register, (int) BFD_RELOC_LO16,
-                              mips_frame_reg);
+                 macro_build_ldst_constoffset ((char *) NULL, &icnt, &expr1,
+                                               HAVE_32BIT_ADDRESSES ? "lw" : "ld",
+                                               mips_gp_register, mips_frame_reg);
                }
            }
        }
@@ -5196,10 +5250,9 @@ macro (ip)
                    macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
                                 "nop", "");
                  expr1.X_add_number = mips_cprestore_offset;
-                 macro_build ((char *) NULL, &icnt, &expr1,
-                              HAVE_32BIT_ADDRESSES ? "lw" : "ld", "t,o(b)",
-                              mips_gp_register, (int) BFD_RELOC_LO16,
-                              mips_frame_reg);
+                 macro_build_ldst_constoffset ((char *) NULL, &icnt, &expr1,
+                                               HAVE_32BIT_ADDRESSES ? "lw" : "ld",
+                                               mips_gp_register, mips_frame_reg);
                }
            }
        }
@@ -11863,8 +11916,9 @@ s_cprestore (ignore)
   ex.X_op_symbol = NULL;
   ex.X_add_number = mips_cprestore_offset;
 
-  macro_build ((char *) NULL, &icnt, &ex, HAVE_32BIT_ADDRESSES ? "sw" : "sd",
-              "t,o(b)", mips_gp_register, (int) BFD_RELOC_LO16, SP);
+  macro_build_ldst_constoffset ((char *) NULL, &icnt, &ex,
+                               HAVE_32BIT_ADDRESSES ? "sw" : "sd",
+                               mips_gp_register, SP);
 
   demand_empty_rest_of_line ();
 }
index 7ab5e588a3cf4bc7d919051095a2b4062f122649..6ba656705cde06e6060b26404420e81fa9233549 100644 (file)
@@ -1,4 +1,10 @@
-2002-09-12  Chris Demetriou  <cgd@broadcom.com>
+2002-09-18  Chris Demetriou  <cgd@broadcom.com>
+
+       * gas/mips/mips-abi32-pic2.s: New file.
+       * gas/mips/mips-abi32-pic2.d: New file.
+       * gas/mips/mips.exp: Run new test.
+
+2002-09-18  Chris Demetriou  <cgd@broadcom.com>
 
        * gas/mips/baddata1.s: New file.
        * gas/mips/baddata1.l: New file.
diff --git a/gas/testsuite/gas/mips/mips-abi32-pic2.d b/gas/testsuite/gas/mips/mips-abi32-pic2.d
new file mode 100644 (file)
index 0000000..1f3811e
--- /dev/null
@@ -0,0 +1,74 @@
+#objdump: -d -mmips:8000 -r --prefix-addresses --show-raw-insn
+#as: -march=8000 -EB -mabi=32 -KPIC
+#name: MIPS -mabi=32 test 2 (SVR4 PIC)
+
+.*: +file format.*
+
+Disassembly of section \.text:
+0+000 <[^>]*> 3c1c0000         lui     gp,0x0
+                       0: R_MIPS_HI16  _gp_disp
+0+004 <[^>]*> 279c0000         addiu   gp,gp,0
+                       4: R_MIPS_LO16  _gp_disp
+0+008 <[^>]*> 0399e021         addu    gp,gp,t9
+0+00c <[^>]*> afbc0008         sw      gp,8\(sp\)
+0+010 <[^>]*> 8f990000         lw      t9,0\(gp\)
+                       10: R_MIPS_GOT16        \.text
+0+014 <[^>]*> 00000000         nop
+0+018 <[^>]*> 273900d8         addiu   t9,t9,216
+                       18: R_MIPS_LO16 \.text
+0+01c <[^>]*> 0320f809         jalr    t9
+0+020 <[^>]*> 00000000         nop
+0+024 <[^>]*> 8fbc0008         lw      gp,8\(sp\)
+0+028 <[^>]*> 00000000         nop
+0+02c <[^>]*> 0320f809         jalr    t9
+0+030 <[^>]*> 00000000         nop
+0+034 <[^>]*> 8fbc0008         lw      gp,8\(sp\)
+0+038 <[^>]*> 3c1c0000         lui     gp,0x0
+                       38: R_MIPS_HI16 _gp_disp
+0+03c <[^>]*> 279c0000         addiu   gp,gp,0
+                       3c: R_MIPS_LO16 _gp_disp
+0+040 <[^>]*> 0399e021         addu    gp,gp,t9
+0+044 <[^>]*> 3c010001         lui     at,0x1
+0+048 <[^>]*> 003d0821         addu    at,at,sp
+0+04c <[^>]*> ac3c8000         sw      gp,-32768\(at\)
+0+050 <[^>]*> 8f990000         lw      t9,0\(gp\)
+                       50: R_MIPS_GOT16        \.text
+0+054 <[^>]*> 00000000         nop
+0+058 <[^>]*> 273900d8         addiu   t9,t9,216
+                       58: R_MIPS_LO16 \.text
+0+05c <[^>]*> 0320f809         jalr    t9
+0+060 <[^>]*> 00000000         nop
+0+064 <[^>]*> 3c010001         lui     at,0x1
+0+068 <[^>]*> 003d0821         addu    at,at,sp
+0+06c <[^>]*> 8c3c8000         lw      gp,-32768\(at\)
+0+070 <[^>]*> 00000000         nop
+0+074 <[^>]*> 0320f809         jalr    t9
+0+078 <[^>]*> 00000000         nop
+0+07c <[^>]*> 3c010001         lui     at,0x1
+0+080 <[^>]*> 003d0821         addu    at,at,sp
+0+084 <[^>]*> 8c3c8000         lw      gp,-32768\(at\)
+0+088 <[^>]*> 3c1c0000         lui     gp,0x0
+                       88: R_MIPS_HI16 _gp_disp
+0+08c <[^>]*> 279c0000         addiu   gp,gp,0
+                       8c: R_MIPS_LO16 _gp_disp
+0+090 <[^>]*> 0399e021         addu    gp,gp,t9
+0+094 <[^>]*> 3c010001         lui     at,0x1
+0+098 <[^>]*> 003d0821         addu    at,at,sp
+0+09c <[^>]*> ac3c0000         sw      gp,0\(at\)
+0+0a0 <[^>]*> 8f990000         lw      t9,0\(gp\)
+                       a0: R_MIPS_GOT16        \.text
+0+0a4 <[^>]*> 00000000         nop
+0+0a8 <[^>]*> 273900d8         addiu   t9,t9,216
+                       a8: R_MIPS_LO16 \.text
+0+0ac <[^>]*> 0320f809         jalr    t9
+0+0b0 <[^>]*> 00000000         nop
+0+0b4 <[^>]*> 3c010001         lui     at,0x1
+0+0b8 <[^>]*> 003d0821         addu    at,at,sp
+0+0bc <[^>]*> 8c3c0000         lw      gp,0\(at\)
+0+0c0 <[^>]*> 00000000         nop
+0+0c4 <[^>]*> 0320f809         jalr    t9
+0+0c8 <[^>]*> 00000000         nop
+0+0cc <[^>]*> 3c010001         lui     at,0x1
+0+0d0 <[^>]*> 003d0821         addu    at,at,sp
+0+0d4 <[^>]*> 8c3c0000         lw      gp,0\(at\)
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/mips-abi32-pic2.s b/gas/testsuite/gas/mips/mips-abi32-pic2.s
new file mode 100644 (file)
index 0000000..3e22e26
--- /dev/null
@@ -0,0 +1,107 @@
+
+       .text
+       .ent    func1
+func1:
+       .frame $sp,0,$31
+       .set noreorder
+       .cpload $25             # 0000 lui      gp,hi(_gp_disp)
+                               # 0004 addiu    gp,gp,lo(_gp_disp)
+                               # 0008 addu     gp,gp,t9
+       .set reorder
+       .cprestore 8            # 000c sw       gp,8(sp)
+
+       jal     end             # 0010 lw       t9,got(.text)(gp)
+                               # 0014 nop
+                               # 0018 addiu    t9,t9,lo(end)
+                               # 001c jalr     t9
+                               # 0020 nop
+                               # 0024 lw       gp,8(sp)
+
+       # Avoid confusion: avoid the 'lw' above being put into the delay
+       # slot for the jalr below!
+       .set noreorder
+       nop                     # 0028 nop
+       .set reorder
+
+       jal     $25             # 002c jalr     t9
+                               # 0030 nop
+                               # 0034 lw       gp,8(sp)
+       .end    func1
+
+
+       .text
+       .ent    func2
+func2:
+       .frame $sp,0,$31
+       .set noreorder
+       .cpload $25             # 0038 lui      gp,hi(_gp_disp)
+                               # 003c addiu    gp,gp,lo(_gp_disp)
+                               # 0040 addu     gp,gp,t9
+       .set reorder
+       .cprestore 32768        # 0044 lui      at,0x1
+                               # 0048 addu     at,at,sp
+                               # 004c sw       gp,-32768(at)
+
+       jal     end             # 0050 lw       t9,got(.text)(gp)
+                               # 0054 nop
+                               # 0058 addiu    t9,t9,lo(end)
+                               # 005c jalr     t9
+                               # 0060 nop
+                               # 0064 lui      at,0x1
+                               # 0068 addu     at,at,sp
+                               # 006c lw       gp,-32768(at)
+
+       # Avoid confusion: avoid the 'lw' above being put into the delay
+       # slot for the jalr below!
+       .set noreorder
+       nop                     # 0070 nop
+       .set reorder
+
+       jal     $25             # 0074 jalr     t9
+                               # 0078 nop
+                               # 007c lui      at,0x1
+                               # 0080 addu     at,at,sp
+                               # 0084 lw       gp,-32768(at)
+       .end    func2
+
+
+       .text
+       .ent    func3
+func3:
+       .frame $sp,0,$31
+       .set noreorder
+       .cpload $25             # 0088 lui      gp,hi(_gp_disp)
+                               # 008c addiu    gp,gp,lo(_gp_disp)
+                               # 0090 addu     gp,gp,t9
+       .set reorder
+       .cprestore 65536        # 0094 lui      at,0x1
+                               # 0098 addu     at,at,sp
+                               # 009c sw       gp,0(at)
+
+       jal     end             # 00a0 lw       t9,got(.text)(gp)
+                               # 00a4 nop
+                               # 00a8 addiu    t9,t9,lo(end)
+                               # 00ac jalr     t9
+                               # 00b0 nop
+                               # 00b4 lui      at,0x1
+                               # 00b8 addu     at,at,sp
+                               # 00bc lw       gp,0(at)
+
+       # Avoid confusion: avoid the 'lw' above being put into the delay
+       # slot for the jalr below!
+       .set noreorder
+       nop                     # 00c0 nop
+       .set reorder
+
+       jal     $25             # 00c4 jalr     t9
+                               # 00c8 nop
+                               # 00cc lui      at,0x1
+                               # 00d0 addu     at,at,sp
+                               # 00d4 lw       gp,0(at)
+
+       .end    func3
+
+end:
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .space  8
index 12613ea9470dba3092ee7488e903a9399d296d8f..d23390d0adb2b518ab39258b5faa9cc9ddda8eca 100644 (file)
@@ -193,6 +193,7 @@ if { [istarget mips*-*-*] } then {
 
        run_dump_test "mips-abi32"
        run_dump_test "mips-abi32-pic"
+       run_dump_test "mips-abi32-pic2"
 
        run_dump_test "elf${el}-rel"
        if {[istarget mips64*-*-*] || [istarget mipsisa32*-*-*]