This is the mail archive of the binutils@sourceware.org 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]

64-bit host failures, h8300


Fix assembler failures due to sign extension of 32-bit values into
a 64-bit long.

h8300-elf  +FAIL: gas/h8300/h8sx_mov_imm

	* config/tc-h8300.c (constant_fits_width_p): Trim constant to 32 bits
	and sign extend before range tests.
	(constant_fits_size_p): Similarly.
	(get_specific): Trim X_add_number to 32 bits.
	(fix_operand_size): Likewise, and use unsigned test for signed
	ranges.

Index: gas/config/tc-h8300.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-h8300.c,v
retrieving revision 1.65
diff -u -p -r1.65 tc-h8300.c
--- gas/config/tc-h8300.c	20 Jan 2011 12:49:05 -0000	1.65
+++ gas/config/tc-h8300.c	26 Feb 2012 03:49:27 -0000
@@ -1,6 +1,6 @@
 /* tc-h8300.c -- Assemble code for the Renesas H8/300
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -558,17 +558,21 @@ skip_colonthing (char *src, int *mode)
 static int
 constant_fits_width_p (struct h8_op *operand, unsigned int width)
 {
-  return ((operand->exp.X_add_number & ~width) == 0
-	  || (operand->exp.X_add_number | (offsetT) width) == (offsetT)(~0));
+  offsetT num;
+
+  num = ((operand->exp.X_add_number & 0xffffffff) ^ 0x80000000) - 0x80000000;
+  return (num & ~width) == 0 || (num | width) == ~0;
 }
 
 static int
 constant_fits_size_p (struct h8_op *operand, int size, int no_symbols)
 {
-  offsetT num = operand->exp.X_add_number;
+  offsetT num;
+
   if (no_symbols
       && (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
     return 0;
+  num = operand->exp.X_add_number & 0xffffffff;
   switch (size)
     {
     case L_2:
@@ -582,11 +586,13 @@ constant_fits_size_p (struct h8_op *oper
     case L_5:
       return num >= 1 && num < 32;
     case L_8:
-      return (num & ~0xFF) == 0 || ((unsigned)num | 0x7F) == ~0u;
+      num = (num ^ 0x80000000) - 0x80000000;
+      return (num & ~0xFF) == 0 || (num | 0x7F) == ~0;
     case L_8U:
       return (num & ~0xFF) == 0;
     case L_16:
-      return (num & ~0xFFFF) == 0 || ((unsigned)num | 0x7FFF) == ~0u;
+      num = (num ^ 0x80000000) - 0x80000000;
+      return (num & ~0xFFFF) == 0 || (num | 0x7FFF) == ~0;
     case L_16U:
       return (num & ~0xFFFF) == 0;
     case L_32:
@@ -1184,7 +1190,7 @@ get_specific (const struct h8_instructio
 		}
 	      else if (x_mode == IMM && op_mode != IMM)
 		{
-		  offsetT num = operands[i].exp.X_add_number;
+		  offsetT num = operands[i].exp.X_add_number & 0xffffffff;
 		  if (op_mode == KBIT || op_mode == DBIT)
 		    /* This is ok if the immediate value is sensible.  */;
 		  else if (op_mode == CONST_2)
@@ -1866,8 +1872,8 @@ fix_operand_size (struct h8_op *operand,
 	   necessary.  */
 	if (Hmode
 	    && !Nmode 
-	    && (operand->exp.X_add_number < -32768
-		|| operand->exp.X_add_number > 32767
+	    && ((((addressT) operand->exp.X_add_number + 0x8000)
+		 & 0xffffffff) > 0xffff
 		|| operand->exp.X_add_symbol != 0
 		|| operand->exp.X_op_symbol != 0))
 	  operand->mode |= L_24;
@@ -1876,9 +1882,8 @@ fix_operand_size (struct h8_op *operand,
 	break;
 
       case PCREL:
-	/* This condition is long standing, though somewhat suspect.  */
-	if (operand->exp.X_add_number > -128
-	    && operand->exp.X_add_number < 127)
+	if ((((addressT) operand->exp.X_add_number + 0x80)
+	     & 0xffffffff) <= 0xff)
 	  {
 	    if (operand->exp.X_add_symbol != NULL)
 	      operand->mode |= bsize;

-- 
Alan Modra
Australia Development Lab, IBM


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