+2018-09-25 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (frndintxf2_mask_pm): Remove.
+ (frndintxf2_mask_pm_i387): Ditto.
+ (nearbyintxf2): Rewrite expander pattern to match rintxf2.
+ Enable for !flag_trapping_math.
+ (nearbyint<mode>2): Enable x87 modes for !flag_trapping_math.
+ Enable SSE modes for TARGET_SSE4_1 and expand them with round insn.
+ Change operand 1 predicate to nonimmediate_operand.
+ (attr "i387_cw"): Remove mask_pm.
+ * config/i386/i386.h (enum ix86_stack_slot): Remove SLOT_CW_MASK_PM.
+ (enum ix86_entity): Remove I387_MASK_PM.
+ * config/i386/i386.c (ix86_i387_mode_needed): Do not
+ handle I387_MASK_PM.
+ (ix86_mode_needed): Ditto.
+ (ix86_mode_after): Ditto.
+ (ix86_mode_entry): Ditto.
+ (ix86_mode_exit): Ditto.
+ (emit_i387_cw_initialization): Do not handle I387_CW_MASK_PM.
+
2018-09-25 Jakub Jelinek <jakub@redhat.com>
* vr-values.c (vr_values::vr_values): Initialize to_remove_edges and
UNSPEC_FRNDINT_FLOOR
UNSPEC_FRNDINT_CEIL
UNSPEC_FRNDINT_TRUNC
- UNSPEC_FRNDINT_MASK_PM
UNSPEC_FIST_FLOOR
UNSPEC_FIST_CEIL
;; Defines rounding mode of an FP operation.
-(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
+(define_attr "i387_cw" "trunc,floor,ceil,uninitialized,any"
(const_string "any"))
;; Define attribute to classify add/sub insns that consumes carry flag (CF)
DONE;
})
-;; Rounding mode control word calculation could clobber FLAGS_REG.
-(define_insn_and_split "frndintxf2_mask_pm"
+(define_expand "nearbyintxf2"
[(set (match_operand:XF 0 "register_operand")
(unspec:XF [(match_operand:XF 1 "register_operand")]
- UNSPEC_FRNDINT_MASK_PM))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- ix86_optimize_mode_switching[I387_MASK_PM] = 1;
-
- operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
- operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
-
- 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_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
- UNSPEC_FRNDINT_MASK_PM))
- (use (match_operand:HI 2 "memory_operand" "m"))
- (use (match_operand:HI 3 "memory_operand" "m"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
- [(set_attr "type" "frndint")
- (set_attr "i387_cw" "mask_pm")
- (set_attr "mode" "XF")])
-
-(define_expand "nearbyintxf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")]
- UNSPEC_FRNDINT_MASK_PM))
- (clobber (reg:CC FLAGS_REG))])]
+ UNSPEC_FRNDINT))]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations")
+ && !flag_trapping_math")
(define_expand "nearbyint<mode>2"
[(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
+ (use (match_operand:MODEF 1 "nonimmediate_operand"))]
+ "(TARGET_USE_FANCY_MATH_387
+ && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+ || TARGET_MIX_SSE_I387)
+ && !flag_trapping_math)
+ || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
+{
+ if (TARGET_SSE4_1 && TARGET_SSE_MATH)
+ emit_insn (gen_sse4_1_round<mode>2
+ (operands[0], operands[1], GEN_INT (ROUND_MXCSR
+ | ROUND_NO_EXC)));
+ else
+ {
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = gen_reg_rtx (XFmode);
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_mask_pm (op0, op1));
- emit_insn (gen_truncxf<mode>2 (operands[0], op0));
+ emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
+ emit_insn (gen_nearbyintxf2 (op0, op1));
+ emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
+ }
DONE;
})