]> gcc.gnu.org Git - gcc.git/commitdiff
reg-stack.c (subst_stack_regs_pat): Handle <UNSPEC_FIST> case.
authorUros Bizjak <uros@kss-loka.si>
Tue, 29 Mar 2005 05:46:46 +0000 (07:46 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 29 Mar 2005 05:46:46 +0000 (07:46 +0200)
* reg-stack.c (subst_stack_regs_pat): Handle <UNSPEC_FIST> case.
* config/i386/i386.c (output_fix_trunc): Add new round_mode
variable.  Output "fldcw" depending on round_mode.
* config/i386/i386.md (UNSPEC_FIST): New.
(fistdi2, fistdi2_with_temp, fist<mode>2, fist<mode>2_with_temp):
New isns patterns to implement lrint and llrint built-ins as x87
intrinsic function.
(fistdi2, fist<mode>2 splitters): New splitters.
(lrint<mode>2): New expanders.

From-SVN: r97151

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/reg-stack.c

index 9d62a101b1562f60171df73bfdf9150af4de46da..5ba2bc665a92a60263235a44e857d1bfd0970002 100644 (file)
@@ -1,3 +1,15 @@
+2005-03-29  Uros Bizjak  <uros@kss-loka.si>
+
+       * reg-stack.c (subst_stack_regs_pat): Handle <UNSPEC_FIST> case.
+       * config/i386/i386.c (output_fix_trunc): Add new round_mode
+       variable.  Output "fldcw" depending on round_mode.
+       * config/i386/i386.md (UNSPEC_FIST): New.
+       (fistdi2, fistdi2_with_temp, fist<mode>2, fist<mode>2_with_temp):
+       New isns patterns to implement lrint and llrint built-ins as x87
+       intrinsic function.
+       (fistdi2, fist<mode>2 splitters): New splitters.
+       (lrint<mode>2): New expanders.
+
 2005-03-28  Ian Lance Taylor  <ian@airs.com>
 
        * config/arc/arc.c (arc_output_function_epilogue): Pass prescan as
index e2540173819112f967e2830af1c1f142ccc82711..1e9165f4412affc228f02e28d1febb7e56e28308 100644 (file)
@@ -7287,6 +7287,7 @@ output_fix_trunc (rtx insn, rtx *operands, int fisttp)
 {
   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
   int dimode_p = GET_MODE (operands[0]) == DImode;
+  int round_mode = get_attr_i387_cw (insn);
 
   /* Jump through a hoop or two for DImode, since the hardware has no
      non-popping instruction.  We used to do this a different way, but
@@ -7304,12 +7305,14 @@ output_fix_trunc (rtx insn, rtx *operands, int fisttp)
       output_asm_insn ("fisttp%z0\t%0", operands);
   else
     {
-      output_asm_insn ("fldcw\t%3", operands);
+      if (round_mode != I387_CW_ANY)
+       output_asm_insn ("fldcw\t%3", operands);
       if (stack_top_dies || dimode_p)
        output_asm_insn ("fistp%z0\t%0", operands);
       else
        output_asm_insn ("fist%z0\t%0", operands);
-      output_asm_insn ("fldcw\t%2", operands);
+      if (round_mode != I387_CW_ANY)
+       output_asm_insn ("fldcw\t%2", operands);
     }
 
   return "";
index e168d112933e713cdf23b47eb5499c8499aaaf96..9041cd0b534722bf116211e02d3c67c7e4887dfa 100644 (file)
    (UNSPEC_FYL2X               66)
    (UNSPEC_FYL2XP1             67)
    (UNSPEC_FRNDINT             68)
-   (UNSPEC_F2XM1               69)
+   (UNSPEC_FIST                        69)
+   (UNSPEC_F2XM1               70)
 
    ; x87 Double output FP
    (UNSPEC_SINCOS_COS          80)
   DONE;
 })
 
+(define_insn "fistdi2"
+  [(set (match_operand:DI 0 "memory_operand" "=m")
+       (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
+        UNSPEC_FIST))
+   (clobber (match_scratch:XF 2 "=&1f"))]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations"
+  "* return output_fix_trunc (insn, operands, 0);"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "DI")])
+
+(define_insn "fistdi2_with_temp"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
+       (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
+        UNSPEC_FIST))
+   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
+   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations"
+  "#"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "DI")])
+
+(define_split 
+  [(set (match_operand:DI 0 "register_operand" "")
+       (unspec:DI [(match_operand:XF 1 "register_operand" "")]
+        UNSPEC_FIST))
+   (clobber (match_operand:DI 2 "memory_operand" ""))
+   (clobber (match_scratch 3 ""))]
+  "reload_completed"
+  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
+             (clobber (match_dup 3))])
+   (set (match_dup 0) (match_dup 2))]
+  "")
+
+(define_split 
+  [(set (match_operand:DI 0 "memory_operand" "")
+       (unspec:DI [(match_operand:XF 1 "register_operand" "")]
+        UNSPEC_FIST))
+   (clobber (match_operand:DI 2 "memory_operand" ""))
+   (clobber (match_scratch 3 ""))]
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
+             (clobber (match_dup 3))])]
+  "")
+
+(define_insn "fist<mode>2"
+  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
+       (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
+        UNSPEC_FIST))]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations"
+  "* return output_fix_trunc (insn, operands, 0);"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "fist<mode>2_with_temp"
+  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
+       (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
+        UNSPEC_FIST))
+   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations"
+  "#"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "<MODE>")])
+
+(define_split 
+  [(set (match_operand:X87MODEI12 0 "register_operand" "")
+       (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
+        UNSPEC_FIST))
+   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
+  "reload_completed"
+  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
+                      UNSPEC_FIST))
+   (set (match_dup 0) (match_dup 2))]
+  "")
+
+(define_split 
+  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
+       (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
+        UNSPEC_FIST))
+   (clobber (match_scratch 2 ""))]
+  "reload_completed"
+  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
+                      UNSPEC_FIST))]
+  "")
+
+(define_expand "lrint<mode>2"
+  [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
+   (use (match_operand:XF 1 "register_operand" ""))]
+  "TARGET_USE_FANCY_MATH_387
+   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
+   && flag_unsafe_math_optimizations"
+{
+  if (memory_operand (operands[0], VOIDmode))
+    emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
+  else
+    {
+      operands[2] = assign_386_stack_local (<MODE>mode, 0);
+      emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
+                                           operands[2]));
+    }
+  DONE;
+})
+
 (define_insn "frndintxf2_floor"
   [(set (match_operand:XF 0 "register_operand" "=f")
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
index e92e73cbf547662fa3bf1d74671c1ca75ebac359..6f58341ba2775f327c274738382274ae21ebdd11 100644 (file)
@@ -1672,6 +1672,27 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
          case UNSPEC:
            switch (XINT (pat_src, 1))
              {
+             case UNSPEC_FIST:
+               /* These insns only operate on the top of the stack.  */
+
+               src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+               emit_swap_insn (insn, regstack, *src1);
+
+               src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+
+               if (STACK_REG_P (*dest))
+                 replace_reg (dest, FIRST_STACK_REG);
+
+               if (src1_note)
+                 {
+                   replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
+                   regstack->top--;
+                   CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
+                 }
+
+               replace_reg (src1, FIRST_STACK_REG);
+               break;
+
              case UNSPEC_SIN:
              case UNSPEC_COS:
              case UNSPEC_FRNDINT:
This page took 0.112783 seconds and 5 git commands to generate.