predicates.md (mcore_general_movesrc_operand): Accept CONSTs.

* config/mcore/predicates.md (mcore_general_movesrc_operand): Accept CONSTs.
  (mcore_general_movdst_operand): Do not accept CONST_INTs.
  (mcore_arith_K_S_operand): Run the test for the S constraint not the test for the M constraint.
  (mcore_addsub_operand): Do not accept integer values that are larger than 32 bits.
* config/mcore/mcore.md: Remove unused constraints from split.
  (andsi3): Use HOST_WIDE_INT instead of int to hold an INTVAL.
  (addsi3): Likewise.
  (allocate_stack): Likewise.
* config/mcore/mcore.c (mcore_print_operand): Restrict output of P operands to 32 bits.
  (mcore_const_costs): Use HOST_WIDE_INT instead of int to hold an INTVAL.
  (mcore_and_cost, mcore_modify_comparison, const_ok_for_mcore,
   mcore_const_ok_for_inline, mcore_const_trick_uses_not,
   try_constant_tricks, mcore_num_ones, mcore_num_zeros,
   mcore_output_bclri, mcore_output_andn, output_inline_const,
   mcore_output_move, mcore_output_movedouble): Likewise.
  (mcore_output_cmov): Use CONST_OK_FOR_M and CONST_OK_FOR_N.
  (output_inline_const): Likewise.
  (output_inline_const): Fix format strings used in sprintf statements.
* config/mcore/mcore-protos.h: Update prototypes for changed functions in mcore.c.
* config/mcore/mcore.h (CONST_OK_FOR_I): Cast values to HOST_WIDE_INT and not int.
  (CONST_OK_FOR_J, CONST_OK_FOR_K, CONST_OK_FOR_L, CONST_OK_FOR_M,
   CONST_OK_FOR_N): Likewise.
  (LEGITIMATE_CONSTANT_P): Also check CONSTANT_P.
  (GO_IF_LEGITIMATE_INDEX): Use HOST_WIDE_INT instead of int to hold an INTVAL.

From-SVN: r120669
This commit is contained in:
Nick Clifton 2007-01-11 10:10:54 +00:00 committed by Nick Clifton
parent 4d499824ed
commit 6e3a343d88
6 changed files with 244 additions and 196 deletions

View File

@ -1,3 +1,39 @@
2007-01-11 Nick Clifton <nickc@redhat.com>
* config/mcore/predicates.md (mcore_general_movesrc_operand):
Accept CONSTs.
(mcore_general_movdst_operand): Do not accept CONST_INTs.
(mcore_arith_K_S_operand): Run the test for the S constraint not
the test for the M constraint.
(mcore_addsub_operand): Do not accept integer values that are
larger than 32 bits.
* config/mcore/mcore.md: Remove unused constraints from split.
(andsi3): Use HOST_WIDE_INT instead of int to hold an INTVAL.
(addsi3): Likewise.
(allocate_stack): Likewise.
* config/mcore/mcore.c (mcore_print_operand): Restrict output of P
operands to 32 bits.
(mcore_const_costs): Use HOST_WIDE_INT instead of int to hold an
INTVAL.
(mcore_and_cost, mcore_modify_comparison, const_ok_for_mcore,
mcore_const_ok_for_inline, mcore_const_trick_uses_not,
try_constant_tricks, mcore_num_ones, mcore_num_zeros,
mcore_output_bclri, mcore_output_andn, output_inline_const,
mcore_output_move, mcore_output_movedouble): Likewise.
(mcore_output_cmov): Use CONST_OK_FOR_M and CONST_OK_FOR_N.
(output_inline_const): Likewise.
(output_inline_const): Fix format strings used in sprintf
statements.
* config/mcore/mcore-protos.h: Update prototypes for changed
functions in mcore.c.
* config/mcore/mcore.h (CONST_OK_FOR_I): Cast values to
HOST_WIDE_INT and not int.
(CONST_OK_FOR_J, CONST_OK_FOR_K, CONST_OK_FOR_L, CONST_OK_FOR_M,
CONST_OK_FOR_N): Likewise.
(LEGITIMATE_CONSTANT_P): Also check CONSTANT_P.
(GO_IF_LEGITIMATE_INDEX): Use HOST_WIDE_INT instead of int to hold
an INTVAL.
2007-01-10 Jan Hubicka <jh@suse.cz>
* tree-vrp.c (remove_range_assertions): Release defs.

