mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-23 15:01:17 +08:00
cris: Move trivially from cc0 to reg:CC model, removing most optimizations.
In the parlance of <https://gcc.gnu.org/wiki/CC0Transition>, this is a basic "type 2" conversion, without condition-code-related optimizations (just plain CCmode), but with "cstore{M}4" defined. CRIS is somewhat similar to the m68k; most instructions affect condition-codes. To wit, it lacks sufficient instructions to compose an arbitrary valid address in a register, specifically from a valid address where involved registers have to be spilled or adjusted, without affecting condition-codes in CRIS_CC0_REGNUM aka. dccr. On the other hand, moving dccr to and from a stackpointer-plus- constant-offset-address *can* be done without additional register use, and moving to or from a general register does not affect it. There's no instruction to add a constant to a register or to put a constant in a register, without affecting dccr, but there *is* an instruction to add a register (optionally scaled) to another without affecting dccr (i.e. "addi"). Also, moves *to* memory from any register do not affect dccr, and likewise between another special registers and a general register. Maybe some of that opens up the solution-space to a better solution than clobbering dccr until reload_completed; to be investigated. FAOD: I know what to do in the direction of defining and using additional CCmodes, but prefer to do the full transition in smaller steps. Regarding the similarity to m68k, I didn't follow the steps of the m68k cc0 transition, making use of the final_postscan_insn hook as with the a NOTICE_UPDATE_CC machinery. For one, because it seems to be lacking in that it keeps compare-elimination restricted to output-time, but also because it seems a bad match considering that CRIS has delay-slots; better try to eliminate compares earlier. Another approach which I originally intended to implement, that of the visium port of defining three variants for most insns (not counting the define_subst expansions; unaffecting-before-reload, clobbering and setting), seems overworked and bloating the machine description. I may be proven wrong, but I prefer we fix gcc if some something bails on seeing a parallel with a clobber of that specific hard-register. Also, I chose to remove most anonymous combination-matching patterns; matchers, splitters and peepholes instead of converting them to add clobbers of CRIS_CC0_REGNUM. There are exclusions: those covered in the test-suite, if trivial enough. Many of these patterns are used to handle the side-effect- assignment addressing-modes as put together by combine: a "prefix instruction" before the main instruction, where the main instruction uses the post-incremented-register addressing-mode and the "left-over" instruction-field in the prefixed insn to assign a register. An example: the hopefully descriptive "move.d $r9,[$r0=$r1+1234]" compared to "move.d $r9,[$r1+1234]"; both formed by the prefix insn "biap.w 1234,$r1" before respectively "move.d $r9,[$r0+]" and "move.d $r9,[$r0]". Other prefix variants exist. Useful, but optional, except where side-effect assignment was used in a special case in the function prologue; adjusted to a less optimal combination. Support like the function cris_side_effect_mode_ok is kept. I intend to put back as many as I find use for, of those anonymous patterns in a controlled manner, with self-contained test-cases proving their usability, rather than symmetry with other instructions and similar addressing modes, which guided the original introduction. I've entered pr93372 to track code performance regressions related to this transition, with focus on target-side causes and fixes; besides the function prologue special-case, there were some checking presence of the bit-test (btstq) instruction. The now-gone "tst<mode>" patterns deserve a comment too: they were an artefact from pre-"cbranch" era, now fully folded into the "cmp<mode>" patterns. I've left the now-unused "cc" insn attribute in, for the time being; to be removed, used or transformed to be useful with further work to fix pr93372. It can't be used as is, because "normal" doesn't mean "like a compare instruction" but "handled by NOTICE_UPDATE_CC" and may in fact be reflecting e.g. reverse operands, something that bit me during the conversion. gcc: Move trivially from cc0 to reg:CC model, removing most optimizations. * config/cris/cris.md: Remove all side-effect patterns and their splitters. Remove most peepholes. Add clobbers of CRIS_CC0_REGNUM to all but post-reload control-flow and movem insns. Remove constraints on all modified expanders. Remove obsoleted cc0-related references. (attr "cc"): Remove alternative "rev". (mode_iterator BWDD, DI_, SI_): New. (mode_attr sCC_destc, cmp_op1c, cmp_op2c): New. ("tst<mode>"): Remove; fold as "M" alternative into compare insn. ("mstep_shift", "mstep_mul"): Remove patterns. ("s<rcond>", "s<ocond>", "s<ncond>"): Anonymize. * config/cris/cris.c: Change all non-condition-code, non-control-flow emitted insns to add a parallel with clobber of CRIS_CC0_REGNUM, mostly by changing from gen_rtx_SET with emit_insn to use of emit_move_insn, gen_add2_insn or cris_emit_insn, as convenient. (cris_reg_overlap_mentioned_p) (cris_normal_notice_update_cc, cris_notice_update_cc): Remove. (cris_movem_load_rest_p): Don't assume all elements in a PARALLEL are SETs. (cris_store_multiple_op_p): Ditto. (cris_emit_insn): New function. * cris/cris-protos.h (cris_emit_insn): Declare.
This commit is contained in:
parent
d0780379c1
commit
fb062a8b7b
@ -9,6 +9,31 @@
|
||||
* config/cris/t-elfmulti: Remove crisv32 multilib.
|
||||
* config/cris: Remove shared-library and CRIS v32 support.
|
||||
|
||||
Move trivially from cc0 to reg:CC model, removing most optimizations.
|
||||
* config/cris/cris.md: Remove all side-effect patterns and their
|
||||
splitters. Remove most peepholes. Add clobbers of CRIS_CC0_REGNUM
|
||||
to all but post-reload control-flow and movem insns. Remove
|
||||
constraints on all modified expanders. Remove obsoleted cc0-related
|
||||
references.
|
||||
(attr "cc"): Remove alternative "rev".
|
||||
(mode_iterator BWDD, DI_, SI_): New.
|
||||
(mode_attr sCC_destc, cmp_op1c, cmp_op2c): New.
|
||||
("tst<mode>"): Remove; fold as "M" alternative into compare insn.
|
||||
("mstep_shift", "mstep_mul"): Remove patterns.
|
||||
("s<rcond>", "s<ocond>", "s<ncond>"): Anonymize.
|
||||
* config/cris/cris.c: Change all non-condition-code,
|
||||
non-control-flow emitted insns to add a parallel with clobber of
|
||||
CRIS_CC0_REGNUM, mostly by changing from gen_rtx_SET with
|
||||
emit_insn to use of emit_move_insn, gen_add2_insn or
|
||||
cris_emit_insn, as convenient.
|
||||
(cris_reg_overlap_mentioned_p)
|
||||
(cris_normal_notice_update_cc, cris_notice_update_cc): Remove.
|
||||
(cris_movem_load_rest_p): Don't assume all elements in a
|
||||
PARALLEL are SETs.
|
||||
(cris_store_multiple_op_p): Ditto.
|
||||
(cris_emit_insn): New function.
|
||||
* cris/cris-protos.h (cris_emit_insn): Declare.
|
||||
|
||||
2020-05-08 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
* ira-color.c (update_costs_from_allocno): Remove
|
||||
|
@ -36,11 +36,12 @@ extern void cris_reduce_compare (rtx *, rtx *, rtx *);
|
||||
extern bool cris_biap_index_p (const_rtx, bool);
|
||||
extern bool cris_legitimate_address_p (machine_mode, rtx, bool);
|
||||
extern bool cris_store_multiple_op_p (rtx);
|
||||
extern bool cris_movem_load_rest_p (rtx, int);
|
||||
extern bool cris_movem_load_rest_p (rtx);
|
||||
extern void cris_asm_output_symbol_ref (FILE *, rtx);
|
||||
extern void cris_asm_output_case_end (FILE *, int, rtx_insn *);
|
||||
extern rtx cris_gen_movem_load (rtx, rtx, int);
|
||||
extern rtx cris_gen_movem_load (rtx, rtx);
|
||||
extern rtx cris_emit_movem_store (rtx, rtx, int, bool);
|
||||
extern rtx_insn *cris_emit_insn (rtx x);
|
||||
extern void cris_order_for_addsi3 (rtx *, int);
|
||||
extern void cris_emit_trap_for_misalignment (rtx);
|
||||
#endif /* RTX_CODE */
|
||||
|
@ -90,9 +90,6 @@ static char cris_output_insn_is_bound = 0;
|
||||
goes in code or in a static initializer. */
|
||||
static int in_code = 0;
|
||||
|
||||
/* Fix for reg_overlap_mentioned_p. */
|
||||
static int cris_reg_overlap_mentioned_p (rtx, rtx);
|
||||
|
||||
static machine_mode cris_promote_function_mode (const_tree, machine_mode,
|
||||
int *, const_tree, int);
|
||||
|
||||
@ -290,9 +287,9 @@ struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
/* Helper for cris_load_multiple_op and cris_ret_movem_op. */
|
||||
|
||||
bool
|
||||
cris_movem_load_rest_p (rtx op, int offs)
|
||||
cris_movem_load_rest_p (rtx op)
|
||||
{
|
||||
unsigned int reg_count = XVECLEN (op, 0) - offs;
|
||||
unsigned int reg_count = XVECLEN (op, 0);
|
||||
rtx src_addr;
|
||||
int i;
|
||||
rtx elt;
|
||||
@ -303,35 +300,36 @@ cris_movem_load_rest_p (rtx op, int offs)
|
||||
/* Perform a quick check so we don't blow up below. FIXME: Adjust for
|
||||
other than (MEM reg). */
|
||||
if (reg_count <= 1
|
||||
|| GET_CODE (XVECEXP (op, 0, offs)) != SET
|
||||
|| !REG_P (SET_DEST (XVECEXP (op, 0, offs)))
|
||||
|| !MEM_P (SET_SRC (XVECEXP (op, 0, offs))))
|
||||
|| GET_CODE (XVECEXP (op, 0, 0)) != SET
|
||||
|| !REG_P (SET_DEST (XVECEXP (op, 0, 0)))
|
||||
|| !MEM_P (SET_SRC (XVECEXP (op, 0, 0))))
|
||||
return false;
|
||||
|
||||
/* Check a possible post-inc indicator. */
|
||||
if (GET_CODE (SET_SRC (XVECEXP (op, 0, offs + 1))) == PLUS)
|
||||
if (GET_CODE (XVECEXP (op, 0, 1)) == SET
|
||||
&& GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) == PLUS)
|
||||
{
|
||||
rtx reg = XEXP (SET_SRC (XVECEXP (op, 0, offs + 1)), 0);
|
||||
rtx inc = XEXP (SET_SRC (XVECEXP (op, 0, offs + 1)), 1);
|
||||
rtx reg = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 0);
|
||||
rtx inc = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1);
|
||||
|
||||
reg_count--;
|
||||
|
||||
if (reg_count == 1
|
||||
|| !REG_P (reg)
|
||||
|| !REG_P (SET_DEST (XVECEXP (op, 0, offs + 1)))
|
||||
|| REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, offs + 1)))
|
||||
|| !REG_P (SET_DEST (XVECEXP (op, 0, 1)))
|
||||
|| REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, 1)))
|
||||
|| !CONST_INT_P (inc)
|
||||
|| INTVAL (inc) != (HOST_WIDE_INT) reg_count * 4)
|
||||
return false;
|
||||
i = offs + 2;
|
||||
i = 2;
|
||||
}
|
||||
else
|
||||
i = offs + 1;
|
||||
i = 1;
|
||||
|
||||
regno_dir = -1;
|
||||
regno = reg_count - 1;
|
||||
|
||||
elt = XVECEXP (op, 0, offs);
|
||||
elt = XVECEXP (op, 0, 0);
|
||||
src_addr = XEXP (SET_SRC (elt), 0);
|
||||
|
||||
if (GET_CODE (elt) != SET
|
||||
@ -399,15 +397,15 @@ cris_store_multiple_op_p (rtx op)
|
||||
dest_addr = XEXP (dest, 0);
|
||||
|
||||
/* Check a possible post-inc indicator. */
|
||||
if (GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) == PLUS)
|
||||
if (GET_CODE (XVECEXP (op, 0, 1)) == SET
|
||||
&& GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) == PLUS)
|
||||
{
|
||||
rtx reg = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 0);
|
||||
rtx inc = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1);
|
||||
|
||||
reg_count--;
|
||||
|
||||
if (reg_count == 1
|
||||
|| !REG_P (reg)
|
||||
if (!REG_P (reg)
|
||||
|| !REG_P (SET_DEST (XVECEXP (op, 0, 1)))
|
||||
|| REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, 1)))
|
||||
|| !CONST_INT_P (inc)
|
||||
@ -1501,302 +1499,6 @@ cris_memory_move_cost (machine_mode mode,
|
||||
return 6;
|
||||
}
|
||||
|
||||
/* Worker for cris_notice_update_cc; handles the "normal" cases.
|
||||
FIXME: this code is historical; its functionality should be
|
||||
refactored to look at insn attributes and moved to
|
||||
cris_notice_update_cc. Except, we better lose cc0 entirely. */
|
||||
|
||||
static void
|
||||
cris_normal_notice_update_cc (rtx exp, rtx insn)
|
||||
{
|
||||
/* "Normal" means, for:
|
||||
(set (cc0) (...)):
|
||||
CC is (...).
|
||||
|
||||
(set (reg) (...)):
|
||||
CC is (reg) and (...) - unless (...) is 0 or reg is a special
|
||||
register, then CC does not change.
|
||||
CC_NO_OVERFLOW unless (...) is reg or mem.
|
||||
|
||||
(set (mem) (...)):
|
||||
CC does not change.
|
||||
|
||||
(set (pc) (...)):
|
||||
CC does not change.
|
||||
|
||||
(parallel
|
||||
(set (reg1) (mem (bdap/biap)))
|
||||
(set (reg2) (bdap/biap))):
|
||||
CC is (reg1) and (mem (reg2))
|
||||
|
||||
(parallel
|
||||
(set (mem (bdap/biap)) (reg1)) [or 0]
|
||||
(set (reg2) (bdap/biap))):
|
||||
CC does not change.
|
||||
|
||||
(where reg and mem includes strict_low_parts variants thereof)
|
||||
|
||||
For all others, assume CC is clobbered.
|
||||
Note that we do not have to care about setting CC_NO_OVERFLOW,
|
||||
since the overflow flag is set to 0 (i.e. right) for
|
||||
instructions where it does not have any sane sense, but where
|
||||
other flags have meanings. (This includes shifts; the carry is
|
||||
not set by them).
|
||||
|
||||
Note that there are other parallel constructs we could match,
|
||||
but we don't do that yet. */
|
||||
|
||||
if (GET_CODE (exp) == SET)
|
||||
{
|
||||
/* FIXME: Check when this happens. It looks like we should
|
||||
actually do a CC_STATUS_INIT here to be safe. */
|
||||
if (SET_DEST (exp) == pc_rtx)
|
||||
return;
|
||||
|
||||
/* Record CC0 changes, so we do not have to output multiple
|
||||
test insns. */
|
||||
if (SET_DEST (exp) == cc0_rtx)
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
|
||||
if (GET_CODE (SET_SRC (exp)) == COMPARE
|
||||
&& XEXP (SET_SRC (exp), 1) == const0_rtx)
|
||||
cc_status.value1 = XEXP (SET_SRC (exp), 0);
|
||||
else
|
||||
cc_status.value1 = SET_SRC (exp);
|
||||
|
||||
/* Handle flags for the special btstq on one bit. */
|
||||
if (GET_CODE (cc_status.value1) == ZERO_EXTRACT
|
||||
&& XEXP (cc_status.value1, 1) == const1_rtx)
|
||||
{
|
||||
if (CONST_INT_P (XEXP (cc_status.value1, 0)))
|
||||
/* Using cmpq. */
|
||||
cc_status.flags = CC_INVERTED;
|
||||
else
|
||||
/* A one-bit btstq. */
|
||||
cc_status.flags = CC_Z_IN_NOT_N;
|
||||
}
|
||||
|
||||
else if (GET_CODE (SET_SRC (exp)) == COMPARE)
|
||||
{
|
||||
if (!REG_P (XEXP (SET_SRC (exp), 0))
|
||||
&& XEXP (SET_SRC (exp), 1) != const0_rtx)
|
||||
/* For some reason gcc will not canonicalize compare
|
||||
operations, reversing the sign by itself if
|
||||
operands are in wrong order. */
|
||||
/* (But NOT inverted; eq is still eq.) */
|
||||
cc_status.flags = CC_REVERSED;
|
||||
|
||||
/* This seems to be overlooked by gcc. FIXME: Check again.
|
||||
FIXME: Is it really safe? */
|
||||
cc_status.value2
|
||||
= gen_rtx_MINUS (GET_MODE (SET_SRC (exp)),
|
||||
XEXP (SET_SRC (exp), 0),
|
||||
XEXP (SET_SRC (exp), 1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (REG_P (SET_DEST (exp))
|
||||
|| (GET_CODE (SET_DEST (exp)) == STRICT_LOW_PART
|
||||
&& REG_P (XEXP (SET_DEST (exp), 0))))
|
||||
{
|
||||
/* A register is set; normally CC is set to show that no
|
||||
test insn is needed. Catch the exceptions. */
|
||||
|
||||
/* If not to cc0, then no "set"s in non-natural mode give
|
||||
ok cc0... */
|
||||
if (GET_MODE_SIZE (GET_MODE (SET_DEST (exp))) > UNITS_PER_WORD
|
||||
|| GET_MODE_CLASS (GET_MODE (SET_DEST (exp))) == MODE_FLOAT)
|
||||
{
|
||||
/* ... except add:s and sub:s in DImode. */
|
||||
if (GET_MODE (SET_DEST (exp)) == DImode
|
||||
&& (GET_CODE (SET_SRC (exp)) == PLUS
|
||||
|| GET_CODE (SET_SRC (exp)) == MINUS))
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_DEST (exp);
|
||||
cc_status.value2 = SET_SRC (exp);
|
||||
|
||||
if (cris_reg_overlap_mentioned_p (cc_status.value1,
|
||||
cc_status.value2))
|
||||
cc_status.value2 = 0;
|
||||
|
||||
/* Add and sub may set V, which gets us
|
||||
unoptimizable results in "gt" and "le" condition
|
||||
codes. */
|
||||
cc_status.flags |= CC_NO_OVERFLOW;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (SET_SRC (exp) == const0_rtx
|
||||
|| (REG_P (SET_SRC (exp))
|
||||
&& (REGNO (SET_SRC (exp))
|
||||
> CRIS_LAST_GENERAL_REGISTER)))
|
||||
{
|
||||
/* There's no CC0 change for this case. Just check
|
||||
for overlap. */
|
||||
if (cc_status.value1
|
||||
&& modified_in_p (cc_status.value1, insn))
|
||||
cc_status.value1 = 0;
|
||||
|
||||
if (cc_status.value2
|
||||
&& modified_in_p (cc_status.value2, insn))
|
||||
cc_status.value2 = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_DEST (exp);
|
||||
cc_status.value2 = SET_SRC (exp);
|
||||
|
||||
if (cris_reg_overlap_mentioned_p (cc_status.value1,
|
||||
cc_status.value2))
|
||||
cc_status.value2 = 0;
|
||||
|
||||
/* Some operations may set V, which gets us
|
||||
unoptimizable results in "gt" and "le" condition
|
||||
codes. */
|
||||
if (GET_CODE (SET_SRC (exp)) == PLUS
|
||||
|| GET_CODE (SET_SRC (exp)) == MINUS
|
||||
|| GET_CODE (SET_SRC (exp)) == NEG)
|
||||
cc_status.flags |= CC_NO_OVERFLOW;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (MEM_P (SET_DEST (exp))
|
||||
|| (GET_CODE (SET_DEST (exp)) == STRICT_LOW_PART
|
||||
&& MEM_P (XEXP (SET_DEST (exp), 0))))
|
||||
{
|
||||
/* When SET to MEM, then CC is not changed (except for
|
||||
overlap). */
|
||||
if (cc_status.value1
|
||||
&& modified_in_p (cc_status.value1, insn))
|
||||
cc_status.value1 = 0;
|
||||
|
||||
if (cc_status.value2
|
||||
&& modified_in_p (cc_status.value2, insn))
|
||||
cc_status.value2 = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (GET_CODE (exp) == PARALLEL)
|
||||
{
|
||||
if (GET_CODE (XVECEXP (exp, 0, 0)) == SET
|
||||
&& GET_CODE (XVECEXP (exp, 0, 1)) == SET
|
||||
&& REG_P (XEXP (XVECEXP (exp, 0, 1), 0)))
|
||||
{
|
||||
if (REG_P (XEXP (XVECEXP (exp, 0, 0), 0))
|
||||
&& MEM_P (XEXP (XVECEXP (exp, 0, 0), 1)))
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
|
||||
/* For "move.S [rx=ry+o],rz", say CC reflects
|
||||
value1=rz and value2=[rx] */
|
||||
cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
|
||||
cc_status.value2
|
||||
= replace_equiv_address (XEXP (XVECEXP (exp, 0, 0), 1),
|
||||
XEXP (XVECEXP (exp, 0, 1), 0));
|
||||
|
||||
/* Huh? A side-effect cannot change the destination
|
||||
register. */
|
||||
if (cris_reg_overlap_mentioned_p (cc_status.value1,
|
||||
cc_status.value2))
|
||||
internal_error ("internal error: sideeffect-insn affecting main effect");
|
||||
return;
|
||||
}
|
||||
else if ((REG_P (XEXP (XVECEXP (exp, 0, 0), 1))
|
||||
|| XEXP (XVECEXP (exp, 0, 0), 1) == const0_rtx)
|
||||
&& MEM_P (XEXP (XVECEXP (exp, 0, 0), 0)))
|
||||
{
|
||||
/* For "move.S rz,[rx=ry+o]" and "clear.S [rx=ry+o]",
|
||||
say flags are not changed, except for overlap. */
|
||||
if (cc_status.value1
|
||||
&& modified_in_p (cc_status.value1, insn))
|
||||
cc_status.value1 = 0;
|
||||
|
||||
if (cc_status.value2
|
||||
&& modified_in_p (cc_status.value2, insn))
|
||||
cc_status.value2 = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got here, the case wasn't covered by the code above. */
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
|
||||
/* This function looks into the pattern to see how this insn affects
|
||||
condition codes.
|
||||
|
||||
Used when to eliminate test insns before a condition-code user,
|
||||
such as a "scc" insn or a conditional branch. This includes
|
||||
checking if the entities that cc was updated by, are changed by the
|
||||
operation.
|
||||
|
||||
Currently a jumble of the old peek-inside-the-insn and the newer
|
||||
check-cc-attribute methods. */
|
||||
|
||||
void
|
||||
cris_notice_update_cc (rtx exp, rtx_insn *insn)
|
||||
{
|
||||
enum attr_cc attrval = get_attr_cc (insn);
|
||||
|
||||
/* Check if user specified "-mcc-init" as a bug-workaround. Remember
|
||||
to still set CC_REVERSED as below, since that's required by some
|
||||
compare insn alternatives. (FIXME: GCC should do this virtual
|
||||
operand swap by itself.) A test-case that may otherwise fail is
|
||||
gcc.c-torture/execute/20000217-1.c -O0 and -O1. */
|
||||
if (TARGET_CCINIT)
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
|
||||
if (attrval == CC_REV)
|
||||
cc_status.flags = CC_REVERSED;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Slowly, we're converting to using attributes to control the setting
|
||||
of condition-code status. */
|
||||
switch (attrval)
|
||||
{
|
||||
case CC_NONE:
|
||||
/* Even if it is "none", a setting may clobber a previous
|
||||
cc-value, so check. */
|
||||
if (GET_CODE (exp) == SET)
|
||||
{
|
||||
if (cc_status.value1
|
||||
&& modified_in_p (cc_status.value1, insn))
|
||||
cc_status.value1 = 0;
|
||||
|
||||
if (cc_status.value2
|
||||
&& modified_in_p (cc_status.value2, insn))
|
||||
cc_status.value2 = 0;
|
||||
}
|
||||
return;
|
||||
|
||||
case CC_CLOBBER:
|
||||
CC_STATUS_INIT;
|
||||
return;
|
||||
|
||||
case CC_REV:
|
||||
case CC_NORMAL:
|
||||
cris_normal_notice_update_cc (exp, insn);
|
||||
return;
|
||||
|
||||
default:
|
||||
internal_error ("unknown cc_attr value");
|
||||
}
|
||||
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
|
||||
/* Return != 0 if the return sequence for the current function is short,
|
||||
like "ret" or "jump [sp+]". Prior to reloading, we can't tell if
|
||||
registers must be saved, so return 0 then. */
|
||||
@ -2208,23 +1910,6 @@ cris_side_effect_mode_ok (enum rtx_code code, rtx *ops,
|
||||
internal_error ("internal error: cris_side_effect_mode_ok with bad operands");
|
||||
}
|
||||
|
||||
/* 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
|
||||
care of that for THIS port. FIXME: strict_low_part is going away
|
||||
anyway. */
|
||||
|
||||
static int
|
||||
cris_reg_overlap_mentioned_p (rtx x, rtx in)
|
||||
{
|
||||
/* The function reg_overlap_mentioned now handles when X is
|
||||
strict_low_part, but not when IN is a STRICT_LOW_PART. */
|
||||
if (GET_CODE (in) == STRICT_LOW_PART)
|
||||
in = XEXP (in, 0);
|
||||
|
||||
return reg_overlap_mentioned_p (x, in);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
@ -2480,22 +2165,20 @@ cris_split_movdx (rtx *operands)
|
||||
/* We normally copy the low-numbered register first. However, if
|
||||
the first register operand 0 is the same as the second register of
|
||||
operand 1, we must copy in the opposite order. */
|
||||
emit_insn (gen_rtx_SET (operand_subword (dest, reverse, TRUE, mode),
|
||||
operand_subword (src, reverse, TRUE, mode)));
|
||||
emit_move_insn (operand_subword (dest, reverse, TRUE, mode),
|
||||
operand_subword (src, reverse, TRUE, mode));
|
||||
|
||||
emit_insn (gen_rtx_SET (operand_subword (dest, !reverse, TRUE, mode),
|
||||
operand_subword (src, !reverse, TRUE, mode)));
|
||||
emit_move_insn (operand_subword (dest, !reverse, TRUE, mode),
|
||||
operand_subword (src, !reverse, TRUE, mode));
|
||||
}
|
||||
/* Constant-to-reg copy. */
|
||||
else if (CONST_INT_P (src) || GET_CODE (src) == CONST_DOUBLE)
|
||||
{
|
||||
rtx words[2];
|
||||
split_double (src, &words[0], &words[1]);
|
||||
emit_insn (gen_rtx_SET (operand_subword (dest, 0, TRUE, mode),
|
||||
words[0]));
|
||||
emit_move_insn (operand_subword (dest, 0, TRUE, mode), words[0]);
|
||||
|
||||
emit_insn (gen_rtx_SET (operand_subword (dest, 1, TRUE, mode),
|
||||
words[1]));
|
||||
emit_move_insn (operand_subword (dest, 1, TRUE, mode), words[1]);
|
||||
}
|
||||
/* Mem-to-reg copy. */
|
||||
else if (MEM_P (src))
|
||||
@ -2522,18 +2205,15 @@ cris_split_movdx (rtx *operands)
|
||||
addresses ourselves, we must add a post-inc note
|
||||
manually. */
|
||||
mem = change_address (src, SImode, addr);
|
||||
insn
|
||||
= gen_rtx_SET (operand_subword (dest, 0, TRUE, mode), mem);
|
||||
insn = emit_insn (insn);
|
||||
insn = emit_move_insn (operand_subword (dest, 0, TRUE, mode),
|
||||
mem);
|
||||
if (GET_CODE (XEXP (mem, 0)) == POST_INC)
|
||||
REG_NOTES (insn)
|
||||
= alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
|
||||
REG_NOTES (insn));
|
||||
|
||||
mem = copy_rtx (mem);
|
||||
insn
|
||||
= gen_rtx_SET (operand_subword (dest, 1, TRUE, mode), mem);
|
||||
insn = emit_insn (insn);
|
||||
insn = emit_move_insn (operand_subword (dest, 1, TRUE, mode), mem);
|
||||
if (GET_CODE (XEXP (mem, 0)) == POST_INC)
|
||||
REG_NOTES (insn)
|
||||
= alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
|
||||
@ -2548,19 +2228,17 @@ cris_split_movdx (rtx *operands)
|
||||
if (side_effects_p (addr))
|
||||
fatal_insn ("unexpected side-effects in address", addr);
|
||||
|
||||
emit_insn (gen_rtx_SET
|
||||
(operand_subword (dest, reverse, TRUE, mode),
|
||||
change_address
|
||||
(src, SImode,
|
||||
plus_constant (Pmode, addr,
|
||||
reverse * UNITS_PER_WORD))));
|
||||
emit_insn (gen_rtx_SET
|
||||
(operand_subword (dest, ! reverse, TRUE, mode),
|
||||
change_address
|
||||
(src, SImode,
|
||||
plus_constant (Pmode, addr,
|
||||
(! reverse) *
|
||||
UNITS_PER_WORD))));
|
||||
emit_move_insn (operand_subword (dest, reverse, TRUE, mode),
|
||||
change_address
|
||||
(src, SImode,
|
||||
plus_constant (Pmode, addr,
|
||||
reverse * UNITS_PER_WORD)));
|
||||
emit_move_insn (operand_subword (dest, ! reverse, TRUE, mode),
|
||||
change_address
|
||||
(src, SImode,
|
||||
plus_constant (Pmode, addr,
|
||||
(! reverse) *
|
||||
UNITS_PER_WORD)));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2582,17 +2260,14 @@ cris_split_movdx (rtx *operands)
|
||||
/* Whenever we emit insns with post-incremented addresses
|
||||
ourselves, we must add a post-inc note manually. */
|
||||
mem = change_address (dest, SImode, addr);
|
||||
insn
|
||||
= gen_rtx_SET (mem, operand_subword (src, 0, TRUE, mode));
|
||||
insn = emit_insn (insn);
|
||||
insn = emit_move_insn (mem, operand_subword (src, 0, TRUE, mode));
|
||||
if (GET_CODE (XEXP (mem, 0)) == POST_INC)
|
||||
REG_NOTES (insn)
|
||||
= alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
|
||||
REG_NOTES (insn));
|
||||
|
||||
mem = copy_rtx (mem);
|
||||
insn = gen_rtx_SET (mem, operand_subword (src, 1, TRUE, mode));
|
||||
insn = emit_insn (insn);
|
||||
insn = emit_move_insn (mem, operand_subword (src, 1, TRUE, mode));
|
||||
if (GET_CODE (XEXP (mem, 0)) == POST_INC)
|
||||
REG_NOTES (insn)
|
||||
= alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
|
||||
@ -2606,15 +2281,13 @@ cris_split_movdx (rtx *operands)
|
||||
if (side_effects_p (addr))
|
||||
fatal_insn ("unexpected side-effects in address", addr);
|
||||
|
||||
emit_insn (gen_rtx_SET
|
||||
(change_address (dest, SImode, addr),
|
||||
operand_subword (src, 0, TRUE, mode)));
|
||||
emit_move_insn (change_address (dest, SImode, addr),
|
||||
operand_subword (src, 0, TRUE, mode));
|
||||
|
||||
emit_insn (gen_rtx_SET
|
||||
(change_address (dest, SImode,
|
||||
plus_constant (Pmode, addr,
|
||||
UNITS_PER_WORD)),
|
||||
operand_subword (src, 1, TRUE, mode)));
|
||||
emit_move_insn (change_address (dest, SImode,
|
||||
plus_constant (Pmode, addr,
|
||||
UNITS_PER_WORD)),
|
||||
operand_subword (src, 1, TRUE, mode));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2727,10 +2400,7 @@ cris_expand_prologue (void)
|
||||
stdarg_regs > 0;
|
||||
regno--, pretend -= 4, stdarg_regs--)
|
||||
{
|
||||
insn = emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode,
|
||||
stack_pointer_rtx,
|
||||
-4)));
|
||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (-4)));
|
||||
/* FIXME: When dwarf2 frame output and unless asynchronous
|
||||
exceptions, make dwarf2 bundle together all stack
|
||||
adjustments like it does for registers between stack
|
||||
@ -2755,9 +2425,8 @@ cris_expand_prologue (void)
|
||||
/* Save SRP if not a leaf function. */
|
||||
if (return_address_on_stack)
|
||||
{
|
||||
insn = emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx,
|
||||
-4 - pretend)));
|
||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (-4 - pretend)));
|
||||
pretend = 0;
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
@ -2771,9 +2440,8 @@ cris_expand_prologue (void)
|
||||
/* Set up the frame pointer, if needed. */
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
insn = emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx,
|
||||
-4 - pretend)));
|
||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (-4 - pretend)));
|
||||
pretend = 0;
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
@ -2820,7 +2488,10 @@ cris_expand_prologue (void)
|
||||
side-effects insns are allowed. */
|
||||
if ((last_movem_reg + 1) * 4 + size >= 64
|
||||
&& (last_movem_reg + 1) * 4 + size <= 128
|
||||
&& (cris_cpu_version >= CRIS_CPU_SVINTO || n_saved == 1)
|
||||
&& cris_cpu_version >= CRIS_CPU_SVINTO
|
||||
/* Don't use side-effect assignment for a single
|
||||
move. */
|
||||
&& n_saved > 1
|
||||
&& TARGET_SIDE_EFFECT_PREFIXES)
|
||||
{
|
||||
mem
|
||||
@ -2836,10 +2507,9 @@ cris_expand_prologue (void)
|
||||
else
|
||||
{
|
||||
insn
|
||||
= gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx,
|
||||
-(n_saved * 4 + size)));
|
||||
insn = emit_insn (insn);
|
||||
= emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (-(n_saved * 4
|
||||
+ size))));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
|
||||
@ -2853,10 +2523,8 @@ cris_expand_prologue (void)
|
||||
size = 0;
|
||||
}
|
||||
|
||||
insn = emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode,
|
||||
stack_pointer_rtx,
|
||||
-4 - size)));
|
||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (-4 - size)));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
|
||||
@ -2880,7 +2548,9 @@ cris_expand_prologue (void)
|
||||
do it if side-effects insns are allowed. */
|
||||
if ((last_movem_reg + 1) * 4 + size >= 64
|
||||
&& (last_movem_reg + 1) * 4 + size <= 128
|
||||
&& (cris_cpu_version >= CRIS_CPU_SVINTO || n_saved == 1)
|
||||
&& cris_cpu_version >= CRIS_CPU_SVINTO
|
||||
/* Don't use side-effect assignment for a single move. */
|
||||
&& n_saved > 1
|
||||
&& TARGET_SIDE_EFFECT_PREFIXES)
|
||||
{
|
||||
mem
|
||||
@ -2893,11 +2563,8 @@ cris_expand_prologue (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
insn
|
||||
= gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx,
|
||||
-(n_saved * 4 + size)));
|
||||
insn = emit_insn (insn);
|
||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (-(n_saved * 4 + size))));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
|
||||
@ -2909,20 +2576,16 @@ cris_expand_prologue (void)
|
||||
/* We have to put outgoing argument space after regs. */
|
||||
if (cfoa_size)
|
||||
{
|
||||
insn = emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode,
|
||||
stack_pointer_rtx,
|
||||
-cfoa_size)));
|
||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (-cfoa_size)));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
framesize += cfoa_size;
|
||||
}
|
||||
}
|
||||
else if ((size + cfoa_size) > 0)
|
||||
{
|
||||
insn = emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode,
|
||||
stack_pointer_rtx,
|
||||
-(cfoa_size + size))));
|
||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (-(cfoa_size + size))));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
framesize += size + cfoa_size;
|
||||
}
|
||||
@ -2988,9 +2651,8 @@ cris_expand_epilogue (void)
|
||||
{
|
||||
/* There is an area for outgoing parameters located before
|
||||
the saved registers. We have to adjust for that. */
|
||||
emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx,
|
||||
argspace_offset)));
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
GEN_INT (argspace_offset)));
|
||||
/* Make sure we only do this once. */
|
||||
argspace_offset = 0;
|
||||
}
|
||||
@ -3013,9 +2675,7 @@ cris_expand_epilogue (void)
|
||||
|
||||
if (argspace_offset)
|
||||
{
|
||||
emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx,
|
||||
argspace_offset)));
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (argspace_offset)));
|
||||
argspace_offset = 0;
|
||||
}
|
||||
|
||||
@ -3023,8 +2683,7 @@ cris_expand_epilogue (void)
|
||||
gen_rtx_POST_INC (SImode, stack_pointer_rtx));
|
||||
set_mem_alias_set (mem, get_frame_alias_set ());
|
||||
insn
|
||||
= emit_insn (cris_gen_movem_load (mem,
|
||||
GEN_INT (last_movem_reg + 1), 0));
|
||||
= emit_insn (cris_gen_movem_load (mem, GEN_INT (last_movem_reg + 1)));
|
||||
/* Whenever we emit insns with post-incremented addresses
|
||||
ourselves, we must add a post-inc note manually. */
|
||||
if (side_effects_p (PATTERN (insn)))
|
||||
@ -3071,8 +2730,7 @@ cris_expand_epilogue (void)
|
||||
yet. */
|
||||
size += argspace_offset;
|
||||
|
||||
emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx, size)));
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (size)));
|
||||
}
|
||||
|
||||
/* If this function has no pushed register parameters
|
||||
@ -3097,9 +2755,8 @@ cris_expand_epilogue (void)
|
||||
= alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
|
||||
|
||||
if (crtl->calls_eh_return)
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
gen_raw_REG (SImode, CRIS_STACKADJ_REG)));
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
gen_raw_REG (SImode, CRIS_STACKADJ_REG)));
|
||||
cris_expand_return (false);
|
||||
}
|
||||
else
|
||||
@ -3131,23 +2788,20 @@ cris_expand_epilogue (void)
|
||||
= alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
|
||||
}
|
||||
|
||||
emit_insn (gen_rtx_SET (stack_pointer_rtx,
|
||||
plus_constant (Pmode, stack_pointer_rtx,
|
||||
pretend)));
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (pretend)));
|
||||
}
|
||||
|
||||
/* Perform the "physical" unwinding that the EH machinery calculated. */
|
||||
if (crtl->calls_eh_return)
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
gen_raw_REG (SImode, CRIS_STACKADJ_REG)));
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||
gen_raw_REG (SImode, CRIS_STACKADJ_REG)));
|
||||
cris_expand_return (false);
|
||||
}
|
||||
|
||||
/* Worker function for generating movem from mem for load_multiple. */
|
||||
|
||||
rtx
|
||||
cris_gen_movem_load (rtx src, rtx nregs_rtx, int nprefix)
|
||||
cris_gen_movem_load (rtx src, rtx nregs_rtx)
|
||||
{
|
||||
int nregs = INTVAL (nregs_rtx);
|
||||
rtvec vec;
|
||||
@ -3166,24 +2820,23 @@ cris_gen_movem_load (rtx src, rtx nregs_rtx, int nprefix)
|
||||
if (nregs == 1)
|
||||
return gen_movsi (gen_rtx_REG (SImode, 0), src);
|
||||
|
||||
vec = rtvec_alloc (nprefix + nregs
|
||||
+ (GET_CODE (XEXP (src, 0)) == POST_INC));
|
||||
vec = rtvec_alloc (nregs + (GET_CODE (XEXP (src, 0)) == POST_INC));
|
||||
|
||||
if (GET_CODE (XEXP (src, 0)) == POST_INC)
|
||||
{
|
||||
RTVEC_ELT (vec, nprefix + 1)
|
||||
RTVEC_ELT (vec, 1)
|
||||
= gen_rtx_SET (srcreg, plus_constant (Pmode, srcreg, nregs * 4));
|
||||
eltno++;
|
||||
}
|
||||
|
||||
src = replace_equiv_address (src, srcreg);
|
||||
RTVEC_ELT (vec, nprefix)
|
||||
RTVEC_ELT (vec, 0)
|
||||
= gen_rtx_SET (gen_rtx_REG (SImode, regno), src);
|
||||
regno += regno_inc;
|
||||
|
||||
for (i = 1; i < nregs; i++, eltno++)
|
||||
{
|
||||
RTVEC_ELT (vec, nprefix + eltno)
|
||||
RTVEC_ELT (vec, eltno)
|
||||
= gen_rtx_SET (gen_rtx_REG (SImode, regno),
|
||||
adjust_address_nv (src, SImode, i * 4));
|
||||
regno += regno_inc;
|
||||
@ -3192,6 +2845,22 @@ cris_gen_movem_load (rtx src, rtx nregs_rtx, int nprefix)
|
||||
return gen_rtx_PARALLEL (VOIDmode, vec);
|
||||
}
|
||||
|
||||
/* Convenience function for CRIS-local use of emit_insn, wrapping the
|
||||
argument in a parallel with a clobber of CRIS_CC0_REGNUM before
|
||||
passing on to emit_insn. */
|
||||
|
||||
rtx_insn *
|
||||
cris_emit_insn (rtx x)
|
||||
{
|
||||
rtvec vec = rtvec_alloc (2);
|
||||
|
||||
RTVEC_ELT (vec, 0) = x;
|
||||
RTVEC_ELT (vec, 1)
|
||||
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CRIS_CC0_REGNUM));
|
||||
|
||||
return emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
|
||||
}
|
||||
|
||||
/* Worker function for generating movem to mem. If FRAME_RELATED, notes
|
||||
are added that the dwarf2 machinery understands. */
|
||||
|
||||
@ -3219,11 +2888,9 @@ cris_emit_movem_store (rtx dest, rtx nregs_rtx, int increment,
|
||||
/* 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));
|
||||
|
||||
if (increment == 0)
|
||||
{
|
||||
insn = emit_insn (mov);
|
||||
insn = emit_move_insn (dest, gen_rtx_REG (SImode, 0));
|
||||
if (frame_related)
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
return insn;
|
||||
@ -3231,11 +2898,15 @@ cris_emit_movem_store (rtx dest, rtx nregs_rtx, int increment,
|
||||
|
||||
/* If there was a request for a side-effect, create the ordinary
|
||||
parallel. */
|
||||
vec = rtvec_alloc (2);
|
||||
vec = rtvec_alloc (3);
|
||||
|
||||
rtx mov = gen_rtx_SET (dest, gen_rtx_REG (SImode, 0));
|
||||
RTVEC_ELT (vec, 0) = mov;
|
||||
RTVEC_ELT (vec, 1) = gen_rtx_SET (destreg, plus_constant (Pmode, destreg,
|
||||
increment));
|
||||
RTVEC_ELT (vec, 2)
|
||||
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CRIS_CC0_REGNUM));
|
||||
|
||||
if (frame_related)
|
||||
{
|
||||
RTX_FRAME_RELATED_P (mov) = 1;
|
||||
|
@ -698,11 +698,8 @@ struct cum_args {int regs;};
|
||||
|
||||
/* Node: Condition Code */
|
||||
|
||||
#define NOTICE_UPDATE_CC(EXP, INSN) cris_notice_update_cc (EXP, INSN)
|
||||
|
||||
/* FIXME: Maybe define CANONICALIZE_COMPARISON later, when playing with
|
||||
optimizations. It is needed; currently we do this with instruction
|
||||
patterns and NOTICE_UPDATE_CC. */
|
||||
/* FIXME: Maybe define TARGET_CANONICALIZE_COMPARISON later, when
|
||||
playing with optimizations. Definitely define SELECT_CC_MODE. */
|
||||
|
||||
|
||||
/* Node: Costs */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -51,7 +51,7 @@
|
||||
|
||||
(define_predicate "cris_load_multiple_op"
|
||||
(and (match_code "parallel")
|
||||
(match_test "cris_movem_load_rest_p (op, 0)")))
|
||||
(match_test "cris_movem_load_rest_p (op)")))
|
||||
|
||||
(define_predicate "cris_store_multiple_op"
|
||||
(and (match_code "parallel")
|
||||
|
@ -123,7 +123,8 @@
|
||||
(match_operand:BWD 2 "<atomic_op_op_pred>" "<atomic_op_op_cnstr>")))
|
||||
(set (match_operand:BWD 0 "register_operand" "=&r")
|
||||
(match_dup 1))
|
||||
(clobber (match_scratch:SI 3 "=&r"))]
|
||||
(clobber (match_scratch:SI 3 "=&r"))
|
||||
(clobber (reg:CC CRIS_CC0_REGNUM))]
|
||||
"<MODE>mode == QImode || !TARGET_ATOMICS_MAY_CALL_LIBFUNCS"
|
||||
{
|
||||
/* Can't be too sure; better ICE if this happens. */
|
||||
@ -226,7 +227,8 @@
|
||||
[(match_dup 2)
|
||||
(match_dup 3)
|
||||
(match_operand:BWD 4 "register_operand" "r")]
|
||||
CRIS_UNSPEC_ATOMIC_SWAP_MEM))]
|
||||
CRIS_UNSPEC_ATOMIC_SWAP_MEM))
|
||||
(clobber (reg:CC CRIS_CC0_REGNUM))]
|
||||
"<MODE>mode == QImode || !TARGET_ATOMICS_MAY_CALL_LIBFUNCS"
|
||||
{
|
||||
if (cris_cpu_version == 10)
|
||||
|
Loading…
x
Reference in New Issue
Block a user