OSDN Git Service

* optabs.h (enum optab_index): Add new OTI_scalb.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
index 7dae8e1..920b9dd 100644 (file)
   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   DONE;
 })
+
+(define_expand "scalbxf3"
+  [(parallel [(set (match_operand:XF 0 " register_operand" "")
+                  (unspec:XF [(match_operand:XF 1 "register_operand" "")
+                              (match_operand:XF 2 "register_operand" "")]
+                             UNSPEC_FSCALE_FRACT))
+             (set (match_dup 3)
+                  (unspec:XF [(match_dup 1) (match_dup 2)]
+                             UNSPEC_FSCALE_EXP))])]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations && !optimize_size"
+{
+  operands[3] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "scalb<mode>3"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "general_operand" ""))
+   (use (match_operand:X87MODEF12 2 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+       || TARGET_MIX_SSE_I387)
+   && flag_unsafe_math_optimizations && !optimize_size"
+{
+  rtx op0 = gen_reg_rtx (XFmode);
+  rtx op1 = gen_reg_rtx (XFmode);
+  rtx op2 = gen_reg_rtx (XFmode);
+
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
+  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
+  emit_insn (gen_scalbxf3 (op0, op1, op2));
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  DONE;
+})
 \f
 
 (define_insn "frndintxf2"