aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@superh.com>2002-02-21 21:29:28 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2002-02-21 21:29:28 +0000
commita7f52356c562251c039d47b355b14a48b54bc532 (patch)
tree0f5820c544b68c206cb3d3be69c278b944e6c4df /gcc
parent924fcc4ea50e25cb28bb97b0213c4e4bcb361291 (diff)
downloadgcc-a7f52356c562251c039d47b355b14a48b54bc532.zip
gcc-a7f52356c562251c039d47b355b14a48b54bc532.tar.gz
gcc-a7f52356c562251c039d47b355b14a48b54bc532.tar.bz2
sh.md (insv): Provide byte offsets for gen_rtx_SUBREG.
* sh.md (insv): Provide byte offsets for gen_rtx_SUBREG. If input is constant, do shifts at compile time. From-SVN: r49942
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/sh/sh.md38
2 files changed, 32 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d97d28cb..ebdb60a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Thu Feb 21 21:17:21 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (insv): Provide byte offsets for gen_rtx_SUBREG.
+ If input is constant, do shifts at compile time.
+
2002-02-21 Joseph S. Myers <jsm28@cam.ac.uk>
* doc/extend.texi: Fix some more overfull hboxes.
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 263d9bd..072a33e 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -8336,37 +8336,53 @@
"TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
"
{
- rtx addr_target, orig_address, shift_reg;
- HOST_WIDE_INT size;
+ rtx addr_target, orig_address, shift_reg, qi_val;
+ HOST_WIDE_INT bitsize, size, v;
+ rtx x = operands[3];
/* ??? expmed doesn't care for non-register predicates. */
if (! memory_operand (operands[0], VOIDmode)
|| ! immediate_operand (operands[1], VOIDmode)
|| ! immediate_operand (operands[2], VOIDmode)
- || ! general_operand (operands[3], VOIDmode))
+ || ! general_operand (x, VOIDmode))
FAIL;
/* If this isn't a 16 / 24 / 32 bit field, or if
it doesn't start on a byte boundary, then fail. */
- size = INTVAL (operands[1]);
- if (size < 16 || size > 32 || size % 8 != 0
+ bitsize = INTVAL (operands[1]);
+ if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
|| (INTVAL (operands[2]) % 8) != 0)
FAIL;
- size /= 8;
+ size = bitsize / 8;
orig_address = XEXP (operands[0], 0);
shift_reg = gen_reg_rtx (SImode);
- emit_insn (gen_movsi (shift_reg, operands[3]));
+ if (GET_CODE (x) == CONST_INT)
+ {
+ v = INTVAL (x);
+ qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
+ }
+ else
+ {
+ emit_insn (gen_movsi (shift_reg, operands[3]));
+ qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
+ }
addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
operands[0] = replace_equiv_address (operands[0], addr_target);
- emit_insn (gen_movqi (operands[0], gen_rtx_SUBREG (QImode, shift_reg, 0)));
+ emit_insn (gen_movqi (operands[0], qi_val));
while (size -= 1)
{
- emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
+ if (GET_CODE (x) == CONST_INT)
+ qi_val
+ = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
+ else
+ {
+ emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
+ qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
+ }
emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
- emit_insn (gen_movqi (operands[0],
- gen_rtx_SUBREG (QImode, shift_reg, 0)));
+ emit_insn (gen_movqi (operands[0], qi_val));
}
DONE;