aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1996-12-10 17:13:04 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1996-12-10 17:13:04 -0500
commitb8aa7986909d7752a29cfd612c1fb6d9bfb5f571 (patch)
tree2c08f58a40a204489bdccdbf16b01331ec542f1d /gcc
parentb686ee306b97517bf8805f6ba95999bf431930ec (diff)
downloadgcc-b8aa7986909d7752a29cfd612c1fb6d9bfb5f571.zip
gcc-b8aa7986909d7752a29cfd612c1fb6d9bfb5f571.tar.gz
gcc-b8aa7986909d7752a29cfd612c1fb6d9bfb5f571.tar.bz2
(add[hs]i3): Only use two addq.w or subq.w instructions when...
(add[hs]i3): Only use two addq.w or subq.w instructions when adding or subtracting constants 8 < N < 16 on TARGET_CPU32. Use lea instead of add.w when adding 16 bit constants to address registers on all but TARGET_68040. From-SVN: r13265
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/m68k/m68k.md71
1 files changed, 51 insertions, 20 deletions
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 01dde67..61e4a66 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -789,7 +789,24 @@
"*
{
if (ADDRESS_REG_P (operands[0]))
- return \"sub%.l %0,%0\";
+ {
+ /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
+ if (!TARGET_68040 && !TARGET_68060)
+ return \"sub%.l %0,%0\";
+ else
+ {
+#ifdef MOTOROLA
+#ifdef SGS
+ /* Many SGS assemblers croak on size specifiers for constants. */
+ return \"lea 0,%0\";
+#else
+ return \"lea 0.w,%0\";
+#endif
+#else
+ return \"lea 0:w,%0\";
+#endif
+ }
+ }
/* moveq is faster on the 68000. */
if (DATA_REG_P (operands[0]) && (!TARGET_68020 && !TARGET_5200))
#if defined(MOTOROLA) && !defined(CRDS)
@@ -2149,11 +2166,10 @@
? \"subq%.w %2,%0\"
: \"subq%.l %2,%0\");
}
- /* On the 68020 it is faster to use two addqw instructions to
+ /* On the CPU32 it is faster to use two addqw instructions to
add a small integer (8 < N <= 16) to an address register.
Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ if (TARGET_CPU32 && ADDRESS_REG_P (operands[0]))
{
if (INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16)
@@ -2175,7 +2191,7 @@
&& INTVAL (operands[2]) >= -0x8000
&& INTVAL (operands[2]) < 0x8000)
{
- if (!TARGET_5200)
+ if (TARGET_68040)
return \"add%.w %2,%0\";
else
#ifdef MOTOROLA
@@ -2203,9 +2219,9 @@
"!TARGET_5200"
"*
{
-#ifndef NO_ADDSUB_Q
if (GET_CODE (operands[2]) == CONST_INT)
{
+#ifndef NO_ADDSUB_Q
/* If the constant would be a negative number when interpreted as
HImode, make it negative. This is usually, but not always, done
elsewhere in the compiler. First check for constants out of range,
@@ -2225,11 +2241,10 @@
- INTVAL (operands[2]));
return \"subq%.w %2,%0\";
}
- /* On the 68020 it is faster to use two addqw instructions to
+ /* On the CPU32 it is faster to use two addqw instructions to
add a small integer (8 < N <= 16) to an address register.
Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ if (TARGET_CPU32 && ADDRESS_REG_P (operands[0]))
{
if (INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16)
@@ -2246,8 +2261,14 @@
return \"subq%.w %#8,%0\;subq%.w %2,%0\";
}
}
- }
#endif
+ if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
+#ifdef MOTOROLA
+ return \"lea (%c2,%0),%0\";
+#else
+ return \"lea %0@(%c2),%0\";
+#endif
+ }
return \"add%.w %2,%0\";
}")
@@ -2264,9 +2285,9 @@
"!TARGET_5200"
"*
{
-#ifndef NO_ADDSUB_Q
if (GET_CODE (operands[1]) == CONST_INT)
{
+#ifndef NO_ADDSUB_Q
/* If the constant would be a negative number when interpreted as
HImode, make it negative. This is usually, but not always, done
elsewhere in the compiler. First check for constants out of range,
@@ -2286,11 +2307,10 @@
- INTVAL (operands[1]));
return \"subq%.w %1,%0\";
}
- /* On the 68020 it is faster to use two addqw instructions to
+ /* On the CPU32 it is faster to use two addqw instructions to
add a small integer (8 < N <= 16) to an address register.
Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ if (TARGET_CPU32 && ADDRESS_REG_P (operands[0]))
{
if (INTVAL (operands[1]) > 8
&& INTVAL (operands[1]) <= 16)
@@ -2307,8 +2327,14 @@
return \"subq%.w %#8,%0\;subq%.w %1,%0\";
}
}
- }
#endif
+ if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
+#ifdef MOTOROLA
+ return \"lea (%c1,%0),%0\";
+#else
+ return \"lea %0@(%c1),%0\";
+#endif
+ }
return \"add%.w %1,%0\";
}")
@@ -2319,9 +2345,9 @@
"!TARGET_5200"
"*
{
-#ifndef NO_ADDSUB_Q
if (GET_CODE (operands[1]) == CONST_INT)
{
+#ifndef NO_ADDSUB_Q
/* If the constant would be a negative number when interpreted as
HImode, make it negative. This is usually, but not always, done
elsewhere in the compiler. First check for constants out of range,
@@ -2341,11 +2367,10 @@
- INTVAL (operands[1]));
return \"subq%.w %1,%0\";
}
- /* On the 68020 it is faster to use two addqw instructions to
+ /* On the CPU32 it is faster to use two addqw instructions to
add a small integer (8 < N <= 16) to an address register.
Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ if (TARGET_CPU32 && ADDRESS_REG_P (operands[0]))
{
if (INTVAL (operands[1]) > 8
&& INTVAL (operands[1]) <= 16)
@@ -2362,8 +2387,14 @@
return \"subq%.w %#8,%0\;subq%.w %1,%0\";
}
}
- }
#endif
+ if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
+#ifdef MOTOROLA
+ return \"lea (%c1,%0),%0\";
+#else
+ return \"lea %0@(%c1),%0\";
+#endif
+ }
return \"add%.w %1,%0\";
}")