diff options
author | Uros Bizjak <uros@kss-loka.si> | 2005-04-05 07:23:14 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2005-04-05 07:23:14 +0200 |
commit | c9d3aededbe5dfaf0978b2ff0cf59284b092fbef (patch) | |
tree | b6538ba455f8b329a4f7b2840d60e0bdf7914ba5 /gcc/config | |
parent | 3ce9c82463e3066170e8d8d4177f785e83537966 (diff) | |
download | gcc-c9d3aededbe5dfaf0978b2ff0cf59284b092fbef.zip gcc-c9d3aededbe5dfaf0978b2ff0cf59284b092fbef.tar.gz gcc-c9d3aededbe5dfaf0978b2ff0cf59284b092fbef.tar.bz2 |
re PR target/20421 (387 mode switching clobbers flags)
PR target/20421
* config/i386/i386.md (frndintxf2_floor, frndintxf2_ceil)
(frndintxf2_trunc, frndintxf2_mask_pm): Add FLAGS_REG clobber.
Allocate local stack slots here. Set ix86_optimize_mode_switching.
flag here. Implement using define_insn_and_split.
(frndintxf2_floor_i387, frndintxf2_ceil_i387, frndintxf2_trunc_i387)
(frndintxf2_mask_pm_i387): New insn patterns.
(floorsf2, floordf2, floorxf2): Remove local stack slot allocations.
Do not set ix86_optimize_mode_switching flag.
(ceilsf2, ceildf2, ceilxf2): Same.
(btruncsf2, btruncdf2, btruncxf2): Same.
(nearbyintsf2, nearbyintdf2, nearbyintxf2): Same.
From-SVN: r97604
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.md | 226 |
1 files changed, 139 insertions, 87 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index f9df272..6c5962b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -16367,7 +16367,33 @@ DONE; }) -(define_insn "frndintxf2_floor" +;; Rounding mode control word calculation could clobber FLAGS_REG. +(define_insn_and_split "frndintxf2_floor" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "register_operand" "0")] + UNSPEC_FRNDINT_FLOOR)) + (clobber (reg:CC FLAGS_REG))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations + && !(reload_completed || reload_in_progress)" + "#" + "&& 1" + [(const_int 0)] +{ + ix86_optimize_mode_switching = 1; + + operands[2] = assign_386_stack_local (HImode, 1); + operands[3] = assign_386_stack_local (HImode, 2); + + emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], + operands[2], operands[3])); + DONE; +} + [(set_attr "type" "frndint") + (set_attr "i387_cw" "floor") + (set_attr "mode" "XF")]) + +(define_insn "frndintxf2_floor_i387" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_FRNDINT_FLOOR)) @@ -16380,6 +16406,16 @@ (set_attr "i387_cw" "floor") (set_attr "mode" "XF")]) +(define_expand "floorxf2" + [(use (match_operand:XF 0 "register_operand" "")) + (use (match_operand:XF 1 "register_operand" ""))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations" +{ + emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); + DONE; +}) + (define_expand "floordf2" [(use (match_operand:DF 0 "register_operand" "")) (use (match_operand:DF 1 "register_operand" ""))] @@ -16389,13 +16425,9 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extenddfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_floor (op0, op1)); emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); DONE; @@ -16410,34 +16442,41 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extendsfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_floor (op0, op1)); emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); DONE; }) -(define_expand "floorxf2" - [(use (match_operand:XF 0 "register_operand" "")) - (use (match_operand:XF 1 "register_operand" ""))] +;; Rounding mode control word calculation could clobber FLAGS_REG. +(define_insn_and_split "frndintxf2_ceil" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "register_operand" "0")] + UNSPEC_FRNDINT_CEIL)) + (clobber (reg:CC FLAGS_REG))] "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" + && flag_unsafe_math_optimizations + && !(reload_completed || reload_in_progress)" + "#" + "&& 1" + [(const_int 0)] { - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - ix86_optimize_mode_switching = 1; - emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3)); + operands[2] = assign_386_stack_local (HImode, 1); + operands[3] = assign_386_stack_local (HImode, 2); + + emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], + operands[2], operands[3])); DONE; -}) +} + [(set_attr "type" "frndint") + (set_attr "i387_cw" "ceil") + (set_attr "mode" "XF")]) -(define_insn "frndintxf2_ceil" +(define_insn "frndintxf2_ceil_i387" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_FRNDINT_CEIL)) @@ -16450,6 +16489,16 @@ (set_attr "i387_cw" "ceil") (set_attr "mode" "XF")]) +(define_expand "ceilxf2" + [(use (match_operand:XF 0 "register_operand" "")) + (use (match_operand:XF 1 "register_operand" ""))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations" +{ + emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); + DONE; +}) + (define_expand "ceildf2" [(use (match_operand:DF 0 "register_operand" "")) (use (match_operand:DF 1 "register_operand" ""))] @@ -16459,13 +16508,9 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extenddfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_ceil (op0, op1)); emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); DONE; @@ -16480,34 +16525,41 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extendsfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_ceil (op0, op1)); emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); DONE; }) -(define_expand "ceilxf2" - [(use (match_operand:XF 0 "register_operand" "")) - (use (match_operand:XF 1 "register_operand" ""))] +;; Rounding mode control word calculation could clobber FLAGS_REG. +(define_insn_and_split "frndintxf2_trunc" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "register_operand" "0")] + UNSPEC_FRNDINT_TRUNC)) + (clobber (reg:CC FLAGS_REG))] "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" + && flag_unsafe_math_optimizations + && !(reload_completed || reload_in_progress)" + "#" + "&& 1" + [(const_int 0)] { - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - ix86_optimize_mode_switching = 1; - emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3)); + operands[2] = assign_386_stack_local (HImode, 1); + operands[3] = assign_386_stack_local (HImode, 2); + + emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], + operands[2], operands[3])); DONE; -}) +} + [(set_attr "type" "frndint") + (set_attr "i387_cw" "trunc") + (set_attr "mode" "XF")]) -(define_insn "frndintxf2_trunc" +(define_insn "frndintxf2_trunc_i387" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_FRNDINT_TRUNC)) @@ -16520,6 +16572,16 @@ (set_attr "i387_cw" "trunc") (set_attr "mode" "XF")]) +(define_expand "btruncxf2" + [(use (match_operand:XF 0 "register_operand" "")) + (use (match_operand:XF 1 "register_operand" ""))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations" +{ + emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); + DONE; +}) + (define_expand "btruncdf2" [(use (match_operand:DF 0 "register_operand" "")) (use (match_operand:DF 1 "register_operand" ""))] @@ -16529,13 +16591,9 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extenddfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_trunc (op0, op1)); emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); DONE; @@ -16550,34 +16608,41 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extendsfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_trunc (op0, op1)); emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); DONE; }) -(define_expand "btruncxf2" - [(use (match_operand:XF 0 "register_operand" "")) - (use (match_operand:XF 1 "register_operand" ""))] +;; Rounding mode control word calculation could clobber FLAGS_REG. +(define_insn_and_split "frndintxf2_mask_pm" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "register_operand" "0")] + UNSPEC_FRNDINT_MASK_PM)) + (clobber (reg:CC FLAGS_REG))] "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" + && flag_unsafe_math_optimizations + && !(reload_completed || reload_in_progress)" + "#" + "&& 1" + [(const_int 0)] { - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - ix86_optimize_mode_switching = 1; - emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3)); + operands[2] = assign_386_stack_local (HImode, 1); + operands[3] = assign_386_stack_local (HImode, 2); + + emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], + operands[2], operands[3])); DONE; -}) +} + [(set_attr "type" "frndint") + (set_attr "i387_cw" "mask_pm") + (set_attr "mode" "XF")]) -(define_insn "frndintxf2_mask_pm" +(define_insn "frndintxf2_mask_pm_i387" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_FRNDINT_MASK_PM)) @@ -16590,6 +16655,17 @@ (set_attr "i387_cw" "mask_pm") (set_attr "mode" "XF")]) +(define_expand "nearbyintxf2" + [(use (match_operand:XF 0 "register_operand" "")) + (use (match_operand:XF 1 "register_operand" ""))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations" +{ + emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); + + DONE; +}) + (define_expand "nearbyintdf2" [(use (match_operand:DF 0 "register_operand" "")) (use (match_operand:DF 1 "register_operand" ""))] @@ -16599,13 +16675,9 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extenddfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_mask_pm (op0, op1)); emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); DONE; @@ -16620,34 +16692,14 @@ { rtx op0 = gen_reg_rtx (XFmode); rtx op1 = gen_reg_rtx (XFmode); - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; emit_insn (gen_extendsfxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3)); + emit_insn (gen_frndintxf2_mask_pm (op0, op1)); emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); DONE; }) -(define_expand "nearbyintxf2" - [(use (match_operand:XF 0 "register_operand" "")) - (use (match_operand:XF 1 "register_operand" ""))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" -{ - rtx op2 = assign_386_stack_local (HImode, 1); - rtx op3 = assign_386_stack_local (HImode, 2); - - ix86_optimize_mode_switching = 1; - - emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1], - op2, op3)); - DONE; -}) - ;; Block operation instructions |