aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-01-13 20:28:25 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1995-01-13 20:28:25 -0500
commit0ce6f9fb5c19b089c871725873ae7745b1048463 (patch)
tree6e30e6660403807521e7740a955ddf2937166138
parent97c2a83f6cb8fbfd08366b070392fc51e307445b (diff)
downloadgcc-0ce6f9fb5c19b089c871725873ae7745b1048463.zip
gcc-0ce6f9fb5c19b089c871725873ae7745b1048463.tar.gz
gcc-0ce6f9fb5c19b089c871725873ae7745b1048463.tar.bz2
(use_movqi, const_method): New functions.
(const_int_cost, output_move_const_into_data_reg): Likewise. (singlemove_string): Call output_move_const_into_data_reg. From-SVN: r8750
-rw-r--r--gcc/config/m68k/m68k.c124
1 files changed, 113 insertions, 11 deletions
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 7f57876..836dab3 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for Motorola 68000 family.
- Copyright (C) 1987, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1993, 1994, 1995 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -886,6 +886,116 @@ legitimize_pic_address (orig, mode, reg)
}
+typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
+
+use_movq (i)
+ int i;
+{
+ return (i >= -128 && i <= 127);
+}
+
+CONST_METHOD
+const_method (constant)
+ rtx constant;
+{
+ int i;
+ unsigned u;
+
+ i = INTVAL (constant);
+ if (use_movq (i))
+ return MOVQ;
+ /* if -256 < N < 256 but N is not in range for a moveq
+ N^ff will be, so use moveq #N^ff, dreg; not.b dreg. */
+ if (use_movq (i ^ 0xff))
+ return NOTB;
+ /* Likewise, try with not.w */
+ if (use_movq (i ^ 0xffff))
+ return NOTW;
+ /* This is the only value where neg.w is usefull */
+ if (i == -65408)
+ return NEGW;
+ /* Try also with swap */
+ u = i;
+ if (use_movq ((u >> 16) | (u << 16)))
+ return SWAP;
+ /* Otherwise, use move.l */
+ return MOVL;
+}
+
+const_int_cost (constant)
+ rtx constant;
+{
+ switch (const_method (constant))
+ {
+ case MOVQ :
+ /* Constants between -128 and 127 are cheap due to moveq */
+ return 0;
+ case NOTB :
+ case NOTW :
+ case NEGW :
+ case SWAP :
+ /* Constants easily generated by moveq + not.b/not.w/neg.w/swap */
+ return 1;
+ case MOVL :
+ return 2;
+ default :
+ abort ();
+ }
+}
+
+char *
+output_move_const_into_data_reg (operands)
+ rtx *operands;
+{
+ int i;
+
+ i = INTVAL (operands[1]);
+ switch (const_method (operands[1]))
+ {
+ case MOVQ :
+#if defined (MOTOROLA) && !defined (CRDS)
+ return "moveq%.l %1,%0";
+#else
+ return "moveq %1,%0";
+#endif
+ case NOTB :
+ operands[1] = gen_rtx (CONST_INT, VOIDmode, i ^ 0xff);
+#if defined (MOTOROLA) && !defined (CRDS)
+ return "moveq%.l %1,%0\n\tnot%.b %0";
+#else
+ return "moveq %1,%0\n\tnot%.b %0";
+#endif
+ case NOTW :
+ operands[1] = gen_rtx (CONST_INT, VOIDmode, i ^ 0xffff);
+#if defined (MOTOROLA) && !defined (CRDS)
+ return "moveq%.l %1,%0\n\tnot%.w %0";
+#else
+ return "moveq %1,%0\n\tnot%.w %0";
+#endif
+ case NEGW :
+#if defined (MOTOROLA) && !defined (CRDS)
+ return "moveq%.l %#-128,%0\n\tneg%.w %0";
+#else
+ return "moveq %#-128,%0\n\tneg%.w %0";
+#endif
+ case SWAP :
+ {
+ unsigned u = i;
+
+ operands[1] = gen_rtx (CONST_INT, VOIDmode, (u << 16) | (u >> 16));
+#if defined (MOTOROLA) && !defined (CRDS)
+ return "moveq%.l %1,%0\n\tswap %0";
+#else
+ return "moveq %1,%0\n\tswap %0";
+#endif
+ }
+ case MOVL :
+ return "move%.l %1,%0";
+ default :
+ abort ();
+ }
+}
+
/* Return the best assembler insn template
for moving operands[1] into operands[0] as a fullword. */
@@ -898,16 +1008,8 @@ singlemove_string (operands)
return "fpmoves %1,%0";
#endif
if (DATA_REG_P (operands[0])
- && GET_CODE (operands[1]) == CONST_INT
- && INTVAL (operands[1]) < 128
- && INTVAL (operands[1]) >= -128)
- {
-#if defined (MOTOROLA) && !defined (CRDS)
- return "moveq%.l %1,%0";
-#else
- return "moveq %1,%0";
-#endif
- }
+ && GET_CODE (operands[1]) == CONST_INT)
+ return output_move_const_into_data_reg (operands);
if (operands[1] != const0_rtx)
return "move%.l %1,%0";
if (! ADDRESS_REG_P (operands[0]))