config/i386/i386.md (UNSPEC_TRUNC_NOOP): New unspec definition.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Nov 2006 09:17:57 +0000 (09:17 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Nov 2006 09:17:57 +0000 (09:17 +0000)
        (X87MODEF): New mode macro.
        (ssemodefsuffix): New mode attribute.
        (truncxf<mode>2_i387_noop_unspec): New insn pattern.
        (sqrt_extend<mode>xf2_i387): New insn pattern.
        (sqrt<mode>2): For non-SSE sqrt, emit sqrt_extend<mode>xf2_i387
        insn and truncate result back to original mode using
        UNSPEC_TRUNC_NOOP truncation.
        (*sqrt<mode>2_sse): Implement using SSEMODEF mode macro and
        ssemodefsuffix mode attribute.
        (*sqrtsf2_mixed, *sqrtsf2_i387, *sqrtdf2_mixed, *sqrtdf2_i387)
        (*sqrtextendsfdf2_i387, *sqrtextendsfxf2_i387)
        (*sqrtextenddfxf2_i387): Remove insn patterns.

        (fmodsf3, fmoddf3, remaindersf3, remainderdf3): Use noop
        truncation patterns.

        reg-stack.c (get_true_reg): Handle UNSPEC_TRUNC_NOOP.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119188 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 24ee579..753bf29 100644 (file)
@@ -1,3 +1,24 @@
+2006-11-24  Uros Bizjak  <ubizjak@gmail.com>
+
+       config/i386/i386.md (UNSPEC_TRUNC_NOOP): New unspec definition.
+       (X87MODEF): New mode macro.
+       (ssemodefsuffix): New mode attribute.
+       (truncxf<mode>2_i387_noop_unspec): New insn pattern.
+       (sqrt_extend<mode>xf2_i387): New insn pattern.
+       (sqrt<mode>2): For non-SSE sqrt, emit sqrt_extend<mode>xf2_i387
+       insn and truncate result back to original mode using
+       UNSPEC_TRUNC_NOOP truncation.
+       (*sqrt<mode>2_sse): Implement using SSEMODEF mode macro and
+       ssemodefsuffix mode attribute.
+       (*sqrtsf2_mixed, *sqrtsf2_i387, *sqrtdf2_mixed, *sqrtdf2_i387)
+       (*sqrtextendsfdf2_i387, *sqrtextendsfxf2_i387)
+       (*sqrtextenddfxf2_i387): Remove insn patterns.
+
+       (fmodsf3, fmoddf3, remaindersf3, remainderdf3): Use noop
+       truncation patterns.
+
+       reg-stack.c (get_true_reg): Handle UNSPEC_TRUNC_NOOP. 
+       
 2006-11-24  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/29955
index 458ca0f..f9242fb 100644 (file)
@@ -85,6 +85,7 @@
    (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;
 })
 
index a96b6ef..aca45fe 100644 (file)
@@ -439,6 +439,13 @@ get_true_reg (rtx *pat)
        pat = & XEXP (*pat, 0);
        break;
 
+      case UNSPEC:
+       if (XINT (*pat, 1) == UNSPEC_TRUNC_NOOP)
+         {
+           pat = & XVECEXP (*pat, 0, 0);
+           break;
+         }
+
       case FLOAT_TRUNCATE:
        if (!flag_unsafe_math_optimizations)
          return pat;