diff options
author | Richard Henderson <rth@redhat.com> | 2005-04-05 15:53:08 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-04-05 15:53:08 -0700 |
commit | b4e82619bca237b96d0a85da90d4f67c71428f99 (patch) | |
tree | 98aa6b43aa9c1823b585cac4ca25a427d8f49bd7 /gcc/config | |
parent | aca32e16b027b8b454e1c0ae3ee2e9825fb17bb4 (diff) | |
download | gcc-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.c | 60 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 12 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 8 |
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" |