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/i386/i386.c | |
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/i386/i386.c')
-rw-r--r-- | gcc/config/i386/i386.c | 60 |
1 files changed, 49 insertions, 11 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; |