Commit 0ce6f9fb by Richard Kenner

(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
parent 97c2a83f
/* Subroutines for insn-output.c for Motorola 68000 family. /* 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. This file is part of GNU CC.
...@@ -886,6 +886,116 @@ legitimize_pic_address (orig, mode, reg) ...@@ -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 /* Return the best assembler insn template
for moving operands[1] into operands[0] as a fullword. */ for moving operands[1] into operands[0] as a fullword. */
...@@ -898,16 +1008,8 @@ singlemove_string (operands) ...@@ -898,16 +1008,8 @@ singlemove_string (operands)
return "fpmoves %1,%0"; return "fpmoves %1,%0";
#endif #endif
if (DATA_REG_P (operands[0]) if (DATA_REG_P (operands[0])
&& GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT)
&& INTVAL (operands[1]) < 128 return output_move_const_into_data_reg (operands);
&& INTVAL (operands[1]) >= -128)
{
#if defined (MOTOROLA) && !defined (CRDS)
return "moveq%.l %1,%0";
#else
return "moveq %1,%0";
#endif
}
if (operands[1] != const0_rtx) if (operands[1] != const0_rtx)
return "move%.l %1,%0"; return "move%.l %1,%0";
if (! ADDRESS_REG_P (operands[0])) if (! ADDRESS_REG_P (operands[0]))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment