aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-04-05 15:53:08 -0700
committerRichard Henderson <rth@gcc.gnu.org>2005-04-05 15:53:08 -0700
commitb4e82619bca237b96d0a85da90d4f67c71428f99 (patch)
tree98aa6b43aa9c1823b585cac4ca25a427d8f49bd7 /gcc/config
parentaca32e16b027b8b454e1c0ae3ee2e9825fb17bb4 (diff)
downloadgcc-b4e82619bca237b96d0a85da90d4f67c71428f99.zip
gcc-b4e82619bca237b96d0a85da90d4f67c71428f99.tar.gz
gcc-b4e82619bca237b96d0a85da90d4f67c71428f99.tar.bz2
re PR target/20342 (ICE in spill_failure, at reload1.c:1872)
PR target/20342 PR target/20447 * config/i386/i386.c (print_operand): Handle vector zeros. (ix86_split_to_parts): Handle CONST_VECTOR. (ix86_hard_regno_mode_ok): Allow MMX modes in general regs. (ix86_modes_tieable_p): Use ix86_hard_regno_mode_ok to decide what modes to tie for MMX and SSE registers. * config/i386/i386.h (MMX_REG_MODE_P): Remove. * config/i386/i386.md: Extend move 0 -> xor peephole to apply to vector modes as well. * config/i386/predicates.md (const0_operand): Handle VOIDmode properly as an input mode. From-SVN: r97663
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c60
-rw-r--r--gcc/config/i386/i386.h5
-rw-r--r--gcc/config/i386/i386.md12
-rw-r--r--gcc/config/i386/predicates.md8
4 files changed, 60 insertions, 25 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5eeb548..e762fa7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -6773,6 +6773,17 @@ print_operand (FILE *file, rtx x, int code)
else
{
+ /* We have patterns that allow zero sets of memory, for instance.
+ In 64-bit mode, we should probably support all 8-byte vectors,
+ since we can in fact encode that into an immediate. */
+ if (GET_CODE (x) == CONST_VECTOR)
+ {
+ if (x == CONST0_RTX (GET_MODE (x)))
+ x = const0_rtx;
+ else
+ abort ();
+ }
+
if (code != 'P')
{
if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
@@ -10350,8 +10361,18 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
operand = copy_rtx (operand);
PUT_MODE (operand, Pmode);
parts[0] = parts[1] = parts[2] = operand;
+ return size;
}
- else if (!TARGET_64BIT)
+
+ if (GET_CODE (operand) == CONST_VECTOR)
+ {
+ enum machine_mode imode = int_mode_for_mode (mode);
+ operand = simplify_subreg (imode, operand, mode, 0);
+ gcc_assert (operand != NULL);
+ mode = imode;
+ }
+
+ if (!TARGET_64BIT)
{
if (mode == DImode)
split_di (&operand, 1, &parts[0], &parts[1]);
@@ -15111,15 +15132,30 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
return (VALID_MMX_REG_MODE (mode)
|| VALID_MMX_REG_MODE_3DNOW (mode));
}
- /* We handle both integer and floats in the general purpose registers.
- In future we should be able to handle vector modes as well. */
- if (!VALID_INT_MODE_P (mode) && !VALID_FP_MODE_P (mode))
- return 0;
- /* Take care for QImode values - they can be in non-QI regs, but then
- they do cause partial register stalls. */
- if (regno < 4 || mode != QImode || TARGET_64BIT)
+
+ if (mode == QImode)
+ {
+ /* Take care for QImode values - they can be in non-QI regs,
+ but then they do cause partial register stalls. */
+ if (regno < 4 || TARGET_64BIT)
+ return 1;
+ if (!TARGET_PARTIAL_REG_STALL)
+ return 1;
+ return reload_in_progress || reload_completed;
+ }
+ /* We handle both integer and floats in the general purpose registers. */
+ else if (VALID_INT_MODE_P (mode))
+ return 1;
+ else if (VALID_FP_MODE_P (mode))
+ return 1;
+ /* Lots of MMX code casts 8 byte vector modes to DImode. If we then go
+ on to use that value in smaller contexts, this can easily force a
+ pseudo to be allocated to GENERAL_REGS. Since this is no worse than
+ supporting DImode, allow it. */
+ else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
return 1;
- return reload_in_progress || reload_completed || !TARGET_PARTIAL_REG_STALL;
+
+ return 0;
}
/* A subroutine of ix86_modes_tieable_p. Return true if MODE is a
@@ -15172,12 +15208,14 @@ ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
/* If MODE2 is only appropriate for an SSE register, then tie with
any other mode acceptable to SSE registers. */
- if (SSE_REG_MODE_P (mode2))
+ if (GET_MODE_SIZE (mode2) >= 8
+ && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
return ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1);
/* If MODE2 is appropriate for an MMX (or SSE) register, then tie
with any other mode acceptable to MMX registers. */
- if (MMX_REG_MODE_P (mode2))
+ if (GET_MODE_SIZE (mode2) == 8
+ && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
return ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1);
return false;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 819b0b2..ffba1d7 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1109,11 +1109,6 @@ do { \
|| (MODE) == V8HImode || (MODE) == V2DFmode || (MODE) == V2DImode \
|| (MODE) == V4SFmode || (MODE) == V4SImode)
-/* Return true for modes passed in MMX registers. */
-#define MMX_REG_MODE_P(MODE) \
- ((MODE) == V8QImode || (MODE) == V4HImode || (MODE) == V2SImode \
- || (MODE) == V2SFmode)
-
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6c5962b..1795469 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -18659,18 +18659,16 @@
;; Attempt to always use XOR for zeroing registers.
(define_peephole2
[(set (match_operand 0 "register_operand" "")
- (const_int 0))]
- "(GET_MODE (operands[0]) == QImode
- || GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == SImode
- || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
+ (match_operand 1 "const0_operand" ""))]
+ "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
&& (! TARGET_USE_MOV0 || optimize_size)
&& GENERAL_REG_P (operands[0])
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int 0))
(clobber (reg:CC FLAGS_REG))])]
- "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
- operands[0]);")
+{
+ operands[0] = gen_lowpart (word_mode, operands[0]);
+})
(define_peephole2
[(set (strict_low_part (match_operand 0 "register_operand" ""))
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 66f2505..668c7c0 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -499,8 +499,12 @@
;; Match exactly zero.
(define_predicate "const0_operand"
- (and (match_code "const_int,const_double,const_vector")
- (match_test "op == CONST0_RTX (mode)")))
+ (match_code "const_int,const_double,const_vector")
+{
+ if (mode == VOIDmode)
+ mode = GET_MODE (op);
+ return op == CONST0_RTX (mode);
+})
;; Match exactly one.
(define_predicate "const1_operand"