This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[MIPS PATCH' RFA] fix serious problem w/ MIPS .cprestore.


Here's the updated version of the .cprestore fix patch.

(in addition to the comments being wrong, I actually screwed the test
case entry up in another way, also fixed.)

[ gas/ChangeLog ]
2002-09-16  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-16  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.

Index: 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
--- config/tc-mips.c	5 Sep 2002 00:01:18 -0000	1.162
+++ config/tc-mips.c	16 Sep 2002 20:55:21 -0000
@@ -665,6 +665,17 @@ static const unsigned int mips16_to_32_r
 #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))
+
 
 /* Prototypes for static functions.  */
 
@@ -701,6 +712,9 @@ static void mips16_macro_build PARAMS ((
 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 *));
@@ -3079,6 +3093,52 @@ macro_build_lui (place, counter, ep, reg
     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.
@@ -3193,11 +3253,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.
@@ -5048,10 +5103,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);
 		}
 	    }
 	}
@@ -5181,10 +5235,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);
 		}
 	    }
 	}
@@ -11835,8 +11892,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: testsuite/gas/mips/mips-abi32-pic2.s
===================================================================
RCS file: testsuite/gas/mips/mips-abi32-pic2.s
diff -N testsuite/gas/mips/mips-abi32-pic2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/mips/mips-abi32-pic2.s	16 Sep 2002 20:55:21 -0000
@@ -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			# 0028 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			# 0028 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: testsuite/gas/mips/mips-abi32-pic2.d
===================================================================
RCS file: testsuite/gas/mips/mips-abi32-pic2.d
diff -N testsuite/gas/mips/mips-abi32-pic2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/mips/mips-abi32-pic2.d	16 Sep 2002 20:55:21 -0000
@@ -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\)
+	\.\.\.
Index: 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
--- testsuite/gas/mips/mips.exp	12 Aug 2002 08:30:50 -0000	1.40
+++ testsuite/gas/mips/mips.exp	16 Sep 2002 20:55:21 -0000
@@ -190,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*-*-*]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]