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