summaryrefslogtreecommitdiff
path: root/gcc/config/rx
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rx')
-rw-r--r--gcc/config/rx/constraints.md7
-rw-r--r--gcc/config/rx/predicates.md4
-rw-r--r--gcc/config/rx/rx-modes.def26
-rw-r--r--gcc/config/rx/rx-protos.h3
-rw-r--r--gcc/config/rx/rx.c366
-rw-r--r--gcc/config/rx/rx.h34
-rw-r--r--gcc/config/rx/rx.md609
7 files changed, 658 insertions, 391 deletions
diff --git a/gcc/config/rx/constraints.md b/gcc/config/rx/constraints.md
index 52bf7df3621..b4b037d1a26 100644
--- a/gcc/config/rx/constraints.md
+++ b/gcc/config/rx/constraints.md
@@ -63,6 +63,13 @@
)
)
+(define_constraint "NEGint4"
+ "@internal An signed 4-bit negative immediate value"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (ival, -15, -1)")
+ )
+)
+
;; This is used in arithmetic and logic instructions for
;; a source operand that lies in memory and which satisfies
;; rx_restricted_memory_address().
diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md
index d7a363ebb88..94e5f5630c2 100644
--- a/gcc/config/rx/predicates.md
+++ b/gcc/config/rx/predicates.md
@@ -50,9 +50,9 @@
;; and a restricted subset of memory addresses are allowed.
(define_predicate "rx_source_operand"
- (match_code "const_int,reg,mem")
+ (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
{
- if (CONST_INT_P (op))
+ if (CONSTANT_P (op))
return rx_is_legitimate_constant (op);
if (! MEM_P (op))
diff --git a/gcc/config/rx/rx-modes.def b/gcc/config/rx/rx-modes.def
new file mode 100644
index 00000000000..5936b672b6b
--- /dev/null
+++ b/gcc/config/rx/rx-modes.def
@@ -0,0 +1,26 @@
+/* Definitions of target machine for GNU compiler, for ARM.
+ Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
+ Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
+ and Martin Simmons (@harleqn.co.uk).
+ More major hacks by Richard Earnshaw (rearnsha@arm.com)
+ Minor hacks by Nick Clifton (nickc@cygnus.com)
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+CC_MODE (CC_ZS);
+CC_MODE (CC_ZSO);
+CC_MODE (CC_ZSC);
diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h
index f5ef51108e1..166290de5e7 100644
--- a/gcc/config/rx/rx-protos.h
+++ b/gcc/config/rx/rx-protos.h
@@ -31,6 +31,7 @@ extern int rx_initial_elimination_offset (int, int);
extern void rx_set_optimization_options (void);
#ifdef RTX_CODE
+extern bool rx_compare_redundant (rtx);
extern void rx_emit_stack_popm (rtx *, bool);
extern void rx_emit_stack_pushm (rtx *);
extern void rx_expand_epilogue (bool);
@@ -41,8 +42,6 @@ extern bool rx_is_legitimate_constant (rtx);
extern bool rx_is_mode_dependent_addr (rtx);
extern bool rx_is_restricted_memory_address (rtx, Mmode);
extern void rx_notice_update_cc (rtx body, rtx insn);
-extern void rx_print_operand (FILE *, rtx, int);
-extern void rx_print_operand_address (FILE *, rtx);
#endif
#ifdef TREE_CODE
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index b5a887b64eb..2219efe8559 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -50,6 +50,8 @@
#include "target-def.h"
#include "langhooks.h"
+static void rx_print_operand (FILE *, rtx, int);
+
enum rx_cpu_types rx_cpu_type = RX600;
/* Return true if OP is a reference to an object in a small data area. */
@@ -254,7 +256,7 @@ rx_is_mode_dependent_addr (rtx addr)
assembler syntax for an instruction operand that is a memory
reference whose address is ADDR. */
-void
+static void
rx_print_operand_address (FILE * file, rtx addr)
{
switch (GET_CODE (addr))
@@ -362,10 +364,11 @@ int rx_float_compare_mode;
%F Print a condition code flag name.
%H Print high part of a DImode register, integer or address.
%L Print low part of a DImode register, integer or address.
+ %N Print the negation of the immediate value.
%Q If the operand is a MEM, then correctly generate
register indirect or register relative addressing. */
-void
+static void
rx_print_operand (FILE * file, rtx op, int letter)
{
switch (letter)
@@ -422,7 +425,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
case 0xc: fprintf (file, "intb"); break;
default:
warning (0, "unreocgnized control register number: %d - using 'psw'",
- INTVAL (op));
+ (int) INTVAL (op));
fprintf (file, "psw");
break;
}
@@ -444,46 +447,66 @@ rx_print_operand (FILE * file, rtx op, int letter)
break;
case 'H':
- if (REG_P (op))
- fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
- else if (CONST_INT_P (op))
+ switch (GET_CODE (op))
{
- HOST_WIDE_INT v = INTVAL (op);
+ case REG:
+ fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
+ break;
+ case CONST_INT:
+ {
+ HOST_WIDE_INT v = INTVAL (op);
+ fprintf (file, "#");
+ /* Trickery to avoid problems with shifting 32 bits at a time. */
+ v = v >> 16;
+ v = v >> 16;
+ rx_print_integer (file, v);
+ break;
+ }
+ case CONST_DOUBLE:
fprintf (file, "#");
- /* Trickery to avoid problems with shifting 32 bits at a time. */
- v = v >> 16;
- v = v >> 16;
- rx_print_integer (file, v);
- }
- else
- {
- gcc_assert (MEM_P (op));
-
+ rx_print_integer (file, CONST_DOUBLE_HIGH (op));
+ break;
+ case MEM:
if (! WORDS_BIG_ENDIAN)
op = adjust_address (op, SImode, 4);
output_address (XEXP (op, 0));
+ break;
+ default:
+ gcc_unreachable ();
}
break;
case 'L':
- if (REG_P (op))
- fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
- else if (CONST_INT_P (op))
+ switch (GET_CODE (op))
{
+ case REG:
+ fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
+ break;
+ case CONST_INT:
fprintf (file, "#");
rx_print_integer (file, INTVAL (op) & 0xffffffff);
- }
- else
- {
- gcc_assert (MEM_P (op));
-
+ break;
+ case CONST_DOUBLE:
+ fprintf (file, "#");
+ rx_print_integer (file, CONST_DOUBLE_LOW (op));
+ break;
+ case MEM:
if (WORDS_BIG_ENDIAN)
op = adjust_address (op, SImode, 4);
output_address (XEXP (op, 0));
+ break;
+ default:
+ gcc_unreachable ();
}
break;
+ case 'N':
+ gcc_assert (CONST_INT_P (op));
+ fprintf (file, "#");
+ rx_print_integer (file, - INTVAL (op));
+ break;
+
case 'Q':
if (MEM_P (op))
{
@@ -628,7 +651,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
char *
rx_gen_move_template (rtx * operands, bool is_movu)
{
- static char template [64];
+ static char out_template [64];
const char * extension = TARGET_AS100_SYNTAX ? ".L" : "";
const char * src_template;
const char * dst_template;
@@ -672,9 +695,9 @@ rx_gen_move_template (rtx * operands, bool is_movu)
else
dst_template = "%0";
- sprintf (template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
+ sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
extension, src_template, dst_template);
- return template;
+ return out_template;
}
/* Returns an assembler template for a conditional branch instruction. */
@@ -684,13 +707,6 @@ rx_gen_cond_branch_template (rtx condition, bool reversed)
{
enum rtx_code code = GET_CODE (condition);
-
- if ((cc_status.flags & CC_NO_OVERFLOW) && ! rx_float_compare_mode)
- gcc_assert (code != GT && code != GE && code != LE && code != LT);
-
- if ((cc_status.flags & CC_NO_CARRY) || rx_float_compare_mode)
- gcc_assert (code != GEU && code != GTU && code != LEU && code != LTU);
-
if (reversed)
{
if (rx_float_compare_mode)
@@ -771,6 +787,9 @@ rx_function_arg (Fargs * cum, Mmode mode, const_tree type, bool named)
/* An exploded version of rx_function_arg_size. */
size = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
+ /* If the size is not known it cannot be passed in registers. */
+ if (size < 1)
+ return NULL_RTX;
rounded_size = rx_round_up (size, UNITS_PER_WORD);
@@ -1038,7 +1057,7 @@ rx_get_stack_layout (unsigned int * lowest,
return;
}
- for (save_mask = high = low = 0, reg = 1; reg < FIRST_PSEUDO_REGISTER; reg++)
+ for (save_mask = high = low = 0, reg = 1; reg < CC_REGNUM; reg++)
{
if (df_regs_ever_live_p (reg)
&& (! call_used_regs[reg]
@@ -1216,7 +1235,7 @@ rx_expand_prologue (void)
if (mask)
{
/* Push registers in reverse order. */
- for (reg = FIRST_PSEUDO_REGISTER; reg --;)
+ for (reg = CC_REGNUM; reg --;)
if (mask & (1 << reg))
{
insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg)));
@@ -1245,7 +1264,7 @@ rx_expand_prologue (void)
{
acc_low = acc_high = 0;
- for (reg = 1; reg < FIRST_PSEUDO_REGISTER; reg ++)
+ for (reg = 1; reg < CC_REGNUM; reg ++)
if (mask & (1 << reg))
{
if (acc_low == 0)
@@ -1518,7 +1537,8 @@ rx_expand_epilogue (bool is_sibcall)
if (register_mask)
{
acc_low = acc_high = 0;
- for (reg = 1; reg < FIRST_PSEUDO_REGISTER; reg ++)
+
+ for (reg = 1; reg < CC_REGNUM; reg ++)
if (register_mask & (1 << reg))
{
if (acc_low == 0)
@@ -1549,7 +1569,7 @@ rx_expand_epilogue (bool is_sibcall)
if (register_mask)
{
- for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg ++)
+ for (reg = 0; reg < CC_REGNUM; reg ++)
if (register_mask & (1 << reg))
emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg)));
}
@@ -1649,48 +1669,6 @@ rx_initial_elimination_offset (int from, int to)
return stack_size;
}
-/* Update the status of the condition
- codes (cc0) based on the given INSN. */
-
-void
-rx_notice_update_cc (rtx body, rtx insn)
-{
- switch (get_attr_cc (insn))
- {
- case CC_NONE:
- /* Insn does not affect cc0 at all. */
- break;
- case CC_CLOBBER:
- /* Insn doesn't leave cc0 in a usable state. */
- CC_STATUS_INIT;
- break;
- case CC_SET_ZSOC:
- /* The insn sets all the condition code bits. */
- CC_STATUS_INIT;
- cc_status.value1 = SET_SRC (body);
- break;
- case CC_SET_ZSO:
- /* Insn sets the Z,S and O flags, but not the C flag. */
- CC_STATUS_INIT;
- cc_status.flags |= CC_NO_CARRY;
- /* Do not set the value1 field in this case. The final_scan_insn()
- function naively believes that if cc_status.value1 is set then
- it can eliminate *any* comparison against that value, even if
- the type of comparison cannot be satisfied by the range of flag
- bits being set here. See gcc.c-torture/execute/20041210-1.c
- for an example of this in action. */
- break;
- case CC_SET_ZS:
- /* Insn sets the Z and S flags, but not the O or C flags. */
- CC_STATUS_INIT;
- cc_status.flags |= (CC_NO_CARRY | CC_NO_OVERFLOW);
- /* See comment above regarding cc_status.value1. */
- break;
- default:
- gcc_unreachable ();
- }
-}
-
/* Decide if a variable should go into one of the small data sections. */
static bool
@@ -2486,6 +2464,220 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
}
}
+
+static enum machine_mode
+rx_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
+{
+ if (m1 == CCmode)
+ return m2;
+ if (m2 == CCmode)
+ return m1;
+ if (m1 == m2)
+ return m1;
+ if (m1 == CC_ZSmode)
+ return m1;
+ if (m2 == CC_ZSmode)
+ return m2;
+ return VOIDmode;
+}
+
+#define CC_FLAG_S (1 << 0)
+#define CC_FLAG_Z (1 << 1)
+#define CC_FLAG_O (1 << 2)
+#define CC_FLAG_C (1 << 3)
+
+static unsigned int
+flags_needed_for_conditional (rtx conditional)
+{
+ switch (GET_CODE (conditional))
+ {
+ case LE:
+ case GT: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O;
+
+ case LEU:
+ case GTU: return CC_FLAG_Z | CC_FLAG_C;
+
+ case LT:
+ case GE: return CC_FLAG_S | CC_FLAG_O;
+
+ case LTU:
+ case GEU: return CC_FLAG_C;
+
+ case EQ:
+ case NE: return CC_FLAG_Z;
+
+ default: gcc_unreachable ();
+ }
+}
+
+static unsigned int
+flags_from_mode (enum machine_mode mode)
+{
+ switch (mode)
+ {
+ case CCmode: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O | CC_FLAG_C;
+ case CC_ZSmode: return CC_FLAG_S | CC_FLAG_Z;
+ case CC_ZSOmode: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O;
+ case CC_ZSCmode: return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_C;
+ default: gcc_unreachable ();
+ }
+}
+
+/* Returns true if a compare insn is redundant because it
+ would only set flags that are already set correctly. */
+
+bool
+rx_compare_redundant (rtx cmp)
+{
+ unsigned int flags_needed;
+ unsigned int flags_set;
+ rtx next;
+ rtx prev;
+ rtx source;
+ rtx dest;
+ static rtx cc_reg = NULL_RTX;
+
+ if (cc_reg == NULL_RTX)
+ cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
+
+ /* We can only eliminate compares against 0. */
+ if (GET_CODE (XEXP (SET_SRC (PATTERN (cmp)), 1)) != CONST_INT
+ || INTVAL (XEXP (SET_SRC (PATTERN (cmp)), 1)) != 0)
+ return false;
+
+ /* Locate the branch insn that follows the
+ compare and which tests the bits in the PSW. */
+ next = cmp;
+ do
+ {
+ /* If we have found an insn that sets or clobbers the CC
+ register and it was not the IF_THEN_ELSE insn that we
+ are looking for, then the comparison is redundant. */
+ if (next != cmp && reg_mentioned_p (cc_reg, PATTERN (next)))
+ return true;
+
+ next = next_nonnote_insn (next);
+
+ /* If we run out of insns without finding the
+ user then the comparison is unnecessary. */
+ if (next == NULL_RTX)
+ return true;
+
+ /* If we have found another comparison
+ insn then the first one is redundant. */
+ if (INSN_P (next)
+ && GET_CODE (PATTERN (next)) == SET
+ && REG_P (SET_DEST (PATTERN (next)))
+ && REGNO (SET_DEST (PATTERN (next))) == CC_REGNUM)
+ return true;
+
+ /* If we have found another arithmetic/logic insn that
+ sets the PSW flags then the comparison is redundant. */
+ if (INSN_P (next)
+ && GET_CODE (PATTERN (next)) == PARALLEL
+ && GET_CODE (XVECEXP (PATTERN (next), 0, 1)) == SET
+ && REG_P (SET_DEST (XVECEXP (PATTERN (next), 0, 1)))
+ && REGNO (SET_DEST (XVECEXP (PATTERN (next), 0, 1))) == CC_REGNUM)
+ return true;
+
+ /* If we have found an unconditional branch then the
+ PSW flags might be carried along with the jump, so
+ the comparison is necessary. */
+ if (INSN_P (next) && JUMP_P (next))
+ {
+ if (GET_CODE (PATTERN (next)) != SET)
+ /* If the jump does not involve setting the PC
+ then it is a return of some kind, and we know
+ that the comparison is not used. */
+ return true;
+
+ if (GET_CODE (SET_SRC (PATTERN (next))) != IF_THEN_ELSE)
+ return false;
+ }
+ }
+ while (! INSN_P (next)
+ || DEBUG_INSN_P (next)
+ || GET_CODE (PATTERN (next)) != SET
+ || GET_CODE (SET_SRC (PATTERN (next))) != IF_THEN_ELSE);
+
+ flags_needed = flags_needed_for_conditional (XEXP (SET_SRC (PATTERN (next)), 0));
+
+ /* Now look to see if there was a previous
+ instruction which set the PSW bits. */
+ source = XEXP (SET_SRC (PATTERN (cmp)), 0);
+ prev = cmp;
+ do
+ {
+ /* If this insn uses/sets/clobbers the CC register
+ and it is not the insn that we are looking for
+ below, then we must need the comparison. */
+ if (prev != cmp && reg_mentioned_p (cc_reg, PATTERN (prev)))
+ return false;
+
+ prev = prev_nonnote_insn (prev);
+
+ if (prev == NULL_RTX)
+ return false;
+
+ /* If we encounter an insn which changes the contents of
+ the register which is the source of the comparison then
+ we will definitely need the comparison. */
+ if (INSN_P (prev)
+ && GET_CODE (PATTERN (prev)) == SET
+ && rtx_equal_p (SET_DEST (PATTERN (prev)), source))
+ {
+ /* Unless this instruction is a simple register move
+ instruction. In which case we can continue our
+ scan backwards, but now using the *source* of this
+ set instruction. */
+ if (REG_P (SET_SRC (PATTERN (prev))))
+ source = SET_SRC (PATTERN (prev));
+ /* We can also survive a sign-extension if the test is
+ for EQ/NE. Note the same does not apply to zero-
+ extension as this can turn a non-zero bit-pattern
+ into zero. */
+ else if (flags_needed == CC_FLAG_Z
+ && GET_CODE (SET_SRC (PATTERN (prev))) == SIGN_EXTEND)
+ source = XEXP (SET_SRC (PATTERN (prev)), 0);
+ else
+ return false;
+ }
+
+ /* A label means a possible branch into the
+ code here, so we have to stop scanning. */
+ if (LABEL_P (prev))
+ return false;
+ }
+ while (! INSN_P (prev)
+ || DEBUG_INSN_P (prev)
+ || GET_CODE (PATTERN (prev)) != PARALLEL
+ || GET_CODE (XVECEXP (PATTERN (prev), 0, 1)) != SET
+ || ! REG_P (SET_DEST (XVECEXP (PATTERN (prev), 0, 1)))
+ || REGNO (SET_DEST (XVECEXP (PATTERN (prev), 0, 1))) != CC_REGNUM);
+
+ flags_set = flags_from_mode (GET_MODE (SET_DEST (XVECEXP (PATTERN (prev), 0, 1))));
+
+ dest = SET_DEST (XVECEXP (PATTERN (prev), 0, 0));
+ /* The destination of the previous arithmetic/logic instruction
+ must match the source in the comparison operation. For registers
+ we ignore the mode as there may have been a sign-extension involved. */
+ if (! rtx_equal_p (source, dest))
+ {
+ if (REG_P (source) && REG_P (dest) && REGNO (dest) == REGNO (source))
+ ;
+ else
+ return false;
+ }
+
+ return ((flags_set & flags_needed) == flags_needed);
+}
+
+static int
+rx_memory_move_cost (enum machine_mode mode, enum reg_class regclass, bool in)
+{
+ return 2 + memory_move_secondary_cost (mode, regclass, in);
+}
+
#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE rx_function_value
@@ -2573,6 +2765,18 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT rx_trampoline_init
+#undef TARGET_PRINT_OPERAND
+#define TARGET_PRINT_OPERAND rx_print_operand
+
+#undef TARGET_PRINT_OPERAND_ADDRESS
+#define TARGET_PRINT_OPERAND_ADDRESS rx_print_operand_address
+
+#undef TARGET_CC_MODES_COMPATIBLE
+#define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible
+
+#undef TARGET_MEMORY_MOVE_COST
+#define TARGET_MEMORY_MOVE_COST rx_memory_move_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* #include "gt-rx.h" */
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index 8be66b53d9b..b3a12690b08 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -142,6 +142,8 @@ extern enum rx_cpu_types rx_cpu_type;
#define POINTER_SIZE 32
#undef SIZE_TYPE
#define SIZE_TYPE "long unsigned int"
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "long int"
#define POINTERS_EXTEND_UNSIGNED 1
#define FUNCTION_MODE QImode
#define CASE_VECTOR_MODE Pmode
@@ -152,7 +154,6 @@ extern enum rx_cpu_types rx_cpu_type;
#define MOVE_MAX 4
#define STARTING_FRAME_OFFSET 0
-#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
#define LEGITIMATE_CONSTANT_P(X) rx_is_legitimate_constant (X)
@@ -196,6 +197,7 @@ enum reg_class
GR_REGS, LIM_REG_CLASSES \
}
+#define SMALL_REGISTER_CLASSES 0
#define N_REG_CLASSES (int) LIM_REG_CLASSES
#define CLASS_MAX_NREGS(CLASS, MODE) ((GET_MODE_SIZE (MODE) \
+ UNITS_PER_WORD - 1) \
@@ -205,7 +207,7 @@ enum reg_class
#define BASE_REG_CLASS GR_REGS
#define INDEX_REG_CLASS GR_REGS
-#define FIRST_PSEUDO_REGISTER 16
+#define FIRST_PSEUDO_REGISTER 17
#define REGNO_REG_CLASS(REGNO) ((REGNO) < FIRST_PSEUDO_REGISTER \
? GR_REGS : NO_REGS)
@@ -217,6 +219,7 @@ enum reg_class
#define STATIC_CHAIN_REGNUM 8
#define TRAMPOLINE_TEMP_REGNUM 9
#define STRUCT_VAL_REGNUM 15
+#define CC_REGNUM 16
/* This is the register which is used to hold the address of the start
of the small data area, if that feature is being used. Note - this
@@ -243,12 +246,12 @@ enum reg_class
#define FIXED_REGISTERS \
{ \
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
}
#define CALL_USED_REGISTERS \
{ \
- 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 \
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 \
}
#define CONDITIONAL_REGISTER_USAGE \
@@ -349,7 +352,7 @@ typedef unsigned int CUMULATIVE_ARGS;
#define REGISTER_NAMES \
{ \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc" \
};
#define ADDITIONAL_REGISTER_NAMES \
@@ -607,14 +610,6 @@ typedef unsigned int CUMULATIVE_ARGS;
they contain are always computed between two same-section symbols. */
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
-#define PRINT_OPERAND(FILE, X, CODE) \
- rx_print_operand (FILE, X, CODE)
-#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
- rx_print_operand_address (FILE, ADDR)
-
-#define CC_NO_CARRY 0400
-#define NOTICE_UPDATE_CC(EXP, INSN) rx_notice_update_cc (EXP, INSN)
-
extern int rx_float_compare_mode;
/* This is a version of REG_P that also returns TRUE for SUBREGs. */
@@ -649,3 +644,16 @@ extern int rx_float_compare_mode;
/* This macro is used to decide when RX FPU instructions can be used. */
#define ALLOW_RX_FPU_INSNS (TARGET_USE_FPU)
+
+#define BRANCH_COST(SPEED,PREDICT) 1
+#define REGISTER_MOVE_COST(MODE,FROM,TO) 2
+
+#define SELECT_CC_MODE(OP,X,Y) \
+ (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CC_ZSmode : \
+ (GET_CODE (X) == PLUS || GET_CODE (X) == MINUS ? CC_ZSCmode : \
+ (GET_CODE (X) == ABS ? CC_ZSOmode : \
+ (GET_CODE (X) == AND || GET_CODE (X) == NOT || GET_CODE (X) == IOR \
+ || GET_CODE (X) == XOR || GET_CODE (X) == ROTATE \
+ || GET_CODE (X) == ROTATERT || GET_CODE (X) == ASHIFTRT \
+ || GET_CODE (X) == LSHIFTRT || GET_CODE (X) == ASHIFT ? CC_ZSmode : \
+ CCmode))))
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index 274ce6f3c66..aeba85ffe39 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -47,6 +47,7 @@
(define_constants
[
(SP_REG 0)
+ (CC_REG 16)
(UNSPEC_LOW_REG 0)
(UNSPEC_HIGH_REG 1)
@@ -86,14 +87,6 @@
]
)
-;; Condition code settings:
-;; none - insn does not affect the condition code bits
-;; set_zs - insn sets z,s to usable values;
-;; set_zso - insn sets z,s,o to usable values;
-;; set_zsoc - insn sets z,s,o,c to usable values;
-;; clobber - value of cc0 is unknown
-(define_attr "cc" "none,set_zs,set_zso,set_zsoc,clobber" (const_string "none"))
-
(define_attr "length" "" (const_int 8))
(include "predicates.md")
@@ -156,77 +149,120 @@
;; Comparisons
+;; Note - we do not specify the two instructions necessary to perform
+;; a compare-and-branch in the cbranchsi4 pattern because that would
+;; allow the comparison to be moved away from the jump before the reload
+;; pass has completed. That would be problematical because reload can
+;; generate ADDSI3 instructions which would corrupt the PSW flags.
+
(define_expand "cbranchsi4"
- [(set (cc0) (compare:CC (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "rx_source_operand")))
- (set (pc)
- (if_then_else (match_operator:SI 0 "comparison_operator"
- [(cc0) (const_int 0)])
+ [(set (pc)
+ (if_then_else (match_operator:SI 0 "comparison_operator"
+ [(match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "rx_source_operand")])
(label_ref (match_operand 3 ""))
- (pc)))]
+ (pc)))
+ ]
""
""
)
+(define_insn_and_split "*cbranchsi4_<code>"
+ [(set (pc)
+ (if_then_else (most_cond:SI (match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "rx_source_operand" "riQ"))
+ (label_ref (match_operand 2 "" ""))
+ (pc)))
+ ]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "
+ /* We contstruct the split by hand as otherwise the JUMP_LABEL
+ attribute is not set correctly on the jump insn. */
+ emit_insn (gen_cmpsi (operands[0], operands[1]));
+
+ emit_jump_insn (gen_conditional_branch (operands[2],
+ gen_rtx_fmt_ee (<most_cond:CODE>, CCmode,
+ gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
+ "
+)
+
(define_expand "cbranchsf4"
- [(set (cc0) (compare:CC (match_operand:SF 1 "register_operand")
- (match_operand:SF 2 "rx_source_operand")))
- (set (pc)
- (if_then_else (match_operator:SI 0 "comparison_operator"
- [(cc0) (const_int 0)])
+ [(set (pc)
+ (if_then_else (match_operator:SF 0 "comparison_operator"
+ [(match_operand:SF 1 "register_operand")
+ (match_operand:SF 2 "rx_source_operand")])
(label_ref (match_operand 3 ""))
- (pc)))]
- "ALLOW_RX_FPU_INSNS && !cfun->can_throw_non_call_exceptions"
+ (pc)))
+ ]
+ "ALLOW_RX_FPU_INSNS"
""
)
-;; The TST instruction is not used as it does not set the Carry flag,
-;; so for example, the LessThan comparison cannot be tested.
-;;
-;; (define_insn "tstsi"
-;; [(set (cc0)
-;; (match_operand:SI 0 "rx_source_operand" "r,i,Q")))]
-;; ""
-;; {
-;; rx_float_compare_mode = false;
-;; return "tst\t%Q0";
-;; }
-;; [(set_attr "cc" "set_zs")
-;; (set_attr "timings" "11,11,33")
-;; (set_attr "length" "3,7,6")]
-;; )
+(define_insn_and_split "*cbranchsf4_<code>"
+ [(set (pc)
+ (if_then_else (most_cond:SF (match_operand:SF 0 "register_operand" "r")
+ (match_operand:SF 1 "rx_source_operand" "rFiQ"))
+ (label_ref (match_operand 2 "" ""))
+ (pc)))
+ ]
+ "ALLOW_RX_FPU_INSNS"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "
+ /* We contstruct the split by hand as otherwise the JUMP_LABEL
+ attribute is not set correctly on the jump insn. */
+ emit_insn (gen_cmpsf (operands[0], operands[1]));
+
+ emit_jump_insn (gen_conditional_branch (operands[2],
+ gen_rtx_fmt_ee (<most_cond:CODE>, CCmode,
+ gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
+ "
+)
+
+(define_insn "tstsi"
+ [(set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (and:SI (match_operand:SI 0 "register_operand" "r,r,r")
+ (match_operand:SI 1 "rx_source_operand" "r,i,Q"))
+ (const_int 0)))]
+ ""
+ {
+ rx_float_compare_mode = false;
+ return "tst\t%Q1, %0";
+ }
+ [(set_attr "timings" "11,11,33")
+ (set_attr "length" "3,7,6")]
+)
(define_insn "cmpsi"
- [(set (cc0) (compare:CC
- (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r")
- (match_operand:SI 1 "rx_source_operand"
- "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
+ [(set (reg:CC CC_REG)
+ (compare:CC (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r")
+ (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
""
{
rx_float_compare_mode = false;
- return "cmp\t%Q1, %Q0";
+ if (rx_compare_redundant (insn))
+ return "; Compare Eliminated: cmp %Q1, %0";
+ return "cmp\t%Q1, %0";
}
- [(set_attr "cc" "set_zsoc")
- (set_attr "timings" "11,11,11,11,11,11,33")
+ [(set_attr "timings" "11,11,11,11,11,11,33")
(set_attr "length" "2,2,3,4,5,6,5")]
)
-;; This pattern is disabled if the function can throw non-call exceptions,
-;; it could generate a floating point exception, which would introduce an
-;; edge into the flow graph between this insn and the conditional branch
-;; insn to follow, thus breaking the cc0 relationship. Run the g++ test
-;; g++.dg/eh/080514-1.C to see this happen.
+;; ??? g++.dg/eh/080514-1.C to see this happen.
(define_insn "cmpsf"
- [(set (cc0)
- (compare:CC (match_operand:SF 0 "register_operand" "r,r,r")
- (match_operand:SF 1 "rx_source_operand" "r,i,Q")))]
- "ALLOW_RX_FPU_INSNS && !cfun->can_throw_non_call_exceptions"
+ [(set (reg:CC_ZSO CC_REG)
+ (compare:CC_ZSO (match_operand:SF 0 "register_operand" "r,r,r")
+ (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
+ "ALLOW_RX_FPU_INSNS"
{
rx_float_compare_mode = true;
return "fcmp\t%1, %0";
}
- [(set_attr "cc" "set_zso")
- (set_attr "timings" "11,11,33")
+ [(set_attr "timings" "11,11,33")
(set_attr "length" "3,7,5")]
)
@@ -234,17 +270,17 @@
(define_expand "b<code>"
[(set (pc)
- (if_then_else (most_cond (cc0) (const_int 0))
+ (if_then_else (most_cond (reg:CC CC_REG) (const_int 0))
(label_ref (match_operand 0))
(pc)))]
""
""
)
-(define_insn "*conditional_branch"
+(define_insn "conditional_branch"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
- [(cc0) (const_int 0)])
+ [(reg:CC CC_REG) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
@@ -253,14 +289,13 @@
}
[(set_attr "length" "8") ;; This length is wrong, but it is
;; too hard to compute statically.
- (set_attr "timings" "33") ;; The timing assumes that the branch is taken.
- (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
+ (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
)
(define_insn "*reveresed_conditional_branch"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
- [(cc0) (const_int 0)])
+ [(reg:CC CC_REG) (const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
""
@@ -269,38 +304,37 @@
}
[(set_attr "length" "8") ;; This length is wrong, but it is
;; too hard to compute statically.
- (set_attr "timings" "33") ;; The timing assumes that the branch is taken.
- (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
+ (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
)
(define_insn "jump"
- [(set (pc) (label_ref (match_operand 0 "" "")))]
+ [(set (pc)
+ (label_ref (match_operand 0 "" "")))]
""
"bra\t%0"
[(set_attr "length" "4")
- (set_attr "timings" "33")
- (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
+ (set_attr "timings" "33")]
)
(define_insn "indirect_jump"
- [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
+ [(set (pc)
+ (match_operand:SI 0 "register_operand" "r"))]
""
"jmp\t%0"
[(set_attr "length" "2")
- (set_attr "timings" "33")
- (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
+ (set_attr "timings" "33")]
)
(define_insn "tablejump"
- [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+ [(set (pc)
+ (match_operand:SI 0 "register_operand" "r"))
(use (label_ref (match_operand 1 "" "")))]
""
{ return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
: "\n1:\tbra\t%0")
: "jmp\t%0";
}
- [(set_attr "cc" "clobber") ;; FIXME: This clobber is wrong.
- (set_attr "timings" "33")
+ [(set_attr "timings" "33")
(set_attr "length" "2")]
)
@@ -324,11 +358,10 @@
)
(define_insn "pop_and_return"
- [(match_parallel 1 "rx_rtsd_vector"
+ [(match_parallel 1 "rx_rtsd_vector"
[(set:SI (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
- (match_operand:SI
- 0 "const_int_operand" "n")))])]
+ (match_operand:SI 0 "const_int_operand" "n")))])]
"reload_completed"
{
rx_emit_stack_popm (operands, false);
@@ -385,7 +418,8 @@
(define_insn "call_internal"
[(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
- (match_operand:SI 1 "general_operand" "g,g"))]
+ (match_operand:SI 1 "general_operand" "g,g"))
+ (clobber (reg:CC CC_REG))]
""
"@
jsr\t%0
@@ -412,7 +446,8 @@
(define_insn "call_value_internal"
[(set (match_operand 0 "register_operand" "=r,r")
(call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol"))
- (match_operand:SI 2 "general_operand" "g,g")))]
+ (match_operand:SI 2 "general_operand" "g,g")))
+ (clobber (reg:CC CC_REG))]
""
"@
jsr\t%1
@@ -562,11 +597,10 @@
)
(define_insn "stack_pushm"
- [(match_parallel 1 "rx_store_multiple_vector"
+ [(match_parallel 1 "rx_store_multiple_vector"
[(set:SI (reg:SI SP_REG)
(minus:SI (reg:SI SP_REG)
- (match_operand:SI
- 0 "const_int_operand" "n")))])]
+ (match_operand:SI 0 "const_int_operand" "n")))])]
"reload_completed"
{
rx_emit_stack_pushm (operands);
@@ -589,11 +623,10 @@
)
(define_insn "stack_popm"
- [(match_parallel 1 "rx_load_multiple_vector"
+ [(match_parallel 1 "rx_load_multiple_vector"
[(set:SI (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
- (match_operand:SI
- 0 "const_int_operand" "n")))])]
+ (match_operand:SI 0 "const_int_operand" "n")))])]
"reload_completed"
{
rx_emit_stack_popm (operands, true);
@@ -603,29 +636,29 @@
(set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
)
+;; FIXME: Add memory destination options ?
(define_insn "cstoresi4"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
- (match_operator:SI
- 1 "comparison_operator"
- [(match_operand:SI
- 2 "register_operand" "r,r,r,r,r,r,r")
- (match_operand:SI
- 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))]
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:SI 2 "register_operand" "r,r,r,r,r,r,r")
+ (match_operand:SI 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))
+ (clobber (reg:CC CC_REG))] ;; Because the cc flags are set based on comparing ops 2 & 3 not the value in op 0.
""
{
rx_float_compare_mode = false;
return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0";
}
- [(set_attr "cc" "set_zsoc")
- (set_attr "timings" "22,22,22,22,22,22,44")
+ [(set_attr "timings" "22,22,22,22,22,22,44")
(set_attr "length" "5,5,6,7,8,9,8")]
)
(define_expand "movsicc"
- [(set (match_operand:SI 0 "register_operand")
- (if_then_else:SI (match_operand:SI 1 "comparison_operator")
- (match_operand:SI 2 "nonmemory_operand")
- (match_operand:SI 3 "immediate_operand")))]
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand")
+ (if_then_else:SI (match_operand:SI 1 "comparison_operator")
+ (match_operand:SI 2 "nonmemory_operand")
+ (match_operand:SI 3 "immediate_operand")))
+ (clobber (reg:CC CC_REG))])] ;; See cstoresi4
""
{
if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
@@ -636,22 +669,18 @@
)
(define_insn "*movsieq"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (if_then_else:SI (eq (match_operand:SI
- 3 "register_operand" "r,r,r")
- (match_operand:SI
- 4 "rx_source_operand" "riQ,riQ,riQ"))
- (match_operand:SI
- 1 "nonmemory_operand" "0,i,r")
- (match_operand:SI
- 2 "immediate_operand" "i,i,i")))]
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (if_then_else:SI (eq (match_operand:SI 3 "register_operand" "r,r,r")
+ (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
+ (match_operand:SI 1 "nonmemory_operand" "0,i,r")
+ (match_operand:SI 2 "immediate_operand" "i,i,i")))
+ (clobber (reg:CC CC_REG))] ;; See cstoresi4
""
"@
cmp\t%Q4, %Q3\n\tstnz\t%2, %0
cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0
cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "length" "13,19,15")
+ [(set_attr "length" "13,19,15")
(set_attr "timings" "22,33,33")]
)
@@ -660,14 +689,14 @@
(if_then_else:SI (ne (match_operand:SI 3 "register_operand" "r,r,r")
(match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
(match_operand:SI 1 "nonmemory_operand" "0,i,r")
- (match_operand:SI 2 "immediate_operand" "i,i,i")))]
+ (match_operand:SI 2 "immediate_operand" "i,i,i")))
+ (clobber (reg:CC CC_REG))] ;; See cstoresi4
""
"@
cmp\t%Q4, %Q3\n\tstz\t%2, %0
cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0
cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "length" "13,19,15")
+ [(set_attr "length" "13,19,15")
(set_attr "timings" "22,33,33")]
)
@@ -675,61 +704,65 @@
(define_insn "abssi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (abs:SI (match_operand:SI 1 "register_operand" "0,r")))]
+ (abs:SI (match_operand:SI 1 "register_operand" "0,r")))
+ (set (reg:CC_ZSO CC_REG)
+ (compare:CC_ZSO (abs:SI (match_dup 1))
+ (const_int 0)))]
""
"@
abs\t%0
abs\t%1, %0"
- [(set_attr "cc" "set_zso")
- (set_attr "length" "2,3")]
+ [(set_attr "length" "2,3")]
)
(define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand"
- "=r,r,r,r,r,r,r,r,r,r,r,r")
- (plus:SI (match_operand:SI
- 1 "register_operand"
- "%0,0,0,0,0,0,r,r,r,r,r,0")
- (match_operand:SI
- 2 "rx_source_operand"
- "r,Uint04,Sint08,Sint16,Sint24,i,r,Sint08,Sint16,Sint24,i,Q")))]
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,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,r,r,r,r,0")
+ (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
+ (set (reg:CC_ZSC CC_REG) ;; See subsi3
+ (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"@
add\t%2, %0
add\t%2, %0
+ sub\t%N2, %0
add\t%2, %0
add\t%2, %0
add\t%2, %0
add\t%2, %0
+ add\t%1, %0
add\t%2, %1, %0
add\t%2, %1, %0
add\t%2, %1, %0
add\t%2, %1, %0
add\t%2, %1, %0
add\t%Q2, %0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,33")
- (set_attr "length" "2,2,3,4,5,6,3,3,4,5,6,5")]
+ [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
+ (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
)
(define_insn "adddi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
(plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:DI 2 "rx_source_operand"
- "r,Sint08,Sint16,Sint24,i,Q")))]
+ "r,Sint08,Sint16,Sint24,i,Q")))
+ (set (reg:CC_ZSC CC_REG) ;; See subsi3
+ (compare:CC_ZSC (plus:DI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"add\t%L2, %L0\n\tadc\t%H2, %H0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "timings" "22,22,22,22,22,44")
+ [(set_attr "timings" "22,22,22,22,22,44")
(set_attr "length" "5,7,9,11,13,11")]
)
(define_insn "andsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
- (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,0,Q")
- (match_operand:SI
- 2 "rx_source_operand"
- "r,Uint04,Sint08,Sint16,Sint24,i,r,Q,0")))]
+ (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
+ (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (and:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"@
and\t%2, %0
@@ -738,12 +771,11 @@
and\t%2, %0
and\t%2, %0
and\t%2, %0
+ and\t%1, %0
and\t%2, %1, %0
- and\t%Q2, %0
- and\t%Q1, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "11,11,11,11,11,11,11,33,33")
- (set_attr "length" "2,2,3,4,5,6,3,5,5")]
+ and\t%Q2, %0"
+ [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
+ (set_attr "length" "2,2,3,4,5,6,2,5,5")]
)
;; Byte swap (single 32-bit value).
@@ -767,12 +799,11 @@
(define_insn "divsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
(div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
- (match_operand:SI
- 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))]
+ (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
+ (clobber (reg:CC CC_REG))]
""
"div\t%Q2, %0"
- [(set_attr "cc" "clobber")
- (set_attr "timings" "1111") ;; Strictly speaking the timing should be
+ [(set_attr "timings" "1111") ;; Strictly speaking the timing should be
;; 2222, but that is a worst case sceanario.
(set_attr "length" "3,4,5,6,7,6")]
)
@@ -780,12 +811,11 @@
(define_insn "udivsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
(udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
- (match_operand:SI
- 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))]
+ (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
+ (clobber (reg:CC CC_REG))]
""
"divu\t%Q2, %0"
- [(set_attr "cc" "clobber")
- (set_attr "timings" "1010") ;; Strictly speaking the timing should be
+ [(set_attr "timings" "1010") ;; Strictly speaking the timing should be
;; 2020, but that is a worst case sceanario.
(set_attr "length" "3,4,5,6,7,6")]
)
@@ -803,13 +833,7 @@
2 "rx_source_operand"
"r,Sint08,Sint16,Sint24,i,Q"))))]
"! TARGET_BIG_ENDIAN_DATA"
- "@
- emul\t%Q2, %0
- emul\t%Q2, %0
- emul\t%Q2, %0
- emul\t%Q2, %0
- emul\t%Q2, %0
- emul\t%Q2, %0"
+ "emul\t%Q2, %0"
[(set_attr "length" "3,4,5,6,7,6")
(set_attr "timings" "22,22,22,22,22,44")]
)
@@ -819,16 +843,11 @@
;; mulsidi3 pattern. Immediate mode addressing is not supported
;; because gcc cannot handle the expression: (zero_extend (const_int)).
(define_insn "umulsidi3"
- [(set (match_operand:DI 0 "register_operand"
- "=r,r")
- (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"
- "%0,0"))
- (zero_extend:DI (match_operand:SI 2 "rx_compare_operand"
- "r,Q"))))]
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,0"))
+ (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
"! TARGET_BIG_ENDIAN_DATA"
- "@
- emulu\t%Q2, %0
- emulu\t%Q2, %0"
+ "emulu\t%Q2, %0"
[(set_attr "length" "3,6")
(set_attr "timings" "22,44")]
)
@@ -850,40 +869,37 @@
(match_operand:SI 2 "rx_source_operand"
"r,Sint08,Sint16,Sint24,i,Q")))]
""
- "@
- min\t%Q2, %0
- min\t%Q2, %0
- min\t%Q2, %0
- min\t%Q2, %0
- min\t%Q2, %0
- min\t%Q2, %0"
+ "min\t%Q2, %0"
[(set_attr "length" "3,4,5,6,7,6")
(set_attr "timings" "11,11,11,11,11,33")]
)
(define_insn "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
- (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,Q,r")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")
(match_operand:SI 2 "rx_source_operand"
"r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
""
"@
+ mul\t%2, %0
+ mul\t%2, %0
+ mul\t%2, %0
+ mul\t%2, %0
+ mul\t%2, %0
mul\t%Q2, %0
mul\t%Q2, %0
- mul\t%Q2, %0
- mul\t%Q2, %0
- mul\t%Q2, %0
- mul\t%Q2, %0
- mul\t%Q2, %0
- mul\t%Q1, %0
- mul\t%Q2, %1, %0"
- [(set_attr "length" "2,2,3,4,5,6,5,5,3")
- (set_attr "timings" "11,11,11,11,11,11,33,33,11")]
+ mul\t%1, %0
+ mul\t%2, %1, %0"
+ [(set_attr "length" "2,2,3,4,5,6,5,2,3")
+ (set_attr "timings" "11,11,11,11,11,11,33,11,11")]
)
(define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (neg:SI (match_operand:SI 1 "register_operand" "0,r")))]
+ (neg:SI (match_operand:SI 1 "register_operand" "0,r")))
+ (set (reg:CC CC_REG)
+ (compare:CC (neg:SI (match_dup 1))
+ (const_int 0)))]
;; The NEG instruction does not comply with -fwrapv semantics.
;; See gcc.c-torture/execute/pr22493-1.c for an example of this.
"! flag_wrapv"
@@ -895,20 +911,24 @@
(define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (not:SI (match_operand:SI 1 "register_operand" "0,r")))]
+ (not:SI (match_operand:SI 1 "register_operand" "0,r")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (not:SI (match_dup 1))
+ (const_int 0)))]
""
"@
not\t%0
not\t%1, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "length" "2,3")]
+ [(set_attr "length" "2,3")]
)
(define_insn "iorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
- (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,0,Q")
- (match_operand:SI 2 "rx_source_operand"
- "r,Uint04,Sint08,Sint16,Sint24,i,r,Q,0")))]
+ (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
+ (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (ior:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"@
or\t%2, %0
@@ -916,78 +936,93 @@
or\t%2, %0
or\t%2, %0
or\t%2, %0
- or\t%2, %0
- or\t%2, %1, %0
or\t%Q2, %0
- or\t%Q1, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "11,11,11,11,11,11,11,33,33")
- (set_attr "length" "2,2,3,4,5,6,3,5,5")]
+ or\t%1, %0
+ or\t%2, %1, %0
+ or\t%Q2, %0"
+ [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
+ (set_attr "length" "2,2,3,4,5,6,2,3,5")]
)
(define_insn "rotlsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(rotate:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "rx_shift_operand" "rn")))]
+ (match_operand:SI 2 "rx_shift_operand" "rn")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (rotate:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"rotl\t%2, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "length" "3")]
+ [(set_attr "length" "3")]
)
(define_insn "rotrsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(rotatert:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "rx_shift_operand" "rn")))]
+ (match_operand:SI 2 "rx_shift_operand" "rn")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (rotatert:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"rotr\t%2, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "length" "3")]
+ [(set_attr "length" "3")]
)
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
- (match_operand:SI 2 "rx_shift_operand" "r,n,n")))]
+ (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (ashiftrt:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"@
shar\t%2, %0
shar\t%2, %0
shar\t%2, %1, %0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "length" "3,2,3")]
+ [(set_attr "length" "3,2,3")]
)
(define_insn "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
- (match_operand:SI 2 "rx_shift_operand" "r,n,n")))]
+ (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (lshiftrt:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"@
shlr\t%2, %0
shlr\t%2, %0
shlr\t%2, %1, %0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "length" "3,2,3")]
+ [(set_attr "length" "3,2,3")]
)
(define_insn "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
- (match_operand:SI 2 "rx_shift_operand" "r,n,n")))]
+ (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (ashift:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"@
shll\t%2, %0
shll\t%2, %0
shll\t%2, %1, %0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "length" "3,2,3")]
+ [(set_attr "length" "3,2,3")]
)
(define_insn "subsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
(minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0")
- (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))]
+ (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
+ (set (reg:CC_ZSC CC_REG)
+ ;; Note - we do not acknowledge that the SUB instruction sets the Overflow
+ ;; flag because its interpretation is different from comparing the result
+ ;; against zero. Compile and run gcc.c-torture/execute/cmpsi-1.c to see this.
+ (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"@
sub\t%2, %0
@@ -995,19 +1030,20 @@
add\t%N2, %0
sub\t%2, %1, %0
sub\t%Q2, %0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "timings" "11,11,11,11,33")
+ [(set_attr "timings" "11,11,11,11,33")
(set_attr "length" "2,2,6,3,5")]
)
(define_insn "subdi3"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(minus:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:DI 2 "rx_source_operand" "r,Q")))]
+ (match_operand:DI 2 "rx_source_operand" "r,Q")))
+ (set (reg:CC_ZSC CC_REG) ;; See subsi3
+ (compare:CC_ZSC (minus:DI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
"sub\t%L2, %L0\n\tsbb\t%H2, %H0"
- [(set_attr "cc" "set_zsoc")
- (set_attr "timings" "22,44")
+ [(set_attr "timings" "22,44")
(set_attr "length" "5,11")]
)
@@ -1015,17 +1051,13 @@
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
(xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:SI 2 "rx_source_operand"
- "r,Sint08,Sint16,Sint24,i,Q")))]
+ "r,Sint08,Sint16,Sint24,i,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (xor:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
""
- "@
- xor\t%Q2, %0
- xor\t%Q2, %0
- xor\t%Q2, %0
- xor\t%Q2, %0
- xor\t%Q2, %0
- xor\t%Q2, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "11,11,11,11,11,33")
+ "xor\t%Q2, %0"
+ [(set_attr "timings" "11,11,11,11,11,33")
(set_attr "length" "3,4,5,6,7,6")]
)
@@ -1034,70 +1066,76 @@
(define_insn "addsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r")
(plus:SF (match_operand:SF 1 "register_operand" "%0,0,0")
- (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
+ (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (plus:SF (match_dup 1) (match_dup 2))
+ (const_int 0)))]
"ALLOW_RX_FPU_INSNS"
- "@
- fadd\t%2, %0
- fadd\t%2, %0
- fadd\t%2, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "44,44,66")
+ "fadd\t%2, %0"
+ [(set_attr "timings" "44,44,66")
(set_attr "length" "3,7,5")]
)
(define_insn "divsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r")
(div:SF (match_operand:SF 1 "register_operand" "0,0,0")
- (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
+ (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (div:SF (match_dup 1) (match_dup 2))
+ (const_int 0)))]
"ALLOW_RX_FPU_INSNS"
"fdiv\t%2, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "1616,1616,1818")
+ [(set_attr "timings" "1616,1616,1818")
(set_attr "length" "3,7,5")]
)
(define_insn "mulsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r")
(mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
- (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
+ (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (mult:SF (match_dup 1) (match_dup 2))
+ (const_int 0)))]
"ALLOW_RX_FPU_INSNS"
- "@
- fmul\t%2, %0
- fmul\t%2, %0
- fmul\t%2, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "33,33,55")
+ "fmul\t%2, %0"
+ [(set_attr "timings" "33,33,55")
(set_attr "length" "3,7,5")]
)
(define_insn "subsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r")
(minus:SF (match_operand:SF 1 "register_operand" "0,0,0")
- (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
+ (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (minus:SF (match_dup 1) (match_dup 2))
+ (const_int 0)))]
"ALLOW_RX_FPU_INSNS"
- "fsub\t%2, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "44,44,66")
+ "fsub\t%Q2, %0"
+ [(set_attr "timings" "44,44,66")
(set_attr "length" "3,7,5")]
)
(define_insn "fix_truncsfsi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))]
+ (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (fix:SI (match_dup 1))
+ (const_int 0)))]
"ALLOW_RX_FPU_INSNS"
- "ftoi\t%1, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "22,44")
+ "ftoi\t%Q1, %0"
+ [(set_attr "timings" "22,44")
(set_attr "length" "3,5")]
)
(define_insn "floatsisf2"
[(set (match_operand:SF 0 "register_operand" "=r,r")
- (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))]
+ (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))
+ (set (reg:CC_ZS CC_REG)
+ (compare:CC_ZS (float:SF (match_dup 1))
+ (const_int 0)))]
"ALLOW_RX_FPU_INSNS"
- "itof\t%1, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "22,44")
+ "itof\t%Q1, %0"
+ [(set_attr "timings" "22,44")
(set_attr "length" "3,6")]
)
@@ -1109,8 +1147,8 @@
;; of three instructions at a time.
(define_insn "bitset"
- [(set:SI (match_operand:SI 0 "register_operand" "+r")
- (ior:SI (match_operand:SI 1 "register_operand" "0")
+ [(set:SI (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (match_operand:SI 1 "register_operand" "0")
(ashift:SI (const_int 1)
(match_operand:SI 2 "nonmemory_operand" "ri"))))]
""
@@ -1119,8 +1157,8 @@
)
(define_insn "bitset_in_memory"
- [(set:QI (match_operand:QI 0 "memory_operand" "+m")
- (ior:QI (match_operand:QI 1 "memory_operand" "0")
+ [(set:QI (match_operand:QI 0 "memory_operand" "=m")
+ (ior:QI (match_operand:QI 1 "memory_operand" "0")
(ashift:QI (const_int 1)
(match_operand:QI 2 "nonmemory_operand" "ri"))))]
""
@@ -1294,14 +1332,10 @@
)
(define_expand "insv"
- [(set:SI (zero_extract:SI (match_operand:SI
- 0 "nonimmediate_operand") ;; Destination
- (match_operand
- 1 "immediate_operand") ;; # of bits to set
- (match_operand
- 2 "immediate_operand")) ;; Starting bit
- (match_operand
- 3 "immediate_operand"))] ;; Bits to insert
+ [(set:SI (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand") ;; Destination
+ (match_operand 1 "immediate_operand") ;; # of bits to set
+ (match_operand 2 "immediate_operand")) ;; Starting bit
+ (match_operand 3 "immediate_operand"))] ;; Bits to insert
""
{
if (rx_expand_insv (operands))
@@ -1356,8 +1390,7 @@
(unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 3))
- ]
+ (clobber (reg:SI 3))]
""
"smovu"
[(set_attr "length" "2")
@@ -1371,11 +1404,11 @@
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(clobber (reg:SI 3))
- ]
+ (clobber (reg:CC CC_REG))
+ ]
""
"mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
[(set_attr "length" "10")
- (set_attr "cc" "clobber")
(set_attr "timings" "1111")] ;; The timing is a guesstimate.
)
@@ -1458,17 +1491,12 @@
)
(define_expand "cmpstrnsi"
- [(set (match_operand:SI
- 0 "register_operand") ;; Result
- (unspec_volatile:SI [(match_operand:BLK
- 1 "memory_operand") ;; String1
- (match_operand:BLK
- 2 "memory_operand")] ;; String2
+ [(set (match_operand:SI 0 "register_operand") ;; Result
+ (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
+ (match_operand:BLK 2 "memory_operand")] ;; String2
UNSPEC_CMPSTRN))
- (use (match_operand:SI
- 3 "register_operand")) ;; Max Length
- (match_operand:SI
- 4 "immediate_operand")] ;; Known Align
+ (use (match_operand:SI 3 "register_operand")) ;; Max Length
+ (match_operand:SI 4 "immediate_operand")] ;; Known Align
""
{
rtx str1 = gen_rtx_REG (SImode, 1);
@@ -1485,15 +1513,11 @@
)
(define_expand "cmpstrsi"
- [(set (match_operand:SI
- 0 "register_operand") ;; Result
- (unspec_volatile:SI [(match_operand:BLK
- 1 "memory_operand") ;; String1
- (match_operand:BLK
- 2 "memory_operand")] ;; String2
+ [(set (match_operand:SI 0 "register_operand") ;; Result
+ (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
+ (match_operand:BLK 2 "memory_operand")] ;; String2
UNSPEC_CMPSTRN))
- (match_operand:SI
- 3 "immediate_operand")] ;; Known Align
+ (match_operand:SI 3 "immediate_operand")] ;; Known Align
""
{
rtx str1 = gen_rtx_REG (SImode, 1);
@@ -1517,7 +1541,8 @@
(use (match_operand:BLK 2 "memory_operand" "m"))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 3))]
+ (clobber (reg:SI 3))
+ (clobber (reg:CC CC_REG))]
""
"scmpu ; Perform the string comparison
mov #-1, %0 ; Set up -1 result (which cannot be created
@@ -1658,11 +1683,11 @@
(define_insn "lrintsf2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
- UNSPEC_BUILTIN_ROUND))]
+ UNSPEC_BUILTIN_ROUND))
+ (clobber (reg:CC CC_REG))]
""
"round\t%1, %0"
- [(set_attr "cc" "set_zs")
- (set_attr "timings" "22,44")
+ [(set_attr "timings" "22,44")
(set_attr "length" "3,5")]
)
@@ -1682,22 +1707,20 @@
(define_insn "clrpsw"
[(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
UNSPEC_BUILTIN_CLRPSW)
- (clobber (cc0))]
+ (clobber (reg:CC CC_REG))]
""
"clrpsw\t%F0"
- [(set_attr "length" "2")
- (set_attr "cc" "clobber")]
+ [(set_attr "length" "2")]
)
;; Set Processor Status Word
(define_insn "setpsw"
[(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
UNSPEC_BUILTIN_SETPSW)
- (clobber (cc0))]
+ (clobber (reg:CC CC_REG))]
""
"setpsw\t%F0"
- [(set_attr "length" "2")
- (set_attr "cc" "clobber")]
+ [(set_attr "length" "2")]
)
;; Move from control register