diff options
author | Nick Clifton <nickc@redhat.com> | 2007-01-11 10:10:54 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 2007-01-11 10:10:54 +0000 |
commit | 6e3a343d888bce3a2e92ce86ff8c09a3d77d909f (patch) | |
tree | 953008ca699afb9450947e2b6af2bfd99e64408a /gcc/config/mcore | |
parent | 4d499824ede45b788cd35a4d9cd6c560fce7f11d (diff) | |
download | gcc-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.h | 12 | ||||
-rw-r--r-- | gcc/config/mcore/mcore.c | 297 | ||||
-rw-r--r-- | gcc/config/mcore/mcore.h | 33 | ||||
-rw-r--r-- | gcc/config/mcore/mcore.md | 32 | ||||
-rw-r--r-- | gcc/config/mcore/predicates.md | 30 |
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; |