From: Alan Modra Date: Wed, 1 Mar 2006 01:04:29 +0000 (+0000) Subject: re PR target/21616 ([3.4 only] ICE: unable to find a register to spill in class ... X-Git-Tag: releases/gcc-3.4.6~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77bfa8ba2e6bbe7568d5b60fac0b988e658592be;p=thirdparty%2Fgcc.git re PR target/21616 ([3.4 only] ICE: unable to find a register to spill in class `FLOAT_REGS') PR target/21616 Revert most of 2004-03-10 changes, apply mainline 2005-01-07. * config/rs6000/rs6000.c (invalid_gpr_mem): Delete. (base_reg_operand): Delete. (legitimate_offset_address_p): Revert 2004-03-10 changes. (secondary_reload_class): Likewise. (rs6000_legitimize_reload_address): Convert non-word aligned offset address using ld/std into indirect address. * config/rs6000/rs6000.h (SECONDARY_RELOAD_CLASS): Define. (SECONDARY_INPUT_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS): Delete. (PREDICATE_CODES): Delete invalid_gpr_mem and base_reg_operand. * config/rs6000/rs6000-protos.h (secondary_reload_class): Update. * config/rs6000/rs6000.md (movdf_hardfloat64): Remove m->b alternative and split. (movdi_internal64): Likewise. (reload_outdf, reload_indf, reload_outdi, reload_indi): Delete. From-SVN: r111592 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 53e0e661c111..822d6a98dbe4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2006-03-01 Alan Modra + + PR target/21616 + Revert most of 2004-03-10 changes, apply mainline 2005-01-07. + * config/rs6000/rs6000.c (invalid_gpr_mem): Delete. + (base_reg_operand): Delete. + (legitimate_offset_address_p): Revert 2004-03-10 changes. + (secondary_reload_class): Likewise. + (rs6000_legitimize_reload_address): Convert non-word aligned + offset address using ld/std into indirect address. + * config/rs6000/rs6000.h (SECONDARY_RELOAD_CLASS): Define. + (SECONDARY_INPUT_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS): Delete. + (PREDICATE_CODES): Delete invalid_gpr_mem and base_reg_operand. + * config/rs6000/rs6000-protos.h (secondary_reload_class): Update. + * config/rs6000/rs6000.md (movdf_hardfloat64): Remove m->b + alternative and split. + (movdi_internal64): Likewise. + (reload_outdf, reload_indf, reload_outdi, reload_indi): Delete. + 2006-02-28 Gabriel Dos Reis * Backport diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 3d17162e6472..3303ecd4eb14 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -105,7 +105,7 @@ extern int registers_ok_for_quad_peep (rtx, rtx); extern int addrs_ok_for_quad_peep (rtx, rtx); extern bool gpr_or_gpr_p (rtx, rtx); extern enum reg_class secondary_reload_class (enum reg_class, - enum machine_mode, rtx, int); + enum machine_mode, rtx); extern int ccr_bit (rtx, int); extern int extract_MB (rtx); extern int extract_ME (rtx); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 7a0ca184a72a..ea35843341f6 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2497,43 +2497,6 @@ word_offset_memref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) return (off % 4) == 0; } -/* Return true if operand is a (MEM (PLUS (REG) (offset))) where offset - is not divisible by four. */ - -int -invalid_gpr_mem (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - rtx addr; - long off; - - if (GET_CODE (op) != MEM) - return 0; - - addr = XEXP (op, 0); - if (GET_CODE (addr) != PLUS - || GET_CODE (XEXP (addr, 0)) != REG - || GET_CODE (XEXP (addr, 1)) != CONST_INT) - return 0; - - off = INTVAL (XEXP (addr, 1)); - return (off & 3) != 0; -} - -/* Return true if operand is a hard register that can be used as a base - register. */ - -int -base_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - unsigned int regno; - - if (!REG_P (op)) - return 0; - - regno = REGNO (op); - return regno != 0 && regno <= 31; -} - /* Return true if either operand is a general purpose register. */ bool @@ -2658,16 +2621,18 @@ legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict) case DFmode: case DImode: - /* Both DFmode and DImode may end up in gprs. If gprs are 32-bit, - then we need to load/store at both offset and offset+4. */ - if (!TARGET_POWERPC64) + if (mode == DFmode || !TARGET_POWERPC64) extra = 4; + else if (offset & 3) + return false; break; case TFmode: case TImode: - if (!TARGET_POWERPC64) + if (mode == TFmode || !TARGET_POWERPC64) extra = 12; + else if (offset & 3) + return false; else extra = 8; break; @@ -3206,6 +3171,26 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, return x; } #endif + + /* Force ld/std non-word aligned offset into base register by wrapping + in offset 0. */ + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == REG + && REGNO (XEXP (x, 0)) < 32 + && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode) + && GET_CODE (XEXP (x, 1)) == CONST_INT + && (INTVAL (XEXP (x, 1)) & 3) != 0 + && GET_MODE_SIZE (mode) >= UNITS_PER_WORD + && TARGET_POWERPC64) + { + x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0)); + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, + opnum, (enum reload_type) type); + *win = 1; + return x; + } + if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER @@ -3240,6 +3225,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, *win = 1; return x; } + #if TARGET_MACHO if (GET_CODE (x) == SYMBOL_REF && DEFAULT_ABI == ABI_DARWIN @@ -3269,6 +3255,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, return x; } #endif + if (TARGET_TOC && constant_pool_expr_p (x) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode)) @@ -8726,14 +8713,12 @@ addrs_ok_for_quad_peep (rtx addr1, rtx addr2) /* Return the register class of a scratch register needed to copy IN into or out of a register in CLASS in MODE. If it can be done directly, - NO_REGS is returned. INP is nonzero if we are loading the reg, zero - for storing. */ + NO_REGS is returned. */ enum reg_class secondary_reload_class (enum reg_class class, enum machine_mode mode, - rtx in, - int inp) + rtx in) { int regno; @@ -8758,14 +8743,6 @@ secondary_reload_class (enum reg_class class, return BASE_REGS; } - /* A 64-bit gpr load or store using an offset that isn't a multiple of - four needs a secondary reload. */ - if (TARGET_POWERPC64 - && GET_MODE_UNIT_SIZE (mode) >= 8 - && (!inp || class != BASE_REGS) - && invalid_gpr_mem (in, mode)) - return BASE_REGS; - if (GET_CODE (in) == REG) { regno = REGNO (in); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f1ad8968755e..01a97da4bf61 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1492,11 +1492,8 @@ enum reg_class or out of a register in CLASS in MODE. If it can be done directly, NO_REGS is returned. */ -#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ - secondary_reload_class (CLASS, MODE, IN, 1) - -#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \ - secondary_reload_class (CLASS, MODE, IN, 0) +#define SECONDARY_RELOAD_CLASS(CLASS, MODE, IN) \ + secondary_reload_class (CLASS, MODE, IN) /* If we are copying between FP or AltiVec registers and anything else, we need a memory location. */ @@ -2671,8 +2668,6 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ {"lwa_operand", {SUBREG, MEM, REG}}, \ {"volatile_mem_operand", {MEM}}, \ {"offsettable_mem_operand", {MEM}}, \ - {"invalid_gpr_mem", {MEM}}, \ - {"base_reg_operand", {REG}}, \ {"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \ {"add_operand", {SUBREG, REG, CONST_INT}}, \ {"non_add_cint_operand", {CONST_INT}}, \ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index e530dd94fee4..0e242d4cfa61 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -8115,15 +8115,14 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdf_hardfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,b,!r,f,f,m,!cl,!r,!h,!r,!r,!r") - (match_operand:DF 1 "input_operand" "r,Y,m,r,f,m,f,r,h,0,G,H,F"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,!cl,!r,!h,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ std%U0%X0 %1,%0 ld%U1%X1 %0,%1 - # mr %0,%1 fmr %0,%1 lfd%U1%X1 %0,%1 @@ -8134,49 +8133,8 @@ # # #" - [(set_attr "type" "store,load,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*,*") - (set_attr "length" "4,4,8,4,4,4,4,4,4,4,8,12,16")]) - -(define_split - [(set (match_operand:DF 0 "base_reg_operand" "") - (match_operand:DF 1 "invalid_gpr_mem" ""))] - "TARGET_POWERPC64 && no_new_pseudos" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (match_dup 4))] - " -{ - operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0])); - operands[3] = XEXP (operands[1], 0); - operands[4] = replace_equiv_address (operands[1], operands[2]); -}") - -(define_expand "reload_outdf" - [(parallel [(match_operand:DF 0 "invalid_gpr_mem" "") - (match_operand:DF 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "=&b")])] - "TARGET_POWERPC64" -{ - if (!TARGET_64BIT) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[2])); - emit_move_insn (operands[2], XEXP (operands[0], 0)); - operands[0] = replace_equiv_address (operands[0], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - -(define_expand "reload_indf" - [(parallel [(match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "invalid_gpr_mem" "") - (match_operand:DI 2 "register_operand" "=&b")])] - "TARGET_POWERPC64" -{ - if (!TARGET_64BIT) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[2])); - emit_move_insn (operands[2], XEXP (operands[1], 0)); - operands[1] = replace_equiv_address (operands[1], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) + [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")]) (define_insn "*movdf_softfloat64" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h") @@ -8521,15 +8479,14 @@ }") (define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,b,r,r,r,r,r,??f,f,m,r,*h,*h") - (match_operand:DI 1 "input_operand" "r,Y,m,r,I,L,nF,R,f,m,f,*h,r,0"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,r,??f,f,m,r,*h,*h") + (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,R,f,m,f,*h,r,0"))] "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" "@ std%U0%X0 %1,%0 ld%U1%X1 %0,%1 - # mr %0,%1 li %0,%1 lis %0,%v1 @@ -8541,51 +8498,8 @@ mf%1 %0 mt%0 %1 {cror 0,0,0|nop}" - [(set_attr "type" "store,load,load,*,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*") - (set_attr "length" "4,4,8,4,4,4,20,4,4,4,4,4,4,4")]) - -(define_split - [(set (match_operand:DI 0 "base_reg_operand" "") - (match_operand:DI 1 "invalid_gpr_mem" ""))] - "TARGET_POWERPC64 && no_new_pseudos" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (match_dup 4))] - " -{ - operands[2] = operands[0]; - if (!TARGET_64BIT) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[0])); - operands[3] = XEXP (operands[1], 0); - operands[4] = replace_equiv_address (operands[1], operands[2]); -}") - -(define_expand "reload_outdi" - [(parallel [(match_operand:DI 0 "invalid_gpr_mem" "") - (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "=&b")])] - "TARGET_POWERPC64" -{ - if (!TARGET_64BIT) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[2])); - emit_move_insn (operands[2], XEXP (operands[0], 0)); - operands[0] = replace_equiv_address (operands[0], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - -(define_expand "reload_indi" - [(parallel [(match_operand:DI 0 "register_operand" "") - (match_operand:DI 1 "invalid_gpr_mem" "") - (match_operand:DI 2 "register_operand" "=&b")])] - "TARGET_POWERPC64" -{ - if (!TARGET_64BIT) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[2])); - emit_move_insn (operands[2], XEXP (operands[1], 0)); - operands[1] = replace_equiv_address (operands[1], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) + [(set_attr "type" "store,load,*,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*") + (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")]) ;; immediate value valid for a single instruction hiding in a const_double (define_insn ""