diff options
author | Fariborz Jahanian <fjahanian@gcc.gnu.org> | 2004-01-26 17:40:06 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@gcc.gnu.org> | 2004-01-26 17:40:06 +0000 |
commit | d9b7db1265b9f8285eabd73d6d9725db75ae309d (patch) | |
tree | 730f4f1d21d90dd65351ee7cc1f7b3fb7d097369 /gcc/config | |
parent | 11b25716763ef8ca1c8b8f05f11e9e7d0c093ead (diff) | |
download | gcc-d9b7db1265b9f8285eabd73d6d9725db75ae309d.tar.gz |
Split slow unaligned load/store into smaller loads and stores.
OKed by David Edelsohn.
From-SVN: r76646
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5b079acbf27..10a791e8dee 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3426,6 +3426,46 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) adjust_address (operands[1], SImode, 4)); return; } + else if (mode == DImode && TARGET_POWERPC64 + && GET_CODE (operands[0]) == REG + && GET_CODE (operands[1]) == MEM && optimize > 0 + && SLOW_UNALIGNED_ACCESS (DImode, + MEM_ALIGN (operands[1]) > 32 + ? 32 + : MEM_ALIGN (operands[1])) + && !no_new_pseudos) + { + rtx mem; + rtx reg = gen_reg_rtx (SImode); + mem = adjust_address (operands[1], SImode, 0); + emit_insn (gen_rtx_SET (SImode, reg, mem)); + reg = simplify_gen_subreg (DImode, reg, SImode, 0); + emit_insn (gen_insvdi (operands[0], GEN_INT (32), const0_rtx, reg)); + reg = gen_reg_rtx (SImode); + mem = adjust_address (operands[1], SImode, 4); + emit_insn (gen_rtx_SET (SImode, reg, mem)); + reg = simplify_gen_subreg (DImode, reg, SImode, 0); + emit_insn (gen_insvdi (operands[0], GEN_INT (32), GEN_INT (32), reg)); + return; + } + else if (mode == DImode && TARGET_POWERPC64 + && GET_CODE (operands[1]) == REG + && GET_CODE (operands[0]) == MEM && optimize > 0 + && SLOW_UNALIGNED_ACCESS (DImode, + MEM_ALIGN (operands[0]) > 32 + ? 32 + : MEM_ALIGN (operands[0])) + && !no_new_pseudos) + { + rtx mem; + rtx reg = gen_reg_rtx (DImode); + emit_move_insn (reg, gen_rtx_LSHIFTRT (DImode, operands[1], GEN_INT (32))); + mem = adjust_address (operands[0], SImode, 0); + emit_move_insn (mem, simplify_gen_subreg (SImode, reg, DImode, 0)); + mem = adjust_address (operands[0], SImode, 4); + emit_move_insn (mem, simplify_gen_subreg (SImode, operands[1], DImode, 0)); + return; + } if (!no_new_pseudos) { |