diff options
Diffstat (limited to 'contrib/gcc/config/rs6000/rs6000.c')
-rw-r--r-- | contrib/gcc/config/rs6000/rs6000.c | 94 |
1 files changed, 37 insertions, 57 deletions
diff --git a/contrib/gcc/config/rs6000/rs6000.c b/contrib/gcc/config/rs6000/rs6000.c index 1ffd4da..ea35843 100644 --- a/contrib/gcc/config/rs6000/rs6000.c +++ b/contrib/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; @@ -2989,7 +2954,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) rtx r3, got, tga, tmp1, tmp2, eqv; if (TARGET_64BIT) - got = gen_rtx_REG (Pmode, TOC_REGISTER); + got = gen_rtx_REG (Pmode, 2); else { if (flag_pic == 1) @@ -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)) @@ -4369,9 +4356,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (mode == VOIDmode) { if (abi == ABI_V4 - && cum->nargs_prototype < 0 && (cum->call_cookie & CALL_LIBCALL) == 0 - && (cum->prototype || TARGET_NO_PROTOTYPE)) + && (cum->stdarg + || (cum->nargs_prototype < 0 + && (cum->prototype || TARGET_NO_PROTOTYPE)))) { /* For the SPE, we need to crxor CR6 always. */ if (TARGET_SPE_ABI) @@ -7856,7 +7844,7 @@ expand_block_move (rtx operands[]) mode = SImode; gen_func.mov = gen_movsi; } - else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT)) + else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT)) { /* move 2 bytes */ move_bytes = 2; mode = HImode; @@ -8725,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; @@ -8757,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); @@ -11620,6 +11598,8 @@ uses_TOC (void) rtx create_TOC_reference (rtx symbol) { + if (no_new_pseudos) + regs_ever_live[TOC_REGISTER] = 1; return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, TOC_REGISTER), gen_rtx_CONST (Pmode, |