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")])
\f
;; The 387 requires that the stack top dies after converting to DImode.