summaryrefslogtreecommitdiff
path: root/gcc/config/m32c/m32c.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/m32c/m32c.c')
-rw-r--r--gcc/config/m32c/m32c.c341
1 files changed, 52 insertions, 289 deletions
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index 79b03fa0650..23791788522 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -48,6 +48,7 @@
#include "langhooks.h"
#include "gimple.h"
#include "df.h"
+#include "tm-constrs.h"
/* Prototypes */
@@ -629,94 +630,6 @@ m32c_regno_reg_class (int regno)
}
}
-/* Implements REG_CLASS_FROM_CONSTRAINT. Note that some constraints only match
- for certain chip families. */
-int
-m32c_reg_class_from_constraint (char c ATTRIBUTE_UNUSED, const char *s)
-{
- if (memcmp (s, "Rsp", 3) == 0)
- return SP_REGS;
- if (memcmp (s, "Rfb", 3) == 0)
- return FB_REGS;
- if (memcmp (s, "Rsb", 3) == 0)
- return SB_REGS;
- if (memcmp (s, "Rcr", 3) == 0)
- return TARGET_A16 ? CR_REGS : NO_REGS;
- if (memcmp (s, "Rcl", 3) == 0)
- return TARGET_A24 ? CR_REGS : NO_REGS;
- if (memcmp (s, "R0w", 3) == 0)
- return R0_REGS;
- if (memcmp (s, "R1w", 3) == 0)
- return R1_REGS;
- if (memcmp (s, "R2w", 3) == 0)
- return R2_REGS;
- if (memcmp (s, "R3w", 3) == 0)
- return R3_REGS;
- if (memcmp (s, "R02", 3) == 0)
- return R02_REGS;
- if (memcmp (s, "R13", 3) == 0)
- return R13_REGS;
- if (memcmp (s, "R03", 3) == 0)
- return R03_REGS;
- if (memcmp (s, "Rdi", 3) == 0)
- return DI_REGS;
- if (memcmp (s, "Rhl", 3) == 0)
- return HL_REGS;
- if (memcmp (s, "R23", 3) == 0)
- return R23_REGS;
- if (memcmp (s, "Ra0", 3) == 0)
- return A0_REGS;
- if (memcmp (s, "Ra1", 3) == 0)
- return A1_REGS;
- if (memcmp (s, "Raa", 3) == 0)
- return A_REGS;
- if (memcmp (s, "Raw", 3) == 0)
- return TARGET_A16 ? A_REGS : NO_REGS;
- if (memcmp (s, "Ral", 3) == 0)
- return TARGET_A24 ? A_REGS : NO_REGS;
- if (memcmp (s, "Rqi", 3) == 0)
- return QI_REGS;
- if (memcmp (s, "Rad", 3) == 0)
- return AD_REGS;
- if (memcmp (s, "Rsi", 3) == 0)
- return SI_REGS;
- if (memcmp (s, "Rhi", 3) == 0)
- return HI_REGS;
- if (memcmp (s, "Rhc", 3) == 0)
- return HC_REGS;
- if (memcmp (s, "Rra", 3) == 0)
- return RA_REGS;
- if (memcmp (s, "Rfl", 3) == 0)
- return FLG_REGS;
- if (memcmp (s, "Rmm", 3) == 0)
- {
- if (fixed_regs[MEM0_REGNO])
- return NO_REGS;
- return MEM_REGS;
- }
-
- /* PSImode registers - i.e. whatever can hold a pointer. */
- if (memcmp (s, "Rpi", 3) == 0)
- {
- if (TARGET_A16)
- return HI_REGS;
- else
- return RA_REGS; /* r2r0 and r3r1 can hold pointers. */
- }
-
- /* We handle this one as an EXTRA_CONSTRAINT. */
- if (memcmp (s, "Rpa", 3) == 0)
- return NO_REGS;
-
- if (*s == 'R')
- {
- fprintf(stderr, "unrecognized R constraint: %.3s\n", s);
- gcc_unreachable();
- }
-
- return NO_REGS;
-}
-
/* Implements REGNO_OK_FOR_BASE_P. */
int
m32c_regno_ok_for_base_p (int regno)
@@ -926,141 +839,57 @@ m32c_cannot_change_mode_class (enum machine_mode from,
&& (REGNO (rtx) == AP_REGNO \
|| REGNO (rtx) >= FIRST_PSEUDO_REGISTER))
-/* Implements CONST_OK_FOR_CONSTRAINT_P. Currently, all constant
- constraints start with 'I', with the next two characters indicating
- the type and size of the range allowed. */
-int
-m32c_const_ok_for_constraint_p (HOST_WIDE_INT value,
- char c ATTRIBUTE_UNUSED, const char *str)
-{
- /* s=signed u=unsigned n=nonzero m=minus l=log2able,
- [sun] bits [SUN] bytes, p=pointer size
- I[-0-9][0-9] matches that number */
- if (memcmp (str, "Is3", 3) == 0)
- {
- return (-8 <= value && value <= 7);
- }
- if (memcmp (str, "IS1", 3) == 0)
- {
- return (-128 <= value && value <= 127);
- }
- if (memcmp (str, "IS2", 3) == 0)
- {
- return (-32768 <= value && value <= 32767);
- }
- if (memcmp (str, "IU2", 3) == 0)
- {
- return (0 <= value && value <= 65535);
- }
- if (memcmp (str, "IU3", 3) == 0)
- {
- return (0 <= value && value <= 0x00ffffff);
- }
- if (memcmp (str, "In4", 3) == 0)
- {
- return (-8 <= value && value && value <= 8);
- }
- if (memcmp (str, "In5", 3) == 0)
- {
- return (-16 <= value && value && value <= 16);
- }
- if (memcmp (str, "In6", 3) == 0)
- {
- return (-32 <= value && value && value <= 32);
- }
- if (memcmp (str, "IM2", 3) == 0)
- {
- return (-65536 <= value && value && value <= -1);
- }
- if (memcmp (str, "Ilb", 3) == 0)
- {
- int b = exact_log2 (value);
- return (b >= 0 && b <= 7);
- }
- if (memcmp (str, "Imb", 3) == 0)
- {
- int b = exact_log2 ((value ^ 0xff) & 0xff);
- return (b >= 0 && b <= 7);
- }
- if (memcmp (str, "ImB", 3) == 0)
- {
- int b = exact_log2 ((value ^ 0xffff) & 0xffff);
- return (b >= 0 && b <= 7);
- }
- if (memcmp (str, "Ilw", 3) == 0)
- {
- int b = exact_log2 (value);
- return (b >= 0 && b <= 15);
- }
- if (memcmp (str, "Imw", 3) == 0)
- {
- int b = exact_log2 ((value ^ 0xffff) & 0xffff);
- return (b >= 0 && b <= 15);
- }
- if (memcmp (str, "I00", 3) == 0)
- {
- return (value == 0);
- }
- return 0;
-}
-
#define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER)
/* Implements EXTRA_CONSTRAINT_STR (see next function too). 'S' is
for memory constraints, plus "Rpa" for PARALLEL rtx's we use for
call return values. */
-int
-m32c_extra_constraint_p2 (rtx value, char c ATTRIBUTE_UNUSED, const char *str)
+bool
+m32c_matches_constraint_p (rtx value, int constraint)
{
encode_pattern (value);
- if (far_addr_space_p (value))
- {
- if (memcmp (str, "SF", 2) == 0)
- {
- return ( (RTX_IS ("mr")
- && A0_OR_PSEUDO (patternr[1])
- && GET_MODE (patternr[1]) == SImode)
- || (RTX_IS ("m+^Sri")
- && A0_OR_PSEUDO (patternr[4])
- && GET_MODE (patternr[4]) == HImode)
- || (RTX_IS ("m+^Srs")
- && A0_OR_PSEUDO (patternr[4])
- && GET_MODE (patternr[4]) == HImode)
- || (RTX_IS ("m+^S+ris")
- && A0_OR_PSEUDO (patternr[5])
- && GET_MODE (patternr[5]) == HImode)
- || RTX_IS ("ms")
- );
- }
- return 0;
- }
-
- if (memcmp (str, "Sd", 2) == 0)
+ switch (constraint) {
+ case CONSTRAINT_SF:
+ return (far_addr_space_p (value)
+ && ((RTX_IS ("mr")
+ && A0_OR_PSEUDO (patternr[1])
+ && GET_MODE (patternr[1]) == SImode)
+ || (RTX_IS ("m+^Sri")
+ && A0_OR_PSEUDO (patternr[4])
+ && GET_MODE (patternr[4]) == HImode)
+ || (RTX_IS ("m+^Srs")
+ && A0_OR_PSEUDO (patternr[4])
+ && GET_MODE (patternr[4]) == HImode)
+ || (RTX_IS ("m+^S+ris")
+ && A0_OR_PSEUDO (patternr[5])
+ && GET_MODE (patternr[5]) == HImode)
+ || RTX_IS ("ms")));
+ case CONSTRAINT_Sd:
{
/* This is the common "src/dest" address */
rtx r;
if (GET_CODE (value) == MEM && CONSTANT_P (XEXP (value, 0)))
- return 1;
+ return true;
if (RTX_IS ("ms") || RTX_IS ("m+si"))
- return 1;
+ return true;
if (RTX_IS ("m++rii"))
{
if (REGNO (patternr[3]) == FB_REGNO
&& INTVAL (patternr[4]) == 0)
- return 1;
+ return true;
}
if (RTX_IS ("mr"))
r = patternr[1];
else if (RTX_IS ("m+ri") || RTX_IS ("m+rs") || RTX_IS ("m+r+si"))
r = patternr[2];
else
- return 0;
+ return false;
if (REGNO (r) == SP_REGNO)
- return 0;
+ return false;
return m32c_legitimate_address_p (GET_MODE (value), XEXP (value, 0), 1);
}
- else if (memcmp (str, "Sa", 2) == 0)
+ case CONSTRAINT_Sa:
{
rtx r;
if (RTX_IS ("mr"))
@@ -1068,81 +897,34 @@ m32c_extra_constraint_p2 (rtx value, char c ATTRIBUTE_UNUSED, const char *str)
else if (RTX_IS ("m+ri"))
r = patternr[2];
else
- return 0;
+ return false;
return (IS_REG (r, A0_REGNO) || IS_REG (r, A1_REGNO));
}
- else if (memcmp (str, "Si", 2) == 0)
- {
- return (RTX_IS ("mi") || RTX_IS ("ms") || RTX_IS ("m+si"));
- }
- else if (memcmp (str, "Ss", 2) == 0)
- {
- return ((RTX_IS ("mr")
- && (IS_REG (patternr[1], SP_REGNO)))
- || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SP_REGNO))));
- }
- else if (memcmp (str, "Sf", 2) == 0)
- {
- return ((RTX_IS ("mr")
- && (IS_REG (patternr[1], FB_REGNO)))
- || (RTX_IS ("m+ri") && (IS_REG (patternr[2], FB_REGNO))));
- }
- else if (memcmp (str, "Sb", 2) == 0)
- {
- return ((RTX_IS ("mr")
- && (IS_REG (patternr[1], SB_REGNO)))
- || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SB_REGNO))));
- }
- else if (memcmp (str, "Sp", 2) == 0)
- {
- /* Absolute addresses 0..0x1fff used for bit addressing (I/O ports) */
- return (RTX_IS ("mi")
- && !(INTVAL (patternr[1]) & ~0x1fff));
- }
- else if (memcmp (str, "S1", 2) == 0)
- {
- return r1h_operand (value, QImode);
- }
- else if (memcmp (str, "SF", 2) == 0)
- {
- return 0;
- }
-
- gcc_assert (str[0] != 'S');
-
- if (memcmp (str, "Rpa", 2) == 0)
+ case CONSTRAINT_Si:
+ return (RTX_IS ("mi") || RTX_IS ("ms") || RTX_IS ("m+si"));
+ case CONSTRAINT_Ss:
+ return ((RTX_IS ("mr")
+ && (IS_REG (patternr[1], SP_REGNO)))
+ || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SP_REGNO))));
+ case CONSTRAINT_Sf:
+ return ((RTX_IS ("mr")
+ && (IS_REG (patternr[1], FB_REGNO)))
+ || (RTX_IS ("m+ri") && (IS_REG (patternr[2], FB_REGNO))));
+ case CONSTRAINT_Sb:
+ return ((RTX_IS ("mr")
+ && (IS_REG (patternr[1], SB_REGNO)))
+ || (RTX_IS ("m+ri") && (IS_REG (patternr[2], SB_REGNO))));
+ case CONSTRAINT_Sp:
+ /* Absolute addresses 0..0x1fff used for bit addressing (I/O ports) */
+ return (RTX_IS ("mi")
+ && !(INTVAL (patternr[1]) & ~0x1fff));
+ case CONSTRAINT_S1:
+ return r1h_operand (value, QImode);
+ case CONSTRAINT_Rpa:
return GET_CODE (value) == PARALLEL;
-
- return 0;
-}
-
-/* This is for when we're debugging the above. */
-int
-m32c_extra_constraint_p (rtx value, char c, const char *str)
-{
- int rv = m32c_extra_constraint_p2 (value, c, str);
-#if DEBUG0
- fprintf (stderr, "\nconstraint %.*s: %d\n", CONSTRAINT_LEN (c, str), str,
- rv);
- debug_rtx (value);
-#endif
- return rv;
-}
-
-/* Implements EXTRA_MEMORY_CONSTRAINT. Currently, we only use strings
- starting with 'S'. */
-int
-m32c_extra_memory_constraint (char c, const char *str ATTRIBUTE_UNUSED)
-{
- return c == 'S';
-}
-
-/* Implements EXTRA_ADDRESS_CONSTRAINT. We reserve 'A' strings for these,
- but don't currently define any. */
-int
-m32c_extra_address_constraint (char c, const char *str ATTRIBUTE_UNUSED)
-{
- return c == 'A';
+ default:
+ return false;
+ }
}
/* STACK AND CALLING */
@@ -1857,25 +1639,6 @@ m32c_trampoline_init (rtx m_tramp, tree fndecl, rtx chainval)
#undef A0
}
-/* Implicit Calls to Library Routines */
-
-#undef TARGET_INIT_LIBFUNCS
-#define TARGET_INIT_LIBFUNCS m32c_init_libfuncs
-static void
-m32c_init_libfuncs (void)
-{
- /* We do this because the M32C has an HImode operand, but the
- M16C has an 8-bit operand. Since gcc looks at the match data
- and not the expanded rtl, we have to reset the optab so that
- the right modes are found. */
- if (TARGET_A24)
- {
- set_optab_handler (cstore_optab, QImode, CODE_FOR_cstoreqi4_24);
- set_optab_handler (cstore_optab, HImode, CODE_FOR_cstorehi4_24);
- set_optab_handler (cstore_optab, PSImode, CODE_FOR_cstorepsi4_24);
- }
-}
-
/* Addressing Modes */
/* The r8c/m32c family supports a wide range of non-orthogonal
@@ -3686,7 +3449,7 @@ m32c_split_move (rtx * operands, enum machine_mode mode, int split_all)
point, so it's safe to set it to 3 even with define_insn. */
/* None of the chips can move SI operands to sp-relative addresses,
so we always split those. */
- if (m32c_extra_constraint_p (operands[0], 'S', "Ss"))
+ if (satisfies_constraint_Ss (operands[0]))
split_all = 3;
if (TARGET_A16