This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


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

Re: reload error in current x86 mainline version


The attached patch fixes the ICE reported in msg00223.html

gcc/ChangeLog
* config/i386/i386.c (split_xf1): New.
* config/i386/i386-protos.h: Declare it.
* config/i386/i386.md: Correct some comment typos.
(movxf_1): Fix attr.  Add G -> r alternative.
(movxf_1+2): New splitter for XF G -> r.

Warning:  Patch generated by someone with minimal understanding of gcc
internals.  Highly likely to be non-optimal, quite likely to be wrong.
--- gcc/config/i386/i386.c~	Sat Nov  6 10:16:36 1999
+++ gcc/config/i386/i386.c	Tue Nov 16 14:20:06 1999
@@ -3015,6 +3015,62 @@ split_xf (orig, out)
       out[2] = adj_offsettable_operand (out[0], 8);
     }
 }
+
+/*  Like final.c:split_double, but only for CONST_DOUBLE orig and
+    96 bit real out.  */
+void
+split_xf1 (orig, out)
+     rtx orig;
+     rtx out[3];
+{
+#ifdef REAL_ARITHMETIC
+  REAL_VALUE_TYPE r;
+  long l[3];
+
+  REAL_VALUE_FROM_CONST_DOUBLE (r, orig);
+  REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
+
+#if HOST_BITS_PER_LONG > 32
+  if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32)
+    {
+      if (l[0] & ((long) 1 << 31))
+	l[0] |= ((long) (-1) << 32);
+      if (l[1] & ((long) 1 << 31))
+	l[1] |= ((long) (-1) << 32);
+      if (l[2] & ((long) 1 << 31))
+	l[2] |= ((long) (-1) << 32);
+    }
+#endif
+
+  out[0] = GEN_INT ((HOST_WIDE_INT) l[0]);
+  out[1] = GEN_INT ((HOST_WIDE_INT) l[1]);
+  out[2] = GEN_INT ((HOST_WIDE_INT) l[2]);
+#else
+  if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
+       || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
+      && ! flag_pretend_float)
+    abort ();
+
+  if (
+#ifdef HOST_WORDS_BIG_ENDIAN
+      WORDS_BIG_ENDIAN
+#else
+      ! WORDS_BIG_ENDIAN
+#endif
+      )
+    {
+      out[0] = GEN_INT (XWINT (value, 2));
+      out[1] = GEN_INT (XWINT (value, 3));
+      out[2] = GEN_INT (XWINT (value, 4));
+    }
+  else
+    {
+      out[2] = GEN_INT (XWINT (value, 2));
+      out[1] = GEN_INT (XWINT (value, 3));
+      out[0] = GEN_INT (XWINT (value, 4));
+    }
+#endif /* no REAL_ARITHMETIC */
+}
 
 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
--- gcc/config/i386/i386-protos.h~	Sat Nov  6 10:16:36 1999
+++ gcc/config/i386/i386-protos.h	Tue Nov 16 15:51:40 1999
@@ -74,6 +74,7 @@ extern void print_operand_address PROTO(
 
 extern void split_di PROTO((rtx[], int, rtx[], rtx[]));
 extern void split_xf PROTO((rtx, rtx[3]));
+extern void split_xf1 PROTO((rtx, rtx[3]));
 
 extern char *output_387_binary_op PROTO((rtx, rtx*));
 extern char *output_fix_trunc PROTO((rtx, rtx*));
--- gcc/config/i386/i386.md~	Mon Nov  8 17:49:07 1999
+++ gcc/config/i386/i386.md	Tue Nov 16 13:39:52 1999
@@ -1712,7 +1712,7 @@
   switch (which_alternative)
     {
     case 0:
-      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
+      /* %%% We lose REG_DEAD notes for controling pops if we split late.  */
       operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
       operands[2] = stack_pointer_rtx;
       operands[3] = GEN_INT (4);
@@ -1812,7 +1812,7 @@
   switch (which_alternative)
     {
     case 0:
-      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
+      /* %%% We lose REG_DEAD notes for controling pops if we split late.  */
       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
       operands[2] = stack_pointer_rtx;
       operands[3] = GEN_INT (8);
@@ -1941,7 +1941,7 @@
   ""
   "*
 {
-  /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
+  /* %%% We lose REG_DEAD notes for controling pops if we split late.  */
   operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
   operands[2] = stack_pointer_rtx;
   operands[3] = GEN_INT (12);
@@ -1980,8 +1980,8 @@
 }")
 
 (define_insn "*movxf_1"
-  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*&r,o")
-	(match_operand:XF 1 "general_operand" "fm,f,G,*ro,*r"))]
+  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*&r,o,*r")
+	(match_operand:XF 1 "general_operand" "fm,f,G,*ro,*r,G"))]
   ""
   "*
 {
@@ -2014,12 +2014,12 @@
 	}
       break;
 
-    case 3: case 4:
+    case 3: case 4: case 5:
       return \"#\";
     }
   abort();
 }"
-  [(set_attr "type" "fmov")])
+  [(set_attr "type" "fmov,fmov,fmov,multi,multi,multi")])
 
 (define_split
   [(set (match_operand:XF 0 "nonimmediate_operand" "")
@@ -2030,6 +2030,16 @@
    (set (match_dup 1) (match_dup 4))
    (set (match_dup 2) (match_dup 5))]
   "split_xf (operands[1], &operands[3]);
+   split_xf (operands[0], &operands[0]);")
+
+(define_split
+  [(set (match_operand:XF 0 "register_operand" "")
+	(match_operand:XF 1 "immediate_operand" ""))]
+  "REG_P (operands[0]) && ! FP_REGNO_P (REGNO (operands[0]))"
+  [(set (match_dup 0) (match_dup 3))
+   (set (match_dup 1) (match_dup 4))
+   (set (match_dup 2) (match_dup 5))]
+  "split_xf1 (operands[1], &operands[3]);
    split_xf (operands[0], &operands[0]);")
 
 (define_insn "swapxf"

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