static void cris_operand_lossage (const char *, rtx);
-static int cris_reg_saved_in_regsave_area (unsigned int, bool);
+static int cris_reg_saved_in_regsave_area (unsigned int);
static void cris_print_operand (FILE *, rtx, int);
static bool cris_print_operand_punct_valid_p (unsigned char code);
-static bool cris_output_addr_const_extra (FILE *, rtx);
-
static void cris_conditional_register_usage (void);
static void cris_asm_output_mi_thunk
static rtx_insn *cris_md_asm_adjust (vec<rtx> &, vec<rtx> &,
vec<const char *> &,
vec<rtx> &, HARD_REG_SET &);
-static bool cris_cannot_force_const_mem (machine_mode, rtx);
static void cris_option_override (void);
static rtx cris_function_value(const_tree, const_tree, bool);
static rtx cris_libcall_value (machine_mode, const_rtx);
static bool cris_function_value_regno_p (const unsigned int);
-static void cris_file_end (void);
static unsigned int cris_hard_regno_nregs (unsigned int, machine_mode);
static bool cris_hard_regno_mode_ok (unsigned int, machine_mode);
static HOST_WIDE_INT cris_static_rtx_alignment (machine_mode);
#define TARGET_PRINT_OPERAND_ADDRESS cris_print_operand_address
#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P cris_print_operand_punct_valid_p
-#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
-#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA cris_output_addr_const_extra
#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE cris_conditional_register_usage
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START cris_file_start
-#undef TARGET_ASM_FILE_END
-#define TARGET_ASM_FILE_END cris_file_end
#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_LEGITIMATE_CONSTANT_P
-#define TARGET_LEGITIMATE_CONSTANT_P cris_legitimate_constant_p
-
#undef TARGET_PREFERRED_RELOAD_CLASS
#define TARGET_PREFERRED_RELOAD_CLASS cris_preferred_reload_class
#undef TARGET_MD_ASM_ADJUST
#define TARGET_MD_ASM_ADJUST cris_md_asm_adjust
-#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM cris_cannot_force_const_mem
-
#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required
else
i = offs + 1;
- if (!TARGET_V32)
- {
- regno_dir = -1;
- regno = reg_count - 1;
- }
+ regno_dir = -1;
+ regno = reg_count - 1;
elt = XVECEXP (op, 0, offs);
src_addr = XEXP (SET_SRC (elt), 0);
else
i = 1;
- if (!TARGET_V32)
- {
- regno_dir = -1;
- regno = reg_count - 1;
- }
+ regno_dir = -1;
+ regno = reg_count - 1;
if (GET_CODE (elt) != SET
|| !REG_P (SET_SRC (elt))
static void
cris_conditional_register_usage (void)
{
- /* FIXME: This isn't nice. We should be able to use that register for
- something else if the PIC table isn't needed. */
- if (flag_pic)
- fixed_regs[PIC_OFFSET_TABLE_REGNUM]
- = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
-
- /* Allow use of ACR (PC in pre-V32) and tweak order. */
- if (TARGET_V32)
- {
- static const int reg_alloc_order_v32[] = REG_ALLOC_ORDER_V32;
- unsigned int i;
-
- fixed_regs[CRIS_ACR_REGNUM] = 0;
-
- for (i = 0;
- i < sizeof (reg_alloc_order_v32)/sizeof (reg_alloc_order_v32[0]);
- i++)
- reg_alloc_order[i] = reg_alloc_order_v32[i];
- }
-
if (TARGET_HAS_MUL_INSNS)
fixed_regs[CRIS_MOF_REGNUM] = 0;
reg_names[CRIS_CC0_REGNUM] = "ccr";
}
-/* Return crtl->uses_pic_offset_table. For use in cris.md,
- since some generated files do not include function.h. */
-
-int
-cris_cfun_uses_pic_table (void)
-{
- return crtl->uses_pic_offset_table;
-}
-
-/* Worker function for TARGET_CANNOT_FORCE_CONST_MEM.
- We can't put PIC addresses in the constant pool, not even the ones that
- can be reached as pc-relative as we can't tell when or how to do that. */
-
-static bool
-cris_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
-{
- enum cris_symbol_type t = cris_symbol_type_of (x);
-
- return
- t == cris_unspec
- || t == cris_got_symbol
- || t == cris_rel_symbol;
-}
-
/* Given an rtx, return the text string corresponding to the CODE of X.
Intended for use in the assembly language output section of a
define_insn. */
if (REG_P (index))
fprintf (file, "$%s.b", reg_names[REGNO (index)]);
- else if (CRIS_CONSTANT_P (index))
+ else if (CONSTANT_P (index))
cris_output_addr_const (file, index);
else if (GET_CODE (index) == MULT)
{
if (REG_P (base))
fprintf (file, "$%s", reg_names[REGNO (base)]);
else if (GET_CODE (base) == POST_INC)
- {
- gcc_assert (REGNO (XEXP (base, 0)) != CRIS_ACR_REGNUM);
- fprintf (file, "$%s+", reg_names[REGNO (XEXP (base, 0))]);
- }
+ fprintf (file, "$%s+", reg_names[REGNO (XEXP (base, 0))]);
else
cris_operand_lossage ("unexpected base-type in cris_print_base",
base);
wrapper for a complicated conditional. */
static int
-cris_reg_saved_in_regsave_area (unsigned int regno, bool got_really_used)
+cris_reg_saved_in_regsave_area (unsigned int regno)
{
return
(((df_regs_ever_live_p (regno)
- && !call_used_or_fixed_reg_p (regno))
- || (regno == PIC_OFFSET_TABLE_REGNUM
- && (got_really_used
- /* It is saved anyway, if there would be a gap. */
- || (flag_pic
- && df_regs_ever_live_p (regno + 1)
- && !call_used_or_fixed_reg_p (regno + 1)))))
+ && !call_used_or_fixed_reg_p (regno)))
&& (regno != FRAME_POINTER_REGNUM || !frame_pointer_needed)
&& regno != CRIS_SRP_REGNUM)
|| (crtl->calls_eh_return
putc (INTVAL (x) >= -128 && INTVAL (x) <= 255 ? 'b' : 'w', file);
return;
- case 'Z':
- /* If this is a GOT-symbol, print the size-letter corresponding to
- -fpic/-fPIC. For everything else, print "d". */
- putc ((flag_pic == 1
- && GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == UNSPEC
- && XINT (XEXP (x, 0), 1) == CRIS_UNSPEC_GOTREAD)
- ? 'w' : 'd', file);
- return;
-
case '#':
/* Output a 'nop' if there's nothing for the delay slot.
This method stolen from the sparc files. */
: ".p2alignw 5,0x050f,2\n\t", file);
return;
- case ':':
- /* The PIC register. */
- if (! flag_pic)
- internal_error ("invalid use of %<:%> modifier");
- fprintf (file, "$%s", reg_names [PIC_OFFSET_TABLE_REGNUM]);
- return;
-
case 'H':
/* Print high (most significant) part of something. */
switch (GET_CODE (operand))
fprintf (file, ".d");
return;
- case 'd':
- /* If this is a GOT symbol, force it to be emitted as :GOT and
- :GOTPLT regardless of -fpic (i.e. not as :GOT16, :GOTPLT16).
- Avoid making this too much of a special case. */
- if (flag_pic == 1 && CRIS_CONSTANT_P (operand))
- {
- int flag_pic_save = flag_pic;
-
- flag_pic = 2;
- cris_output_addr_const (file, operand);
- flag_pic = flag_pic_save;
- return;
- }
- break;
-
case 'D':
/* When emitting an sub for the high part of a DImode constant, we
want to use subq for 0 and subs.w for -1. */
fprintf (file, "%s", mults[INTVAL (operand)]);
return;
- case 'u':
- /* Print "u.w" if a GOT symbol and flag_pic == 1, else ".d". */
- if (flag_pic == 1
- && GET_CODE (operand) == CONST
- && GET_CODE (XEXP (operand, 0)) == UNSPEC
- && XINT (XEXP (operand, 0), 1) == CRIS_UNSPEC_GOTREAD)
- fprintf (file, "u.w");
- else
- fprintf (file, ".d");
- return;
-
case 0:
/* No code, print as usual. */
break;
}
return;
- case UNSPEC:
- /* Fall through. */
case CONST:
cris_output_addr_const (file, operand);
return;
default:
/* No need to handle all strange variants, let output_addr_const
do it for us. */
- if (CRIS_CONSTANT_P (operand))
+ if (CONSTANT_P (operand))
{
cris_output_addr_const (file, operand);
return;
static bool
cris_print_operand_punct_valid_p (unsigned char code)
{
- return (code == '#' || code == '!' || code == ':');
+ return (code == '#' || code == '!');
}
/* The PRINT_OPERAND_ADDRESS worker. */
/* Initial offset is 0 if we don't have a frame pointer. */
int offs = 0;
- bool got_really_used = false;
-
- if (crtl->uses_pic_offset_table)
- {
- push_topmost_sequence ();
- got_really_used
- = reg_used_between_p (pic_offset_table_rtx, get_insns (),
- NULL);
- pop_topmost_sequence ();
- }
/* And 4 for each register pushed. */
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (cris_reg_saved_in_regsave_area (regno, got_really_used))
+ if (cris_reg_saved_in_regsave_area (regno))
offs += 4;
/* And then, last, we add the locals allocated. */
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 (CRIS_CONSTANT_P (x) && (!flag_pic || cris_valid_pic_const (x, true)));
-}
-
/* True if X is a valid base register. */
bool
{
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));
+ && cris_base_p (XEXP (x, 0), strict)));
}
/* True if X is a valid (register) index for BDAP, i.e. [Rs].S or [Rs+].S. */
&& 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. */
+/* Worker function for TARGET_LEGITIMATE_ADDRESS_P. */
bool
cris_legitimate_address_p (machine_mode mode, rtx x, bool strict)
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))
+ else if (CONSTANT_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))
+ if ((cris_base_p (x1, strict) && CONSTANT_P (x2))
+ || (cris_base_p (x2, strict) && CONSTANT_P (x1))
/* BDAP Rs[+], Rd. */
|| (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
&& ((cris_base_p (x1, strict)
return false;
}
-/* Worker function for TARGET_LEGITIMATE_CONSTANT_P. We have to handle
- PIC constants that aren't legitimized. FIXME: there used to be a
- guarantee that the target LEGITIMATE_CONSTANT_P didn't have to handle
- PIC constants, but no more (4.7 era); testcase: glibc init-first.c.
- While that may be seen as a bug, that guarantee seems a wart by design,
- so don't bother; fix the documentation instead. */
-
-bool
-cris_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
-{
- enum cris_symbol_type t;
-
- if (flag_pic)
- return LEGITIMATE_PIC_OPERAND_P (x);
-
- t = cris_symbol_type_of (x);
-
- return
- t == cris_no_symbol
- || t == cris_offsettable_symbol
- || t == cris_unspec;
-}
-
/* Worker function for LEGITIMIZE_RELOAD_ADDRESS. */
bool
if (GET_CODE (x) != PLUS)
return false;
- if (TARGET_V32)
- return false;
-
op0 = XEXP (x, 0);
op1 = XEXP (x, 1);
op1p = &XEXP (x, 1);
(set (reg) (...)):
CC is (reg) and (...) - unless (...) is 0 or reg is a special
- register or (v32 and (...) is -32..-1), then CC does not change.
+ register, then CC does not change.
CC_NO_OVERFLOW unless (...) is reg or mem.
(set (mem) (...)):
else if (SET_SRC (exp) == const0_rtx
|| (REG_P (SET_SRC (exp))
&& (REGNO (SET_SRC (exp))
- > CRIS_LAST_GENERAL_REGISTER))
- || (TARGET_V32
- && REG_P (SET_DEST (exp))
- && satisfies_constraint_I (SET_SRC (exp))))
+ > CRIS_LAST_GENERAL_REGISTER)))
{
/* There's no CC0 change for this case. Just check
for overlap. */
|| GET_CODE (SET_SRC (exp)) == NEG)
cc_status.flags |= CC_NO_OVERFLOW;
- /* For V32, nothing with a register destination sets
- C and V usefully. */
- if (TARGET_V32)
- cc_status.flags |= CC_NO_OVERFLOW;
-
return;
}
}
if (cris_reg_overlap_mentioned_p (cc_status.value1,
cc_status.value2))
internal_error ("internal error: sideeffect-insn affecting main effect");
-
- /* For V32, moves to registers don't set C and V. */
- if (TARGET_V32)
- cc_status.flags |= CC_NO_OVERFLOW;
return;
}
else if ((REG_P (XEXP (XVECEXP (exp, 0, 0), 1))
return;
case CC_REV:
- case CC_NOOV32:
case CC_NORMAL:
cris_normal_notice_update_cc (exp, insn);
-
- /* The "test" insn doesn't clear (carry and) overflow on V32. We
- can change bge => bpl and blt => bmi by passing on to the cc0
- user that V should not be considered; bgt and ble are taken
- care of by other methods (see {tst,cmp}{si,hi,qi}). */
- if (attrval == CC_NOOV32 && TARGET_V32)
- cc_status.flags |= CC_NO_OVERFLOW;
return;
default:
{
unsigned int regno;
unsigned int reglimit = STACK_POINTER_REGNUM;
- bool got_really_used = false;
if (! reload_completed
|| frame_pointer_needed
|| !TARGET_PROLOGUE_EPILOGUE)
return false;
- /* Can't return from stacked return address with v32. */
- if (TARGET_V32 && cris_return_address_on_stack ())
- return false;
-
- if (crtl->uses_pic_offset_table)
- {
- push_topmost_sequence ();
- got_really_used
- = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL);
- pop_topmost_sequence ();
- }
-
/* No simple epilogue if there are saved registers. */
for (regno = 0; regno < reglimit; regno++)
- if (cris_reg_saved_in_regsave_area (regno, got_really_used))
+ if (cris_reg_saved_in_regsave_area (regno))
return false;
return true;
return (2 + 2) / 2;
/* A BDAP with some other constant is 2 bytes extra. */
- if (CRIS_CONSTANT_P (tem2))
+ if (CONSTANT_P (tem2))
return (2 + 2 + 2) / 2;
/* BDAP with something indirect should have a higher cost than
return 0;
/* Check allowed cases, like [r(+)?].[bwd] and const. */
- if (CRIS_CONSTANT_P (val_rtx))
+ if (CONSTANT_P (val_rtx))
return 1;
if (MEM_P (val_rtx)
internal_error ("internal error: cris_side_effect_mode_ok with bad operands");
}
-/* Whether next_cc0_user of insn is LE or GT or requires a real compare
- insn for other reasons. */
-
-bool
-cris_cc0_user_requires_cmp (rtx_insn *insn)
-{
- rtx_insn *cc0_user = NULL;
- rtx body;
- rtx set;
-
- gcc_assert (insn != NULL);
-
- if (!TARGET_V32)
- return false;
-
- cc0_user = next_cc0_user (insn);
- if (cc0_user == NULL)
- return false;
-
- body = PATTERN (cc0_user);
- set = single_set (cc0_user);
-
- /* Users can be sCC and bCC. */
- if (JUMP_P (cc0_user)
- && GET_CODE (body) == SET
- && SET_DEST (body) == pc_rtx
- && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
- && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx)
- {
- return
- GET_CODE (XEXP (SET_SRC (body), 0)) == GT
- || GET_CODE (XEXP (SET_SRC (body), 0)) == LE;
- }
- else if (set)
- {
- return
- GET_CODE (SET_SRC (body)) == GT
- || GET_CODE (SET_SRC (body)) == LE;
- }
-
- gcc_unreachable ();
-}
-
/* The function reg_overlap_mentioned_p in CVS (still as of 2001-05-16)
does not handle the case where the IN operand is strict_low_part; it
does handle it for X. Test-case in Axis-20010516. This function takes
return reg_overlap_mentioned_p (x, in);
}
-/* Return TRUE iff X is a CONST valid for e.g. indexing.
- ANY_OPERAND is 0 if X is in a CALL_P insn or movsi, 1
- elsewhere. */
-
-bool
-cris_valid_pic_const (const_rtx x, bool any_operand)
-{
- gcc_assert (flag_pic);
-
- switch (GET_CODE (x))
- {
- case CONST_INT:
- case CONST_DOUBLE:
- return true;
- default:
- ;
- }
-
- if (GET_CODE (x) != CONST)
- return false;
-
- x = XEXP (x, 0);
-
- /* Handle (const (plus (unspec .. UNSPEC_GOTREL) (const_int ...))). */
- if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 0)) == UNSPEC
- && (XINT (XEXP (x, 0), 1) == CRIS_UNSPEC_GOTREL
- || XINT (XEXP (x, 0), 1) == CRIS_UNSPEC_PCREL)
- && CONST_INT_P (XEXP (x, 1)))
- x = XEXP (x, 0);
-
- if (GET_CODE (x) == UNSPEC)
- switch (XINT (x, 1))
- {
- /* A PCREL operand is only valid for call and movsi. */
- case CRIS_UNSPEC_PLT_PCREL:
- case CRIS_UNSPEC_PCREL:
- return !any_operand;
-
- case CRIS_UNSPEC_PLT_GOTREL:
- case CRIS_UNSPEC_PLTGOTREAD:
- case CRIS_UNSPEC_GOTREAD:
- case CRIS_UNSPEC_GOTREL:
- return true;
- default:
- gcc_unreachable ();
- }
-
- return cris_symbol_type_of (x) == cris_no_symbol;
-}
-
-/* Helper function to find the right symbol-type to generate,
- given the original (non-PIC) representation. */
-
-enum cris_symbol_type
-cris_symbol_type_of (const_rtx x)
-{
- switch (GET_CODE (x))
- {
- case SYMBOL_REF:
- return flag_pic
- ? (SYMBOL_REF_LOCAL_P (x)
- ? cris_rel_symbol : cris_got_symbol)
- : cris_offsettable_symbol;
-
- case LABEL_REF:
- return flag_pic ? cris_rel_symbol : cris_offsettable_symbol;
-
- case CONST:
- return cris_symbol_type_of (XEXP (x, 0));
-
- case PLUS:
- case MINUS:
- {
- enum cris_symbol_type t1 = cris_symbol_type_of (XEXP (x, 0));
- enum cris_symbol_type t2 = cris_symbol_type_of (XEXP (x, 1));
-
- gcc_assert (t1 == cris_no_symbol || t2 == cris_no_symbol);
-
- if (t1 == cris_got_symbol || t2 == cris_got_symbol)
- return cris_got_symbol_needing_fixup;
-
- return t1 != cris_no_symbol ? t1 : t2;
- }
-
- case CONST_INT:
- case CONST_DOUBLE:
- return cris_no_symbol;
-
- case UNSPEC:
- return cris_unspec;
-
- default:
- fatal_insn ("unrecognized supposed constant", x);
- }
-
- gcc_unreachable ();
-}
-
-/* The LEGITIMATE_PIC_OPERAND_P worker. */
-
-int
-cris_legitimate_pic_operand (rtx x)
-{
- /* Symbols are not valid PIC operands as-is; just constants. */
- return cris_valid_pic_const (x, true);
-}
-
/* Queue an .ident string in the queue of top-level asm statements.
If the front-end is done, we must be being called from toplev.c.
In that case, do nothing. */
assert that we find only what's expected. */
rtx_insn *whole_jump_insn = prev_nonnote_nondebug_insn (table);
gcc_assert (whole_jump_insn != NULL_RTX && LABEL_P (whole_jump_insn));
+
whole_jump_insn = prev_nonnote_nondebug_insn (whole_jump_insn);
- gcc_assert (whole_jump_insn != NULL_RTX
- && (JUMP_P (whole_jump_insn)
- || (TARGET_V32 && INSN_P (whole_jump_insn)
- && GET_CODE (PATTERN (whole_jump_insn)) == SEQUENCE)));
+ gcc_assert (whole_jump_insn != NULL_RTX && JUMP_P (whole_jump_insn));
+
/* Get the pattern of the casejump, so we can extract the default label. */
rtx whole_jump_pat = PATTERN (whole_jump_insn);
- if (TARGET_V32)
- {
- /* This can be a SEQUENCE, meaning the delay-slot of the jump is
- filled. We also output the offset word a little differently. */
- rtx parallel_jump
- = (GET_CODE (whole_jump_pat) == SEQUENCE
- ? PATTERN (XVECEXP (whole_jump_pat, 0, 0)) : whole_jump_pat);
-
- asm_fprintf (stream,
- "\t.word %LL%d-.%s\n",
- CODE_LABEL_NUMBER (XEXP (XEXP (XEXP (XVECEXP
- (parallel_jump, 0, 0),
- 1), 2), 0)),
- (TARGET_PDEBUG ? "; default" : ""));
- return;
- }
-
asm_fprintf (stream,
"\t.word %LL%d-%LL%d%s\n",
CODE_LABEL_NUMBER (XEXP
|| strcmp ("etrax100lx", cris_cpu_str) == 0)
cris_cpu_version = 10;
- if (cris_cpu_version < 0 || cris_cpu_version > 32)
+ if (cris_cpu_version < 0 || cris_cpu_version > 10)
error ("unknown CRIS version specification in %<-march=%> or "
"%<-mcpu=%> : %s", cris_cpu_str);
| MASK_DATA_ALIGN | MASK_ALIGN_BY_32);
}
- if (cris_cpu_version >= CRIS_CPU_V32)
- target_flags &= ~(MASK_SIDE_EFFECT_PREFIXES|MASK_MUL_BUG);
-
if (flag_pic)
{
/* Use error rather than warning, so invalid use is easily
detectable. Still change to the values we expect, to avoid
further errors. */
- if (! TARGET_LINUX)
- {
- error ("%<-fPIC%> and %<-fpic%> are not supported "
- "in this configuration");
- flag_pic = 0;
- }
-
- /* Turn off function CSE. We need to have the addresses reach the
- call expanders to get PLT-marked, as they could otherwise be
- compared against zero directly or indirectly. After visiting the
- call expanders they will then be cse:ed, as the call expanders
- force_reg the addresses, effectively forcing flag_no_function_cse
- to 0. */
- flag_no_function_cse = 1;
+ error ("%<-fPIC%> and %<-fpic%> are not supported on this target");
+ flag_pic = 0;
}
/* Set the per-function-data initializer. */
ADDITIVE_SIZE_MODIFIER (-delta), -delta,
reg_names[CRIS_FIRST_ARG_REG]);
- if (flag_pic)
- {
- const char *name = XSTR (XEXP (DECL_RTL (funcdecl), 0), 0);
-
- name = (* targetm.strip_name_encoding) (name);
-
- if (TARGET_V32)
- {
- fprintf (stream, "\tba ");
- assemble_name (stream, name);
- fprintf (stream, "%s\n\tnop\n", CRIS_PLT_PCOFFSET_SUFFIX);
- }
- else
- {
- fprintf (stream, "\tadd.d ");
- assemble_name (stream, name);
- fprintf (stream, "%s,$pc\n", CRIS_PLT_PCOFFSET_SUFFIX);
- }
- }
- else
- {
- fprintf (stream, "\tjump ");
- assemble_name (stream, XSTR (XEXP (DECL_RTL (funcdecl), 0), 0));
- fprintf (stream, "\n");
-
- if (TARGET_V32)
- fprintf (stream, "\tnop\n");
- }
+ fprintf (stream, "\tjump ");
+ assemble_name (stream, XSTR (XEXP (DECL_RTL (funcdecl), 0), 0));
+ fprintf (stream, "\n");
final_end_function ();
assemble_end_function (thunkdecl, fnname);
default_file_start ();
}
-/* Output that goes at the end of the file, similarly. */
-
-static void
-cris_file_end (void)
-{
- /* For CRIS, the default is to assume *no* executable stack, so output
- an executable-stack-note only when needed. */
- if (TARGET_LINUX && trampolines_created)
- file_end_indicate_exec_stack ();
-}
-
/* Rename the function calls for integer multiply and divide. */
static void
cris_init_libfuncs (void)
int framesize = 0;
rtx mem, insn;
int return_address_on_stack = cris_return_address_on_stack ();
- int got_really_used = false;
int n_movem_regs = 0;
int pretend = crtl->args.pretend_args_size;
CRIS_ASSERT (size >= 0);
- if (crtl->uses_pic_offset_table)
- {
- /* A reference may have been optimized out (like the abort () in
- fde_split in unwind-dw2-fde.c, at least 3.2.1) so check that
- it's still used. */
- push_topmost_sequence ();
- got_really_used
- = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL);
- pop_topmost_sequence ();
- }
-
/* Align the size to what's best for the CPU model. */
if (TARGET_STACK_ALIGN)
size = TARGET_ALIGN_BY_32 ? (size + 3) & ~3 : (size + 1) & ~1;
to be saved. */
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
{
- if (cris_reg_saved_in_regsave_area (regno, got_really_used))
+ if (cris_reg_saved_in_regsave_area (regno))
{
n_movem_regs++;
framesize += size + cfoa_size;
}
- /* Set up the PIC register, if it is used. */
- if (got_really_used)
- {
- rtx got
- = gen_rtx_UNSPEC (SImode, gen_rtvec (1, const0_rtx), CRIS_UNSPEC_GOT);
- emit_move_insn (pic_offset_table_rtx, got);
-
- /* FIXME: This is a cover-up for flow2 messing up; it doesn't
- follow exceptional paths and tries to delete the GOT load as
- unused, if it isn't used on the non-exceptional paths. Other
- ports have similar or other cover-ups, or plain bugs marking
- the GOT register load as maybe-dead. To see this, remove the
- line below and try libsupc++/vec.cc or a trivial
- "static void y (); void x () {try {y ();} catch (...) {}}". */
- emit_use (pic_offset_table_rtx);
- }
-
if (cris_max_stackframe && framesize > cris_max_stackframe)
warning (0, "stackframe too big: %d bytes", framesize);
}
/* A reference may have been optimized out
(like the abort () in fde_split in unwind-dw2-fde.c, at least 3.2.1)
so check that it's still used. */
- int got_really_used = false;
int n_movem_regs = 0;
if (!TARGET_PROLOGUE_EPILOGUE)
return;
- if (crtl->uses_pic_offset_table)
- {
- /* A reference may have been optimized out (like the abort () in
- fde_split in unwind-dw2-fde.c, at least 3.2.1) so check that
- it's still used. */
- push_topmost_sequence ();
- got_really_used
- = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL);
- pop_topmost_sequence ();
- }
-
/* Align byte count of stack frame. */
if (TARGET_STACK_ALIGN)
size = TARGET_ALIGN_BY_32 ? (size + 3) & ~3 : (size + 1) & ~1;
for (regno = 0;
regno < FIRST_PSEUDO_REGISTER;
regno++)
- if (cris_reg_saved_in_regsave_area (regno, got_really_used))
+ if (cris_reg_saved_in_regsave_area (regno))
{
n_movem_regs++;
for (regno = FIRST_PSEUDO_REGISTER - 1;
regno > last_movem_reg;
regno--)
- if (cris_reg_saved_in_regsave_area (regno, got_really_used))
+ if (cris_reg_saved_in_regsave_area (regno))
{
rtx insn;
the return address on the stack. */
if (return_address_on_stack && pretend == 0)
{
- if (TARGET_V32 || crtl->calls_eh_return)
+ if (crtl->calls_eh_return)
{
rtx mem;
rtx insn;
unsigned int regno = nregs - 1;
int regno_inc = -1;
- if (TARGET_V32)
- {
- regno = 0;
- regno_inc = 1;
- }
-
if (GET_CODE (srcreg) == POST_INC)
srcreg = XEXP (srcreg, 0);
CRIS_ASSERT (REG_P (srcreg));
- /* Don't use movem for just one insn. The insns are equivalent except
- for the pipeline hazard (on v32); movem does not forward the loaded
- registers so there's a three cycles penalty for their use. */
+ /* Don't use movem for just one insn. The insns are equivalent. */
if (nregs == 1)
return gen_movsi (gen_rtx_REG (SImode, 0), src);
unsigned int regno = nregs - 1;
int regno_inc = -1;
- if (TARGET_V32)
- {
- regno = 0;
- regno_inc = 1;
- }
-
if (GET_CODE (destreg) == POST_INC)
increment += nregs * 4;
CRIS_ASSERT (REG_P (destreg));
- /* Don't use movem for just one insn. The insns are equivalent except
- for the pipeline hazard (on v32); movem does not forward the loaded
- registers so there's a three cycles penalty for use. */
+ /* Don't use movem for just one insn. The insns are equivalent. */
if (nregs == 1)
{
rtx mov = gen_rtx_SET (dest, gen_rtx_REG (SImode, 0));
return insn;
}
-/* Worker function for expanding the address for PIC function calls. */
-
-void
-cris_expand_pic_call_address (rtx *opp, rtx *markerp)
-{
- rtx op = *opp;
-
- gcc_assert (flag_pic && MEM_P (op));
- op = XEXP (op, 0);
-
- /* It might be that code can be generated that jumps to 0 (or to a
- specific address). Don't die on that. (There is a
- testcase.) */
- if (CONSTANT_P (op) && !CONST_INT_P (op))
- {
- enum cris_symbol_type t = cris_symbol_type_of (op);
-
- CRIS_ASSERT (can_create_pseudo_p ());
-
- /* For local symbols (non-PLT), just get the plain symbol
- reference into a register. For symbols that can be PLT, make
- them PLT. */
- if (t == cris_rel_symbol)
- {
- /* For v32, we're fine as-is; just PICify the symbol. Forcing
- into a register caused performance regression for 3.2.1,
- observable in __floatdidf and elsewhere in libgcc. */
- if (TARGET_V32)
- {
- rtx sym = GET_CODE (op) != CONST ? op : get_related_value (op);
- HOST_WIDE_INT offs = get_integer_term (op);
-
- /* We can't get calls to sym+N, N integer, can we? */
- gcc_assert (offs == 0);
-
- op = gen_rtx_CONST (Pmode,
- gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym),
- CRIS_UNSPEC_PCREL));
- }
- else
- op = force_reg (Pmode, op);
-
- /* A local call. */
- *markerp = const0_rtx;
- }
- else if (t == cris_got_symbol)
- {
- if (TARGET_AVOID_GOTPLT)
- {
- /* Change a "jsr sym" into (allocate register rM, rO)
- "move.d (const (unspec [sym] CRIS_UNSPEC_PLT_GOTREL)),rM"
- "add.d rPIC,rM,rO", "jsr rO" for pre-v32 and
- "jsr (const (unspec [sym] CRIS_UNSPEC_PLT_PCREL))"
- for v32. */
- rtx tem, rm, ro;
-
- crtl->uses_pic_offset_table = 1;
- tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op),
- TARGET_V32
- ? CRIS_UNSPEC_PLT_PCREL
- : CRIS_UNSPEC_PLT_GOTREL);
- tem = gen_rtx_CONST (Pmode, tem);
- if (TARGET_V32)
- op = tem;
- else
- {
- rm = gen_reg_rtx (Pmode);
- emit_move_insn (rm, tem);
- ro = gen_reg_rtx (Pmode);
- if (expand_binop (Pmode, add_optab, rm,
- pic_offset_table_rtx,
- ro, 0, OPTAB_LIB_WIDEN) != ro)
- internal_error ("expand_binop failed in movsi got");
- op = ro;
- }
- }
- else
- {
- /* Change a "jsr sym" into (allocate register rM, rO)
- "move.d (const (unspec [sym] CRIS_UNSPEC_PLTGOTREAD)),rM"
- "add.d rPIC,rM,rO" "jsr [rO]" with the memory access
- marked as not trapping and not aliasing. No "move.d
- [rO],rP" as that would invite to re-use of a value
- that should not be reused. FIXME: Need a peephole2
- for cases when this is cse:d from the call, to change
- back to just get the PLT entry address, so we don't
- resolve the same symbol over and over (the memory
- access of the PLTGOT isn't constant). */
- rtx tem, mem, rm, ro;
-
- gcc_assert (can_create_pseudo_p ());
- crtl->uses_pic_offset_table = 1;
- tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op),
- CRIS_UNSPEC_PLTGOTREAD);
- rm = gen_reg_rtx (Pmode);
- emit_move_insn (rm, gen_rtx_CONST (Pmode, tem));
- ro = gen_reg_rtx (Pmode);
- if (expand_binop (Pmode, add_optab, rm,
- pic_offset_table_rtx,
- ro, 0, OPTAB_LIB_WIDEN) != ro)
- internal_error ("expand_binop failed in movsi got");
- mem = gen_rtx_MEM (Pmode, ro);
-
- /* This MEM doesn't alias anything. Whether it aliases
- other same symbols is unimportant. */
- set_mem_alias_set (mem, new_alias_set ());
- MEM_NOTRAP_P (mem) = 1;
- op = mem;
- }
-
- /* We need to prepare this call to go through the PLT; we
- need to make GOT available. */
- *markerp = pic_offset_table_rtx;
- }
- else
- /* Can't possibly get anything else for a function-call, right? */
- fatal_insn ("unidentifiable call op", op);
-
- /* If the validizing variant is called, it will try to validize
- the address as a valid any-operand constant, but as it's only
- valid for calls and moves, it will fail and always be forced
- into a register. */
- *opp = replace_equiv_address_nv (*opp, op);
- }
- else
- /* Can't tell what locality a call to a non-constant address has;
- better make the GOT register alive at it.
- FIXME: Can we see whether the register has known constant
- contents? */
- *markerp = pic_offset_table_rtx;
-}
-
/* Make sure operands are in the right order for an addsi3 insn as
generated by a define_split. Nothing but REG_P as the first
operand is recognized by addsi3 after reload. OPERANDS contains
cris_asm_output_symbol_ref (FILE *file, rtx x)
{
gcc_assert (GET_CODE (x) == SYMBOL_REF);
-
- if (flag_pic && in_code > 0)
- {
- const char *origstr = XSTR (x, 0);
- const char *str;
- str = (* targetm.strip_name_encoding) (origstr);
- assemble_name (file, str);
-
- /* Sanity check. */
- if (!TARGET_V32 && !crtl->uses_pic_offset_table)
- output_operand_lossage ("PIC register isn't set up");
- }
- else
- assemble_name (file, XSTR (x, 0));
+ assemble_name (file, XSTR (x, 0));
}
/* Worker function for ASM_OUTPUT_LABEL_REF. */
void
cris_asm_output_label_ref (FILE *file, char *buf)
{
- if (flag_pic && in_code > 0)
- {
- assemble_name (file, buf);
-
- /* Sanity check. */
- if (!TARGET_V32 && !crtl->uses_pic_offset_table)
- internal_error ("emitting PIC operand, but PIC register "
- "isn%'t set up");
- }
- else
- assemble_name (file, buf);
-}
-
-/* Worker function for TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
-
-static bool
-cris_output_addr_const_extra (FILE *file, rtx xconst)
-{
- switch (GET_CODE (xconst))
- {
- rtx x;
-
- case UNSPEC:
- x = XVECEXP (xconst, 0, 0);
- CRIS_ASSERT (GET_CODE (x) == SYMBOL_REF
- || GET_CODE (x) == LABEL_REF
- || GET_CODE (x) == CONST);
- output_addr_const (file, x);
- switch (XINT (xconst, 1))
- {
- case CRIS_UNSPEC_PCREL:
- /* We only get this with -fpic/PIC to tell it apart from an
- invalid symbol. We can't tell here, but it should only
- be the operand of a call or movsi. */
- gcc_assert (TARGET_V32 && flag_pic);
- break;
-
- case CRIS_UNSPEC_PLT_PCREL:
- gcc_assert (TARGET_V32);
- fprintf (file, ":PLT");
- break;
-
- case CRIS_UNSPEC_PLT_GOTREL:
- gcc_assert (!TARGET_V32);
- fprintf (file, ":PLTG");
- break;
-
- case CRIS_UNSPEC_GOTREL:
- gcc_assert (!TARGET_V32);
- fprintf (file, ":GOTOFF");
- break;
-
- case CRIS_UNSPEC_GOTREAD:
- if (flag_pic == 1)
- fprintf (file, ":GOT16");
- else
- fprintf (file, ":GOT");
- break;
-
- case CRIS_UNSPEC_PLTGOTREAD:
- if (flag_pic == 1)
- fprintf (file, CRIS_GOTPLT_SUFFIX "16");
- else
- fprintf (file, CRIS_GOTPLT_SUFFIX);
- break;
-
- default:
- gcc_unreachable ();
- }
- return true;
-
- default:
- return false;
- }
+ assemble_name (file, buf);
}
/* Worker function for TARGET_STRUCT_VALUE_RTX. */
static void
cris_asm_trampoline_template (FILE *f)
{
- if (TARGET_V32)
- {
- /* This normally-unused nop insn acts as an instruction to
- the simulator to flush its instruction cache. None of
- the other instructions in the trampoline template suits
- as a trigger for V32. The pc-relative addressing mode
- works nicely as a trigger for V10.
- FIXME: Have specific V32 template (possibly avoiding the
- use of a special instruction). */
- fprintf (f, "\tclearf x\n");
- /* We have to use a register as an intermediate, choosing
- semi-randomly R1 (which has to not be the STATIC_CHAIN_REGNUM),
- so we can use it for address indirection and jsr target. */
- fprintf (f, "\tmove $r1,$mof\n");
- /* +4 */
- fprintf (f, "\tmove.d 0,$r1\n");
- fprintf (f, "\tmove.d $%s,[$r1]\n", reg_names[STATIC_CHAIN_REGNUM]);
- fprintf (f, "\taddq 6,$r1\n");
- fprintf (f, "\tmove $mof,[$r1]\n");
- fprintf (f, "\taddq 6,$r1\n");
- fprintf (f, "\tmove $srp,[$r1]\n");
- /* +20 */
- fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
- /* +26 */
- fprintf (f, "\tmove.d 0,$r1\n");
- fprintf (f, "\tjsr $r1\n");
- fprintf (f, "\tsetf\n");
- /* +36 */
- fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
- /* +42 */
- fprintf (f, "\tmove.d 0,$r1\n");
- /* +48 */
- fprintf (f, "\tmove.d 0,$r9\n");
- fprintf (f, "\tjump $r9\n");
- fprintf (f, "\tsetf\n");
- }
- else
- {
- fprintf (f, "\tmove.d $%s,[$pc+20]\n", reg_names[STATIC_CHAIN_REGNUM]);
- fprintf (f, "\tmove $srp,[$pc+22]\n");
- fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
- fprintf (f, "\tjsr 0\n");
- fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
- fprintf (f, "\tjump 0\n");
- }
+ fprintf (f, "\tmove.d $%s,[$pc+20]\n", reg_names[STATIC_CHAIN_REGNUM]);
+ fprintf (f, "\tmove $srp,[$pc+22]\n");
+ fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
+ fprintf (f, "\tjsr 0\n");
+ fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
+ fprintf (f, "\tjump 0\n");
}
/* Implement TARGET_TRAMPOLINE_INIT. */
cris_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
{
rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
- rtx tramp = XEXP (m_tramp, 0);
rtx mem;
emit_block_move (m_tramp, assemble_trampoline_template (),
GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
- if (TARGET_V32)
- {
- mem = adjust_address (m_tramp, SImode, 6);
- emit_move_insn (mem, plus_constant (Pmode, tramp, 38));
- mem = adjust_address (m_tramp, SImode, 22);
- emit_move_insn (mem, chain_value);
- mem = adjust_address (m_tramp, SImode, 28);
- emit_move_insn (mem, fnaddr);
- }
- else
- {
- mem = adjust_address (m_tramp, SImode, 10);
- emit_move_insn (mem, chain_value);
- mem = adjust_address (m_tramp, SImode, 16);
- emit_move_insn (mem, fnaddr);
- }
+ mem = adjust_address (m_tramp, SImode, 10);
+ emit_move_insn (mem, chain_value);
+ mem = adjust_address (m_tramp, SImode, 16);
+ emit_move_insn (mem, fnaddr);
/* Note that there is no need to do anything with the cache for
sake of a trampoline. */
{
return ((mode == CCmode || regno != CRIS_CC0_REGNUM)
&& (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
- || (regno != CRIS_MOF_REGNUM && regno != CRIS_ACR_REGNUM)));
+ || regno != CRIS_MOF_REGNUM));
}
/* Return the preferred minimum alignment for a static object. */
;; ??? But it should be re-checked for gcc > 2.7.2
;; FIXME: This changed some time ago (from 2000-03-16) for gcc-2.9x.
-;; FIXME: When PIC, all [rX=rY+S] could be enabled to match
-;; [rX=gotless_symbol].
-;; The movsi for a gotless symbol could be split (post reload).
-\f
-
(define_c_enum ""
[
- ;; PLT reference from call expansion: operand 0 is the address,
- ;; the mode is VOIDmode. Always wrapped in CONST.
- ;; The value is relative to the GOT.
- CRIS_UNSPEC_PLT_GOTREL
-
- ;; PLT reference from call expansion: operand 0 is the address,
- ;; the mode is VOIDmode. Always wrapped in CONST.
- ;; The value is relative to the PC. It's arch-dependent whether
- ;; the offset counts from the start or the end of the current item.
- CRIS_UNSPEC_PLT_PCREL
-
- ;; The address of the global offset table as a source operand.
- CRIS_UNSPEC_GOT
-
- ;; The offset from the global offset table to the operand.
- CRIS_UNSPEC_GOTREL
-
- ;; The PC-relative offset to the operand. It's arch-dependent whether
- ;; the offset counts from the start or the end of the current item.
- CRIS_UNSPEC_PCREL
-
- ;; The index into the global offset table of a symbol, while
- ;; also generating a GOT entry for the symbol.
- CRIS_UNSPEC_GOTREAD
-
- ;; Similar to CRIS_UNSPEC_GOTREAD, but also generating a PLT entry.
- CRIS_UNSPEC_PLTGOTREAD
-
- ;; Condition for v32 casesi jump, since it needs to have if_then_else
- ;; form with register as one branch and default label as other.
- ;; Operand 0 is const_int 0.
- CRIS_UNSPEC_CASESI
-
;; Stack frame deallocation barrier.
CRIS_UNSPEC_FRAME_DEALLOC
;; Register numbers.
(define_constants
- [(CRIS_GOT_REGNUM 0)
- (CRIS_STATIC_CHAIN_REGNUM 7)
+ [(CRIS_STATIC_CHAIN_REGNUM 7)
(CRIS_FP_REGNUM 8)
(CRIS_SP_REGNUM 14)
(CRIS_ACR_REGNUM 15)
;; In short, any "slottable" instruction must be 16 bit and not refer
;; to pc, or alter it.
;;
-;; The possible values are "yes", "no", "has_slot", "has_return_slot"
-;; and "has_call_slot".
-;; Yes/no tells whether the insn is slottable or not. Has_call_slot means
-;; that the insn is a call insn, which for CRIS v32 has a delay-slot.
+;; The possible values are "yes", "no", "has_slot", and "has_return_slot".
+;; Yes/no tells whether the insn is slottable or not.
;; Of special concern is that no RTX_FRAME_RELATED insn must go in that
;; call delay slot, as it's located in the address *after* the call insn,
;; and the unwind machinery doesn't know about delay slots.
;; constraint pattern for the slottable pattern. An alternative using
;; only "r" constraints is most often slottable.
-(define_attr "slottable" "no,yes,has_slot,has_return_slot,has_call_slot"
+(define_attr "slottable" "no,yes,has_slot,has_return_slot"
(const_string "no"))
;; We also need attributes to sanely determine the condition code
;; state. See cris_notice_update_cc for how this is used.
-(define_attr "cc" "none,clobber,normal,noov32,rev" (const_string "normal"))
+(define_attr "cc" "none,clobber,normal,rev" (const_string "normal"))
;; At the moment, this attribute is just used to help bb-reorder do its
;; work; the default 0 doesn't help it. Many insns have other lengths,
(define_delay (eq_attr "slottable" "has_slot")
[(eq_attr "slottable" "yes") (nil) (nil)])
-;; We can't put prologue insns in call-insn delay-slots when
-;; DWARF2 unwind info is emitted, because the unwinder matches the
-;; address after the insn. It must see the return address of a call at
-;; a position at least *one byte after* the insn, or it'll think that
-;; the insn hasn't been executed. If the insn is in a delay-slot of a
-;; call, it's just *exactly* after the insn.
-
-(define_delay (eq_attr "slottable" "has_call_slot")
- [(and (eq_attr "slottable" "yes")
- (ior (not (match_test "RTX_FRAME_RELATED_P (insn)"))
- (not (match_test "flag_exceptions"))))
- (nil) (nil)])
-
;; The insn in the return insn slot must not be the
;; return-address-register restore. FIXME: Use has_slot and express
;; as a parallel with a use of the return-address-register (currently
;; Normal named test patterns from SI on.
-(define_insn "*tstsi"
+(define_insn "tst<mode>"
[(set (cc0)
- (compare (match_operand:SI 0 "nonimmediate_operand" "r,Q>,m")
+ (compare (match_operand:BWD 0 "nonimmediate_operand" "r,Q>,m")
(const_int 0)))]
""
-{
- if (which_alternative == 0 && TARGET_V32)
- return "cmpq 0,%0";
- return "test.d %0";
-}
+ "test<m> %0"
[(set_attr "slottable" "yes,yes,no")])
-(define_insn "*tst<mode>_cmp"
- [(set (cc0)
- (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
- (const_int 0)))]
- "cris_cc0_user_requires_cmp (insn)"
- "@
- cmp<m> 0,%0
- test<m> %0
- test<m> %0"
- [(set_attr "slottable" "no,yes,no")])
-
-(define_insn "*tst<mode>_non_cmp"
- [(set (cc0)
- (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
- (const_int 0)))]
- "!cris_cc0_user_requires_cmp (insn)"
- "@
- move<m> %0,%0
- test<m> %0
- test<m> %0"
- [(set_attr "slottable" "yes,yes,no")
- (set_attr "cc" "noov32,*,*")])
-
;; It seems that the position of the sign-bit and the fact that 0.0 is
;; all 0-bits would make "tstsf" a straight-forward implementation;
;; either "test.d" it for positive/negative or "btstq 30,r" it for
;; DImode for anything else but a structure/block-mode. Just do the
;; obvious stuff for the straight-forward constraint letters.
-(define_insn "*cmpdi_non_v32"
+(define_insn "*cmpdi"
[(set (cc0)
(compare (match_operand:DI 0 "nonimmediate_operand" "rm,r,r,r,r,r,r,o")
(match_operand:DI 1 "general_operand" "M,Kc,I,P,n,r,o,r")))]
- "!TARGET_V32"
+ ""
"@
test.d %M0\;ax\;test.d %H0
cmpq %1,%M0\;ax\;cmpq 0,%H0
cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
cmp.d %M0,%M1\;ax\;cmp.d %H0,%H1")
-(define_insn "*cmpdi_v32"
- [(set (cc0)
- (compare (match_operand:DI 0 "register_operand" "r,r,r,r,r")
- (match_operand:DI 1 "nonmemory_operand" "Kc,I,P,n,r")))]
- "TARGET_V32"
- "@
- cmpq %1,%M0\;ax\;cmpq 0,%H0
- cmpq %1,%M0\;ax\;cmpq -1,%H0
- cmp%e1.%z1 %1,%M0\;ax\;cmpq %H1,%H0
- cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
- cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0")
-
;; Note that compare insns with side effect addressing mode (e.g.):
;;
;; cmp.S [rx=ry+i],rz;
btst %2,%0
clearf nz
cmpq %p0,%2"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
\f
;; Move insns.
{
if (MEM_P (operands[0])
&& operands[1] != const0_rtx
- && can_create_pseudo_p ()
- && (!TARGET_V32 || !REG_P (operands[1])))
+ && can_create_pseudo_p ())
operands[1] = copy_to_mode_reg (DImode, operands[1]);
/* Some other ports (as of 2001-09-10 for example mcore and romp) also
}
})
-(define_insn_and_split "*movdi_insn_non_v32"
+(define_insn_and_split "*movdi_insn"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,rx,m")
(match_operand:DI 1 "general_operand" "rx,g,rxM"))]
"(register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
- || operands[1] == const0_rtx)
- && !TARGET_V32"
+ || operands[1] == const0_rtx)"
"#"
"&& reload_completed"
[(match_dup 2)]
"operands[2] = cris_split_movdx (operands);")
-
-;; Overlapping (but non-identical) source memory address and destination
-;; register would be a compiler bug, so we don't have to specify that.
-(define_insn "*movdi_v32"
- [(set
- (match_operand:DI 0 "nonimmediate_operand" "=r,rx,&r,>, m,r,x,m")
- (match_operand:DI 1 "general_operand" "rxi,r>,m, rx,r,m,m,x"))]
- "TARGET_V32"
-{
- switch (which_alternative)
- {
- /* FIXME: 1) Use autoincrement where possible. 2) Have peephole2,
- particularly for cases where the address register is dead. */
- case 5:
- if (REGNO (operands[0]) == REGNO (XEXP (operands[1], 0)))
- return "addq 4,%L1\;move.d %1,%H0\;subq 4,%L1\;move.d %1,%M0";
- gcc_assert (REGNO (operands[0]) + 1 == REGNO (XEXP (operands[1], 0)));
- return "move.d [%L1+],%M0\;move.d [%L1],%H0";
- case 2:
- /* We could do away with the addq if we knew the address-register
- isn't ACR. If we knew the address-register is dead, we could do
- away with the subq too. */
- return "move.d [%L1],%M0\;addq 4,%L1\;move.d [%L1],%H0\;subq 4,%L1";
- case 4:
- return "move.d %M1,[%L0]\;addq 4,%L0\;move.d %H1,[%L0]\;subq 4,%L0";
- case 6:
- return "move [%L1],%M0\;addq 4,%L1\;move [%L1],%H0\;subq 4,%L1";
- case 7:
- return "move %M1,[%L0]\;addq 4,%L0\;move %H1,[%L0]\;subq 4,%L0";
-
- default:
- return "#";
- }
-}
- ;; The non-split cases clobber cc0 because of their adds and subs.
- ;; Beware that NOTICE_UPDATE_CC is called before the forced split happens.
- [(set_attr "cc" "*,*,clobber,*,clobber,clobber,*,*")])
-
-;; Much like "*movdi_insn_non_v32". Overlapping registers and constants
-;; is handled so much better in cris_split_movdx.
-(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
- "TARGET_V32
- && reload_completed
- && (!MEM_P (operands[0]) || !REG_P (XEXP (operands[0], 0)))
- && (!MEM_P (operands[1]) || !REG_P (XEXP (operands[1], 0)))"
- [(match_dup 2)]
- "operands[2] = cris_split_movdx (operands);")
\f
;; Side-effect patterns for move.S1 [rx=ry+rx.S2],rw
;; and move.S1 [rx=ry+i],rz
(define_expand "movsi"
[(set
(match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "cris_general_operand_or_symbol" ""))]
+ (match_operand:SI 1 "general_operand" ""))]
""
{
- enum cris_symbol_type t;
-
/* If the output goes to a MEM, make sure we have zero or a register as
input. */
if (MEM_P (operands[0])
&& operands[1] != const0_rtx
&& can_create_pseudo_p ())
operands[1] = force_reg (SImode, operands[1]);
-
- /* If we're generating PIC and have an incoming symbol, validize it to a
- general operand or something that will match a special pattern.
-
- FIXME: Do we *have* to recognize anything that would normally be a
- valid symbol? Can we exclude global PIC addresses with an added
- offset? */
- if (flag_pic
- && CONSTANT_P (operands[1])
- && !cris_valid_pic_const (operands[1], false))
- {
- t = cris_symbol_type_of (operands[1]);
-
- gcc_assert (t != cris_no_symbol && t != cris_offsettable_symbol);
-
- if (! REG_S_P (operands[0]))
- {
- /* We must have a register as destination for what we're about to
- do, and for the patterns we generate. */
- CRIS_ASSERT (can_create_pseudo_p ());
- operands[1] = force_reg (SImode, operands[1]);
- }
- else
- {
- /* FIXME: add a REG_EQUAL (or is it REG_EQUIV) note to the
- destination register for the symbol. It might not be
- worth it. Measure. */
- crtl->uses_pic_offset_table = 1;
- if (t == cris_rel_symbol)
- {
- /* Change a "move.d sym(+offs),rN" into (allocate register rM)
- for pre-v32:
- "move.d (const (plus (unspec [sym]
- CRIS_UNSPEC_GOTREL) offs)),rM" "add.d rPIC,rM,rN"
- and for v32:
- "move.d (const (plus (unspec [sym]
- CRIS_UNSPEC_PCREL) offs)),rN". */
- rtx tem, rm, rn = operands[0];
- rtx sym = GET_CODE (operands[1]) != CONST
- ? operands[1] : get_related_value (operands[1]);
- HOST_WIDE_INT offs = get_integer_term (operands[1]);
-
- gcc_assert (can_create_pseudo_p ());
-
- if (TARGET_V32)
- {
- tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym),
- CRIS_UNSPEC_PCREL);
- if (offs != 0)
- tem = plus_constant (Pmode, tem, offs);
- rm = rn;
- emit_move_insn (rm, gen_rtx_CONST (Pmode, tem));
- }
- else
- {
- /* We still uses GOT-relative addressing for
- pre-v32. */
- crtl->uses_pic_offset_table = 1;
- tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym),
- CRIS_UNSPEC_GOTREL);
- if (offs != 0)
- tem = plus_constant (Pmode, tem, offs);
- rm = gen_reg_rtx (Pmode);
- emit_move_insn (rm, gen_rtx_CONST (Pmode, tem));
- if (expand_binop (Pmode, add_optab, rm, pic_offset_table_rtx,
- rn, 0, OPTAB_LIB_WIDEN) != rn)
- internal_error ("expand_binop failed in movsi gotrel");
- }
- DONE;
- }
- else if (t == cris_got_symbol)
- {
- /* Change a "move.d sym,rN" into (allocate register rM, rO)
- "move.d (const (unspec [sym] CRIS_UNSPEC_GOTREAD)),rM"
- "add.d rPIC,rM,rO", "move.d [rO],rN" with
- the memory access marked as read-only. */
- rtx tem, mem, rm, ro, rn = operands[0];
- gcc_assert (can_create_pseudo_p ());
- tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
- CRIS_UNSPEC_GOTREAD);
- rm = gen_reg_rtx (Pmode);
- emit_move_insn (rm, gen_rtx_CONST (Pmode, tem));
- ro = gen_reg_rtx (Pmode);
- if (expand_binop (Pmode, add_optab, rm, pic_offset_table_rtx,
- ro, 0, OPTAB_LIB_WIDEN) != ro)
- internal_error ("expand_binop failed in movsi got");
- mem = gen_rtx_MEM (Pmode, ro);
-
- /* This MEM doesn't alias anything. Whether it
- aliases other same symbols is unimportant. */
- set_mem_alias_set (mem, new_alias_set ());
- MEM_NOTRAP_P (mem) = 1;
-
- /* We can set the GOT memory read of a non-called symbol
- to readonly, but not that of a call symbol, as those
- are subject to lazy evaluation and usually have the value
- changed from the first call to the second (but
- constant thereafter). */
- MEM_READONLY_P (mem) = 1;
- emit_move_insn (rn, mem);
- DONE;
- }
- else
- {
- /* We get here when we have to change something that would
- be recognizable if it wasn't PIC. A ``sym'' is ok for
- PIC symbols both with and without a GOT entry. And ``sym
- + offset'' is ok for local symbols, so the only thing it
- could be, is a global symbol with an offset. Check and
- abort if not. */
- rtx reg = gen_reg_rtx (Pmode);
- rtx sym = get_related_value (operands[1]);
- HOST_WIDE_INT offs = get_integer_term (operands[1]);
-
- gcc_assert (can_create_pseudo_p ()
- && t == cris_got_symbol_needing_fixup
- && sym != NULL_RTX && offs != 0);
-
- emit_move_insn (reg, sym);
- if (expand_binop (SImode, add_optab, reg,
- GEN_INT (offs), operands[0], 0,
- OPTAB_LIB_WIDEN) != operands[0])
- internal_error ("expand_binop failed in movsi got+offs");
- DONE;
- }
- }
- }
})
-(define_insn "*movsi_got_load"
- [(set (reg:SI CRIS_GOT_REGNUM) (unspec:SI [(const_int 0)] CRIS_UNSPEC_GOT))]
- "flag_pic"
-{
- return TARGET_V32
- ? "lapc _GLOBAL_OFFSET_TABLE_,%:"
- : "move.d $pc,%:\;sub.d .:GOTOFF,%:";
-}
- [(set_attr "cc" "clobber")])
-
(define_insn "*movsi_internal"
[(set
(match_operand:SI 0 "nonimmediate_operand"
- "=r,r, r,Q>,r,Q>,g,r,r, r,g,rQ>,x, m,x")
- (match_operand:SI 1 "cris_general_operand_or_pic_source"
- "r,Q>,M,M, I,r, M,n,!S,g,r,x, rQ>,x,gi"))]
+ "=r,r, r,Q>,r,Q>,g,r,r,g,rQ>,x, m,x")
+ (match_operand:SI 1 "general_operand"
+ "r,Q>,M,M, I,r, M,n,g,r,x, rQ>,x,gi"))]
;; Note that we prefer not to use the S alternative (if for some reason
;; it competes with others) above, but g matches S.
""
letters. FIXME: Check again. It seems this could shrink a bit. */
switch (which_alternative)
{
- case 9:
- if (TARGET_V32)
- {
- if (!flag_pic
- && (GET_CODE (operands[1]) == SYMBOL_REF
- || GET_CODE (operands[1]) == LABEL_REF
- || (GET_CODE (operands[1]) == CONST
- && (GET_CODE (XEXP (operands[1], 0)) != UNSPEC
- || (XINT (XEXP (operands[1], 0), 1)
- == CRIS_UNSPEC_PLT_PCREL)
- || (XINT (XEXP (operands[1], 0), 1)
- == CRIS_UNSPEC_PCREL)))))
- {
- /* FIXME: Express this through (set_attr cc none) instead,
- since we can't express the ``none'' at this point. FIXME:
- Use lapc for everything except const_int and when next cc0
- user would want the flag setting. */
- CC_STATUS_INIT;
- return "lapc %1,%0";
- }
- if (flag_pic == 1
- && GET_CODE (operands[1]) == CONST
- && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
- && XINT (XEXP (operands[1], 0), 1) == CRIS_UNSPEC_GOTREAD)
- return "movu.w %1,%0";
- }
- /* FALLTHROUGH */
case 0:
case 1:
case 5:
- case 10:
+ case 8:
+ case 9:
return "move.d %1,%0";
+ case 10:
case 11:
case 12:
case 13:
- case 14:
- return "move %d1,%0";
+ return "move %1,%0";
case 2:
case 3:
}
return "move.d %1,%0";
- case 8:
- {
- rtx tem = operands[1];
- gcc_assert (GET_CODE (tem) == CONST);
- tem = XEXP (tem, 0);
- if (GET_CODE (tem) == PLUS
- && GET_CODE (XEXP (tem, 0)) == UNSPEC
- && (XINT (XEXP (tem, 0), 1) == CRIS_UNSPEC_GOTREL
- || XINT (XEXP (tem, 0), 1) == CRIS_UNSPEC_PCREL)
- && CONST_INT_P (XEXP (tem, 1)))
- tem = XEXP (tem, 0);
- gcc_assert (GET_CODE (tem) == UNSPEC);
- switch (XINT (tem, 1))
- {
- case CRIS_UNSPEC_GOTREAD:
- case CRIS_UNSPEC_PLTGOTREAD:
- /* Using sign-extend mostly to be consistent with the
- indexed addressing mode. */
- if (flag_pic == 1)
- return "movs.w %1,%0";
- return "move.d %1,%0";
-
- case CRIS_UNSPEC_GOTREL:
- case CRIS_UNSPEC_PLT_GOTREL:
- gcc_assert (!TARGET_V32);
- return "move.d %1,%0";
-
- case CRIS_UNSPEC_PCREL:
- case CRIS_UNSPEC_PLT_PCREL:
- gcc_assert (TARGET_V32);
- /* LAPC doesn't set condition codes; clear them to make the
- (equivalence-marked) result of this insn not presumed
- present. This instruction can be a PIC symbol load (for
- a hidden symbol) which for weak symbols will be followed
- by a test for NULL. */
- CC_STATUS_INIT;
- return "lapc %1,%0";
-
- default:
- gcc_unreachable ();
- }
- }
default:
- return "BOGUS: %1 to %0";
+ gcc_unreachable ();
}
}
- [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,no,no,no,yes,yes,no,no")
- (set_attr "cc" "*,*,*,*,*,*,*,*,*,*,*,none,none,none,none")])
+ [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,no,no,yes,yes,no,no")
+ (set_attr "cc" "*,*,*,*,*,*,*,*,*,*,none,none,none,none")])
\f
;; Extend operations with side-effect from mem to register, using
;; MOVS/MOVU. These are from mem to register only.
[(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no,yes,yes,yes,no,yes,no")])
\f
;; Movem patterns. Primarily for use in function prologue and epilogue.
-;; The V32 variants have an ordering matching the expectations of the
-;; standard names "load_multiple" and "store_multiple"; pre-v32 movem
-;; store R0 in the highest memory location.
-
-(define_expand "load_multiple"
- [(match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "memory_operand" "")
- (match_operand:SI 2 "const_int_operand" "")]
- "TARGET_V32"
-{
- rtx indreg;
-
- /* Apparently the predicate isn't checked, so we need to do so
- manually. Once happened for libstdc++-v3 locale_facets.tcc. */
- if (!MEM_P (operands[1]))
- FAIL;
-
- indreg = XEXP (operands[1], 0);
-
- if (GET_CODE (indreg) == POST_INC)
- indreg = XEXP (indreg, 0);
- if (!REG_P (indreg)
- || GET_CODE (operands[2]) != CONST_INT
- || !REG_P (operands[0])
- || REGNO (operands[0]) != 0
- || INTVAL (operands[2]) > CRIS_SP_REGNUM
- || (int) REGNO (indreg) < INTVAL (operands[2]))
- FAIL;
- gcc_unreachable ();
- emit_insn (cris_gen_movem_load (operands[1], operands[2], 0));
- DONE;
-})
-
-(define_expand "store_multiple"
- [(match_operand:SI 0 "memory_operand" "")
- (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")]
- "TARGET_V32"
-{
- rtx indreg;
-
- /* See load_multiple. */
- if (!MEM_P (operands[0]))
- FAIL;
-
- indreg = XEXP (operands[0], 0);
-
- if (GET_CODE (indreg) == POST_INC)
- indreg = XEXP (indreg, 0);
- if (!REG_P (indreg)
- || GET_CODE (operands[2]) != CONST_INT
- || !REG_P (operands[1])
- || REGNO (operands[1]) != 0
- || INTVAL (operands[2]) > CRIS_SP_REGNUM
- || (int) REGNO (indreg) < INTVAL (operands[2]))
- FAIL;
- gcc_unreachable ();
- cris_emit_movem_store (operands[0], operands[2], 0, false);
- DONE;
-})
+;; Unfortunately, movem stores R0 in the highest memory location, thus
+;; the opposite of the expectation for the standard names "load_multiple"
+;; and "store_multiple".
(define_insn "*cris_load_multiple"
[(match_parallel 0 "cris_load_multiple_op"
(plus:DI (match_operand:DI 1 "register_operand")
(match_operand:DI 2 "general_operand")))]
""
-{
- if (MEM_P (operands[2]) && TARGET_V32)
- operands[2] = force_reg (DImode, operands[2]);
-})
+ "")
-(define_insn "*adddi3_non_v32"
+(define_insn "*adddi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
(plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,r")
(match_operand:DI 2 "general_operand" "J,N,P,g,!To")))]
- "!TARGET_V32"
+ ""
"@
addq %2,%M0\;ax\;addq 0,%H0
subq %n2,%M0\;ax\;subq 0,%H0
add.d %M2,%M0\;ax\;add.d %H2,%H0
add.d %M2,%M1,%M0\;ax\;add.d %H2,%H1,%H0")
-; It seems no use allowing a memory operand for this one, because we'd
-; need a scratch register for incrementing the address.
-(define_insn "*adddi3_v32"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
- (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0")
- (match_operand:DI 2 "nonmemory_operand" "J,N,P,r,n")))]
- "TARGET_V32"
- "@
- addq %2,%M0\;addc 0,%H0
- subq %n2,%M0\;ax\;subq 0,%H0
- add%e2.%z2 %2,%M0\;addc %H2,%H0
- add.d %M2,%M0\;addc %H2,%H0
- add.d %M2,%M0\;addc %H2,%H0")
-
(define_expand "add<mode>3"
[(set (match_operand:BWD 0 "register_operand")
(plus:BWD
""
"")
-(define_insn "*addsi3_non_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r,r, r")
+(define_insn "*addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r,r, r")
(plus:SI
- (match_operand:SI 1 "register_operand" "%0,0, 0,0,0,0, 0,r, r")
- (match_operand:SI 2 "general_operand" "r,Q>,J,N,n,!S,g,!To,0")))]
+ (match_operand:SI 1 "register_operand" "%0,0, 0,0,0,0,r, r")
+ (match_operand:SI 2 "general_operand" "r,Q>,J,N,n,g,!To,0")))]
;; The last constraint is due to that after reload, the '%' is not
;; honored, and canonicalization doesn't care about keeping the same
;; register as in destination. This will happen after insn splitting.
;; gcc <= 2.7.2. FIXME: Check for gcc-2.9x
- "!TARGET_V32"
+ ""
{
switch (which_alternative)
{
}
return "add.d %2,%0";
case 5:
- {
- rtx tem = operands[2];
- gcc_assert (GET_CODE (tem) == CONST);
- tem = XEXP (tem, 0);
- if (GET_CODE (tem) == PLUS
- && GET_CODE (XEXP (tem, 0)) == UNSPEC
- /* We don't allow CRIS_UNSPEC_PCREL here; we can't have a
- pc-relative operand in an add insn. */
- && XINT (XEXP (tem, 0), 1) == CRIS_UNSPEC_GOTREL
- && CONST_INT_P (XEXP (tem, 1)))
- tem = XEXP (tem, 0);
- gcc_assert (GET_CODE (tem) == UNSPEC);
- switch (XINT (tem, 1))
- {
- case CRIS_UNSPEC_GOTREAD:
- case CRIS_UNSPEC_PLTGOTREAD:
- /* Using sign-extend mostly to be consistent with the
- indexed addressing mode. */
- if (flag_pic == 1)
- return "adds.w %2,%0";
- return "add.d %2,%0";
-
- case CRIS_UNSPEC_PLT_GOTREL:
- case CRIS_UNSPEC_GOTREL:
- return "add.d %2,%0";
- default:
- gcc_unreachable ();
- }
- }
+ return "add.d %2,%0";
case 6:
- return "add%u2 %2,%0";
- case 7:
return "add.d %2,%1,%0";
- case 8:
+ case 7:
return "add.d %1,%0";
default:
return "BOGUS addsi %2+%1 to %0";
}
}
- [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,no,yes")])
-
-; FIXME: Check what's best: having the three-operand ACR alternative
-; before or after the corresponding-operand2 alternative. Check for
-; *all* insns. FIXME: constant constraint letter for -128..127.
-(define_insn "*addsi3_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,!a,r,!a, r,r,!a,r,!a,r,r,r,!a")
- (plus:SI
- (match_operand:SI 1 "register_operand" "%0,r, 0, r, 0,0,r, 0,r, 0,0,0,r")
- (match_operand:SI 2 "general_operand" "r, r, Q>,Q>,J,N,NJ,L,L, P,n,g,g")))]
- "TARGET_V32"
- "@
- add.d %2,%0
- addi %2.b,%1,%0
- add.d %2,%0
- addo.d %2,%1,%0
- addq %2,%0
- subq %n2,%0
- addoq %2,%1,%0
- adds.w %2,%0
- addo %2,%1,%0
- addu.w %2,%0
- add.d %2,%0
- add%u2 %2,%0
- addo.%Z2 %2,%1,%0"
- [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,yes,no,no,no,no,no,no")
- (set_attr "cc" "*,none,*,none,*,*,none,*,none,*,*,*,none")])
+ [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,yes")])
\f
-(define_insn "*addhi3_non_v32"
+(define_insn "*addhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r, r,r,r,r")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0, 0,0,0,r")
(match_operand:HI 2 "general_operand" "r,Q>,J,N,g,!To")))]
- "!TARGET_V32"
+ ""
"@
add.w %2,%0
add.w %2,%0
[(set_attr "slottable" "yes,yes,yes,yes,no,no")
(set_attr "cc" "normal,normal,clobber,clobber,normal,normal")])
-(define_insn "*addhi3_v32"
- [(set (match_operand:HI 0 "register_operand" "=r, !a,r,!a, r,r,!a,r,!a")
- (plus:HI
- (match_operand:HI 1 "register_operand" "%0,r, 0, r, 0,0,r, 0,r")
- (match_operand:HI 2 "general_operand" "r, r, Q>,Q>,J,N,NJ,g,g")))]
- "TARGET_V32"
- "@
- add.w %2,%0
- addi %2.b,%1,%0
- add.w %2,%0
- addo.w %2,%1,%0
- addq %2,%0
- subq %n2,%0
- addoq %2,%1,%0
- add.w %2,%0
- addo.w %2,%1,%0"
- [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,yes,no,no")
- (set_attr "cc" "*,none,*,none,clobber,clobber,none,*,none")])
-
-(define_insn "*addqi3_non_v32"
+(define_insn "*addqi3"
[(set (match_operand:QI 0 "register_operand" "=r,r, r,r,r,r,r")
(plus:QI (match_operand:QI 1 "register_operand" "%0,0, 0,0,0,0,r")
(match_operand:QI 2 "general_operand" "r,Q>,J,N,O,g,!To")))]
- "!TARGET_V32"
+ ""
"@
add.b %2,%0
add.b %2,%0
add.b %2,%1,%0"
[(set_attr "slottable" "yes,yes,yes,yes,yes,no,no")
(set_attr "cc" "normal,normal,clobber,clobber,clobber,normal,normal")])
-
-(define_insn "*addqi3_v32"
- [(set (match_operand:QI 0 "register_operand" "=r,!a,r,!a, r,r,!a,r,r,!a")
- (plus:QI
- (match_operand:QI 1 "register_operand" "%0,r, 0, r, 0,0,r, 0,0,r")
- (match_operand:QI 2 "general_operand" "r,r, Q>,Q>,J,N,NJ,O,g,g")))]
- "TARGET_V32"
- "@
- add.b %2,%0
- addi %2.b,%1,%0
- add.b %2,%0
- addo.b %2,%1,%0
- addq %2,%0
- subq %n2,%0
- addoq %2,%1,%0
- subQ -%b2,%0
- add.b %2,%0
- addo.b %2,%1,%0"
- [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,yes,yes,no,no")
- (set_attr "cc" "*,none,*,none,clobber,clobber,none,clobber,*,none")])
\f
;; Subtract.
;;
(minus:DI (match_operand:DI 1 "register_operand")
(match_operand:DI 2 "general_operand")))]
""
-{
- if (TARGET_V32 && MEM_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
-})
+ "")
-(define_insn "*subdi3_non_v32"
+(define_insn "*subdi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
(minus:DI (match_operand:DI 1 "register_operand" "0,0,0,0,r")
(match_operand:DI 2 "general_operand" "J,N,P,g,!To")))]
- "!TARGET_V32"
+ ""
"@
subq %2,%M0\;ax\;subq 0,%H0
addq %n2,%M0\;ax\;addq 0,%H0
sub.d %M2,%M0\;ax\;sub.d %H2,%H0
sub.d %M2,%M1,%M0\;ax\;sub.d %H2,%H1,%H0")
-(define_insn "*subdi3_v32"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r")
- (minus:DI (match_operand:DI 1 "register_operand" "0,0,0,0")
- (match_operand:DI 2 "nonmemory_operand" "J,N,P,r")))]
- "TARGET_V32"
- "@
- subq %2,%M0\;ax\;subq 0,%H0
- addq %n2,%M0\;ax\;addq 0,%H0
- sub%e2.%z2 %2,%M0\;ax\;%D2 %H2,%H0
- sub.d %M2,%M0\;ax\;sub.d %H2,%H0")
-
(define_expand "sub<mode>3"
[(set (match_operand:BWD 0 "register_operand")
(minus:BWD
""
"")
-(define_insn "*subsi3_non_v32"
+(define_insn "*subsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r,r,r")
(minus:SI
(match_operand:SI 1 "register_operand" "0,0, 0,0,0,0,0,r")
(match_operand:SI 2 "general_operand" "r,Q>,J,N,P,n,g,!To")))]
- "!TARGET_V32"
+ ""
;; This does not do the optimal: "addu.w 65535,r0" when %2 is negative.
;; But then again, %2 should not be negative.
sub.d %2,%0
sub.d %2,%1,%0"
[(set_attr "slottable" "yes,yes,yes,yes,no,no,no,no")])
-
-(define_insn "*subsi3_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
- (minus:SI
- (match_operand:SI 1 "register_operand" "0,0,0,0,0,0,0")
- (match_operand:SI 2 "general_operand" "r,Q>,J,N,P,n,g")))]
- "TARGET_V32"
- "@
- sub.d %2,%0
- sub.d %2,%0
- subq %2,%0
- addq %n2,%0
- sub%e2.%z2 %2,%0
- sub.d %2,%0
- sub.d %2,%0"
- [(set_attr "slottable" "yes,yes,yes,yes,no,no,no")])
\f
-(define_insn "*sub<mode>3_nonv32"
+(define_insn "*sub<mode>3"
[(set (match_operand:BW 0 "register_operand" "=r,r, r,r,r,r")
(minus:BW (match_operand:BW 1 "register_operand" "0,0, 0,0,0,r")
(match_operand:BW 2 "general_operand" "r,Q>,J,N,g,!To")))]
- "!TARGET_V32"
+ ""
"@
sub<m> %2,%0
sub<m> %2,%0
sub<m> %2,%1,%0"
[(set_attr "slottable" "yes,yes,yes,yes,no,no")
(set_attr "cc" "normal,normal,clobber,clobber,normal,normal")])
-
-(define_insn "*sub<mode>3_v32"
- [(set (match_operand:BW 0 "register_operand" "=r,r,r,r,r")
- (minus:BW (match_operand:BW 1 "register_operand" "0,0,0,0,0")
- (match_operand:BW 2 "general_operand" "r,Q>,J,N,g")))]
- "TARGET_V32"
- "@
- sub<m> %2,%0
- sub<m> %2,%0
- subq %2,%0
- addq %n2,%0
- sub<m> %2,%0"
- [(set_attr "slottable" "yes,yes,yes,yes,no")
- (set_attr "cc" "normal,normal,clobber,clobber,normal")])
\f
;; CRIS has some add/sub-with-sign/zero-extend instructions.
;; Although these perform sign/zero-extension to SImode, they are
;; QImode to HImode
;; FIXME: GCC should widen.
-(define_insn "*extopqihi_non_v32"
+(define_insn "*extopqihi"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(match_operator:HI
3 "cris_additive_operand_extend_operator"
(match_operator:HI
4 "cris_extend_operator"
[(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])]))]
- "!TARGET_V32 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
+ "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
&& (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
"@
%x3%E4.%m4 %2,%0
[(set_attr "slottable" "yes,yes,no,no")
(set_attr "cc" "clobber")])
-(define_insn "*extopqihi_v32"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (match_operator:HI
- 3 "cris_additive_operand_extend_operator"
- [(match_operand:HI 1 "register_operand" "0,0")
- (match_operator:HI
- 4 "cris_extend_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "r,m")])]))]
- "TARGET_V32"
- "%x3%e4.%m4 %2,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "clobber")])
-
;; QImode to SImode
-(define_insn "*extop<mode>si_non_v32"
+(define_insn "*extop<mode>si"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(match_operator:SI
3 "cris_operand_extend_operator"
(match_operator:SI
4 "cris_extend_operator"
[(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])]))]
- "!TARGET_V32
- && (GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
+ "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
&& (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
"@
%x3%E4<m> %2,%0
%x3%E4<m> %2,%1,%0"
[(set_attr "slottable" "yes,yes,no,no")])
-
-(define_insn "*extop<mode>si_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (match_operator:SI
- 3 "cris_additive_operand_extend_operator"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operator:SI
- 4 "cris_extend_operator"
- [(match_operand:BW 2 "nonimmediate_operand" "r,m")])]))]
- "TARGET_V32"
- "%x3%e4.%m4 %2,%0"
- [(set_attr "slottable" "yes")])
\f
;; As with the side-effect patterns, may have to have swapped operands for add.
;; For commutative operands, these are the canonical forms.
;; QImode to HImode
-(define_insn "*addxqihi_swap_non_v32"
+(define_insn "*addxqihi_swap"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(plus:HI
(match_operator:HI
3 "cris_extend_operator"
[(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])
(match_operand:HI 1 "register_operand" "0,0,0,r")))]
- "!TARGET_V32 && operands[1] != frame_pointer_rtx"
+ "operands[1] != frame_pointer_rtx"
"@
add%e3.b %2,%0
add%e3.b %2,%0
[(set_attr "slottable" "yes,yes,no,no")
(set_attr "cc" "clobber")])
-;; A case for v32, to catch the "addo" insn in addition to "adds". We
-;; only care to match the canonical form; there should be no other.
-
-(define_insn "*addsbw_v32"
- [(set (match_operand:HI 0 "register_operand" "=r,r,!a")
- (plus:HI
- (sign_extend:HI
- (match_operand:QI 2 "nonimmediate_operand" "r,m,m"))
- (match_operand:HI 1 "register_operand" "0,0,r")))]
- "TARGET_V32"
- "@
- adds.b %2,%0
- adds.b %2,%0
- addo.b %2,%1,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "clobber,clobber,none")])
-
-(define_insn "*addubw_v32"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (plus:HI
- (zero_extend:HI
- (match_operand:QI 2 "nonimmediate_operand" "r,m"))
- (match_operand:HI 1 "register_operand" "0,0")))]
- "TARGET_V32"
- "addu.b %2,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "clobber")])
-
-(define_insn "*extop<mode>si_swap_non_v32"
+(define_insn "*extop<mode>si"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(match_operator:SI
4 "cris_plus_or_bound_operator"
3 "cris_extend_operator"
[(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])
(match_operand:SI 1 "register_operand" "0,0,0,r")]))]
- "!TARGET_V32
- && (GET_CODE (operands[4]) != UMIN || GET_CODE (operands[3]) == ZERO_EXTEND)
+ "(GET_CODE (operands[4]) != UMIN || GET_CODE (operands[3]) == ZERO_EXTEND)
&& operands[1] != frame_pointer_rtx"
"@
%x4%E3<m> %2,%0
%x4%E3<m> %2,%0
%x4%E3<m> %2,%1,%0"
[(set_attr "slottable" "yes,yes,no,no")])
-
-(define_insn "*adds<mode>_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r,!a")
- (plus:SI
- (sign_extend:SI
- (match_operand:BW 2 "nonimmediate_operand" "r,m,m"))
- (match_operand:SI 1 "register_operand" "0,0,r")))]
- "TARGET_V32"
- "@
- adds<m> %2,%0
- adds<m> %2,%0
- addo<m> %2,%1,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "*,*,none")])
-
-(define_insn "*addu<mode>_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI
- (zero_extend:SI
- (match_operand:BW 2 "nonimmediate_operand" "r,m"))
- (match_operand:SI 1 "register_operand" "0,0")))]
- "TARGET_V32 && operands[1] != frame_pointer_rtx"
- "addu<m> %2,%0"
- [(set_attr "slottable" "yes")])
-
-(define_insn "*bound<mode>_v32"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (umin:SI
- (zero_extend:SI
- (match_operand:BW 2 "register_operand" "r"))
- (match_operand:SI 1 "register_operand" "0")))]
- "TARGET_V32 && operands[1] != frame_pointer_rtx"
- "bound<m> %2,%0"
- [(set_attr "slottable" "yes")])
\f
;; This is the special case when we use what corresponds to the
;; instruction above in "casesi". Do *not* change it to use the generic
(pc))
(label_ref (match_operand 2 "" ""))))
(use (label_ref (match_operand 3 "" "")))]
- "!TARGET_V32 && operands[0] != frame_pointer_rtx"
+ "operands[0] != frame_pointer_rtx"
"adds.w [$pc+%0.w],$pc"
[(set_attr "cc" "clobber")])
-
-;; For V32, we just have a jump, but we need to mark the table as used,
-;; and the jump insn must have the if_then_else form expected by core
-;; GCC. Since we don't want to prolong the lifetime of the original
-;; index value, we compare against "unspec 0". It's a pity we have to
-;; jump through to get the default label in place and to keep the jump
-;; table around. FIXME: Look into it some time.
-
-(define_insn "*casesi_jump_v32"
- [(set (pc)
- (if_then_else
- (ltu (unspec [(const_int 0)] CRIS_UNSPEC_CASESI)
- (match_operand:SI 0 "const_int_operand" "n"))
- (match_operand:SI 1 "register_operand" "r")
- (label_ref (match_operand 2 "" ""))))
- (use (label_ref (match_operand 3 "" "")))]
- "TARGET_V32"
- "jump %1%#"
- [(set_attr "cc" "clobber")
- (set_attr "slottable" "has_slot")])
\f
;; Multiply instructions.
;; The addi insn as it is normally used.
-;; Make the ACR alternative taste bad enough to not choose it as a
-;; preference to avoid spilling problems (unwind-dw2-fde.c at build).
-;; FIXME: Revisit for new register allocator.
-
(define_insn "*addi"
- [(set (match_operand:SI 0 "register_operand" "=r,!a")
+ [(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI
- (mult:SI (match_operand:SI 2 "register_operand" "r,r")
- (match_operand:SI 3 "const_int_operand" "n,n"))
- (match_operand:SI 1 "register_operand" "0,r")))]
+ (mult:SI (match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "const_int_operand" "n"))
+ (match_operand:SI 1 "register_operand" "0")))]
"operands[0] != frame_pointer_rtx
&& operands[1] != frame_pointer_rtx
&& CONST_INT_P (operands[3])
&& (INTVAL (operands[3]) == 1
|| INTVAL (operands[3]) == 2 || INTVAL (operands[3]) == 4)"
- "@
- addi %2%T3,%0
- addi %2%T3,%1,%0"
+ "addi %2%T3,%0"
[(set_attr "slottable" "yes")
(set_attr "cc" "none")])
(match_operand:SI 2 "register_operand" "r"))
(ashift:SI (match_operand:SI 3 "register_operand" "0")
(const_int 1))))]
- "!TARGET_V32"
+ ""
"mstep %2,%0"
[(set_attr "slottable" "yes")])
(match_operand:SI 2 "register_operand" "r"))
(mult:SI (match_operand:SI 3 "register_operand" "0")
(const_int 2))))]
- "!TARGET_V32
- && operands[0] != frame_pointer_rtx
+ "operands[0] != frame_pointer_rtx
&& operands[1] != frame_pointer_rtx
&& operands[2] != frame_pointer_rtx
&& operands[3] != frame_pointer_rtx"
(const_int 1))))]
""
"dstep %2,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
;; Here's a variant with mult instead of ashift.
;;
&& operands[2] != frame_pointer_rtx
&& operands[3] != frame_pointer_rtx"
"dstep %2,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
\f
;; Logical operators.
;; pressure (worse code). That will hopefully change with an
;; improved reload pass.
-(define_insn "*expanded_andsi_non_v32"
+(define_insn "*expanded_andsi"
[(set (match_operand:SI 0 "register_operand" "=r,r,r, r,r")
(and:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0,r")
(match_operand:SI 2 "general_operand" "I,r,Q>,g,!To")))]
- "!TARGET_V32"
+ ""
"@
andq %2,%0
and.d %2,%0
and.d %2,%0
and.d %2,%1,%0"
[(set_attr "slottable" "yes,yes,yes,no,no")])
-
-(define_insn "*expanded_andsi_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
- (match_operand:SI 2 "general_operand" "I,r,Q>,g")))]
- "TARGET_V32"
- "@
- andq %2,%0
- and.d %2,%0
- and.d %2,%0
- and.d %2,%0"
- [(set_attr "slottable" "yes,yes,yes,no")
- (set_attr "cc" "noov32")])
\f
;; For both QI and HI we may use the quick patterns. This results in
;; useless condition codes, but that is used rarely enough for it to
;; Catch-all andhi3 pattern.
-(define_insn "*expanded_andhi_non_v32"
+(define_insn "*expanded_andhi"
[(set (match_operand:HI 0 "register_operand" "=r,r,r, r,r,r,r")
(and:HI (match_operand:HI 1 "register_operand" "%0,0,0, 0,0,0,r")
(match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g,!To")))]
;; pressure (worse code). That will hopefully change with an
;; improved reload pass.
- "!TARGET_V32"
+ ""
"@
andq %2,%0
and.w %2,%0
[(set_attr "slottable" "yes,yes,yes,no,yes,no,no")
(set_attr "cc" "clobber,normal,normal,normal,clobber,normal,normal")])
-(define_insn "*expanded_andhi_v32"
- [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
- (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
- (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g")))]
- "TARGET_V32"
- "@
- andq %2,%0
- and.w %2,%0
- and.w %2,%0
- and.w %2,%0
- anDq %b2,%0
- and.w %2,%0"
- [(set_attr "slottable" "yes,yes,yes,no,yes,no")
- (set_attr "cc" "clobber,noov32,noov32,noov32,clobber,noov32")])
-
;; A strict_low_part pattern.
;; Note the use of (match_dup 0) for the first operand of the operation
;; (subreg:QI (reg:SI 15 acr [orig:27 D.7531 ] [27]) 0)
;; (const_int -64 [0xf..fc0]))) x.c:126 147 {*andqi_lowpart_v32}
;; (nil))
+;; (Note: the example is obsolete.)
;; In theory, it could reload this as a movstrictqi of the register
;; operand at the and:QI to the destination register and change the
;; and:QI operand to the same as the read-write output operand and the
;; match_dup. FIXME: a sanity-check in gen* to refuse an insn with
;; input-constraints matching input-output-constraints, e.g. "+r" <- "0".
-(define_insn "*andhi_lowpart_non_v32"
+(define_insn "*andhi_lowpart"
[(set (strict_low_part
(match_operand:HI 0 "register_operand" "+r,r,r"))
(and:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "r,Q>,g")))]
- "!TARGET_V32"
+ ""
"@
and.w %1,%0
and.w %1,%0
and.w %1,%0"
[(set_attr "slottable" "yes,yes,no")])
-
-(define_insn "*andhi_lowpart_v32"
- [(set (strict_low_part
- (match_operand:HI 0 "register_operand" "+r,r,r"))
- (and:HI (match_dup 0)
- (match_operand:HI 1 "general_operand" "r,Q>,g")))]
- "TARGET_V32"
- "@
- and.w %1,%0
- and.w %1,%0
- and.w %1,%0"
- [(set_attr "slottable" "yes,yes,no")
- (set_attr "cc" "noov32")])
\f
(define_expand "andqi3"
[(set (match_operand:QI 0 "register_operand")
""
"")
-(define_insn "*andqi3_non_v32"
+(define_insn "*andqi3"
[(set (match_operand:QI 0 "register_operand" "=r,r,r, r,r,r")
(and:QI (match_operand:QI 1 "register_operand" "%0,0,0, 0,0,r")
(match_operand:QI 2 "general_operand" "I,r,Q>,O,g,!To")))]
- "!TARGET_V32"
+ ""
"@
andq %2,%0
and.b %2,%0
[(set_attr "slottable" "yes,yes,yes,yes,no,no")
(set_attr "cc" "clobber,normal,normal,clobber,normal,normal")])
-(define_insn "*andqi3_v32"
- [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
- (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0")
- (match_operand:QI 2 "general_operand" "I,r,Q>,O,g")))]
- "TARGET_V32"
- "@
- andq %2,%0
- and.b %2,%0
- and.b %2,%0
- andQ %b2,%0
- and.b %2,%0"
- [(set_attr "slottable" "yes,yes,yes,yes,no")
- (set_attr "cc" "clobber,noov32,noov32,clobber,noov32")])
-
-(define_insn "*andqi_lowpart_non_v32"
+(define_insn "*andqi_lowpart"
[(set (strict_low_part
(match_operand:QI 0 "register_operand" "+r,r,r"))
(and:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "r,Q>,g")))]
- "!TARGET_V32"
+ ""
"@
and.b %1,%0
and.b %1,%0
and.b %1,%0"
[(set_attr "slottable" "yes,yes,no")])
-
-(define_insn "*andqi_lowpart_v32"
- [(set (strict_low_part
- (match_operand:QI 0 "register_operand" "+r,r,r"))
- (and:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "r,Q>,g")))]
- "TARGET_V32"
- "@
- and.b %1,%0
- and.b %1,%0
- and.b %1,%0"
- [(set_attr "slottable" "yes,yes,no")
- (set_attr "cc" "noov32")])
\f
;; Bitwise or.
""
"")
-(define_insn "*iorsi3_non_v32"
+(define_insn "*iorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r, r,r,r")
(ior:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0,0,r")
(match_operand:SI 2 "general_operand" "I, r,Q>,n,g,!To")))]
- "!TARGET_V32"
+ ""
"@
orq %2,%0
or.d %2,%0
[(set_attr "slottable" "yes,yes,yes,no,no,no")
(set_attr "cc" "normal,normal,normal,clobber,normal,normal")])
-(define_insn "*iorsi3_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
- (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
- (match_operand:SI 2 "general_operand" "I,r,Q>,n,g")))]
- "TARGET_V32"
- "@
- orq %2,%0
- or.d %2,%0
- or.d %2,%0
- oR.%s2 %2,%0
- or.d %2,%0"
- [(set_attr "slottable" "yes,yes,yes,no,no")
- (set_attr "cc" "noov32,noov32,noov32,clobber,noov32")])
-
-(define_insn "*iorhi3_non_v32"
+(define_insn "*iorhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r,r, r,r,r,r")
(ior:HI (match_operand:HI 1 "register_operand" "%0,0,0, 0,0,0,r")
(match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g,!To")))]
- "!TARGET_V32"
+ ""
"@
orq %2,%0
or.w %2,%0
[(set_attr "slottable" "yes,yes,yes,no,yes,no,no")
(set_attr "cc" "clobber,normal,normal,normal,clobber,normal,normal")])
-(define_insn "*iorhi3_v32"
- [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
- (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
- (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g")))]
- "TARGET_V32"
- "@
- orq %2,%0
- or.w %2,%0
- or.w %2,%0
- or.w %2,%0
- oRq %b2,%0
- or.w %2,%0"
- [(set_attr "slottable" "yes,yes,yes,no,yes,no")
- (set_attr "cc" "clobber,noov32,noov32,noov32,clobber,noov32")])
-
-(define_insn "*iorqi3_non_v32"
+(define_insn "*iorqi3"
[(set (match_operand:QI 0 "register_operand" "=r,r,r, r,r,r")
(ior:QI (match_operand:QI 1 "register_operand" "%0,0,0, 0,0,r")
(match_operand:QI 2 "general_operand" "I,r,Q>,O,g,!To")))]
- "!TARGET_V32"
+ ""
"@
orq %2,%0
or.b %2,%0
or.b %2,%1,%0"
[(set_attr "slottable" "yes,yes,yes,yes,no,no")
(set_attr "cc" "clobber,normal,normal,clobber,normal,normal")])
-
-(define_insn "*iorqi3_v32"
- [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
- (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0")
- (match_operand:QI 2 "general_operand" "I,r,Q>,O,g")))]
- "TARGET_V32"
- "@
- orq %2,%0
- or.b %2,%0
- or.b %2,%0
- orQ %b2,%0
- or.b %2,%0"
- [(set_attr "slottable" "yes,yes,yes,yes,no")
- (set_attr "cc" "clobber,noov32,noov32,clobber,noov32")])
\f
;; Exclusive-or
(match_operand:SI 2 "register_operand" "r")))]
""
"xor %2,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
(define_insn "xor<mode>3"
[(set (match_operand:BW 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "register_operand" "0")))]
""
"not %0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
(define_insn "one_cmpl<mode>2"
[(set (match_operand:BW 0 "register_operand" "=r")
return "<slr>q %2,%0";
}
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
;; Since gcc gets lost, and forgets to zero-extend the source (or mask
;; the destination) when it changes shifts of lower modes into SImode,
(match_operand:BW 2 "register_operand" "r")))]
""
"<slr><m> %2,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
(define_insn "*<shlr><mode>_lowpart"
[(set (strict_low_part (match_operand:BW 0 "register_operand" "+r"))
(match_operand:BW 1 "register_operand" "r")))]
""
"<slr><m> %1,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
\f
;; Arithmetic/logical shift left.
? "lslq %2,%0" : "lsl<m> %2,%0");
}
[(set_attr "slottable" "yes")
- (set_attr "cc" "noov32,clobber")])
+ (set_attr "cc" "*,clobber")])
;; A strict_low_part matcher.
(match_operand:HI 1 "register_operand" "r")))]
""
"lsl<m> %1,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
\f
;; Various strange insns that gcc likes.
(abs:SI (match_operand:SI 1 "register_operand" "r")))]
""
"abs %1,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
;; FIXME: GCC should be able to do these expansions itself.
(clz:SI (match_operand:SI 1 "register_operand" "r")))]
"TARGET_HAS_LZ"
"lz %1,%0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
(define_insn "bswapsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(bswap:SI (match_operand:SI 1 "register_operand" "0")))]
"TARGET_HAS_SWAP"
"swapwb %0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
;; This instruction swaps all bits in a register.
;; That means that the most significant bit is put in the place
CRIS_UNSPEC_SWAP_BITS))]
"TARGET_HAS_SWAP"
"swapwbr %0"
- [(set_attr "slottable" "yes")
- (set_attr "cc" "noov32")])
+ [(set_attr "slottable" "yes")])
;; Implement ctz using two instructions, one for bit swap and one for clz.
;; Defines a scratch register to avoid clobbering input.
(umin:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "general_operand" "")))]
""
-{
- if (MEM_P (operands[2]) && TARGET_V32)
- operands[2] = force_reg (SImode, operands[2]);
-})
+ "")
-(define_insn "*uminsi3_non_v32"
+(define_insn "*uminsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
(umin:SI (match_operand:SI 1 "register_operand" "%0,0, 0,r")
(match_operand:SI 2 "general_operand" "r,Q>,g,!To")))]
- "!TARGET_V32"
+ ""
{
if (CONST_INT_P (operands[2]))
{
return "bound.d %2,%0";
}
[(set_attr "slottable" "yes,yes,no,no")])
-
-(define_insn "*uminsi3_v32"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
- (match_operand:SI 2 "nonmemory_operand" "r,i")))]
- "TARGET_V32"
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- {
- /* Constant operands are zero-extended, so only 32-bit operands
- may be negative. */
- if (INTVAL (operands[2]) >= 0)
- {
- if (INTVAL (operands[2]) < 256)
- return "bound.b %2,%0";
-
- if (INTVAL (operands[2]) < 65536)
- return "bound.w %2,%0";
- }
- }
-
- return "bound.d %2,%0";
-}
- [(set_attr "slottable" "yes,no")])
\f
;; Jump and branch insns.
(define_expand "indirect_jump"
[(set (pc) (match_operand:SI 0 "nonimmediate_operand"))]
""
-{
- if (TARGET_V32 && MEM_P (operands[0]))
- operands[0] = force_reg (SImode, operands[0]);
-})
+ "")
-(define_insn "*indirect_jump_non_v32"
+(define_insn "*indirect_jump"
[(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
- "!TARGET_V32"
+ ""
"jump %0")
-(define_insn "*indirect_jump_v32"
- [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
- "TARGET_V32"
- "jump %0%#"
- [(set_attr "slottable" "has_slot")])
-
;; Return insn. Used whenever the epilogue is very simple; if it is only
;; a single ret or jump [sp+]. No allocated stack space or saved
;; registers are allowed.
(label_ref (match_operand 3 "" ""))
(pc)))]
""
-{
- cris_reduce_compare (&operands[0], &operands[1], &operands[2]);
- if (TARGET_V32 && !REG_P (operands[1]))
- operands[1] = force_reg (DImode, operands[1]);
- if (TARGET_V32 && MEM_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
-})
+ "cris_reduce_compare (&operands[0], &operands[1], &operands[2]);")
;; We suffer from the same overflow-bit-gets-in-the-way problem as
(match_operator:SI 1 "ordered_comparison_operator"
[(cc0) (const_int 0)]))]
""
-{
- cris_reduce_compare (&operands[1], &operands[2], &operands[3]);
- if (TARGET_V32 && !REG_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
- if (TARGET_V32 && MEM_P (operands[3]))
- operands[3] = force_reg (DImode, operands[3]);
-})
+ "cris_reduce_compare (&operands[1], &operands[2], &operands[3]);")
(define_expand "cstore<mode>4"
[(set (cc0) (compare
;; instructions is a different issue.
(define_expand "call"
- [(parallel [(call (match_operand:QI 0 "cris_mem_call_operand" "")
- (match_operand 1 "general_operand" ""))
+ [(parallel [(call (match_operand:SI 0 "indirect_operand")
+ (match_operand 1 "general_operand"))
(clobber (reg:SI CRIS_SRP_REGNUM))])]
""
{
- gcc_assert (MEM_P (operands[0]));
- if (flag_pic)
- cris_expand_pic_call_address (&operands[0], &operands[1]);
- else
- operands[1] = const0_rtx;
+ operands[1] = const0_rtx;
})
;; Accept operands for operand 0 in order of preference.
-(define_insn "*expanded_call_non_v32"
+(define_insn "*expanded_call"
[(call (mem:QI (match_operand:SI 0 "general_operand" "r,Q>,g"))
- (match_operand:SI 1 "cris_call_type_marker" "rM,rM,rM"))
+ (const_int 0))
(clobber (reg:SI CRIS_SRP_REGNUM))]
- "!TARGET_V32"
+ ""
"jsr %0")
-(define_insn "*expanded_call_v32"
- [(call
- (mem:QI
- (match_operand:SI 0 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
- (match_operand:SI 1 "cris_call_type_marker" "rM,rM,rM,rM"))
- (clobber (reg:SI CRIS_SRP_REGNUM))]
- "TARGET_V32"
- "@
- jsr %0%#
- jsr %0%#
- bsr %0%#
- bsr %0%#"
- [(set_attr "slottable" "has_call_slot")])
-
-;; Parallel when calculating and reusing address of indirect pointer
-;; with simple offset. (Makes most sense with PIC.) It looks a bit
-;; wrong not to have the clobber last, but that's the way combine
-;; generates it (except it doesn't look into the *inner* mem, so this
-;; just matches a peephole2). FIXME: investigate that.
-(define_insn "*expanded_call_side"
- [(call (mem:QI
- (mem:SI
- (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r, r,r")
- (match_operand:SI 1 "cris_bdap_operand" "r>Rn,r,>Rn"))))
- (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM"))
- (clobber (reg:SI CRIS_SRP_REGNUM))
- (set (match_operand:SI 3 "register_operand" "=*0,r,r")
- (plus:SI (match_dup 0)
- (match_dup 1)))]
- ;; Disabled until after reload until we can avoid an output reload for
- ;; operand 3 (being forbidden for call insns).
- "reload_completed && !TARGET_AVOID_GOTPLT && !TARGET_V32"
- "jsr [%3=%0%S1]")
-
(define_expand "call_value"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand:QI 1 "cris_mem_call_operand" "")
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0 "")
+ (call (match_operand:SI 1 "indirect_operand")
+ (match_operand 2 "")))
(clobber (reg:SI CRIS_SRP_REGNUM))])]
""
{
- gcc_assert (MEM_P (operands[1]));
- if (flag_pic)
- cris_expand_pic_call_address (&operands[1], &operands[2]);
- else
- operands[2] = const0_rtx;
+ operands[2] = const0_rtx;
})
;; The validity other than "general" of
;; We also accept a PLT symbol. We output it as [rPIC+sym:GOTPLT] rather
;; than requiring getting rPIC + sym:PLT into a register.
-(define_insn "*expanded_call_value_non_v32"
+(define_insn "*expanded_call_value"
[(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
(call (mem:QI (match_operand:SI 1 "general_operand" "r,Q>,g"))
- (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM")))
+ (const_int 0)))
(clobber (reg:SI CRIS_SRP_REGNUM))]
- "!TARGET_V32"
+ ""
"Jsr %1"
[(set_attr "cc" "clobber")])
-;; See similar call special-case.
-(define_insn "*expanded_call_value_side"
- [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
- (call
- (mem:QI
- (mem:SI
- (plus:SI (match_operand:SI 1 "cris_bdap_operand" "%r, r,r")
- (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn"))))
- (match_operand:SI 3 "cris_call_type_marker" "rM,rM,rM")))
- (clobber (reg:SI CRIS_SRP_REGNUM))
- (set (match_operand:SI 4 "register_operand" "=*1,r,r")
- (plus:SI (match_dup 1)
- (match_dup 2)))]
- ;; Disabled until after reload until we can avoid an output reload for
- ;; operand 4 (being forbidden for call insns).
- "reload_completed && !TARGET_AVOID_GOTPLT && !TARGET_V32"
- "Jsr [%4=%1%S2]"
- [(set_attr "cc" "clobber")])
-
-(define_insn "*expanded_call_value_v32"
- [(set
- (match_operand 0 "nonimmediate_operand" "=g,g,g,g")
- (call
- (mem:QI
- (match_operand:SI 1 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
- (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM,rM")))
- (clobber (reg:SI 16))]
- "TARGET_V32"
- "@
- Jsr %1%#
- Jsr %1%#
- Bsr %1%#
- Bsr %1%#"
- [(set_attr "cc" "clobber")
- (set_attr "slottable" "has_call_slot")])
-
;; Used in debugging. No use for the direct pattern; unfilled
;; delayed-branches are taken care of by other means.
"nop"
[(set_attr "cc" "none")])
-;; Same as the gdb trap breakpoint, will cause a SIGTRAP for
-;; cris-linux* and crisv32-linux*, as intended. Will work in
-;; freestanding environments with sufficient framework.
+;; Same as the gdb trap breakpoint: would cause a SIGTRAP for
+;; cris-linux* and will work in freestanding environments with
+;; sufficient framework.
(define_insn "trap"
[(trap_if (const_int 1) (const_int 8))]
"TARGET_TRAP_USING_BREAK8"
;; this expansion, you must change the macro ASM_OUTPUT_CASE_END
;; accordingly, to add the default case at the end of the jump-table.
-(define_expand "cris_casesi_non_v32"
+(define_expand "casesi"
[(set (match_dup 5) (match_operand:SI 0 "general_operand" ""))
(set (match_dup 6)
(minus:SI (match_dup 5)
operands[6] = gen_reg_rtx (SImode);
operands[7] = gen_reg_rtx (SImode);
})
-
-;; FIXME: Check effect of not JUMP_TABLES_IN_TEXT_SECTION.
-(define_expand "cris_casesi_v32"
- [(set (match_dup 5) (match_operand:SI 0 "general_operand"))
- (set (match_dup 6)
- (minus:SI (match_dup 5)
- (match_operand:SI 1 "const_int_operand")))
- (set (match_dup 7)
- (umin:SI (match_dup 6)
- (match_operand:SI 2 "const_int_operand")))
- (set (match_dup 8) (match_dup 11))
- (set (match_dup 9)
- (plus:SI (mult:SI (match_dup 7) (const_int 2))
- (match_dup 8)))
- (set (match_dup 10)
- (plus:SI (sign_extend:SI (mem:HI (match_dup 9)))
- (match_dup 9)))
- (parallel
- [(set (pc)
- (if_then_else
- (ltu (unspec [(const_int 0)] CRIS_UNSPEC_CASESI) (match_dup 2))
- (match_dup 10)
- (label_ref (match_operand 4 "" ""))))
- (use (label_ref (match_dup 3)))])]
- "TARGET_V32"
-{
- int i;
- rtx xlabel = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
- for (i = 5; i <= 10; i++)
- operands[i] = gen_reg_rtx (SImode);
- operands[2] = plus_constant (SImode, operands[2], 1);
-
- /* Don't forget to decorate labels too, for PIC. */
- operands[11] = flag_pic
- ? gen_rtx_CONST (Pmode,
- gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xlabel),
- CRIS_UNSPEC_PCREL))
- : xlabel;
-})
-
-(define_expand "casesi"
- [(match_operand:SI 0 "general_operand")
- (match_operand:SI 1 "const_int_operand")
- (match_operand:SI 2 "const_int_operand")
- (match_operand 3 "" "")
- (match_operand 4 "" "")]
- ""
-{
- if (TARGET_V32)
- emit_insn (gen_cris_casesi_v32 (operands[0], operands[1], operands[2],
- operands[3], operands[4]));
- else
- emit_insn (gen_cris_casesi_non_v32 (operands[0], operands[1], operands[2],
- operands[3], operands[4]));
- DONE;
-})
\f
;; Split-patterns. Some of them have modes unspecified. This
;; should always be ok; if for no other reason sparc.md has it as
;; op [rx],rz
;; Lose if rz=ry or rx=rz.
;; Call this op-extend-split.
-;; Do not match for V32; the addo and addi shouldn't be split
-;; up.
(define_split
[(set (match_operand 0 "cris_nonsp_register_operand" "")
(match_operator
3 "cris_extend_operator"
[(match_operand 2 "memory_operand" "")])]))]
- "!TARGET_V32
- && REG_P (operands[0])
+ "REG_P (operands[0])
&& REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
(match_operator
3 "cris_extend_operator"
[(match_operand 2 "memory_operand" "")])]))]
- "!TARGET_V32
- && REG_P (operands[0])
+ "REG_P (operands[0])
&& REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3 "cris_extend_operator"
[(match_operand 2 "memory_operand" "")])
(match_operand 1 "register_operand" "")]))]
- "!TARGET_V32
- && REG_P (operands[0])
+ "REG_P (operands[0])
&& REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3 "cris_extend_operator"
[(match_operand 2 "memory_operand" "")])
(match_operand 1 "register_operand" "")]))]
- "!TARGET_V32
- && REG_P (operands[0])
+ "REG_P (operands[0])
&& REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3 "cris_orthogonal_operator"
[(match_operand 1 "register_operand" "")
(match_operand 2 "memory_operand" "")]))]
- "!TARGET_V32
- && REG_P (operands[0])
+ "REG_P (operands[0])
&& REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3 "cris_commutative_orth_op"
[(match_operand 2 "memory_operand" "")
(match_operand 1 "register_operand" "")]))]
- "!TARGET_V32
- && REG_P (operands[0])
+ "REG_P (operands[0])
&& REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3 "cris_commutative_orth_op"
[(match_operand 1 "register_operand" "")
(match_operand 2 "memory_operand" "")]))]
- "!TARGET_V32
- && REG_P (operands[0]) && REG_P (operands[1])
+ "REG_P (operands[0]) && REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
&& REG_P (XEXP (operands[2], 0))
3 "cris_orthogonal_operator"
[(match_operand 2 "memory_operand" "")
(match_operand 1 "register_operand" "")]))]
- "!TARGET_V32
- && REG_P (operands[0]) && REG_P (operands[1])
+ "REG_P (operands[0]) && REG_P (operands[1])
&& REGNO (operands[1]) != REGNO (operands[0])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
&& REG_P (XEXP (operands[2], 0))
/* Make sure we have canonical RTX so we match the insn pattern -
not a constant in the first operand. We also require the order
(plus reg mem) to match the final pattern. */
- if (CRIS_CONSTANT_P (otherop) || MEM_P (otherop))
+ if (CONSTANT_P (otherop) || MEM_P (otherop))
{
operands[7] = operands[1];
operands[8] = otherop;
/* Make sure we have canonical RTX so we match the insn pattern -
not a constant in the first operand. We also require the order
(plus reg mem) to match the final pattern. */
- if (CRIS_CONSTANT_P (otherop) || MEM_P (otherop))
+ if (CONSTANT_P (otherop) || MEM_P (otherop))
{
operands[7] = operands[1];
operands[8] = otherop;
operands[3] = gen_rtx_ZERO_EXTEND (SImode, op1);
operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]), QImode));
})
-
-;; Try and avoid GOTPLT reads escaping a call: transform them into
-;; PLT. Curiously (but thankfully), peepholes for instructions
-;; *without side-effects* that just feed a call (or call_value) are
-;; not matched neither in a build or test-suite, so those patterns are
-;; omitted.
-
-;; A "normal" move where we don't check the consumer.
-
-(define_peephole2 ; gotplt-to-plt
- [(set
- (match_operand:SI 0 "register_operand" "")
- (match_operator:SI
- 1 "cris_mem_op"
- [(plus:SI
- (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_operand:SI 2 "cris_general_operand_or_symbol" "")]
- CRIS_UNSPEC_PLTGOTREAD)))]))]
- "flag_pic
- && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
- && REGNO_REG_CLASS (REGNO (operands[0])) == REGNO_REG_CLASS (0)"
- [(set (match_dup 0) (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLT_GOTREL)))
- (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI CRIS_GOT_REGNUM)))]
- "")
-
-;; And one set with a side-effect getting the PLTGOT offset.
-;; First call and call_value variants.
-
-(define_peephole2 ; gotplt-to-plt-side-call
- [(parallel
- [(set
- (match_operand:SI 0 "register_operand" "")
- (match_operator:SI
- 1 "cris_mem_op"
- [(plus:SI
- (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_operand:SI
- 2 "cris_general_operand_or_symbol" "")]
- CRIS_UNSPEC_PLTGOTREAD)))]))
- (set (match_operand:SI 3 "register_operand" "")
- (plus:SI (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])
- (parallel [(call (mem:QI (match_dup 0))
- (match_operand 4 "" ""))
- (clobber (reg:SI CRIS_SRP_REGNUM))])]
- "flag_pic
- && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
- && peep2_reg_dead_p (2, operands[0])"
- [(parallel [(call (mem:QI (match_dup 1))
- (match_dup 4))
- (clobber (reg:SI CRIS_SRP_REGNUM))
- (set (match_dup 3)
- (plus:SI (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_dup 2)]
- CRIS_UNSPEC_PLTGOTREAD))))])]
- "")
-
-(define_peephole2 ; gotplt-to-plt-side-call-value
- [(parallel
- [(set
- (match_operand:SI 0 "register_operand" "")
- (match_operator:SI
- 1 "cris_mem_op"
- [(plus:SI
- (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_operand:SI
- 2 "cris_general_operand_or_symbol" "")]
- CRIS_UNSPEC_PLTGOTREAD)))]))
- (set (match_operand:SI 3 "register_operand" "")
- (plus:SI (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])
- (parallel [(set (match_operand 5 "" "")
- (call (mem:QI (match_dup 0))
- (match_operand 4 "" "")))
- (clobber (reg:SI CRIS_SRP_REGNUM))])]
- "flag_pic
- && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
- && peep2_reg_dead_p (2, operands[0])"
- [(parallel [(set (match_dup 5)
- (call (mem:QI (match_dup 1))
- (match_dup 4)))
- (clobber (reg:SI CRIS_SRP_REGNUM))
- (set (match_dup 3)
- (plus:SI (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_dup 2)]
- CRIS_UNSPEC_PLTGOTREAD))))])]
- "")
-
-(define_peephole2 ; gotplt-to-plt-side
- [(parallel
- [(set
- (match_operand:SI 0 "register_operand" "")
- (match_operator:SI
- 1 "cris_mem_op"
- [(plus:SI
- (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_operand:SI
- 2 "cris_general_operand_or_symbol" "")]
- CRIS_UNSPEC_PLTGOTREAD)))]))
- (set (match_operand:SI 3 "register_operand" "")
- (plus:SI (reg:SI CRIS_GOT_REGNUM)
- (const:SI
- (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])]
- "flag_pic
- && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
- && REGNO_REG_CLASS (REGNO (operands[0])) == REGNO_REG_CLASS (0)"
- [(set (match_dup 3)
- (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD)))
- (set (match_dup 3) (plus:SI (match_dup 3) (reg:SI CRIS_GOT_REGNUM)))
- (set (match_dup 0)
- (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLT_GOTREL)))
- (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI CRIS_GOT_REGNUM)))]
- "")
\f
;; Local variables:
;; mode:emacs-lisp