Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Jan 2003 21:17:28 +0100
From:      Thomas Moestl <tmoestl@gmx.net>
To:        Kris Kennaway <kris@obsecurity.org>
Cc:        kan@FreeBSD.org, obrien@FreeBSD.org, sparc64@FreeBSD.org
Subject:   Re: assembler error in XFree86 snapshot
Message-ID:  <20030116201728.GA279@crow.dom2ip.de>
In-Reply-To: <20030116072448.GA29468@rot13.obsecurity.org>
References:  <20030116072448.GA29468@rot13.obsecurity.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 2003/01/15 at 23:24:48 -0800, Kris Kennaway wrote:
> I'm trying to compile anholt's XFree86 4.2.99 snapshot on sparc, and I
> get the following error message:
> 
> cc -c -O -pipe  -ansi -Dasm=__asm -Wall -Wpointer-arith -Wundef    -I/usr/tmp/XFree86-4-libraries-devel/work/xc -I/usr/tmp/XFree86-4-libraries-devel/work/xc/exports/include   -DCSRG_BASED  -DFUNCPROTO=15 -DNARROWPROTO -DXTHREADS  -D_REENTRANT -D_THREAD_SAFE -DXUSE_MTSAFE_API -DXNO_MTSAFE_PWDAPI    -DMALLOC_0_RETURNS_NULL   XRes.c
> {standard input}: Assembler messages:
> {standard input}:667: Error: relocation overflow
> *** Error code 1
> 
> line 667 of the .s file is:
> 
> > .LL86:
> >         umul    %o0, 4294967295, %o0

This is a arguably a gcc bug. All (13-bit) immediate operands are
sign-extended, even those to instructions which operate on unsigned
values, so umul can handle a range of very small and a range of very
large operands. gcc correctly recognizes that it can use an immediate
here; however, it chooses to output it as an unsigned number and does
not sign-extended it from 32 to 64 bit.

All sign extensions for instructions are made to the full 64 bit
however (even if umul only happens to use 32 of those), so when the
assembler checks whether a value is representable as an immediate, it
will check that the 64-bit sign extension of the immediate creates
the desired value (in sparc64 mode), i.e. it doesn't ignore the upper
32 bits even if a particular instruction does not use them.

One solution is to generate negative literals for immediates if we
mean them to be sign-extended (which gcc does already for some other
instructions). The attached patch implements this, I'm not sure it
uses the best possible way to do this though, and it also needs a bit
more testing.

	- Thomas

-- 
Thomas Moestl <tmoestl@gmx.net>	http://www.tu-bs.de/~y0015675/
              <tmm@FreeBSD.org>	http://people.FreeBSD.org/~tmm/
PGP fingerprint: 1C97 A604 2BD0 E492 51D0  9C0F 1FE6 4F1D 419C 776C

Index: config/sparc/sparc.c
===================================================================
RCS file: /ncvs/src/contrib/gcc/config/sparc/sparc.c,v
retrieving revision 1.1.1.9
diff -u -r1.1.1.9 sparc.c
--- config/sparc/sparc.c	10 Oct 2002 04:40:04 -0000	1.1.1.9
+++ config/sparc/sparc.c	16 Jan 2003 18:09:06 -0000
@@ -6462,6 +6462,22 @@
       output_address (XEXP (x, 0));
       return;
 
+    case 's':
+      {
+	/* Print a sign-extended 32-bit value.  */
+	HOST_WIDE_INT xi;
+	int i;
+	if (GET_CODE(x) == CONST_INT)
+	  xi = INTVAL (x);
+	else if (GET_CODE(x) == CONST_DOUBLE)
+	  xi = CONST_DOUBLE_LOW (x);
+	else
+	  output_operand_lossage ("invalid %%s operand");
+	i = trunc_int_for_mode (xi, SImode);
+	fprintf (file, "%d", i);
+	return;
+      }
+
     case 0:
       /* Do nothing special.  */
       break;
Index: config/sparc/sparc.md
===================================================================
RCS file: /ncvs/src/contrib/gcc/config/sparc/sparc.md,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 sparc.md
--- config/sparc/sparc.md	10 Oct 2002 04:40:08 -0000	1.1.1.8
+++ config/sparc/sparc.md	16 Jan 2003 17:09:36 -0000
@@ -6120,7 +6120,7 @@
   "TARGET_HARD_MUL32"
   "*
 {
-  return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
+  return TARGET_SPARCLET ? \"umuld\\t%1, %s2, %L0\" : \"umul\\t%1, %s2, %L0\\n\\trd\\t%%y, %H0\";
 }"
   [(set (attr "type")
 	(if_then_else (eq_attr "isa" "sparclet")
@@ -6134,7 +6134,7 @@
 	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
 		 (match_operand:SI 2 "uns_small_int" "")))]
   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
-  "umul\\t%1, %2, %0"
+  "umul\\t%1, %s2, %0"
   [(set_attr "type" "imul")])
 
 ;; XXX
@@ -6145,8 +6145,8 @@
    (clobber (match_scratch:SI 3 "=X,h"))]
   "TARGET_V8PLUS"
   "@
-   umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
-   umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
+   umul\\t%1, %s2, %L0\\n\\tsrlx\\t%L0, 32, %H0
+   umul\\t%1, %s2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
   [(set_attr "type" "multi")
    (set_attr "length" "2,3")])
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-sparc" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030116201728.GA279>