diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-06 15:16:32 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-06 15:16:32 +0000 |
commit | 31ba6c3ff2311bad9422246f49d59c532cbb5078 (patch) | |
tree | 6e862e3ea14b2edf93a92c404a0d9b29f3f9ba65 /gcc/config/cris | |
parent | bab85b65e545231656361b997a81fb8a44b266b4 (diff) | |
download | gcc-31ba6c3ff2311bad9422246f49d59c532cbb5078.tar.gz |
2011-11-06 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 181026 using svnmerge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@181034 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/cris')
-rw-r--r-- | gcc/config/cris/arit.c | 304 | ||||
-rw-r--r-- | gcc/config/cris/cris-protos.h | 9 | ||||
-rw-r--r-- | gcc/config/cris/cris.c | 175 | ||||
-rw-r--r-- | gcc/config/cris/cris.h | 153 | ||||
-rw-r--r-- | gcc/config/cris/cris.md | 4 | ||||
-rw-r--r-- | gcc/config/cris/cris_abi_symbol.c | 45 | ||||
-rw-r--r-- | gcc/config/cris/libgcc.ver | 7 | ||||
-rw-r--r-- | gcc/config/cris/mulsi3.asm | 255 | ||||
-rw-r--r-- | gcc/config/cris/t-cris | 12 | ||||
-rw-r--r-- | gcc/config/cris/t-elfmulti | 4 | ||||
-rw-r--r-- | gcc/config/cris/t-linux | 4 |
11 files changed, 190 insertions, 782 deletions
diff --git a/gcc/config/cris/arit.c b/gcc/config/cris/arit.c deleted file mode 100644 index 32255f99d39..00000000000 --- a/gcc/config/cris/arit.c +++ /dev/null @@ -1,304 +0,0 @@ -/* Signed and unsigned multiplication and division and modulus for CRIS. - Contributed by Axis Communications. - Written by Hans-Peter Nilsson <hp@axis.se>, c:a 1992. - - Copyright (C) 1998, 1999, 2000, 2001, 2002, - 2005, 2009 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This file is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - - -/* Note that we provide prototypes for all "const" functions, to attach - the const attribute. This is necessary in 2.7.2 - adding the - attribute to the function *definition* is a syntax error. - This did not work with e.g. 2.1; back then, the return type had to - be "const". */ - -#include "config.h" - -#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 3 -#define LZ(v) __builtin_clz (v) -#endif - - -#if defined (L_udivsi3) || defined (L_divsi3) || defined (L_umodsi3) \ - || defined (L_modsi3) -/* Result type of divmod worker function. */ -struct quot_rem - { - long quot; - long rem; - }; - -/* This is the worker function for div and mod. It is inlined into the - respective library function. Parameter A must have bit 31 == 0. */ - -static __inline__ struct quot_rem -do_31div (unsigned long a, unsigned long b) - __attribute__ ((__const__, __always_inline__)); - -static __inline__ struct quot_rem -do_31div (unsigned long a, unsigned long b) -{ - /* Adjust operands and result if a is 31 bits. */ - long extra = 0; - int quot_digits = 0; - - if (b == 0) - { - struct quot_rem ret; - ret.quot = 0xffffffff; - ret.rem = 0xffffffff; - return ret; - } - - if (a < b) - return (struct quot_rem) { 0, a }; - -#ifdef LZ - if (b <= a) - { - quot_digits = LZ (b) - LZ (a); - quot_digits += (a >= (b << quot_digits)); - b <<= quot_digits; - } -#else - while (b <= a) - { - b <<= 1; - quot_digits++; - } -#endif - - /* Is a 31 bits? Note that bit 31 is handled by the caller. */ - if (a & 0x40000000) - { - /* Then make b:s highest bit max 0x40000000, because it must have - been 0x80000000 to be 1 bit higher than a. */ - b >>= 1; - - /* Adjust a to be maximum 0x3fffffff, i.e. two upper bits zero. */ - if (a >= b) - { - a -= b; - extra = 1 << (quot_digits - 1); - } - else - { - a -= b >> 1; - - /* Remember that we adjusted a by subtracting b * 2 ** Something. */ - extra = 1 << quot_digits; - } - - /* The number of quotient digits will be one less, because - we just adjusted b. */ - quot_digits--; - } - - /* Now do the division part. */ - - /* Subtract b and add ones to the right when a >= b - i.e. "a - (b - 1) == (a - b) + 1". */ - b--; - -#define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b)) - - switch (quot_digits) - { - case 32: DS; case 31: DS; case 30: DS; case 29: DS; - case 28: DS; case 27: DS; case 26: DS; case 25: DS; - case 24: DS; case 23: DS; case 22: DS; case 21: DS; - case 20: DS; case 19: DS; case 18: DS; case 17: DS; - case 16: DS; case 15: DS; case 14: DS; case 13: DS; - case 12: DS; case 11: DS; case 10: DS; case 9: DS; - case 8: DS; case 7: DS; case 6: DS; case 5: DS; - case 4: DS; case 3: DS; case 2: DS; case 1: DS; - case 0:; - } - - { - struct quot_rem ret; - ret.quot = (a & ((1 << quot_digits) - 1)) + extra; - ret.rem = a >> quot_digits; - return ret; - } -} - -#ifdef L_udivsi3 -unsigned long -__Udiv (unsigned long a, unsigned long b) __attribute__ ((__const__)); - -unsigned long -__Udiv (unsigned long a, unsigned long b) -{ - long extra = 0; - - /* Adjust operands and result, if a and/or b is 32 bits. */ - /* Effectively: b & 0x80000000. */ - if ((long) b < 0) - return a >= b; - - /* Effectively: a & 0x80000000. */ - if ((long) a < 0) - { - int tmp = 0; - - if (b == 0) - return 0xffffffff; -#ifdef LZ - tmp = LZ (b); -#else - for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--) - ; - - tmp = 31 - tmp; -#endif - - if ((b << tmp) > a) - { - extra = 1 << (tmp-1); - a -= b << (tmp - 1); - } - else - { - extra = 1 << tmp; - a -= b << tmp; - } - } - - return do_31div (a, b).quot+extra; -} -#endif /* L_udivsi3 */ - -#ifdef L_divsi3 -long -__Div (long a, long b) __attribute__ ((__const__)); - -long -__Div (long a, long b) -{ - long extra = 0; - long sign = (b < 0) ? -1 : 1; - - /* We need to handle a == -2147483648 as expected and must while - doing that avoid producing a sequence like "abs (a) < 0" as GCC - may optimize out the test. That sequence may not be obvious as - we call inline functions. Testing for a being negative and - handling (presumably much rarer than positive) enables us to get - a bit of optimization for an (accumulated) reduction of the - penalty of the 0x80000000 special-case. */ - if (a < 0) - { - sign = -sign; - - if ((a & 0x7fffffff) == 0) - { - /* We're at 0x80000000. Tread carefully. */ - a -= b * sign; - extra = sign; - } - a = -a; - } - - /* We knowingly penalize pre-v10 models by multiplication with the - sign. */ - return sign * do_31div (a, __builtin_labs (b)).quot + extra; -} -#endif /* L_divsi3 */ - - -#ifdef L_umodsi3 -unsigned long -__Umod (unsigned long a, unsigned long b) __attribute__ ((__const__)); - -unsigned long -__Umod (unsigned long a, unsigned long b) -{ - /* Adjust operands and result if a and/or b is 32 bits. */ - if ((long) b < 0) - return a >= b ? a - b : a; - - if ((long) a < 0) - { - int tmp = 0; - - if (b == 0) - return a; -#ifdef LZ - tmp = LZ (b); -#else - for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--) - ; - tmp = 31 - tmp; -#endif - - if ((b << tmp) > a) - { - a -= b << (tmp - 1); - } - else - { - a -= b << tmp; - } - } - - return do_31div (a, b).rem; -} -#endif /* L_umodsi3 */ - -#ifdef L_modsi3 -long -__Mod (long a, long b) __attribute__ ((__const__)); - -long -__Mod (long a, long b) -{ - long sign = 1; - - /* We need to handle a == -2147483648 as expected and must while - doing that avoid producing a sequence like "abs (a) < 0" as GCC - may optimize out the test. That sequence may not be obvious as - we call inline functions. Testing for a being negative and - handling (presumably much rarer than positive) enables us to get - a bit of optimization for an (accumulated) reduction of the - penalty of the 0x80000000 special-case. */ - if (a < 0) - { - sign = -1; - if ((a & 0x7fffffff) == 0) - /* We're at 0x80000000. Tread carefully. */ - a += __builtin_labs (b); - a = -a; - } - - return sign * do_31div (a, __builtin_labs (b)).rem; -} -#endif /* L_modsi3 */ -#endif /* L_udivsi3 || L_divsi3 || L_umodsi3 || L_modsi3 */ - -/* - * Local variables: - * eval: (c-set-style "gnu") - * indent-tabs-mode: t - * End: - */ diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h index f37927e1971..291981d5707 100644 --- a/gcc/config/cris/cris-protos.h +++ b/gcc/config/cris/cris-protos.h @@ -33,8 +33,13 @@ extern bool cris_cc0_user_requires_cmp (rtx); extern rtx cris_return_addr_rtx (int, rtx); extern rtx cris_split_movdx (rtx *); extern int cris_legitimate_pic_operand (rtx); -extern enum cris_pic_symbol_type cris_pic_symbol_type_of (rtx); -extern bool cris_valid_pic_const (rtx, bool); +extern enum cris_pic_symbol_type cris_pic_symbol_type_of (const_rtx); +extern bool cris_valid_pic_const (const_rtx, bool); +extern bool cris_constant_index_p (const_rtx); +extern bool cris_base_p (const_rtx, bool); +extern bool cris_base_or_autoincr_p (const_rtx, bool); +extern bool cris_bdap_index_p (const_rtx, bool); +extern bool cris_biap_index_p (const_rtx, bool); extern bool cris_store_multiple_op_p (rtx); extern bool cris_movem_load_rest_p (rtx, int); extern void cris_asm_output_symbol_ref (FILE *, rtx); diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 35ecaa8e2fd..4a08ae03aee 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -125,6 +125,8 @@ static void cris_init_libfuncs (void); static reg_class_t cris_preferred_reload_class (rtx, reg_class_t); +static bool cris_legitimate_address_p (enum machine_mode, rtx, bool); + static int cris_register_move_cost (enum machine_mode, reg_class_t, reg_class_t); static int cris_memory_move_cost (enum machine_mode, reg_class_t, bool); static bool cris_rtx_costs (rtx, int, int, int, int *, bool); @@ -200,6 +202,9 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; #undef TARGET_INIT_LIBFUNCS #define TARGET_INIT_LIBFUNCS cris_init_libfuncs +#undef TARGET_LEGITIMATE_ADDRESS_P +#define TARGET_LEGITIMATE_ADDRESS_P cris_legitimate_address_p + #undef TARGET_PREFERRED_RELOAD_CLASS #define TARGET_PREFERRED_RELOAD_CLASS cris_preferred_reload_class @@ -1122,7 +1127,7 @@ cris_print_operand_address (FILE *file, rtx x) if (CONSTANT_ADDRESS_P (x)) cris_output_addr_const (file, x); - else if (BASE_OR_AUTOINCR_P (x)) + else if (cris_base_or_autoincr_p (x, true)) cris_print_base (x, file); else if (GET_CODE (x) == PLUS) { @@ -1130,12 +1135,12 @@ cris_print_operand_address (FILE *file, rtx x) x1 = XEXP (x, 0); x2 = XEXP (x, 1); - if (BASE_P (x1)) + if (cris_base_p (x1, true)) { cris_print_base (x1, file); cris_print_index (x2, file); } - else if (BASE_P (x2)) + else if (cris_base_p (x2, true)) { cris_print_base (x2, file); cris_print_index (x1, file); @@ -1272,6 +1277,136 @@ cris_initial_elimination_offset (int fromreg, int toreg) gcc_unreachable (); } +/* Nonzero if X is a hard reg that can be used as an index. */ +static inline bool +reg_ok_for_base_p (const_rtx x, bool strict) +{ + return ((! strict && ! HARD_REGISTER_P (x)) + || REGNO_OK_FOR_BASE_P (REGNO (x))); +} + +/* Nonzero if X is a hard reg that can be used as an index. */ +static inline bool +reg_ok_for_index_p (const_rtx x, bool strict) +{ + return reg_ok_for_base_p (x, strict); +} + +/* No symbol can be used as an index (or more correct, as a base) together + with a register with PIC; the PIC register must be there. */ + +bool +cris_constant_index_p (const_rtx x) +{ + return (CONSTANT_P (x) && (!flag_pic || cris_valid_pic_const (x, true))); +} + +/* True if X is a valid base register. */ + +bool +cris_base_p (const_rtx x, bool strict) +{ + return (REG_P (x) && reg_ok_for_base_p (x, strict)); +} + +/* True if X is a valid index register. */ + +static inline bool +cris_index_p (const_rtx x, bool strict) +{ + return (REG_P (x) && reg_ok_for_index_p (x, strict)); +} + +/* True if X is a valid base register with or without autoincrement. */ + +bool +cris_base_or_autoincr_p (const_rtx x, bool strict) +{ + return (cris_base_p (x, strict) + || (GET_CODE (x) == POST_INC + && cris_base_p (XEXP (x, 0), strict) + && REGNO (XEXP (x, 0)) != CRIS_ACR_REGNUM)); +} + +/* True if X is a valid (register) index for BDAP, i.e. [Rs].S or [Rs+].S. */ + +bool +cris_bdap_index_p (const_rtx x, bool strict) +{ + return ((MEM_P (x) + && GET_MODE (x) == SImode + && cris_base_or_autoincr_p (XEXP (x, 0), strict)) + || (GET_CODE (x) == SIGN_EXTEND + && MEM_P (XEXP (x, 0)) + && (GET_MODE (XEXP (x, 0)) == HImode + || GET_MODE (XEXP (x, 0)) == QImode) + && cris_base_or_autoincr_p (XEXP (XEXP (x, 0), 0), strict))); +} + +/* True if X is a valid (register) index for BIAP, i.e. Rd.m. */ + +bool +cris_biap_index_p (const_rtx x, bool strict) +{ + return (cris_index_p (x, strict) + || (GET_CODE (x) == MULT + && cris_index_p (XEXP (x, 0), strict) + && cris_scale_int_operand (XEXP (x, 1), VOIDmode))); +} + +/* Worker function for TARGET_LEGITIMATE_ADDRESS_P. + + A PIC operand looks like a normal symbol here. At output we dress it + in "[rPIC+symbol:GOT]" (global symbol) or "rPIC+symbol:GOTOFF" (local + symbol) so we exclude all addressing modes where we can't replace a + plain "symbol" with that. A global PIC symbol does not fit anywhere + here (but is thankfully a general_operand in itself). A local PIC + symbol is valid for the plain "symbol + offset" case. */ + +static bool +cris_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) +{ + const_rtx x1, x2; + + if (cris_base_or_autoincr_p (x, strict)) + return true; + else if (TARGET_V32) + /* Nothing else is valid then. */ + return false; + else if (cris_constant_index_p (x)) + return true; + /* Indexed? */ + else if (GET_CODE (x) == PLUS) + { + x1 = XEXP (x, 0); + x2 = XEXP (x, 1); + /* BDAP o, Rd. */ + if ((cris_base_p (x1, strict) && cris_constant_index_p (x2)) + || (cris_base_p (x2, strict) && cris_constant_index_p (x1)) + /* BDAP Rs[+], Rd. */ + || (GET_MODE_SIZE (mode) <= UNITS_PER_WORD + && ((cris_base_p (x1, strict) + && cris_bdap_index_p (x2, strict)) + || (cris_base_p (x2, strict) + && cris_bdap_index_p (x1, strict)) + /* BIAP.m Rs, Rd */ + || (cris_base_p (x1, strict) + && cris_biap_index_p (x2, strict)) + || (cris_base_p (x2, strict) + && cris_biap_index_p (x1, strict))))) + return true; + } + else if (MEM_P (x)) + { + /* DIP (Rs). Reject [[reg+]] and [[reg]] for DImode (long long). */ + if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD + && cris_base_or_autoincr_p (XEXP (x, 0), strict)) + return true; + } + + return false; +} + /* Worker function for LEGITIMIZE_RELOAD_ADDRESS. */ bool @@ -1860,7 +1995,7 @@ cris_rtx_costs (rtx x, int code, int outer_code, int opno, int *total, FIXME: this case is a stop-gap for 4.3 and 4.4, this whole function should be rewritten. */ - if (outer_code == PLUS && BIAP_INDEX_P (x)) + if (outer_code == PLUS && cris_biap_index_p (x, false)) { *total = 0; return true; @@ -1942,7 +2077,7 @@ cris_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED) loop there, without apparent reason. */ /* The cheapest addressing modes get 0, since nothing extra is needed. */ - if (BASE_OR_AUTOINCR_P (x)) + if (cris_base_or_autoincr_p (x, false)) return 0; /* An indirect mem must be a DIP. This means two bytes extra for code, @@ -1972,7 +2107,7 @@ cris_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED) /* A BIAP is 2 extra bytes for the prefix insn, nothing more. We recognize the typical MULT which is always in tem1 because of insn canonicalization. */ - if ((GET_CODE (tem1) == MULT && BIAP_INDEX_P (tem1)) + if ((GET_CODE (tem1) == MULT && cris_biap_index_p (tem1, false)) || REG_P (tem2)) return 2 / 2; @@ -2030,12 +2165,12 @@ cris_side_effect_mode_ok (enum rtx_code code, rtx *ops, /* The operands may be swapped. Canonicalize them in reg_rtx and val_rtx, where reg_rtx always is a reg (for this constraint to match). */ - if (! BASE_P (reg_rtx)) + if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed)) reg_rtx = val_rtx, val_rtx = ops[rreg]; /* Don't forget to check that reg_rtx really is a reg. If it isn't, we have no business. */ - if (! BASE_P (reg_rtx)) + if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed)) return 0; /* Don't do this when -mno-split. */ @@ -2060,8 +2195,9 @@ cris_side_effect_mode_ok (enum rtx_code code, rtx *ops, /* Check if the lvalue register is the same as the "other operand". If so, the result is undefined and we shouldn't do this. FIXME: Check again. */ - if ((BASE_P (ops[lreg]) - && BASE_P (ops[other_op]) + if ((cris_base_p (ops[lreg], reload_in_progress || reload_completed) + && cris_base_p (ops[other_op], + reload_in_progress || reload_completed) && REGNO (ops[lreg]) == REGNO (ops[other_op])) || rtx_equal_p (ops[other_op], ops[lreg])) return 0; @@ -2074,7 +2210,7 @@ cris_side_effect_mode_ok (enum rtx_code code, rtx *ops, return 0; if (code == PLUS - && ! BASE_P (val_rtx)) + && ! cris_base_p (val_rtx, reload_in_progress || reload_completed)) { /* Do not allow rx = rx + n if a normal add or sub with same size @@ -2088,19 +2224,24 @@ cris_side_effect_mode_ok (enum rtx_code code, rtx *ops, if (CONSTANT_P (val_rtx)) return 1; - if (MEM_P (val_rtx) && BASE_OR_AUTOINCR_P (XEXP (val_rtx, 0))) + if (MEM_P (val_rtx) + && cris_base_or_autoincr_p (XEXP (val_rtx, 0), + reload_in_progress || reload_completed)) return 1; if (GET_CODE (val_rtx) == SIGN_EXTEND && MEM_P (XEXP (val_rtx, 0)) - && BASE_OR_AUTOINCR_P (XEXP (XEXP (val_rtx, 0), 0))) + && cris_base_or_autoincr_p (XEXP (XEXP (val_rtx, 0), 0), + reload_in_progress || reload_completed)) return 1; /* If we got here, it's not a valid addressing mode. */ return 0; } else if (code == MULT - || (code == PLUS && BASE_P (val_rtx))) + || (code == PLUS + && cris_base_p (val_rtx, + reload_in_progress || reload_completed))) { /* Do not allow rx = rx + ry.S, since it doesn't give better code. */ if (rtx_equal_p (ops[lreg], reg_rtx) @@ -2112,7 +2253,7 @@ cris_side_effect_mode_ok (enum rtx_code code, rtx *ops, return 0; /* Only allow r + ... */ - if (! BASE_P (reg_rtx)) + if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed)) return 0; /* If we got here, all seems ok. @@ -2202,7 +2343,7 @@ cris_target_asm_named_section (const char *name, unsigned int flags, elsewhere. */ bool -cris_valid_pic_const (rtx x, bool any_operand) +cris_valid_pic_const (const_rtx x, bool any_operand) { gcc_assert (flag_pic); @@ -2252,7 +2393,7 @@ cris_valid_pic_const (rtx x, bool any_operand) given the original (non-PIC) representation. */ enum cris_pic_symbol_type -cris_pic_symbol_type_of (rtx x) +cris_pic_symbol_type_of (const_rtx x) { switch (GET_CODE (x)) { diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 4c28e4530ab..135b03bb1a4 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -84,11 +84,7 @@ extern int cris_cpu_version; /* Changing the order used to be necessary to put the fourth __make_dp argument (a DImode parameter) in registers, to fit with the libfunc parameter passing scheme used for intrinsic functions. FIXME: Check - performance and maybe remove definition from TARGET_LIBGCC2_CFLAGS now - that it isn't strictly necessary. We used to do this through - TARGET_LIBGCC2_CFLAGS, but that became increasingly difficult as the - parenthesis (that needed quoting) travels through several layers of - make and shell invocations. */ + performance. */ #ifdef IN_LIBGCC2 #define __make_dp(a,b,c,d) __cris_make_dp(d,a,b,c) #endif @@ -676,17 +672,18 @@ enum reg_class /* Just an indirect register (happens to also be \ "all" slottable memory addressing modes not \ covered by other constraints, i.e. '>'). */ \ - MEM_P (X) && BASE_P (XEXP (X, 0)) \ + MEM_P (X) \ + && cris_base_p (XEXP (X, 0), reload_in_progress || reload_completed) \ ) #define EXTRA_CONSTRAINT_R(X) \ ( \ /* An operand to BDAP or BIAP: \ A BIAP; r.S? */ \ - BIAP_INDEX_P (X) \ + cris_biap_index_p (X, reload_in_progress || reload_completed) \ /* A [reg] or (int) [reg], maybe with post-increment. */ \ - || BDAP_INDEX_P (X) \ - || CONSTANT_INDEX_P (X) \ + || cris_bdap_index_p (X, reload_in_progress || reload_completed) \ + || cris_constant_index_p (X) \ ) #define EXTRA_CONSTRAINT_T(X) \ @@ -695,25 +692,33 @@ enum reg_class MEM_P (X) \ && ((MEM_P (XEXP (X, 0)) \ /* Double indirect: [[reg]] or [[reg+]]? */ \ - && (BASE_OR_AUTOINCR_P (XEXP (XEXP (X, 0), 0)))) \ + && (cris_base_or_autoincr_p (XEXP (XEXP (X, 0), 0), \ + reload_in_progress || reload_completed))) \ /* Just an explicit indirect reference: [const]? */ \ || CONSTANT_P (XEXP (X, 0)) \ /* Something that is indexed; [...+...]? */ \ || (GET_CODE (XEXP (X, 0)) == PLUS \ /* A BDAP constant: [reg+(8|16|32)bit offset]? */ \ - && ((BASE_P (XEXP (XEXP (X, 0), 0)) \ - && CONSTANT_INDEX_P (XEXP (XEXP (X, 0), 1))) \ + && ((cris_base_p (XEXP (XEXP (X, 0), 0), \ + reload_in_progress || reload_completed) \ + && cris_constant_index_p (XEXP (XEXP (X, 0), 1))) \ /* A BDAP register: [reg+[reg(+)].S]? */ \ - || (BASE_P (XEXP (XEXP (X, 0), 0)) \ - && BDAP_INDEX_P(XEXP(XEXP(X, 0), 1))) \ + || (cris_base_p (XEXP (XEXP (X, 0), 0), \ + reload_in_progress || reload_completed) \ + && cris_bdap_index_p (XEXP(XEXP(X, 0), 1), \ + reload_in_progress || reload_completed)) \ /* Same, but with swapped arguments (no canonical \ ordering between e.g. REG and MEM as of LAST_UPDATED \ "Thu May 12 03:59:11 UTC 2005"). */ \ - || (BASE_P (XEXP (XEXP (X, 0), 1)) \ - && BDAP_INDEX_P (XEXP (XEXP (X, 0), 0))) \ + || (cris_base_p (XEXP (XEXP (X, 0), 1), \ + reload_in_progress | reload_completed) \ + && cris_bdap_index_p (XEXP (XEXP (X, 0), 0), \ + reload_in_progress || reload_completed)) \ /* A BIAP: [reg+reg.S] (MULT comes first). */ \ - || (BASE_P (XEXP (XEXP (X, 0), 1)) \ - && BIAP_INDEX_P (XEXP (XEXP (X, 0), 0)))))) \ + || (cris_base_p (XEXP (XEXP (X, 0), 1), \ + reload_in_progress || reload_completed) \ + && cris_biap_index_p (XEXP (XEXP (X, 0), 0), \ + reload_in_progress || reload_completed))))) \ ) /* PIC-constructs for symbols. */ @@ -888,118 +893,6 @@ struct cum_args {int regs;}; among all CRIS variants. */ #define MAX_REGS_PER_ADDRESS 2 -/* There are helper macros defined here which are used only in - GO_IF_LEGITIMATE_ADDRESS. - - Note that you *have to* reject invalid addressing modes for mode - MODE, even if it is legal for normal addressing modes. You cannot - rely on the constraints to do this work. They can only be used to - doublecheck your intentions. One example is that you HAVE TO reject - (mem:DI (plus:SI (reg:SI x) (reg:SI y))) because for some reason - this cannot be reloaded. (Which of course you can argue that gcc - should have done.) FIXME: Strange. Check. */ - -/* No symbol can be used as an index (or more correct, as a base) together - with a register with PIC; the PIC register must be there. */ -#define CONSTANT_INDEX_P(X) \ - (CONSTANT_P (X) && (!flag_pic || cris_valid_pic_const (X, true))) - -/* True if X is a valid base register. */ -#define BASE_P(X) \ - (REG_P (X) && REG_OK_FOR_BASE_P (X)) - -/* True if X is a valid base register with or without autoincrement. */ -#define BASE_OR_AUTOINCR_P(X) \ - (BASE_P (X) \ - || (GET_CODE (X) == POST_INC \ - && BASE_P (XEXP (X, 0)) \ - && REGNO (XEXP (X, 0)) != CRIS_ACR_REGNUM)) - -/* True if X is a valid (register) index for BDAP, i.e. [Rs].S or [Rs+].S. */ -#define BDAP_INDEX_P(X) \ - ((MEM_P (X) && GET_MODE (X) == SImode \ - && BASE_OR_AUTOINCR_P (XEXP (X, 0))) \ - || (GET_CODE (X) == SIGN_EXTEND \ - && MEM_P (XEXP (X, 0)) \ - && (GET_MODE (XEXP (X, 0)) == HImode \ - || GET_MODE (XEXP (X, 0)) == QImode) \ - && BASE_OR_AUTOINCR_P (XEXP (XEXP (X, 0), 0)))) - -/* True if X is a valid (register) index for BIAP, i.e. Rd.m. */ -#define BIAP_INDEX_P(X) \ - ((BASE_P (X) && REG_OK_FOR_INDEX_P (X)) \ - || (GET_CODE (X) == MULT \ - && BASE_P (XEXP (X, 0)) \ - && REG_OK_FOR_INDEX_P (XEXP (X, 0)) \ - && CONST_INT_P (XEXP (X, 1)) \ - && (INTVAL (XEXP (X, 1)) == 2 \ - || INTVAL (XEXP (X, 1)) == 4))) - -/* A PIC operand looks like a normal symbol here. At output we dress it - in "[rPIC+symbol:GOT]" (global symbol) or "rPIC+symbol:GOTOFF" (local - symbol) so we exclude all addressing modes where we can't replace a - plain "symbol" with that. A global PIC symbol does not fit anywhere - here (but is thankfully a general_operand in itself). A local PIC - symbol is valid for the plain "symbol + offset" case. */ -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ - { \ - rtx x1, x2; \ - if (BASE_OR_AUTOINCR_P (X)) \ - goto ADDR; \ - else if (TARGET_V32) \ - /* Nothing else is valid then. */ \ - ; \ - else if (CONSTANT_INDEX_P (X)) \ - goto ADDR; \ - /* Indexed? */ \ - else if (GET_CODE (X) == PLUS) \ - { \ - x1 = XEXP (X, 0); \ - x2 = XEXP (X, 1); \ - /* BDAP o, Rd. */ \ - if ((BASE_P (x1) && CONSTANT_INDEX_P (x2)) \ - || (BASE_P (x2) && CONSTANT_INDEX_P (x1)) \ - /* BDAP Rs[+], Rd. */ \ - || (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \ - && ((BASE_P (x1) && BDAP_INDEX_P (x2)) \ - || (BASE_P (x2) && BDAP_INDEX_P (x1)) \ - /* BIAP.m Rs, Rd */ \ - || (BASE_P (x1) && BIAP_INDEX_P (x2)) \ - || (BASE_P (x2) && BIAP_INDEX_P (x1))))) \ - goto ADDR; \ - } \ - else if (MEM_P (X)) \ - { \ - /* DIP (Rs). Reject [[reg+]] and [[reg]] for \ - DImode (long long). */ \ - if (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \ - && (BASE_P (XEXP (X, 0)) \ - || BASE_OR_AUTOINCR_P (XEXP (X, 0)))) \ - goto ADDR; \ - } \ - } - -#ifndef REG_OK_STRICT - /* Nonzero if X is a hard reg that can be used as a base reg - or if it is a pseudo reg. */ -# define REG_OK_FOR_BASE_P(X) \ - (REGNO (X) <= CRIS_LAST_GENERAL_REGISTER \ - || REGNO (X) == ARG_POINTER_REGNUM \ - || REGNO (X) >= FIRST_PSEUDO_REGISTER) -#else - /* Nonzero if X is a hard reg that can be used as a base reg. */ -# define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) -#endif - -#ifndef REG_OK_STRICT - /* Nonzero if X is a hard reg that can be used as an index - or if it is a pseudo reg. */ -# define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X) -#else - /* Nonzero if X is a hard reg that can be used as an index. */ -# define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) -#endif - /* Fix reloads known to cause suboptimal spilling. */ #define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN) \ do \ diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index 592bbadf489..428132c2eb4 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -4680,7 +4680,7 @@ (match_operator 4 "cris_mem_op" [(match_dup 0)]))] "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD && REGNO (operands[3]) != REGNO (operands[0]) - && (BASE_P (operands[1]) || BASE_P (operands[2])) + && (cris_base_p (operands[1], true) || cris_base_p (operands[2], true)) && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J') && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N') && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128) @@ -4716,7 +4716,7 @@ (match_operand 4 "register_operand" ""))] "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD && REGNO (operands[4]) != REGNO (operands[0]) - && (BASE_P (operands[1]) || BASE_P (operands[2])) + && (cris_base_p (operands[1], true) || cris_base_p (operands[2], true)) && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J') && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N') && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128) diff --git a/gcc/config/cris/cris_abi_symbol.c b/gcc/config/cris/cris_abi_symbol.c deleted file mode 100644 index db9db2cfe56..00000000000 --- a/gcc/config/cris/cris_abi_symbol.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Define symbol to recognize CRIS ABI version 2, for a.out use. - Contributed by Axis Communications. - Written by Hans-Peter Nilsson <hp@axis.se>, c:a 1992. - - Copyright (C) 2000, 2001, 2003, 2009 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This file is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "tconfig.h" -#include "tm.h" - -#ifdef __AOUT__ - -/* ELF support was not released before the ABI was changed, so we - restrict this awkwardness to a.out. This symbol is for gdb to - recognize, so it can debug both old and new programs successfully. */ -__asm__ (".global " CRIS_ABI_VERSION_SYMBOL_STRING); -__asm__ (".set " CRIS_ABI_VERSION_SYMBOL_STRING ",0"); - -#else /* not __AOUT__ */ - -/* The file must not be empty (declaration/definition-wise) according to - ISO, IIRC. */ -extern int _Dummy; - -#endif /* not __AOUT__ */ diff --git a/gcc/config/cris/libgcc.ver b/gcc/config/cris/libgcc.ver deleted file mode 100644 index e35de83100f..00000000000 --- a/gcc/config/cris/libgcc.ver +++ /dev/null @@ -1,7 +0,0 @@ -GCC_4.3 { - __Mul - __Div - __Udiv - __Mod - __Umod -} diff --git a/gcc/config/cris/mulsi3.asm b/gcc/config/cris/mulsi3.asm deleted file mode 100644 index 76dfb634680..00000000000 --- a/gcc/config/cris/mulsi3.asm +++ /dev/null @@ -1,255 +0,0 @@ -;; Copyright (C) 2001, 2004 Free Software Foundation, Inc. -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it under -;; the terms of the GNU General Public License as published by the Free -;; Software Foundation; either version 3, or (at your option) any later -;; version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -;; WARRANTY; without even the implied warranty of MERCHANTABILITY or -;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -;; for more details. -;; -;; Under Section 7 of GPL version 3, you are granted additional -;; permissions described in the GCC Runtime Library Exception, version -;; 3.1, as published by the Free Software Foundation. -;; -;; You should have received a copy of the GNU General Public License and -;; a copy of the GCC Runtime Library Exception along with this program; -;; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -;; <http://www.gnu.org/licenses/>. -;; -;; This code used to be expanded through interesting expansions in -;; the machine description, compiled from this code: -;; -;; #ifdef L_mulsi3 -;; long __Mul (unsigned long a, unsigned long b) __attribute__ ((__const__)); -;; -;; /* This must be compiled with the -mexpand-mul flag, to synthesize the -;; multiplication from the mstep instructions. The check for -;; smaller-size multiplication pays off in the order of .5-10%; -;; estimated median 1%, depending on application. -;; FIXME: It can be further optimized if we go to assembler code, as -;; gcc 2.7.2 adds a few unnecessary instructions and does not put the -;; basic blocks in optimal order. */ -;; long -;; __Mul (unsigned long a, unsigned long b) -;; { -;; #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10 -;; /* In case other code is compiled without -march=v10, they will -;; contain calls to __Mul, regardless of flags at link-time. The -;; "else"-code below will work, but is unnecessarily slow. This -;; sometimes cuts a few minutes off from simulation time by just -;; returning a "mulu.d". */ -;; return a * b; -;; #else -;; unsigned long min; -;; -;; /* Get minimum via the bound insn. */ -;; min = a < b ? a : b; -;; -;; /* Can we omit computation of the high part? */ -;; if (min > 65535) -;; /* No. Perform full multiplication. */ -;; return a * b; -;; else -;; { -;; /* Check if both operands are within 16 bits. */ -;; unsigned long max; -;; -;; /* Get maximum, by knowing the minimum. -;; This will partition a and b into max and min. -;; This is not currently something GCC understands, -;; so do this trick by asm. */ -;; __asm__ ("xor %1,%0\n\txor %2,%0" -;; : "=r" (max) -;; : "r" (b), "r" (a), "0" (min)); -;; -;; if (max > 65535) -;; /* Make GCC understand that only the low part of "min" will be -;; used. */ -;; return max * (unsigned short) min; -;; else -;; /* Only the low parts of both operands are necessary. */ -;; return ((unsigned short) max) * (unsigned short) min; -;; } -;; #endif /* not __CRIS_arch_version >= 10 */ -;; } -;; #endif /* L_mulsi3 */ -;; -;; That approach was abandoned since the caveats outweighted the -;; benefits. The expand-multiplication machinery is also removed, so you -;; can't do this anymore. -;; -;; For doubters of there being any benefits, some where: insensitivity to: -;; - ABI changes (mostly for experimentation) -;; - assembler syntax differences (mostly debug format). -;; - insn scheduling issues. -;; Most ABI experiments will presumably happen with arches with mul insns, -;; so that argument doesn't really hold anymore, and it's unlikely there -;; being new arch variants needing insn scheduling and not having mul -;; insns. - -;; ELF and a.out have different syntax for local labels: the "wrong" -;; one may not be omitted from the object. -#undef L -#ifdef __AOUT__ -# define L(x) x -#else -# define L(x) .x -#endif - - .global ___Mul - .type ___Mul,@function -___Mul: -#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10 -;; Can't have the mulu.d last on a cache-line (in the delay-slot of the -;; "ret"), due to hardware bug. See documentation for -mmul-bug-workaround. -;; Not worthwhile to conditionalize here. - .p2alignw 2,0x050f - mulu.d $r11,$r10 - ret - nop -#else - move.d $r10,$r12 - move.d $r11,$r9 - bound.d $r12,$r9 - cmpu.w 65535,$r9 - bls L(L3) - move.d $r12,$r13 - - movu.w $r11,$r9 - lslq 16,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - mstep $r9,$r13 - clear.w $r10 - test.d $r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - movu.w $r12,$r12 - move.d $r11,$r9 - clear.w $r9 - test.d $r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - mstep $r12,$r9 - add.w $r9,$r10 - lslq 16,$r10 - ret - add.d $r13,$r10 - -L(L3): - move.d $r9,$r10 - xor $r11,$r10 - xor $r12,$r10 - cmpu.w 65535,$r10 - bls L(L5) - movu.w $r9,$r13 - - movu.w $r13,$r13 - move.d $r10,$r9 - lslq 16,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - mstep $r13,$r9 - clear.w $r10 - test.d $r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - mstep $r13,$r10 - lslq 16,$r10 - ret - add.d $r9,$r10 - -L(L5): - movu.w $r9,$r9 - lslq 16,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - mstep $r9,$r10 - ret - mstep $r9,$r10 -#endif -L(Lfe1): - .size ___Mul,L(Lfe1)-___Mul diff --git a/gcc/config/cris/t-cris b/gcc/config/cris/t-cris index 19d44ce8320..fdaa54e5ce3 100644 --- a/gcc/config/cris/t-cris +++ b/gcc/config/cris/t-cris @@ -25,17 +25,5 @@ # section "Target Fragment" in the gcc info-files (or the paper copy) of # "Using and Porting GCC" -LIB2FUNCS_EXTRA = _udivsi3.c _divsi3.c _umodsi3.c _modsi3.c -CRIS_LIB1CSRC = $(srcdir)/config/cris/arit.c - -# The fixed-point arithmetic code is in one file, arit.c, -# similar to libgcc2.c (or the old libgcc1.c). We need to -# "split it up" with one file per define. -$(LIB2FUNCS_EXTRA): $(CRIS_LIB1CSRC) - name=`echo $@ | sed -e 's,.*/,,' | sed -e 's,.c$$,,'`; \ - echo "#define L$$name" > tmp-$@ \ - && echo '#include "$<"' >> tmp-$@ \ - && mv -f tmp-$@ $@ - $(out_object_file): gt-cris.h gt-cris.h : s-gtype ; @true diff --git a/gcc/config/cris/t-elfmulti b/gcc/config/cris/t-elfmulti index 90eeaaedf44..29ed57dec2f 100644 --- a/gcc/config/cris/t-elfmulti +++ b/gcc/config/cris/t-elfmulti @@ -16,7 +16,6 @@ # along with GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>. -LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/cris/mulsi3.asm MULTILIB_OPTIONS = march=v10/march=v32 MULTILIB_DIRNAMES = v10 v32 MULTILIB_MATCHES = \ @@ -29,6 +28,3 @@ MULTILIB_MATCHES = \ march?v10=mcpu?v10 \ march?v32=mcpu?v32 MULTILIB_EXTRA_OPTS = mbest-lib-options -INSTALL_LIBGCC = install-multilib -LIBGCC = stmp-multilib -CRTSTUFF_T_CFLAGS = -moverride-best-lib-options diff --git a/gcc/config/cris/t-linux b/gcc/config/cris/t-linux index 96e861a4283..71a964936db 100644 --- a/gcc/config/cris/t-linux +++ b/gcc/config/cris/t-linux @@ -1,7 +1,3 @@ -TARGET_LIBGCC2_CFLAGS += -fPIC -CRTSTUFF_T_CFLAGS_S = $(TARGET_LIBGCC2_CFLAGS) -SHLIB_MAPFILES += $(srcdir)/config/cris/libgcc.ver - # We *know* we have a limits.h in the glibc library, with extra # definitions needed for e.g. libgfortran. ifneq ($(inhibit_libc),true) |