John Wehle (john@feith.com)
authorJohn Wehle <john@feith.com>
Wed, 14 Apr 1999 14:27:38 +0000 (14:27 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 14 Apr 1999 14:27:38 +0000 (07:27 -0700)
John Wehle  (john@feith.com)
        * i386.md (extendsfdf, extendsfxf, extenddfxf): Use
        output_float_extend instead specifying '#' as the template.
        * i386.c (output_float_extend): Define.
        * i386.h (output_float_extend): Declare.

From-SVN: r26455

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md

index 0e971bc..30a0868 100644 (file)
@@ -1,3 +1,10 @@
+Wed Apr 14 14:26:36 1999  John Wehle  (john@feith.com)
+
+        * i386.md (extendsfdf, extendsfxf, extenddfxf): Use
+        output_float_extend instead specifying '#' as the template.
+        * i386.c (output_float_extend): Define.
+        * i386.h (output_float_extend): Declare.
+
 Wed Apr 14 10:48:03 1999  Catherine Moore  <clm@cygnus.com>
  
         * config/mips/elf.h, config/mips/elf64.h
index 3da661a..8432443 100644 (file)
@@ -4179,6 +4179,66 @@ output_fix_trunc (insn, operands)
   return AS1 (fldc%W2,%2);
 }
 \f
+/* Output code for INSN to extend a float.  OPERANDS are the insn
+   operands.  The output may be DFmode or XFmode and the input operand
+   may be SFmode or DFmode.  Operands 2 and 3 are scratch memory and
+   are only necessary if operands 0 or 1 are non-stack registers.  */
+
+void
+output_float_extend (insn, operands)
+     rtx insn;
+     rtx *operands;
+{
+  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+  rtx xops[2];
+
+  if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
+    abort ();
+
+  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]) && stack_top_dies)
+    return;
+
+  if (STACK_TOP_P (operands[0]) )
+    {
+      if (NON_STACK_REG_P (operands[1]))
+       {
+         if (GET_MODE (operands[1]) == SFmode)
+           output_asm_insn (AS2 (mov%L0,%1,%2), operands);
+         else
+           {
+             xops[0] = operands[2];
+             xops[1] = operands[1];
+             output_asm_insn (output_move_double (xops), xops);
+           }
+       }
+
+      xops[0] = NON_STACK_REG_P (operands[1]) ? operands[2] : operands[1];
+
+      output_asm_insn (AS1 (fld%z0,%y0), xops);
+    }
+  else
+    {
+      xops[0] = NON_STACK_REG_P (operands[0]) ? operands[3] : operands[0];
+
+      if (stack_top_dies
+         || (GET_CODE (xops[0]) == MEM && GET_MODE (xops[0]) == XFmode))
+       {
+         output_asm_insn (AS1 (fstp%z0,%y0), xops);
+         if (! stack_top_dies)
+           output_asm_insn (AS1 (fld%z0,%y0), xops);
+       }
+      else
+       output_asm_insn (AS1 (fst%z0,%y0), xops);
+
+      if (NON_STACK_REG_P (operands[0]))
+       {
+         xops[0] = operands[0];
+         xops[1] = operands[3];
+         output_asm_insn (output_move_double (xops), xops);
+       }
+    }
+}
+\f
 /* Output code for INSN to compare OPERANDS.  The two operands might
    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
    expression.  If the compare is in mode CCFPEQmode, use an opcode that
index de4da2c..56967a6 100644 (file)
@@ -2743,6 +2743,7 @@ extern int shift_op ();
 extern int VOIDmode_compare_op ();
 extern char *output_387_binary_op ();
 extern char *output_fix_trunc ();
+extern void output_float_extend ();
 extern char *output_float_compare ();
 extern char *output_fp_cc0_set ();
 extern void save_386_machine_status ();
index ef062b9..211b0ba 100644 (file)
    (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
                    || GET_CODE (operands[1]) != MEM)"
-  "#")
+  "*
+{
+  output_float_extend (insn, operands);
+  return \"\";
+}"
+  [(set_attr "type" "fld,fpop,fld,fpop")])
 
 (define_split
   [(set (match_operand:DF 0 "register_operand" "")
                    || GET_CODE (operands[1]) != MEM)"
   "*
 {
-  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-
-  if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
-    abort ();
-
-  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
+    output_float_extend (insn, operands);
     return \"\";
-
-  if (STACK_TOP_P (operands[0]))
-    return AS1 (fld%z1,%y1);
-
-  if (stack_top_dies)
-    return AS1 (fstp%z0,%y0);
-  else
-    return AS1 (fst%z0,%y0);
 }"
   [(set_attr "type" "fld,fpop")])
 
    (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
                    || GET_CODE (operands[1]) != MEM)"
-  "#")
+  "*
+{
+    output_float_extend (insn, operands);
+    return \"\";
+}"
+  [(set_attr "type" "fld,fpop,fld,fpop")])
 
 (define_split
   [(set (match_operand:XF 0 "register_operand" "")
                    || GET_CODE (operands[1]) != MEM)"
   "*
 {
-  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-
-  if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
-    abort ();
-
-  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
+    output_float_extend (insn, operands);
     return \"\";
-
-  if (STACK_TOP_P (operands[0]))
-    return AS1 (fld%z1,%y1);
-
-  if (stack_top_dies || GET_CODE (operands[0]) == MEM)
-    output_asm_insn (AS1 (fstp%z0,%y0), operands);
-  else
-    return AS1 (fst%z0,%y0);
-
-  if (! stack_top_dies)
-    return AS1 (fld%z0,%y0);
-
-  return \"\";
 }"
   [(set_attr "type" "fld,fpop")])
 
    (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
                    || GET_CODE (operands[1]) != MEM)"
-  "#")
+  "*
+{
+    output_float_extend (insn, operands);
+    return \"\";
+}"
+  [(set_attr "type" "fld,fpop,fld,fpop")])
 
 (define_split
   [(set (match_operand:XF 0 "register_operand" "")
                    || GET_CODE (operands[1]) != MEM)"
   "*
 {
-  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-
-  if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
-    abort ();
-
-  if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
+    output_float_extend (insn, operands);
     return \"\";
-
-  if (STACK_TOP_P (operands[0]))
-    return AS1 (fld%z1,%y1);
-
-  if (stack_top_dies || GET_CODE (operands[0]) == MEM)
-    output_asm_insn (AS1 (fstp%z0,%y0), operands);
-  else
-    return AS1 (fst%z0,%y0);
-
-  if (! stack_top_dies)
-    return AS1 (fld%z0,%y0);
-
-  return \"\";
 }"
   [(set_attr "type" "fld,fpop")])