From 0ce6f9fb5c19b089c871725873ae7745b1048463 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Fri, 13 Jan 1995 20:28:25 -0500 Subject: [PATCH] (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 --- gcc/config/m68k/m68k.c | 124 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 11 deletions(-) diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 7f57876eeb7..836dab30c2e 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])) -- 2.30.2