[PATCH 16/20] MIPS/GAS: Correct types used for DEXT/DINS macros

Maciej W. Rozycki macro@codesourcery.com
Thu Dec 2 19:22:00 GMT 2010


Hi,

 Here's a change to correct types used for the bitfield position and 
offset immediates with the DEXT and DINS macros.  There are two issues:

- the "unsigned long" type may be narrower than offsetT/addressT (e.g. on 
  ILP32 hosts); truncation will mask overflow errors for some inputs,

- the "unsigned long" type may be wider than int (e.g. on LP64 hosts) 
  expected for the format specifiers used here and macro_build() is a 
  variadic function so implicit type conversion does not happen; this may 
  cause problems with some ABIs.

There's no C way to say "unsigned offsetT" (.X_add_number is typed 
offsetT), but addressT is equivalent.

2010-12-02  Maciej W. Rozycki  <macro@codesourcery.com>

	gas/
	* config/tc-mips.c (macro)[M_DEXT, M_DINS]: Correct types used
	for pos and size.

 OK to apply?

  Maciej

binutils-gas-mips-dextins.diff
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2010-12-01 21:05:51.000000000 +0000
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2010-12-01 21:05:58.000000000 +0000
@@ -5268,8 +5268,9 @@ macro (struct mips_cl_insn *ip)
 
     case M_DEXT:
       {
-	unsigned long pos;
-	unsigned long size;
+	/* Use unsigned arithmetic.  */
+	addressT pos;
+	addressT size;
 
 	if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
 	  {
@@ -5278,19 +5279,19 @@ macro (struct mips_cl_insn *ip)
 	  }
 	else
 	  {
-	    pos = (unsigned long) imm_expr.X_add_number;
-	    size = (unsigned long) imm2_expr.X_add_number;
+	    pos = imm_expr.X_add_number;
+	    size = imm2_expr.X_add_number;
 	  }
 
 	if (pos > 63)
 	  {
-	    as_bad (_("Improper position (%lu)"), pos);
+	    as_bad (_("Improper position (%lu)"), (unsigned long) pos);
 	    pos = 1;
 	  }
 	if (size == 0 || size > 64 || (pos + size - 1) > 63)
 	  {
 	    as_bad (_("Improper extract size (%lu, position %lu)"),
-		    size, pos);
+		    (unsigned long) size, (unsigned long) pos);
 	    size = 1;
 	  }
 
@@ -5309,14 +5310,16 @@ macro (struct mips_cl_insn *ip)
 	    s = "dextm";
 	    fmt = "t,r,+A,+G";
 	  }
-	macro_build ((expressionS *) NULL, s, fmt, treg, sreg, pos, size - 1);
+	macro_build ((expressionS *) NULL, s, fmt, treg, sreg, (int) pos,
+		     (int) (size - 1));
       }
       break;
 
     case M_DINS:
       {
-	unsigned long pos;
-	unsigned long size;
+	/* Use unsigned arithmetic.  */
+	addressT pos;
+	addressT size;
 
 	if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
 	  {
@@ -5325,19 +5328,19 @@ macro (struct mips_cl_insn *ip)
 	  }
 	else
 	  {
-	    pos = (unsigned long) imm_expr.X_add_number;
-	    size = (unsigned long) imm2_expr.X_add_number;
+	    pos = imm_expr.X_add_number;
+	    size = imm2_expr.X_add_number;
 	  }
 
 	if (pos > 63)
 	  {
-	    as_bad (_("Improper position (%lu)"), pos);
+	    as_bad (_("Improper position (%lu)"), (unsigned long) pos);
 	    pos = 1;
 	  }
 	if (size == 0 || size > 64 || (pos + size - 1) > 63)
 	  {
 	    as_bad (_("Improper insert size (%lu, position %lu)"),
-		    size, pos);
+		    (unsigned long) size, (unsigned long) pos);
 	    size = 1;
 	  }
 



More information about the Binutils mailing list