View File

@ -1,5 +1,5 @@
/* Prototypes for exported functions defined in mcore.c
Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Contributed by Nick Clifton (nickc@redhat.com)
This file is part of GCC.
@ -22,13 +22,13 @@
extern const char * mcore_output_jump_label_table (void);
extern void mcore_expand_prolog (void);
extern void mcore_expand_epilog (void);
extern int mcore_const_ok_for_inline (long);
extern int mcore_num_ones (int);
extern int mcore_num_zeros (int);
extern int mcore_const_ok_for_inline (HOST_WIDE_INT);
extern int mcore_num_ones (HOST_WIDE_INT);
extern int mcore_num_zeros (HOST_WIDE_INT);
extern int mcore_initial_elimination_offset (int, int);
extern int mcore_byte_offset (unsigned int);
extern int mcore_halfword_offset (unsigned int);
extern int mcore_const_trick_uses_not (long);
extern int mcore_const_trick_uses_not (HOST_WIDE_INT);
extern void mcore_override_options (void);
extern int mcore_dllexport_name_p (const char *);
extern int mcore_dllimport_name_p (const char *);
@ -71,7 +71,7 @@ extern int mcore_arith_S_operand (rtx);
#ifdef HAVE_MACHINE_MODES
extern const char * mcore_output_move (rtx, rtx *, enum machine_mode);
extern const char * mcore_output_movedouble (rtx *, enum machine_mode);
extern int const_ok_for_mcore (int);
extern int const_ok_for_mcore (HOST_WIDE_INT);
#ifdef TREE_CODE
extern rtx mcore_function_arg (CUMULATIVE_ARGS, enum machine_mode, tree, int);
#endif /* TREE_CODE */

View File

