summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2016-07-20 17:00:45 -0500
committerPatrick Williams <patrick@stwcx.xyz>2016-08-15 11:45:09 -0500
commit246277a8513f622a65f97cb59e3079fc8834a913 (patch)
treeedd8b0055636b232f0b5308c21ec24568af97c9d
parent79924b0de80bf4b5eda8cd130c2930428aff5183 (diff)
downloadppe42-gcc-246277a8513f622a65f97cb59e3079fc8834a913.tar.gz
ppe42-gcc-246277a8513f622a65f97cb59e3079fc8834a913.zip
requre 8 byte alignment on offsettable memory access for 64bit load/store
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c25
-rw-r--r--gcc/config/rs6000/rs6000.md7
3 files changed, 27 insertions, 6 deletions
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 3c313b1bcaf..cb86ae89811 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -226,4 +226,5 @@ extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER];
extern bool rs6000_linux_float_exceptions_rounding_supported_p (void);
extern bool mem_contiguous(rtx, rtx);
+extern bool offset_8byte_aligned(rtx);
#endif /* rs6000-protos.h */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca5f547f093..90f4a34b59f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -20589,9 +20589,10 @@ rs6000_split_multireg_move (rtx dst, rtx src)
reg_op = src;
}
if(reg_op && mem_op &&
- (GET_MODE (dst) == DImode && GET_MODE (src) == DImode))
+ (GET_MODE (dst) == DImode &&
+ GET_MODE (src) == DImode) &&
+ offset_8byte_aligned(mem_op))
{
- // TODO check for alignment on memory
emit_insn (gen_rtx_SET (DImode, dst, src));
return;
}
@@ -33446,6 +33447,26 @@ bool mem_contiguous(rtx mem1, rtx mem2)
return result;
}
+// PPE42
+bool offset_8byte_aligned(rtx mem)
+{
+ // Test lvd and stvd cases.
+ // lvdu, stvd, lvdx, stvdx should always be aligned
+ int offset = 0;
+ int code = GET_CODE(XEXP(mem,0));
+ if(code == PLUS) //lvd stvd
+ {
+ if(GET_CODE(XEXP(XEXP(mem,0),0)) == REG)
+ {
+ if ( GET_CODE(XEXP(XEXP(mem,0),1)) == CONST_INT)
+ {
+ offset = INTVAL(XEXP(XEXP(mem,0),1));
+ }
+ }
+ }
+ return ((offset & 0x7) == 0);
+}
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 8befce96dec..a27e1c6f6cc 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10280,7 +10280,6 @@
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.
-
;; List r->r after r->Y, otherwise reload will try to reload a
;; non-offsettable address by using r->r which won't make progress.
;; Use of fprs is disparaged slightly otherwise reload prefers to reload
@@ -10292,8 +10291,8 @@
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
"@
- stvd%U0%X0 %1, %0
- lvd%U1%X1 %0, %1
+ stvd%U0%X0 %1, %0##ppe stvd
+ lvd%U1%X1 %0, %1 ##ppe lvd
# movedi_internal32 %0, %1 REPORT ME!
stfd%U0%X0 %1,%0
lfd%U1%X1 %0,%1
@@ -10339,7 +10338,7 @@
operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
}")
-;; DImode load/store splits for PPE reg-to reg
+;; DImode load/store splits
(define_split
[(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
(match_operand:DIFD 1 "input_operand" ""))]
OpenPOWER on IntegriCloud