(UNSPEC_REP 26)
(UNSPEC_EH_RETURN 27)
(UNSPEC_LD_MPIC 28) ; load_macho_picbase
+ (UNSPEC_TRUNC_NOOP 29)
; For SSE/MMX support:
(UNSPEC_FIX_NOTRUNC 30)
;; All x87 floating point modes
(define_mode_macro X87MODEF [SF DF XF])
+;; x87 SFmode and DFMode floating point modes
+(define_mode_macro X87MODEF12 [SF DF])
+
;; All integer modes handled by x87 fisttp operator.
(define_mode_macro X87MODEI [HI SI DI])
;; All integer modes handled by SSE cvtts?2si* operators.
(define_mode_macro SSEMODEI24 [SI DI])
+;; SSE asm suffix for floating point modes
+(define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
+
\f
;; Scheduling descriptions
[(set (match_operand:SF 0 "register_operand" "=f")
(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
"TARGET_80387 && flag_unsafe_math_optimizations"
-{
- return output_387_reg_move (insn, operands);
-}
+ "* return output_387_reg_move (insn, operands);"
[(set_attr "type" "fmov")
(set_attr "mode" "SF")])
[(set (match_operand:DF 0 "register_operand" "=f")
(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
"TARGET_80387 && flag_unsafe_math_optimizations"
-{
- return output_387_reg_move (insn, operands);
-}
+ "* return output_387_reg_move (insn, operands);"
[(set_attr "type" "fmov")
(set_attr "mode" "DF")])
\f
;; FPU special functions.
-(define_expand "sqrtsf2"
- [(set (match_operand:SF 0 "register_operand" "")
- (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
- "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
-{
- if (!TARGET_SSE_MATH)
- operands[1] = force_reg (SFmode, operands[1]);
-})
-
-(define_insn "*sqrtsf2_mixed"
- [(set (match_operand:SF 0 "register_operand" "=f,x")
- (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
- "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
- "@
- fsqrt
- sqrtss\t{%1, %0|%0, %1}"
- [(set_attr "type" "fpspc,sse")
- (set_attr "mode" "SF,SF")
- (set_attr "athlon_decode" "direct,*")])
-
-(define_insn "*sqrtsf2_sse"
- [(set (match_operand:SF 0 "register_operand" "=x")
- (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
- "TARGET_SSE_MATH"
- "sqrtss\t{%1, %0|%0, %1}"
- [(set_attr "type" "sse")
- (set_attr "mode" "SF")
- (set_attr "athlon_decode" "*")])
+;; This pattern implements a no-op XFmode truncation for
+;; all fancy i386 XFmode math functions.
-(define_insn "*sqrtsf2_i387"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
+(define_insn "truncxf<mode>2_i387_noop_unspec"
+ [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
+ (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
+ UNSPEC_TRUNC_NOOP))]
"TARGET_USE_FANCY_MATH_387"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "SF")
- (set_attr "athlon_decode" "direct")])
-
-(define_expand "sqrtdf2"
- [(set (match_operand:DF 0 "register_operand" "")
- (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
- "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
-{
- if (!(TARGET_SSE2 && TARGET_SSE_MATH))
- operands[1] = force_reg (DFmode, operands[1]);
-})
-
-(define_insn "*sqrtdf2_mixed"
- [(set (match_operand:DF 0 "register_operand" "=f,Y")
- (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
- "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
- "@
- fsqrt
- sqrtsd\t{%1, %0|%0, %1}"
- [(set_attr "type" "fpspc,sse")
- (set_attr "mode" "DF,DF")
- (set_attr "athlon_decode" "direct,*")])
-
-(define_insn "*sqrtdf2_sse"
- [(set (match_operand:DF 0 "register_operand" "=Y")
- (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
- "sqrtsd\t{%1, %0|%0, %1}"
- [(set_attr "type" "sse")
- (set_attr "mode" "DF")
- (set_attr "athlon_decode" "*")])
-
-(define_insn "*sqrtdf2_i387"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
- "TARGET_USE_FANCY_MATH_387"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "DF")
- (set_attr "athlon_decode" "direct")])
-
-(define_insn "*sqrtextendsfdf2_i387"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (sqrt:DF (float_extend:DF
- (match_operand:SF 1 "register_operand" "0"))))]
- "TARGET_USE_FANCY_MATH_387
- && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "DF")
- (set_attr "athlon_decode" "direct")])
+ "* return output_387_reg_move (insn, operands);"
+ [(set_attr "type" "fmov")
+ (set_attr "mode" "<MODE>")])
(define_insn "sqrtxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")])
-(define_insn "*sqrtextendsfxf2_i387"
+(define_insn "sqrt<mode>xf2_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
- (sqrt:XF (float_extend:XF
- (match_operand:SF 1 "register_operand" "0"))))]
+ (sqrt:XF
+ (float_extend:XF
+ (match_operand:X87MODEF12 1 "register_operand" "0"))))]
"TARGET_USE_FANCY_MATH_387"
"fsqrt"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")])
-(define_insn "*sqrtextenddfxf2_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (sqrt:XF (float_extend:XF
- (match_operand:DF 1 "register_operand" "0"))))]
- "TARGET_USE_FANCY_MATH_387"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")
- (set_attr "athlon_decode" "direct")])
+(define_insn "*sqrt<mode>2_sse"
+ [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
+ (sqrt:SSEMODEF
+ (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
+ "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
+ "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")
+ (set_attr "mode" "<MODE>")
+ (set_attr "athlon_decode" "*")])
+
+(define_expand "sqrt<mode>2"
+ [(set (match_operand:X87MODEF12 0 "register_operand" "")
+ (sqrt:X87MODEF12
+ (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
+ "TARGET_USE_FANCY_MATH_387
+ || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+{
+ if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
+ {
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = force_reg (<MODE>mode, operands[1]);
+
+ emit_insn (gen_sqrt<mode>xf2_i387 (op0, op1));
+ emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
+ DONE;
+ }
+})
(define_insn "fpremxf4"
[(set (match_operand:XF 0 "register_operand" "=f")
emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
ix86_emit_fp_unordered_jump (label);
- emit_insn (gen_truncxfsf2 (operands[0], op1));
+ emit_insn (gen_truncxfsf2_i387_noop_unspec (operands[0], op1));
DONE;
})
emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
ix86_emit_fp_unordered_jump (label);
- emit_insn (gen_truncxfdf2 (operands[0], op1));
+ emit_insn (gen_truncxfdf2_i387_noop_unspec (operands[0], op1));
DONE;
})
emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
ix86_emit_fp_unordered_jump (label);
- emit_insn (gen_truncxfsf2 (operands[0], op1));
+ emit_insn (gen_truncxfsf2_i387_noop_unspec (operands[0], op1));
DONE;
})
emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
ix86_emit_fp_unordered_jump (label);
- emit_insn (gen_truncxfdf2 (operands[0], op1));
+ emit_insn (gen_truncxfdf2_i387_noop_unspec (operands[0], op1));
DONE;
})