@ -1,5 +1,5 @@
/* Output routines for Motorola MCore processor
Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
This file is part of GCC.
@ -118,7 +118,7 @@ cond_type;
static void output_stack_adjust (int, int);
static int calc_live_regs (int *);
static int try_constant_tricks (long, int *, int *);
static int try_constant_tricks (long, HOST_WIDE_INT *, HOST_WIDE_INT *);
static const char * output_inline_const (enum machine_mode, rtx *);
static void layout_mcore_frame (struct mcore_frame *);
static void mcore_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
@ -345,7 +345,7 @@ mcore_print_operand (FILE * stream, rtx x, int code)
fprintf (asm_out_file, "%d", exact_log2 (INTVAL (x) + 1));
break;
case 'P':
fprintf (asm_out_file, "%d", exact_log2 (INTVAL (x)));
fprintf (asm_out_file, "%d", exact_log2 (INTVAL (x) & 0xffffffff));
break;
case 'Q':
fprintf (asm_out_file, "%d", exact_log2 (~INTVAL (x)));
@ -404,7 +404,7 @@ mcore_print_operand (FILE * stream, rtx x, int code)
static int
mcore_const_costs (rtx exp, enum rtx_code code)
{
int val = INTVAL (exp);
HOST_WIDE_INT val = INTVAL (exp);
/* Easy constants. */
if ( CONST_OK_FOR_I (val)
@ -432,7 +432,7 @@ mcore_const_costs (rtx exp, enum rtx_code code)
static int
mcore_and_cost (rtx x)
{
int val;
HOST_WIDE_INT val;
if (GET_CODE (XEXP (x, 1)) != CONST_INT)
return 2;
@ -458,7 +458,7 @@ mcore_and_cost (rtx x)
static int
mcore_ior_cost (rtx x)
{
int val;
HOST_WIDE_INT val;
if (GET_CODE (XEXP (x, 1)) != CONST_INT)
return 2;
@ -529,7 +529,7 @@ mcore_modify_comparison (enum rtx_code code)
if (GET_CODE (op1) == CONST_INT)
{
int val = INTVAL (op1);
HOST_WIDE_INT val = INTVAL (op1);
switch (code)
{
@ -686,17 +686,17 @@ mcore_output_call (rtx operands[], int index)
/* Can we load a constant with a single instruction ? */
int
const_ok_for_mcore (int value)
const_ok_for_mcore (HOST_WIDE_INT value)
{
if (value >= 0 && value <= 127)
return 1;
/* Try exact power of two. */
if ((value & (value - 1)) == 0)
if (CONST_OK_FOR_M (value))
return 1;
/* Try exact power of two - 1. */
if ((value & (value + 1)) == 0)
if (CONST_OK_FOR_N (value) && value != -1)
return 1;
return 0;
@ -705,9 +705,9 @@ const_ok_for_mcore (int value)
/* Can we load a constant inline with up to 2 instructions ? */
int
mcore_const_ok_for_inline (long value)
mcore_const_ok_for_inline (HOST_WIDE_INT value)
{
int x, y;
HOST_WIDE_INT x, y;
return try_constant_tricks (value, & x, & y) > 0;
}
@ -715,9 +715,9 @@ mcore_const_ok_for_inline (long value)
/* Are we loading the constant using a not ? */
int
mcore_const_trick_uses_not (long value)
mcore_const_trick_uses_not (HOST_WIDE_INT value)
{
int x, y;
HOST_WIDE_INT x, y;
return try_constant_tricks (value, & x, & y) == 2;
}
@ -739,120 +739,119 @@ mcore_const_trick_uses_not (long value)
11: single insn followed by ixw. */
static int
try_constant_tricks (long value, int * x, int * y)
try_constant_tricks (HOST_WIDE_INT value, HOST_WIDE_INT * x, HOST_WIDE_INT * y)
{
int i;
unsigned bit, shf, rot;
HOST_WIDE_INT i;
unsigned HOST_WIDE_INT bit, shf, rot;
if (const_ok_for_mcore (value))
return 1; /* Do the usual thing. */
if (TARGET_HARDLIT)
if (! TARGET_HARDLIT)
return 0;
if (const_ok_for_mcore (~value))
{
if (const_ok_for_mcore (~value))
*x = ~value;
return 2;
}
for (i = 1; i <= 32; i++)
{
if (const_ok_for_mcore (value - i))
{
*x = ~value;
return 2;
*x = value - i;
*y = i;
return 3;
}
for (i = 1; i <= 32; i++)
if (const_ok_for_mcore (value + i))
{
if (const_ok_for_mcore (value - i))
{
*x = value - i;
*y = i;
return 3;
}
if (const_ok_for_mcore (value + i))
{
*x = value + i;
*y = i;
return 4;
}
*x = value + i;
*y = i;
return 4;
}
bit = 0x80000000L;
for (i = 0; i <= 31; i++)
}
bit = 0x80000000ULL;
for (i = 0; i <= 31; i++)
{
if (const_ok_for_mcore (i - value))
{
if (const_ok_for_mcore (i - value))
{
*x = i - value;
*y = i;
return 5;
}
if (const_ok_for_mcore (value & ~bit))
{
*y = bit;
*x = value & ~bit;
return 6;
}
if (const_ok_for_mcore (value | bit))
{
*y = ~bit;
*x = value | bit;
return 7;
}
bit >>= 1;
*x = i - value;
*y = i;
return 5;
}
shf = value;
rot = value;
for (i = 1; i < 31; i++)
if (const_ok_for_mcore (value & ~bit))
{
int c;
/* MCore has rotate left. */
c = rot << 31;
rot >>= 1;
rot &= 0x7FFFFFFF;
rot |= c; /* Simulate rotate. */
if (const_ok_for_mcore (rot))
{
*y = i;
*x = rot;
return 8;
}
if (shf & 1)
shf = 0; /* Can't use logical shift, low order bit is one. */
shf >>= 1;
if (shf != 0 && const_ok_for_mcore (shf))
{
*y = i;
*x = shf;
return 9;
}
*y = bit;
*x = value & ~bit;
return 6;
}
if ((value % 3) == 0 && const_ok_for_mcore (value / 3))
if (const_ok_for_mcore (value | bit))
{
*x = value / 3;
return 10;
*y = ~bit;
*x = value | bit;
return 7;
}
if ((value % 5) == 0 && const_ok_for_mcore (value / 5))
bit >>= 1;
}
shf = value;
rot = value;
for (i = 1; i < 31; i++)
{
int c;
/* MCore has rotate left. */
c = rot << 31;
rot >>= 1;
rot &= 0x7FFFFFFF;
rot |= c; /* Simulate rotate. */
if (const_ok_for_mcore (rot))
{
*x = value / 5;
return 11;
*y = i;
*x = rot;
return 8;
}
if (shf & 1)
shf = 0; /* Can't use logical shift, low order bit is one. */
shf >>= 1;
if (shf != 0 && const_ok_for_mcore (shf))
{
*y = i;
*x = shf;
return 9;
}
}
if ((value % 3) == 0 && const_ok_for_mcore (value / 3))
{
*x = value / 3;
return 10;
}
if ((value % 5) == 0 && const_ok_for_mcore (value / 5))
{
*x = value / 5;
return 11;
}
return 0;
@ -910,7 +909,7 @@ mcore_is_dead (rtx first, rtx reg)
/* Count the number of ones in mask. */
int
mcore_num_ones (int mask)
mcore_num_ones (HOST_WIDE_INT mask)
{
/* A trick to count set bits recently posted on comp.compilers. */
mask = (mask >> 1 & 0x55555555) + (mask & 0x55555555);
@ -924,7 +923,7 @@ mcore_num_ones (int mask)
/* Count the number of zeros in mask. */
int
mcore_num_zeros (int mask)
mcore_num_zeros (HOST_WIDE_INT mask)
{
return 32 - mcore_num_ones (mask);
}
@ -1015,8 +1014,8 @@ mcore_output_bclri (rtx dst, int mask)
const char *
mcore_output_cmov (rtx operands[], int cmp_t, const char * test)
{
int load_value;
int adjust_value;
HOST_WIDE_INT load_value;
HOST_WIDE_INT adjust_value;
rtx out_operands[4];
out_operands[0] = operands[0];
@ -1049,9 +1048,9 @@ mcore_output_cmov (rtx operands[], int cmp_t, const char * test)
instruction sequence has a different length attribute). */
if (load_value >= 0 && load_value <= 127)
output_asm_insn ("movi\t%0,%1", out_operands);
else if ((load_value & (load_value - 1)) == 0)
else if (CONST_OK_FOR_M (load_value))
output_asm_insn ("bgeni\t%0,%P1", out_operands);
else if ((load_value & (load_value + 1)) == 0)
else if (CONST_OK_FOR_N (load_value))
output_asm_insn ("bmaski\t%0,%N1", out_operands);
/* Output the constant adjustment. */
@ -1079,7 +1078,7 @@ mcore_output_cmov (rtx operands[], int cmp_t, const char * test)
const char *
mcore_output_andn (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
{
int x, y;
HOST_WIDE_INT x, y;
rtx out_operands[3];
const char * load_op;
char buf[256];
@ -1089,22 +1088,25 @@ mcore_output_andn (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
gcc_assert (trick_no == 2);
out_operands[0] = operands[0];
out_operands[1] = GEN_INT(x);
out_operands[1] = GEN_INT (x);
out_operands[2] = operands[2];
if (x >= 0 && x <= 127)
load_op = "movi\t%0,%1";
/* Try exact power of two. */
else if ((x & (x - 1)) == 0)
else if (CONST_OK_FOR_M (x))
load_op = "bgeni\t%0,%P1";
/* Try exact power of two - 1. */
else if ((x & (x + 1)) == 0)
else if (CONST_OK_FOR_N (x))
load_op = "bmaski\t%0,%N1";
else
load_op = "BADMOVI\t%0,%1";
else
{
load_op = "BADMOVI-andn\t%0, %1";
gcc_unreachable ();
}
sprintf (buf, "%s\n\tandn\t%%2,%%0", load_op);
output_asm_insn (buf, out_operands);
@ -1117,13 +1119,13 @@ mcore_output_andn (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
static const char *
output_inline_const (enum machine_mode mode, rtx operands[])
{
int x = 0, y = 0;
HOST_WIDE_INT x = 0, y = 0;
int trick_no;
rtx out_operands[3];
char buf[256];
char load_op[256];
const char *dst_fmt;
int value;
HOST_WIDE_INT value;
value = INTVAL (operands[1]);
@ -1153,15 +1155,18 @@ output_inline_const (enum machine_mode mode, rtx operands[])
sprintf (load_op, "movi\t%s,%%1", dst_fmt);
/* Try exact power of two. */
else if ((x & (x - 1)) == 0)
else if (CONST_OK_FOR_M (x))
sprintf (load_op, "bgeni\t%s,%%P1", dst_fmt);
/* Try exact power of two - 1. */
else if ((x & (x + 1)) == 0)
else if (CONST_OK_FOR_N (x))
sprintf (load_op, "bmaski\t%s,%%N1", dst_fmt);
else
sprintf (load_op, "BADMOVI\t%s,%%1", dst_fmt);
else
{
sprintf (load_op, "BADMOVI-inline_const %s, %%1", dst_fmt);
gcc_unreachable ();
}
switch (trick_no)
{
@ -1169,35 +1174,35 @@ output_inline_const (enum machine_mode mode, rtx operands[])
strcpy (buf, load_op);
break;
case 2: /* not */
sprintf (buf, "%s\n\tnot\t%s\t// %d 0x%x", load_op, dst_fmt, value, value);
sprintf (buf, "%s\n\tnot\t%s\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 3: /* add */
sprintf (buf, "%s\n\taddi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
sprintf (buf, "%s\n\taddi\t%s,%%2\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 4: /* sub */
sprintf (buf, "%s\n\tsubi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
sprintf (buf, "%s\n\tsubi\t%s,%%2\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 5: /* rsub */
/* Never happens unless -mrsubi, see try_constant_tricks(). */
sprintf (buf, "%s\n\trsubi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
sprintf (buf, "%s\n\trsubi\t%s,%%2\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 6: /* bset */
sprintf (buf, "%s\n\tbseti\t%s,%%P2\t// %d 0x%x", load_op, dst_fmt, value, value);
case 6: /* bseti */
sprintf (buf, "%s\n\tbseti\t%s,%%P2\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 7: /* bclr */
sprintf (buf, "%s\n\tbclri\t%s,%%Q2\t// %d 0x%x", load_op, dst_fmt, value, value);
sprintf (buf, "%s\n\tbclri\t%s,%%Q2\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 8: /* rotl */
sprintf (buf, "%s\n\trotli\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
sprintf (buf, "%s\n\trotli\t%s,%%2\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 9: /* lsl */
sprintf (buf, "%s\n\tlsli\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);
sprintf (buf, "%s\n\tlsli\t%s,%%2\t// %ld 0x%lx", load_op, dst_fmt, value, value);
break;
case 10: /* ixh */
sprintf (buf, "%s\n\tixh\t%s,%s\t// %d 0x%x", load_op, dst_fmt, dst_fmt, value, value);
sprintf (buf, "%s\n\tixh\t%s,%s\t// %ld 0x%lx", load_op, dst_fmt, dst_fmt, value, value);
break;
case 11: /* ixw */
sprintf (buf, "%s\n\tixw\t%s,%s\t// %d 0x%x", load_op, dst_fmt, dst_fmt, value, value);
sprintf (buf, "%s\n\tixw\t%s,%s\t// %ld 0x%lx", load_op, dst_fmt, dst_fmt, value, value);
break;
default:
return "";
@ -1245,7 +1250,7 @@ mcore_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
}
else if (GET_CODE (src) == CONST_INT)
{
int x, y;
HOST_WIDE_INT x, y;
if (CONST_OK_FOR_I (INTVAL (src))) /* r-I */
return "movi\t%0,%1";
@ -1342,8 +1347,6 @@ mcore_output_movedouble (rtx operands[], enum machine_mode mode ATTRIBUTE_UNUSED
output_asm_insn ("movi %0,%1", operands);
else if (CONST_OK_FOR_M (INTVAL (src)))
output_asm_insn ("bgeni %0,%P1", operands);
else if (INTVAL (src) == -1)
output_asm_insn ("bmaski %0,32", operands);
else if (CONST_OK_FOR_N (INTVAL (src)))
output_asm_insn ("bmaski %0,%N1", operands);
else
@ -1360,13 +1363,11 @@ mcore_output_movedouble (rtx operands[], enum machine_mode mode ATTRIBUTE_UNUSED
output_asm_insn ("movi %R0,%1", operands);
else if (CONST_OK_FOR_M (INTVAL (src)))
output_asm_insn ("bgeni %R0,%P1", operands);
else if (INTVAL (src) == -1)
output_asm_insn ("bmaski %R0,32", operands);
else if (CONST_OK_FOR_N (INTVAL (src)))
output_asm_insn ("bmaski %R0,%N1", operands);
else
gcc_unreachable ();
if (INTVAL (src) < 0)
return "bmaski %0,32";
else
@ -1410,7 +1411,7 @@ mcore_expand_insv (rtx operands[])
{
/* Do directly with bseti or bclri. */
/* RBE: 2/97 consider only low bit of constant. */
if ((INTVAL(operands[3])&1) == 0)
if ((INTVAL (operands[3]) & 1) == 0)
{
mask = ~(1 << posn);
emit_insn (gen_rtx_SET (SImode, operands[0],
@ -1445,8 +1446,8 @@ mcore_expand_insv (rtx operands[])
immediates. */
/* If setting the entire field, do it directly. */
if (GET_CODE (operands[3]) == CONST_INT &&
INTVAL (operands[3]) == ((1 << width) - 1))
if (GET_CODE (operands[3]) == CONST_INT
&& INTVAL (operands[3]) == ((1 << width) - 1))
{
mreg = force_reg (SImode, GEN_INT (INTVAL (operands[3]) << posn));
emit_insn (gen_rtx_SET (SImode, operands[0],

View File

@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for Motorola M*CORE Processor.
Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
This file is part of GCC.
@ -452,17 +452,17 @@ extern const enum reg_class reg_class_from_letter[];
U: constant 0
xxxS: 1 cleared bit out of 32 (complement of power of 2). for bclri
xxxT: 2 cleared bits out of 32. for pairs of bclris. */
#define CONST_OK_FOR_I(VALUE) (((int)(VALUE)) >= 0 && ((int)(VALUE)) <= 0x7f)
#define CONST_OK_FOR_J(VALUE) (((int)(VALUE)) > 0 && ((int)(VALUE)) <= 32)
#define CONST_OK_FOR_L(VALUE) (((int)(VALUE)) < 0 && ((int)(VALUE)) >= -32)
#define CONST_OK_FOR_K(VALUE) (((int)(VALUE)) >= 0 && ((int)(VALUE)) <= 31)
#define CONST_OK_FOR_M(VALUE) (exact_log2 (VALUE) >= 0)
#define CONST_OK_FOR_N(VALUE) (((int)(VALUE)) == -1 || exact_log2 ((VALUE) + 1) >= 0)
#define CONST_OK_FOR_I(VALUE) (((HOST_WIDE_INT)(VALUE)) >= 0 && ((HOST_WIDE_INT)(VALUE)) <= 0x7f)
#define CONST_OK_FOR_J(VALUE) (((HOST_WIDE_INT)(VALUE)) > 0 && ((HOST_WIDE_INT)(VALUE)) <= 32)
#define CONST_OK_FOR_L(VALUE) (((HOST_WIDE_INT)(VALUE)) < 0 && ((HOST_WIDE_INT)(VALUE)) >= -32)
#define CONST_OK_FOR_K(VALUE) (((HOST_WIDE_INT)(VALUE)) >= 0 && ((HOST_WIDE_INT)(VALUE)) <= 31)
#define CONST_OK_FOR_M(VALUE) (exact_log2 (VALUE) >= 0 && exact_log2 (VALUE) <= 30)
#define CONST_OK_FOR_N(VALUE) (((HOST_WIDE_INT)(VALUE)) == -1 || (exact_log2 ((VALUE) + 1) >= 0 && exact_log2 ((VALUE) + 1) <= 30))
#define CONST_OK_FOR_O(VALUE) (CONST_OK_FOR_I(VALUE) || \
CONST_OK_FOR_M(VALUE) || \
CONST_OK_FOR_N(VALUE) || \
CONST_OK_FOR_M((int)(VALUE) - 1) || \
CONST_OK_FOR_N((int)(VALUE) + 1))
CONST_OK_FOR_M((HOST_WIDE_INT)(VALUE) - 1) || \
CONST_OK_FOR_N((HOST_WIDE_INT)(VALUE) + 1))
#define CONST_OK_FOR_P(VALUE) (mcore_const_ok_for_inline (VALUE))
@ -698,7 +698,8 @@ extern const enum reg_class reg_class_from_letter[];
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
On the MCore, allow anything but a double. */
#define LEGITIMATE_CONSTANT_P(X) (GET_CODE(X) != CONST_DOUBLE)
#define LEGITIMATE_CONSTANT_P(X) (GET_CODE(X) != CONST_DOUBLE \
&& CONSTANT_P (X))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@ -755,15 +756,15 @@ extern const enum reg_class reg_class_from_letter[];
if (GET_CODE (OP) == CONST_INT) \
{ \
if (GET_MODE_SIZE (MODE) >= 4 \
&& (((unsigned)INTVAL (OP)) % 4) == 0 \
&& ((unsigned)INTVAL (OP)) <= 64 - GET_MODE_SIZE (MODE)) \
&& (((unsigned HOST_WIDE_INT) INTVAL (OP)) % 4) == 0 \
&& ((unsigned HOST_WIDE_INT) INTVAL (OP)) <= 64 - GET_MODE_SIZE (MODE)) \
goto LABEL; \
if (GET_MODE_SIZE (MODE) == 2 \
&& (((unsigned)INTVAL (OP)) % 2) == 0 \
&& ((unsigned)INTVAL (OP)) <= 30) \
&& (((unsigned HOST_WIDE_INT) INTVAL (OP)) % 2) == 0 \
&& ((unsigned HOST_WIDE_INT) INTVAL (OP)) <= 30) \
goto LABEL; \
if (GET_MODE_SIZE (MODE) == 1 \
&& ((unsigned)INTVAL (OP)) <= 15) \
&& ((unsigned HOST_WIDE_INT) INTVAL (OP)) <= 15) \
goto LABEL; \
} \
} \
@ -853,7 +854,7 @@ extern const enum reg_class reg_class_from_letter[];
#define DATA_SECTION_ASM_OP "\t.data"
/* Switch into a generic section. */
#undef TARGET_ASM_NAMED_SECTION
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION mcore_asm_named_section
/* This is how to output an insn to push a register on the stack.

View File

@ -1,5 +1,5 @@
;; Machine description the Motorola MCore
;; Copyright (C) 1993, 1999, 2000, 2004, 2005
;; Copyright (C) 1993, 1999, 2000, 2004, 2005, 2007
;; Free Software Foundation, Inc.
;; Contributed by Motorola.
@ -192,11 +192,11 @@
(define_split
[(parallel[
(set (reg:CC 17)
(ne:CC (ne:SI (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
(match_operand:SI 1 "mcore_arith_reg_operand" "r"))
(ne:CC (ne:SI (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "")
(match_operand:SI 1 "mcore_arith_reg_operand" ""))
(const_int 0))
(const_int 0)))
(clobber (match_operand:CC 2 "mcore_arith_reg_operand" "=r"))])]
(clobber (match_operand:CC 2 "mcore_arith_reg_operand" ""))])]
""
[(set (reg:CC 17) (ne:SI (match_dup 0) (const_int 0)))
(set (reg:CC 17) (leu:CC (match_dup 0) (match_dup 1)))])
@ -355,7 +355,8 @@
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0
&& ! mcore_arith_S_operand (operands[2]))
{
int not_value = ~ INTVAL (operands[2]);
HOST_WIDE_INT not_value = ~ INTVAL (operands[2]);
if ( CONST_OK_FOR_I (not_value)
|| CONST_OK_FOR_M (not_value)
|| CONST_OK_FOR_N (not_value))
@ -730,9 +731,11 @@
/* Convert adds to subtracts if this makes loading the constant cheaper.
But only if we are allowed to generate new pseudos. */
if (! (reload_in_progress || reload_completed)
&& GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < -32)
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) < -32)
{
int neg_value = - INTVAL (operands[2]);
HOST_WIDE_INT neg_value = - INTVAL (operands[2]);
if ( CONST_OK_FOR_I (neg_value)
|| CONST_OK_FOR_M (neg_value)
|| CONST_OK_FOR_N (neg_value))
@ -764,7 +767,7 @@
;; || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
;; "*
;; {
;; int n = INTVAL(operands[2]);
;; HOST_WIDE_INT n = INTVAL(operands[2]);
;; if (n > 0)
;; {
;; operands[2] = GEN_INT(n - 32);
@ -822,7 +825,7 @@
;; || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
;; "*
;; {
;; int n = INTVAL(operands[2]);
;; HOST_WIDE_INT n = INTVAL(operands[2]);
;; if ( n > 0)
;; {
;; operands[2] = GEN_INT( n - 32);
@ -2976,8 +2979,9 @@
(match_operand:SI 1 "const_int_operand" ""))
(set (match_operand:SI 2 "mcore_arith_reg_operand" "")
(ior:SI (match_dup 2) (match_dup 0)))]
"TARGET_HARDLIT && mcore_num_ones (INTVAL (operands[1])) == 2 &&
mcore_is_dead (insn, operands[0])"
"TARGET_HARDLIT
&& mcore_num_ones (INTVAL (operands[1])) == 2
&& mcore_is_dead (insn, operands[0])"
"* return mcore_output_bseti (operands[2], INTVAL (operands[1]));")
(define_peephole
@ -3276,7 +3280,7 @@
if (GET_CODE (operands[1]) == CONST_INT
&& INTVAL (operands[1]) < 8 * STACK_UNITS_MAXSTEP)
{
int left = INTVAL(operands[1]);
HOST_WIDE_INT left = INTVAL(operands[1]);
/* If it's a long way, get close enough for a last shot. */
if (left >= STACK_UNITS_MAXSTEP)
@ -3295,7 +3299,7 @@
while (left > STACK_UNITS_MAXSTEP);
}
/* Perform the final adjustment. */
emit_insn (gen_addsi3 (stack_pointer_rtx,stack_pointer_rtx,GEN_INT(-left)));
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-left)));
;; emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
DONE;
}
@ -3309,7 +3313,7 @@
#if 1
emit_insn (gen_movsi (tmp, operands[1]));
emit_insn (gen_movsi (step, GEN_INT(STACK_UNITS_MAXSTEP)));
emit_insn (gen_movsi (step, GEN_INT (STACK_UNITS_MAXSTEP)));
if (GET_CODE (operands[1]) != CONST_INT)
{

View File

@ -1,5 +1,5 @@
;; Predicate definitions for Motorola MCore.
;; Copyright (C) 2005 Free Software Foundation, Inc.
;; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
;;
;; This file is part of GCC.
;;
@ -38,7 +38,7 @@
;; Nonzero if OP can be source of a simple move operation.
(define_predicate "mcore_general_movsrc_operand"
(match_code "mem,const_int,reg,subreg,symbol_ref,label_ref")
(match_code "mem,const_int,reg,subreg,symbol_ref,label_ref,const")
{
/* Any (MEM LABEL_REF) is OK. That is a pc-relative load. */
if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == LABEL_REF)
@ -50,7 +50,7 @@
;; Nonzero if OP can be destination of a simple move operation.
(define_predicate "mcore_general_movdst_operand"
(match_code "mem,const_int,reg,subreg")
(match_code "mem,reg,subreg")
{
if (GET_CODE (op) == REG && REGNO (op) == CC_REG)
return 0;
@ -141,7 +141,7 @@
if (GET_CODE (op) == CONST_INT)
{
if (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_M (~INTVAL (op)))
if (CONST_OK_FOR_K (INTVAL (op)) || (mcore_num_zeros (INTVAL (op)) <= 2))
return 1;
}
@ -212,18 +212,24 @@
if (GET_CODE (op) == CONST_INT)
{
return 1;
/* The following is removed because it precludes large constants from being
/* The following has been removed because it precludes large constants from being
returned as valid source operands for and add/sub insn. While large
constants may not directly be used in an add/sub, they may if first loaded
into a register. Thus, this predicate should indicate that they are valid,
and the constraint in mcore.md should control whether an additional load to
register is needed. (see mcore.md, addsi). -- DAC 4/2/1998 */
/*
if (CONST_OK_FOR_J(INTVAL(op)) || CONST_OK_FOR_L(INTVAL(op)))
return 1;
*/
register is needed. (see mcore.md, addsi). -- DAC 4/2/1998
if (CONST_OK_FOR_J (INTVAL (op)) || CONST_OK_FOR_L (INTVAL (op)))
return 1;
However we do still need to check to make sure that the constant is not too
big, especially if we are running on a 64-bit OS... Nickc 8/1/07. */
if (trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
return 0;
return 1;
}
return 0;