summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-26 05:46:00 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-26 05:46:00 +0000
commit024261446b840a6da5526ba42b83a56818ff32ce (patch)
tree74fe5d727d7b73af92500e5d3b1c7b003a903ed7 /gcc
parent9130b63a74860cc65f40c897d866b6aef1d0f635 (diff)
downloadppe42-gcc-024261446b840a6da5526ba42b83a56818ff32ce.tar.gz
ppe42-gcc-024261446b840a6da5526ba42b83a56818ff32ce.zip
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171542 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/rs6000/predicates.md5
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c83
-rw-r--r--gcc/config/rs6000/rs6000.md21
5 files changed, 118 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 69d92785ea8..a8fd3f9642b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@
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
* config/rs6000/rs6000.c (rs6000_output_function_epilogue): Support
GNU Go in traceback table.
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 046f8bca83b..e407eda86b3 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -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);
})
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index d79af36ce04..b7b60c0485f 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -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[]);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index abd09e16d62..b1efc0dc9d3 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index dafc2d2a4f9..89836d7d632 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -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"
OpenPOWER on IntegriCloud