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.md63
1 files changed, 61 insertions, 2 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index de669ba865e..2fbf654a208 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -146,6 +146,7 @@
(UNSPEC_FPREM1_U 91)
(UNSPEC_C2_FLAG 95)
+ (UNSPEC_FXAM_MEM 96)
; SSP patterns
(UNSPEC_SP_SET 100)
@@ -18811,9 +18812,56 @@
(set_attr "unit" "i387")
(set_attr "mode" "<MODE>")])
+(define_insn_and_split "fxam<mode>2_i387_with_temp"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (unspec:HI
+ [(match_operand:MODEF 1 "memory_operand" "")]
+ UNSPEC_FXAM_MEM))]
+ "TARGET_USE_FANCY_MATH_387
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(set (match_dup 2)(match_dup 1))
+ (set (match_dup 0)
+ (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
+{
+ operands[2] = gen_reg_rtx (<MODE>mode);
+
+ MEM_VOLATILE_P (operands[1]) = 1;
+}
+ [(set_attr "type" "multi")
+ (set_attr "unit" "i387")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "isinfxf2"
+ [(use (match_operand:SI 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && TARGET_C99_FUNCTIONS"
+{
+ rtx mask = GEN_INT (0x45);
+ rtx val = GEN_INT (0x05);
+
+ rtx cond;
+
+ rtx scratch = gen_reg_rtx (HImode);
+ rtx res = gen_reg_rtx (QImode);
+
+ emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
+
+ emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
+ emit_insn (gen_cmpqi_ext_3 (scratch, val));
+ cond = gen_rtx_fmt_ee (EQ, QImode,
+ gen_rtx_REG (CCmode, FLAGS_REG),
+ const0_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, res, cond));
+ emit_insn (gen_zero_extendqisi2 (operands[0], res));
+ DONE;
+})
+
(define_expand "isinf<mode>2"
[(use (match_operand:SI 0 "register_operand" ""))
- (use (match_operand:X87MODEF 1 "register_operand" ""))]
+ (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
"TARGET_USE_FANCY_MATH_387
&& TARGET_C99_FUNCTIONS
&& !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
@@ -18826,7 +18874,18 @@
rtx scratch = gen_reg_rtx (HImode);
rtx res = gen_reg_rtx (QImode);
- emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
+ /* Remove excess precision by forcing value through memory. */
+ if (memory_operand (operands[1], VOIDmode))
+ emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
+ else
+ {
+ int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
+ rtx temp = assign_386_stack_local (<MODE>mode, slot);
+
+ emit_move_insn (temp, operands[1]);
+ emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
+ }
+
emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
emit_insn (gen_cmpqi_ext_3 (scratch, val));
cond = gen_rtx_fmt_ee (EQ, QImode,