aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wehle <john@feith.com>1999-04-08 03:19:00 +0000
committerJohn Wehle <wehle@gcc.gnu.org>1999-04-08 03:19:00 +0000
commite4ad100384a5caeec738636d22d5f3988e418347 (patch)
treed91161ac54d6f73734e0312f02e3e1f97514cbf3
parent8f401e4fe30d9c699d810092075e469663eedd62 (diff)
downloadgcc-e4ad100384a5caeec738636d22d5f3988e418347.zip
gcc-e4ad100384a5caeec738636d22d5f3988e418347.tar.gz
gcc-e4ad100384a5caeec738636d22d5f3988e418347.tar.bz2
i386.md (truncdfsf2, [...]): Rewrite using a splitter.
* i386.md (truncdfsf2, truncxfsf2, truncxfdf2): Rewrite using a splitter. From-SVN: r26288
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.md253
2 files changed, 190 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 89b4263..8bcadbe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Thu Apr 8 06:16:14 EDT 1999 John Wehle (john@feith.com)
+
+ * i386.md (truncdfsf2, truncxfsf2,
+ truncxfdf2): Rewrite using a splitter.
+
Thu Apr 8 01:26:05 1999 Arg Haas (ahaas@neosoft.com)
Jeffrey A Law (law@cygnus.com)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index df87d5c..3ec8875 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2287,103 +2287,220 @@
operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
}")
+(define_insn ""
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
+ (float_truncate:SF
+ (match_operand:DF 1 "register_operand" "0,f,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
+ "TARGET_80387"
+ "*
+{
+ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ rtx xops[1];
+
+ xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
+
+ if (stack_top_dies || STACK_REG_P (operands[0]))
+ output_asm_insn (AS1 (fstp%z0,%0), xops);
+ else
+ output_asm_insn (AS1 (fst%z0,%0), xops);
+
+ if (STACK_REG_P (operands[0]))
+ return AS1 (fld%z2,%2);
+ else if (NON_STACK_REG_P (operands[0]))
+ return AS2 (mov%L0,%2,%0);
+
+ return \"\";
+}"
+ [(set_attr "type" "fpop")])
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (float_truncate:SF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 2))]
+ "")
+
+(define_split
+ [(set (match_operand:SF 0 "memory_operand" "")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_truncate:SF (match_dup 1)))]
+ "")
+
;; This cannot output into an f-reg because there is no way to be sure
-;; of truncating in that case. Otherwise this is just like a simple move
-;; insn. So we pretend we can output to a reg in order to get better
-;; register preferencing, but we really use a stack slot.
+;; of truncating in that case.
(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
- (float_truncate:SF
- (match_operand:DF 1 "register_operand" "0,f")))
- (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
+ [(set (match_operand:SF 0 "memory_operand" "=m")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
"TARGET_80387"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
- if (GET_CODE (operands[0]) == MEM)
- {
- if (stack_top_dies)
- return AS1 (fstp%z0,%0);
- else
- return AS1 (fst%z0,%0);
- }
- else if (STACK_TOP_P (operands[0]))
- {
- output_asm_insn (AS1 (fstp%z2,%y2), operands);
- return AS1 (fld%z2,%y2);
- }
+ if (stack_top_dies)
+ return AS1 (fstp%z0,%0);
else
- abort ();
+ return AS1 (fst%z0,%0);
+}"
+ [(set_attr "type" "fpop")])
+
+(define_expand "truncxfsf2"
+ [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (float_truncate:SF
+ (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "
+{
+ operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
}")
-(define_insn "truncxfsf2"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
+(define_insn ""
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
(float_truncate:SF
- (match_operand:XF 1 "register_operand" "f,f")))]
+ (match_operand:XF 1 "register_operand" "0,f,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
"TARGET_80387"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ rtx xops[1];
- if (NON_STACK_REG_P (operands[0]))
- {
- if (stack_top_dies == 0)
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- stack_top_dies = 1;
- }
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
- else if (GET_CODE (operands[0]) == MEM)
- {
- if (stack_top_dies)
- return AS1 (fstp%z0,%0);
- else
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- return AS1 (fstp%z0,%0);
- }
- }
+ xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
+
+ if (stack_top_dies || STACK_REG_P (operands[0]))
+ output_asm_insn (AS1 (fstp%z0,%0), xops);
else
- abort ();
+ output_asm_insn (AS1 (fst%z0,%0), xops);
+
+ if (STACK_REG_P (operands[0]))
+ return AS1 (fld%z2,%2);
+ else if (NON_STACK_REG_P (operands[0]))
+ return AS2 (mov%L0,%2,%0);
+
+ return \"\";
+}"
+ [(set_attr "type" "fpop")])
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (float_truncate:SF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 2))]
+ "")
+
+(define_split
+ [(set (match_operand:SF 0 "memory_operand" "")
+ (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_truncate:SF (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "memory_operand" "=m")
+ (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
+ "TARGET_80387"
+ "*
+{
+ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+
+ if (stack_top_dies)
+ return AS1 (fstp%z0,%0);
+ else
+ return AS1 (fst%z0,%0);
+}"
+ [(set_attr "type" "fpop")])
+
+(define_expand "truncxfdf2"
+ [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (float_truncate:DF
+ (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "
+{
+ operands[2] = (rtx) assign_386_stack_local (DFmode, 0);
}")
-(define_insn "truncxfdf2"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
+(define_insn ""
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r")
(float_truncate:DF
- (match_operand:XF 1 "register_operand" "f,f")))]
+ (match_operand:XF 1 "register_operand" "0,f,f")))
+ (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))]
"TARGET_80387"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ rtx xops[2];
- if (NON_STACK_REG_P (operands[0]))
- {
- if (stack_top_dies == 0)
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- stack_top_dies = 1;
- }
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
- else if (GET_CODE (operands[0]) == MEM)
+ xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
+
+ if (stack_top_dies || STACK_REG_P (operands[0]))
+ output_asm_insn (AS1 (fstp%z0,%0), xops);
+ else
+ output_asm_insn (AS1 (fst%z0,%0), xops);
+
+ if (STACK_REG_P (operands[0]))
+ return AS1 (fld%z2,%2);
+ else if (NON_STACK_REG_P (operands[0]))
{
- if (stack_top_dies)
- return AS1 (fstp%z0,%0);
- else
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- return AS1 (fstp%z0,%0);
- }
+ xops[0] = operands[0];
+ xops[1] = operands[2];
+ return output_move_double (xops);
}
- else
- abort ();
-}")
+ return \"\";
+}"
+ [(set_attr "type" "fpop")])
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 2))]
+ "")
+
+(define_split
+ [(set (match_operand:DF 0 "memory_operand" "")
+ (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_truncate:DF (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "memory_operand" "=m")
+ (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
+ "TARGET_80387"
+ "*
+{
+ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+
+ if (stack_top_dies)
+ return AS1 (fstp%z0,%0);
+ else
+ return AS1 (fst%z0,%0);
+}"
+ [(set_attr "type" "fpop")])
;; The 387 requires that the stack top dies after converting to DImode.