summaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r--gcc/config/i386/i386.md174
1 files changed, 172 insertions, 2 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 26132f1f5c9..e5edad4d5d2 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -129,6 +129,10 @@
(UNSPEC_XTRACT_EXP 85)
(UNSPEC_FSCALE_FRACT 86)
(UNSPEC_FSCALE_EXP 87)
+ (UNSPEC_FPREM_F 88)
+ (UNSPEC_FPREM_U 89)
+ (UNSPEC_FPREM1_F 90)
+ (UNSPEC_FPREM1_U 91)
; REP instruction
(UNSPEC_REP 75)
@@ -941,9 +945,9 @@
;; FP compares, step 2
;; Move the fpsw to ax.
-(define_insn "*x86_fnstsw_1"
+(define_insn "x86_fnstsw_1"
[(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
+ (unspec:HI [(reg:CCFP 18)] UNSPEC_FNSTSW))]
"TARGET_80387"
"fnstsw\t%0"
[(set_attr "length" "2")
@@ -14858,6 +14862,172 @@
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")])
+(define_insn "fpremxf4"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 3 "register_operand" "1")]
+ UNSPEC_FPREM_F))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2) (match_dup 3)]
+ UNSPEC_FPREM_U))
+ (set (reg:CCFP 18)
+ (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fprem"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "fmodsf3"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:SF 1 "register_operand" ""))
+ (use (match_operand:SF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn(gen_extendsfxf2 (op1, operands[1]));
+ emit_insn(gen_extendsfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfsf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "fmoddf3"
+ [(use (match_operand:DF 0 "register_operand" ""))
+ (use (match_operand:DF 1 "register_operand" ""))
+ (use (match_operand:DF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extenddfxf2 (op1, operands[1]));
+ emit_insn (gen_extenddfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfdf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "fmodxf3"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))
+ (use (match_operand:XF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ emit_label (label);
+
+ emit_insn (gen_fpremxf4 (operands[1], operands[2],
+ operands[1], operands[2]));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "fprem1xf4"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 3 "register_operand" "1")]
+ UNSPEC_FPREM1_F))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2) (match_dup 3)]
+ UNSPEC_FPREM1_U))
+ (set (reg:CCFP 18)
+ (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fprem1"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "dremsf3"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:SF 1 "register_operand" ""))
+ (use (match_operand:SF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn(gen_extendsfxf2 (op1, operands[1]));
+ emit_insn(gen_extendsfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfsf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "dremdf3"
+ [(use (match_operand:DF 0 "register_operand" ""))
+ (use (match_operand:DF 1 "register_operand" ""))
+ (use (match_operand:DF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extenddfxf2 (op1, operands[1]));
+ emit_insn (gen_extenddfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfdf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "dremxf3"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))
+ (use (match_operand:XF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ emit_label (label);
+
+ emit_insn (gen_fprem1xf4 (operands[1], operands[2],
+ operands[1], operands[2]));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
(define_insn "*sindf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]