aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mcore
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2007-01-11 10:10:54 +0000
committerNick Clifton <nickc@gcc.gnu.org>2007-01-11 10:10:54 +0000
commit6e3a343d888bce3a2e92ce86ff8c09a3d77d909f (patch)
tree953008ca699afb9450947e2b6af2bfd99e64408a /gcc/config/mcore
parent4d499824ede45b788cd35a4d9cd6c560fce7f11d (diff)
downloadgcc-6e3a343d888bce3a2e92ce86ff8c09a3d77d909f.zip
gcc-6e3a343d888bce3a2e92ce86ff8c09a3d77d909f.tar.gz
gcc-6e3a343d888bce3a2e92ce86ff8c09a3d77d909f.tar.bz2
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
Diffstat (limited to 'gcc/config/mcore')
-rw-r--r--gcc/config/mcore/mcore-protos.h12
-rw-r--r--gcc/config/mcore/mcore.c297
-rw-r--r--gcc/config/mcore/mcore.h33
-rw-r--r--gcc/config/mcore/mcore.md32
-rw-r--r--gcc/config/mcore/predicates.md30
5 files changed, 208 insertions, 196 deletions
diff --git a/gcc/config/mcore/mcore-protos.h b/gcc/config/mcore/mcore-protos.h
index 11a522b..b2c5abb 100644
--- a/gcc/config/mcore/mcore-protos.h
+++ b/gcc/config/mcore/mcore-protos.h
@@ -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 */
diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c
index 8237d45..44035b2 100644
--- a/gcc/config/mcore/mcore.c
+++ b/gcc/config/mcore/mcore.c
@@ -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,121 +739,120 @@ 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))
+ {
+ *x = ~value;
+ return 2;
+ }
+
+ for (i = 1; i <= 32; i++)
{
- if (const_ok_for_mcore (~value))
+ 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],
diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h
index 5e2d8ca..cbc2f33 100644
--- a/gcc/config/mcore/mcore.h
+++ b/gcc/config/mcore/mcore.h
@@ -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.
diff --git a/gcc/config/mcore/mcore.md b/gcc/config/mcore/mcore.md
index 777a03e..c4af69e 100644
--- a/gcc/config/mcore/mcore.md
+++ b/gcc/config/mcore/mcore.md
@@ -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)
{
diff --git a/gcc/config/mcore/predicates.md b/gcc/config/mcore/predicates.md
index 7f1ce39..60c4d6d 100644
--- a/gcc/config/mcore/predicates.md
+++ b/gcc/config/mcore/predicates.md
@@ -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;