summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-25 09:17:57 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-25 09:17:57 +0000
commitfafa4a365aed93818c7bdfa5d37b076f4dea172a (patch)
tree13d6aedbbab4e67a27ac966d32bd18545d7bc2f3 /gcc
parenta2776c9e7c1ff5fc01a6a47b68e169db18cafd11 (diff)
downloadgcc-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/ChangeLog21
-rw-r--r--gcc/config/i386/i386.md159
-rw-r--r--gcc/reg-stack.c7
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;