i386.md (truncdfsf2, [...]): Rewrite using a splitter.

* i386.md (truncdfsf2, truncxfsf2,
	truncxfdf2): Rewrite using a splitter.

From-SVN: r26288
This commit is contained in:
John Wehle 1999-04-08 03:19:00 +00:00 committed by John Wehle
parent 8f401e4fe3
commit e4ad100384
2 changed files with 192 additions and 70 deletions

View file

@ -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)

View file

@ -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];
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: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 (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);
}
}
if (stack_top_dies)
return AS1 (fstp%z0,%0);
else
abort ();
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];
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]))
{
xops[0] = operands[0];
xops[1] = operands[2];
return output_move_double (xops);
}
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 (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);
}
}
if (stack_top_dies)
return AS1 (fstp%z0,%0);
else
abort ();
}")
return AS1 (fst%z0,%0);
}"
[(set_attr "type" "fpop")])
;; The 387 requires that the stack top dies after converting to DImode.