diff options
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r-- | gcc/config/i386/i386.md | 174 |
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))] |