predicates.md (word_offset_memref_op): Handle cmodel medium addresses.
* config/rs6000/predicates.md (word_offset_memref_op): Handle cmodel medium addresses. * config/rs6000/rs6000.c (rs6000_secondary_reload): Handle misaligned 64-bit gpr loads and stores. (rs6000_secondary_reload_ppc64): New function. * config/rs6000/rs6000-protos.h: Declare it. * config/rs6000/rs6000.md (reload_di_store, reload_di_load): New. From-SVN: r171542
This commit is contained in:
parent
2fbb4d751b
commit
f082c00037
@ -1,3 +1,13 @@
|
||||
2011-03-26 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* config/rs6000/predicates.md (word_offset_memref_op): Handle
|
||||
cmodel medium addresses.
|
||||
* config/rs6000/rs6000.c (rs6000_secondary_reload): Handle misaligned
|
||||
64-bit gpr loads and stores.
|
||||
(rs6000_secondary_reload_ppc64): New function.
|
||||
* config/rs6000/rs6000-protos.h: Declare it.
|
||||
* config/rs6000/rs6000.md (reload_di_store, reload_di_load): New.
|
||||
|
||||
2011-03-26 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR target/47487
|
||||
|
@ -435,9 +435,12 @@
|
||||
op = XEXP (op, 0);
|
||||
else if (GET_CODE (op) == PRE_MODIFY)
|
||||
op = XEXP (op, 1);
|
||||
else if (GET_CODE (op) == LO_SUM
|
||||
&& GET_CODE (XEXP (op, 0)) == REG
|
||||
&& GET_CODE (XEXP (op, 1)) == CONST)
|
||||
op = XEXP (XEXP (op, 1), 0);
|
||||
|
||||
return (GET_CODE (op) != PLUS
|
||||
|| ! REG_P (XEXP (op, 0))
|
||||
|| GET_CODE (XEXP (op, 1)) != CONST_INT
|
||||
|| INTVAL (XEXP (op, 1)) % 4 == 0);
|
||||
})
|
||||
|
@ -79,6 +79,7 @@ extern bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
|
||||
enum machine_mode,
|
||||
enum reg_class);
|
||||
extern void rs6000_secondary_reload_inner (rtx, rtx, rtx, bool);
|
||||
extern void rs6000_secondary_reload_ppc64 (rtx, rtx, rtx, bool);
|
||||
extern int paired_emit_vector_cond_expr (rtx, rtx, rtx,
|
||||
rtx, rtx, rtx);
|
||||
extern void paired_expand_vector_move (rtx operands[]);
|
||||
|
@ -14816,7 +14816,10 @@ rs6000_reload_register_type (enum reg_class rclass)
|
||||
needed for the immediate register.
|
||||
|
||||
For VSX and Altivec, we may need a register to convert sp+offset into
|
||||
reg+sp. */
|
||||
reg+sp.
|
||||
|
||||
For misaligned 64-bit gpr loads and stores we need a register to
|
||||
convert an offset address to indirect. */
|
||||
|
||||
static reg_class_t
|
||||
rs6000_secondary_reload (bool in_p,
|
||||
@ -14919,6 +14922,34 @@ rs6000_secondary_reload (bool in_p,
|
||||
else
|
||||
default_p = true;
|
||||
}
|
||||
else if (TARGET_POWERPC64
|
||||
&& rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
|
||||
&& MEM_P (x)
|
||||
&& GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
|
||||
{
|
||||
rtx addr = XEXP (x, 0);
|
||||
|
||||
if (GET_CODE (addr) == PRE_MODIFY)
|
||||
addr = XEXP (addr, 1);
|
||||
else if (GET_CODE (addr) == LO_SUM
|
||||
&& GET_CODE (XEXP (addr, 0)) == REG
|
||||
&& GET_CODE (XEXP (addr, 1)) == CONST)
|
||||
addr = XEXP (XEXP (addr, 1), 0);
|
||||
|
||||
if (GET_CODE (addr) == PLUS
|
||||
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
|
||||
&& (INTVAL (XEXP (addr, 1)) & 3) != 0)
|
||||
{
|
||||
if (in_p)
|
||||
sri->icode = CODE_FOR_reload_di_load;
|
||||
else
|
||||
sri->icode = CODE_FOR_reload_di_store;
|
||||
sri->extra_cost = 2;
|
||||
ret = NO_REGS;
|
||||
}
|
||||
else
|
||||
default_p = true;
|
||||
}
|
||||
else
|
||||
default_p = true;
|
||||
|
||||
@ -15207,6 +15238,56 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert reloads involving 64-bit gprs and misaligned offset
|
||||
addressing to use indirect addressing. */
|
||||
|
||||
void
|
||||
rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
|
||||
{
|
||||
int regno = true_regnum (reg);
|
||||
enum reg_class rclass;
|
||||
rtx addr;
|
||||
rtx scratch_or_premodify = scratch;
|
||||
|
||||
if (TARGET_DEBUG_ADDR)
|
||||
{
|
||||
fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
|
||||
store_p ? "store" : "load");
|
||||
fprintf (stderr, "reg:\n");
|
||||
debug_rtx (reg);
|
||||
fprintf (stderr, "mem:\n");
|
||||
debug_rtx (mem);
|
||||
fprintf (stderr, "scratch:\n");
|
||||
debug_rtx (scratch);
|
||||
}
|
||||
|
||||
gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
|
||||
gcc_assert (GET_CODE (mem) == MEM);
|
||||
rclass = REGNO_REG_CLASS (regno);
|
||||
gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
|
||||
addr = XEXP (mem, 0);
|
||||
|
||||
if (GET_CODE (addr) == PRE_MODIFY)
|
||||
{
|
||||
scratch_or_premodify = XEXP (addr, 0);
|
||||
gcc_assert (REG_P (scratch_or_premodify));
|
||||
addr = XEXP (addr, 1);
|
||||
}
|
||||
gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
|
||||
|
||||
rs6000_emit_move (scratch_or_premodify, addr, Pmode);
|
||||
|
||||
mem = replace_equiv_address_nv (mem, scratch_or_premodify);
|
||||
|
||||
/* Now create the move. */
|
||||
if (store_p)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
|
||||
else
|
||||
emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Target hook to return the cover classes for Integrated Register Allocator.
|
||||
Cover classes is a set of non-intersected register classes covering all hard
|
||||
registers used for register allocation purpose. Any move between two
|
||||
|
@ -9645,6 +9645,27 @@
|
||||
[(set_attr "type" "two,load,store,*,*,*")
|
||||
(set_attr "length" "8,8,8,8,12,16")])
|
||||
|
||||
;; Reload patterns to support gpr load/store with misaligned mem.
|
||||
(define_expand "reload_di_store"
|
||||
[(parallel [(match_operand 0 "memory_operand" "=m")
|
||||
(match_operand 1 "gpc_reg_operand" "r")
|
||||
(match_operand:DI 2 "register_operand" "=&b")])]
|
||||
"TARGET_POWERPC64"
|
||||
{
|
||||
rs6000_secondary_reload_ppc64 (operands[1], operands[0], operands[2], true);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "reload_di_load"
|
||||
[(parallel [(match_operand 0 "gpc_reg_operand" "=r")
|
||||
(match_operand 1 "memory_operand" "m")
|
||||
(match_operand:DI 2 "register_operand" "=b")])]
|
||||
"TARGET_POWERPC64"
|
||||
{
|
||||
rs6000_secondary_reload_ppc64 (operands[0], operands[1], operands[2], false);
|
||||
DONE;
|
||||
})
|
||||
|
||||
; ld/std require word-aligned displacements -> 'Y' constraint.
|
||||
; List Y->r and r->Y before r->r for reload.
|
||||
(define_insn "*movdf_hardfloat64_mfpgpr"
|
||||
|
Loading…
Reference in New Issue
Block a user