summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-14 14:27:38 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-14 14:27:38 +0000
commit37a8f6b4d7f9bedc3438b64eb509c168e3b8087e (patch)
treea97c00a571ca8d697b4ca76134c15ecb94562240 /gcc/config
parent8fc541287d1c021d547e69b63f0f01f598dff133 (diff)
downloadgcc-37a8f6b4d7f9bedc3438b64eb509c168e3b8087e.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26455 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c60
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/i386.md76
3 files changed, 82 insertions, 55 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 3da661affe2..8432443a06a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4179,6 +4179,66 @@ output_fix_trunc (insn, operands)
return AS1 (fldc%W2,%2);
}
+/* 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);
+ }
+ }
+}
+
/* 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
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index de4da2cb6fe..56967a69165 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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 ();
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ef062b95727..211b0ba1214 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2259,7 +2259,12 @@
(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" "")
@@ -2302,21 +2307,8 @@
|| 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")])
@@ -2344,7 +2336,12 @@
(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" "")
@@ -2387,26 +2384,8 @@
|| 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")])
@@ -2434,7 +2413,12 @@
(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" "")
@@ -2478,26 +2462,8 @@
|| 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")])