diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2016-07-20 17:00:45 -0500 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2016-08-15 11:45:09 -0500 |
commit | 246277a8513f622a65f97cb59e3079fc8834a913 (patch) | |
tree | edd8b0055636b232f0b5308c21ec24568af97c9d | |
parent | 79924b0de80bf4b5eda8cd130c2930428aff5183 (diff) | |
download | ppe42-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.h | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 25 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 7 |
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" ""))] |