summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@gcc.gnu.org>2004-01-26 17:40:06 +0000
committerFariborz Jahanian <fjahanian@gcc.gnu.org>2004-01-26 17:40:06 +0000
commitd9b7db1265b9f8285eabd73d6d9725db75ae309d (patch)
tree730f4f1d21d90dd65351ee7cc1f7b3fb7d097369 /gcc/config
parent11b25716763ef8ca1c8b8f05f11e9e7d0c093ead (diff)
downloadgcc-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.c40
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)
{