aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2005-09-30 21:36:44 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2005-09-30 21:36:44 +0000
commit78a5d7279e302f80c3b4ac2b8672b4ec01e3b36d (patch)
tree66995d70c8e0a99c5b9701103d4e14a750360085
parent3c993f84de5f901dde406e4065f3f623e92fff3a (diff)
downloadgcc-78a5d7279e302f80c3b4ac2b8672b4ec01e3b36d.zip
gcc-78a5d7279e302f80c3b4ac2b8672b4ec01e3b36d.tar.gz
gcc-78a5d7279e302f80c3b4ac2b8672b4ec01e3b36d.tar.bz2
arm.md (movqi): On thumb when optimizing...
* arm.md (movqi): On thumb when optimizing, handle loading from memory by describing this as taking a subreg of a zero-extended load into an SImode register. (movhi): Likewise. From-SVN: r104836
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arm/arm.md97
2 files changed, 62 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e6fc8a8..9baa569 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-09-30 Richard Earnshaw <richard.earnshaw@arm.com>
+
+ * arm.md (movqi): On thumb when optimizing, handle loading from
+ memory by describing this as taking a subreg of a zero-extended load
+ into an SImode register.
+ (movhi): Likewise.
+
2005-09-30 Daniel Jacobowitz <dan@codesourcery.com>
* reload1.c (merge_assigned_reloads): Do not change any
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 5d72af9..783fab0 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4729,8 +4729,13 @@
{
if (!no_new_pseudos)
{
- if (GET_CODE (operands[0]) != REG)
- operands[1] = force_reg (HImode, operands[1]);
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ rtx reg = gen_reg_rtx (SImode);
+
+ emit_insn (gen_movsi (reg, operands[1]));
+ operands[1] = gen_lowpart (HImode, reg);
+ }
/* ??? We shouldn't really get invalid addresses here, but this can
happen if we are passed a SP (never OK for HImode/QImode) or
@@ -4753,11 +4758,23 @@
operands[1]
= replace_equiv_address (operands[1],
copy_to_reg (XEXP (operands[1], 0)));
+
+ if (GET_CODE (operands[1]) == MEM && optimize > 0)
+ {
+ rtx reg = gen_reg_rtx (SImode);
+
+ emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
+ operands[1] = gen_lowpart (HImode, reg);
+ }
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (HImode, operands[1]);
}
- /* Handle loading a large integer during reload. */
else if (GET_CODE (operands[1]) == CONST_INT
&& !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
{
+ /* Handle loading a large integer during reload. */
+
/* Writing a constant to memory needs a scratch, which should
be handled with SECONDARY_RELOADs. */
gcc_assert (GET_CODE (operands[0]) == REG);
@@ -4938,37 +4955,20 @@
(match_operand:QI 1 "general_operand" ""))]
"TARGET_EITHER"
"
- if (TARGET_ARM)
- {
- /* Everything except mem = const or mem = mem can be done easily */
-
- if (!no_new_pseudos)
- {
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- rtx reg = gen_reg_rtx (SImode);
-
- emit_insn (gen_movsi (reg, operands[1]));
- operands[1] = gen_lowpart (QImode, reg);
- }
- if (GET_CODE (operands[1]) == MEM && optimize > 0)
- {
- rtx reg = gen_reg_rtx (SImode);
+ /* Everything except mem = const or mem = mem can be done easily */
- emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
- operands[1] = gen_lowpart (QImode, reg);
- }
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (QImode, operands[1]);
- }
- }
- else /* TARGET_THUMB */
+ if (!no_new_pseudos)
{
- if (!no_new_pseudos)
- {
- if (GET_CODE (operands[0]) != REG)
- operands[1] = force_reg (QImode, operands[1]);
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ rtx reg = gen_reg_rtx (SImode);
+ emit_insn (gen_movsi (reg, operands[1]));
+ operands[1] = gen_lowpart (QImode, reg);
+ }
+
+ if (TARGET_THUMB)
+ {
/* ??? We shouldn't really get invalid addresses here, but this can
happen if we are passed a SP (never OK for HImode/QImode) or
virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
@@ -4989,19 +4989,32 @@
operands[1]
= replace_equiv_address (operands[1],
copy_to_reg (XEXP (operands[1], 0)));
- }
+ }
+
+ if (GET_CODE (operands[1]) == MEM && optimize > 0)
+ {
+ rtx reg = gen_reg_rtx (SImode);
+
+ emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
+ operands[1] = gen_lowpart (QImode, reg);
+ }
+
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (QImode, operands[1]);
+ }
+ else if (TARGET_THUMB
+ && GET_CODE (operands[1]) == CONST_INT
+ && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
+ {
/* Handle loading a large integer during reload. */
- else if (GET_CODE (operands[1]) == CONST_INT
- && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
- {
- /* Writing a constant to memory needs a scratch, which should
- be handled with SECONDARY_RELOADs. */
- gcc_assert (GET_CODE (operands[0]) == REG);
- operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
- emit_insn (gen_movsi (operands[0], operands[1]));
- DONE;
- }
+ /* Writing a constant to memory needs a scratch, which should
+ be handled with SECONDARY_RELOADs. */
+ gcc_assert (GET_CODE (operands[0]) == REG);
+
+ operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
+ emit_insn (gen_movsi (operands[0], operands[1]));
+ DONE;
}
"
)