Subject: Re: 64bit ns32k.md changes for GCC
To: Jon Buller <jonb@metronet.com>
From: Matthias Pfaller <leo@dachau.marco.de>
List: port-pc532
Date: 03/27/1996 10:28:32
Hi all,

I found a small bug in Jon's negdi2 code yesterday. It will eventually
produce something like the following:

	negd	r0,r0
	movqd	0,r1
	subcd	r1,r1

:-) I changed this to do

	negd	r1,r1
	negd	r0,r0
	subcd	0,r1

when %0 and %1 refer to the same object. So here comes yet another
version of the patch. I hope I'm the only one who has already installed
a full set of libraries compiled with the new compiler :-( If you have done,
this as well, you will have to replace at least vfprintf.so...
I was really glad that my cc1 was statically linked against the old version
of libc.a.

	Matthias

--- ns32k.md.ORIG	Mon Dec 11 21:14:24 1995
+++ ns32k.md	Tue Mar 26 23:50:53 1996
@@ -858,6 +858,47 @@
   "GET_CODE (operands[1]) == CONST_INT"
   "addr %c1(sp),%0")
 
+(define_insn "adddi3"
+  [(set (match_operand:DI 0 "general_operand" "=ro")
+	(plus:DI (match_operand:DI 1 "general_operand" "%0")
+		 (match_operand:DI 2 "general_operand" "ron")))]
+  ""
+  "*
+{
+  rtx low[3], high[3], xops[4];
+  split_di (operands, 3, low, high);
+  xops[0] = low[0];
+  xops[1] = high[0];
+  xops[2] = low[2];
+  xops[3] = high[2];
+
+  if (GET_CODE (xops[2]) == CONST_INT)
+    {
+      int i = INTVAL (xops[2]);
+
+      if (i <= 7 && i >= -8) 
+        {
+          if (i == 0)
+	    {
+	      i = INTVAL (xops[3]);
+	      if (i <= 7 && i >= -8)
+                output_asm_insn (\"addqd %$%3,%1\", xops);
+	      else
+                output_asm_insn (\"addd %$%3,%1\", xops);
+	    }
+	  else
+	    {
+              output_asm_insn (\"addqd %$%2,%0\", xops);
+              output_asm_insn (\"addcd %$%3,%1\", xops);
+	    }
+	  return \"\";
+	}
+    }
+  output_asm_insn (\"addd %2,%0\", xops);
+  output_asm_insn (\"addcd %3,%1\", xops);
+  return \"\";
+}")
+
 (define_insn "addsi3"
   [(set (match_operand:SI 0 "general_operand" "=g,=g&<")
 	(plus:SI (match_operand:SI 1 "general_operand" "%0,r")
@@ -971,6 +1012,47 @@
   return \"adjspd %$%0\";
 }")
 
+(define_insn "subdi3"
+  [(set (match_operand:DI 0 "general_operand" "=ro")
+	(minus:DI (match_operand:DI 1 "general_operand" "%0")
+		  (match_operand:DI 2 "general_operand" "ron")))]
+  ""
+  "*
+{
+  rtx low[3], high[3], xops[4];
+  split_di (operands, 3, low, high);
+  xops[0] = low[0];
+  xops[1] = high[0];
+  xops[2] = low[2];
+  xops[3] = high[2];
+
+  if (GET_CODE (xops[2]) == CONST_INT)
+    {
+      int i = INTVAL (xops[2]);
+
+      if (i <= 8 && i >= -7)
+        {
+          if (i == 0)
+	    {
+	      i = INTVAL (xops[3]);
+	      if (i <= 8 && i >= -7)
+                output_asm_insn (\"addqd %$%n3,%1\", xops);
+	      else
+                output_asm_insn (\"subd %$%3,%1\", xops);
+	    }
+	  else
+	    {
+              output_asm_insn (\"addqd %$%n2,%0\", xops);
+              output_asm_insn (\"subcd %$%3,%1\", xops);
+	    }
+	  return \"\";
+	}
+    }
+  output_asm_insn (\"subd %2,%0\", xops);
+  output_asm_insn (\"subcd %3,%1\", xops);
+  return \"\";
+}")
+
 (define_insn "subsi3"
   [(set (match_operand:SI 0 "general_operand" "=g")
 	(minus:SI (match_operand:SI 1 "general_operand" "0")
@@ -1389,6 +1471,34 @@
 	(neg:SF (match_operand:SF 1 "general_operand" "fmF")))]
   "TARGET_32081"
   "negf %1,%0")
+
+(define_insn "negdi2"
+  [(set (match_operand:DI 0 "general_operand" "=ro")
+	(neg:DI (match_operand:DI 1 "general_operand" "ro")))]
+  ""
+  "*
+{
+  rtx low[2], high[2], xops[4];
+  split_di (operands, 2, low, high);
+  xops[0] = low[0];
+  xops[1] = high[0];
+  xops[2] = low[1];
+  xops[3] = high[1];
+
+  if (rtx_equal_p (operands[0], operands[1]))
+    {
+      output_asm_insn (\"negd %3,%1\", xops);
+      output_asm_insn (\"negd %2,%0\", xops);
+      output_asm_insn (\"subcd %$0,%1\", xops);
+    }
+  else
+    {
+      output_asm_insn (\"negd %2,%0\", xops);
+      output_asm_insn (\"movqd %$0,%1\", xops);
+      output_asm_insn (\"subcd %3,%1\", xops);
+    }
+  return \"\"; 
+}")
 
 (define_insn "negsi2"
   [(set (match_operand:SI 0 "general_operand" "=g<")

--- ns32k.c.ORIG	Mon Dec 11 21:14:23 1995
+++ ns32k.c	Fri Mar 22 23:35:38 1996
@@ -227,6 +227,39 @@
 	      || GET_CODE (op) == MEM));
 }
 
+/* Split one or more DImode RTL references into pairs of SImode
+   references.  The RTL can be REG, offsettable MEM, integer constant, or
+   CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
+   split and "num" is its length.  lo_half and hi_half are output arrays
+   that parallel "operands". */
+
+void
+split_di (operands, num, lo_half, hi_half)
+     rtx operands[];
+     int num;
+     rtx lo_half[], hi_half[];
+{
+  while (num--)
+    {
+      if (GET_CODE (operands[num]) == REG)
+	{
+	  lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
+	  hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
+	}
+      else if (CONSTANT_P (operands[num]))
+	{
+	  split_double (operands[num], &lo_half[num], &hi_half[num]);
+	}
+      else if (offsettable_memref_p (operands[num]))
+	{
+	  lo_half[num] = operands[num];
+	  hi_half[num] = adj_offsettable_operand (operands[num], 4);
+	}
+      else
+	abort();
+    }
+}
+
 /* Return the best assembler insn template
    for moving operands[1] into operands[0] as a fullword.  */
 

-- 
leo@dachau.marco.de			in real life: Matthias Pfaller
marco GmbH, 85221 Dachau, Germany	tel: +49 8131 516142