diff options
author | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-25 09:17:57 +0000 |
---|---|---|
committer | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-25 09:17:57 +0000 |
commit | fafa4a365aed93818c7bdfa5d37b076f4dea172a (patch) | |
tree | 13d6aedbbab4e67a27ac966d32bd18545d7bc2f3 /gcc | |
parent | a2776c9e7c1ff5fc01a6a47b68e169db18cafd11 (diff) | |
download | gcc-fafa4a365aed93818c7bdfa5d37b076f4dea172a.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119188 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 159 | ||||
-rw-r--r-- | gcc/reg-stack.c | 7 |
3 files changed, 81 insertions, 106 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 24ee5793d7a..753bf292d81 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 458ca0f2ba0..f9242fb44fa 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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) @@ -461,6 +462,9 @@ ;; 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]) @@ -473,6 +477,9 @@ ;; 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")]) + ;; Scheduling descriptions @@ -3908,9 +3915,7 @@ [(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")]) @@ -4006,9 +4011,7 @@ [(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")]) @@ -15525,92 +15528,17 @@ ;; 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") @@ -15621,25 +15549,44 @@ (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") @@ -15676,7 +15623,7 @@ 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; }) @@ -15700,7 +15647,7 @@ 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; }) @@ -15757,7 +15704,7 @@ 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; }) @@ -15781,7 +15728,7 @@ 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; }) diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index a96b6ef57fc..aca45fe32c2 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -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; |