Commit aea8fc97 by Nick Clifton Committed by Nick Clifton

rx-modes.def: New file.

        * config/rx/rx-modes.def: New file.
        * config/rx/rx.h (FIRST_PSEUDO_REGISTER): Increase to 17.
        (CC_REGNUM): Define.
        (FIXED_REGISTERS, CALL_USED_REGISTERS, REGISTER_NAMES): Add cc
        register.
        (CC_NO_CARRY, NOTICE_UPDATE_CC): Delete.
        (SELECT_CC_MODE): Define.
        * config/rx/rx.md (CC_REG): Define.  Update all patterns to use
        (reg:CC CC_REG) instead of (cc0).
        (attr "cc"): Delete.
        (cbranchsi4): Do not split compare and branch here. Instead move
        it to...
        (cbranchsi4_<code>): ... here.  New patterns.
        (cmpsi): Call rx-compare_redundant to find out if it is necessary
        to emit the compare instruction.
        * config/rx/rx.c (rx_gen-cond_branch_template): Remove tests of
        cc_status flags.
        (rx_get_stack_layout): Iterate up to before CC_REGNUM not
        FIRST_PSEUDO_REGNUM.
        (rx_expand_prologue, rx_expand_epilogue): Likewise.
        (rx_notice_update_cc): Delete.
        (rx_cc_modes_compatible): New function.
        (flags_needed_for_conditional): New function.
        (flags_from_mode): New function.
        (rx_compare_redundant): New function - scans backwards through
        insn list to find out if condition flags are already set
        correctly.
        (TARGET_CC_MODES_COMPATIBLE): Define.
        * config/rx/rx-protos.h (rx_compare_redundant): Prototype.

        * config/rx/rx.h (BRANCH_COST): Define.
        (REGISTER_MOVE_COST): Define.
        * config/rx/predicates (rx_source_operand): Allow all constant
        types.
        * config/rx/rx.md (addsi3): Add alternative for swapped operands.
        (tstsi4): New pattern.
        * config/rx/rx.c (rx_memory_move_cost): Define.
        (TARGET_MEMORY_MOVE_COST): Define.

From-SVN: r161592
parent 6662d794
2010-06-30 Nick Clifton <nickc@redhat.com>
* config/rx/rx-modes.def: New file.
* config/rx/rx.h (FIRST_PSEUDO_REGISTER): Increase to 17.
(CC_REGNUM): Define.
(FIXED_REGISTERS, CALL_USED_REGISTERS, REGISTER_NAMES): Add cc
register.
(CC_NO_CARRY, NOTICE_UPDATE_CC): Delete.
(SELECT_CC_MODE): Define.
* config/rx/rx.md (CC_REG): Define. Update all patterns to use
(reg:CC CC_REG) instead of (cc0).
(attr "cc"): Delete.
(cbranchsi4): Do not split compare and branch here. Instead move
it to...
(cbranchsi4_<code>): ... here. New patterns.
(cmpsi): Call rx-compare_redundant to find out if it is necessary
to emit the compare instruction.
* config/rx/rx.c (rx_gen-cond_branch_template): Remove tests of
cc_status flags.
(rx_get_stack_layout): Iterate up to before CC_REGNUM not
FIRST_PSEUDO_REGNUM.
(rx_expand_prologue, rx_expand_epilogue): Likewise.
(rx_notice_update_cc): Delete.
(rx_cc_modes_compatible): New function.
(flags_needed_for_conditional): New function.
(flags_from_mode): New function.
(rx_compare_redundant): New function - scans backwards through
insn list to find out if condition flags are already set
correctly.
(TARGET_CC_MODES_COMPATIBLE): Define.
* config/rx/rx-protos.h (rx_compare_redundant): Prototype.
* config/rx/rx.h (BRANCH_COST): Define.
(REGISTER_MOVE_COST): Define.
* config/rx/predicates (rx_source_operand): Allow all constant
types.
* config/rx/rx.md (addsi3): Add alternative for swapped operands.
(tstsi4): New pattern.
* config/rx/rx.c (rx_memory_move_cost): Define.
(TARGET_MEMORY_MOVE_COST): Define.
2010-06-30 Manuel López-Ibáñez <manu@gcc.gnu.org> 2010-06-30 Manuel López-Ibáñez <manu@gcc.gnu.org>
* tree.h (block_may_fallthru): Declare here. * tree.h (block_may_fallthru): Declare here.
......
...@@ -50,9 +50,9 @@ ...@@ -50,9 +50,9 @@
;; and a restricted subset of memory addresses are allowed. ;; and a restricted subset of memory addresses are allowed.
(define_predicate "rx_source_operand" (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); return rx_is_legitimate_constant (op);
if (! MEM_P (op)) if (! MEM_P (op))
......
/* 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);
...@@ -31,6 +31,7 @@ extern int rx_initial_elimination_offset (int, int); ...@@ -31,6 +31,7 @@ extern int rx_initial_elimination_offset (int, int);
extern void rx_set_optimization_options (void); extern void rx_set_optimization_options (void);
#ifdef RTX_CODE #ifdef RTX_CODE
extern bool rx_compare_redundant (rtx);
extern void rx_emit_stack_popm (rtx *, bool); extern void rx_emit_stack_popm (rtx *, bool);
extern void rx_emit_stack_pushm (rtx *); extern void rx_emit_stack_pushm (rtx *);
extern void rx_expand_epilogue (bool); extern void rx_expand_epilogue (bool);
......
...@@ -707,12 +707,6 @@ rx_gen_cond_branch_template (rtx condition, bool reversed) ...@@ -707,12 +707,6 @@ rx_gen_cond_branch_template (rtx condition, bool reversed)
{ {
enum rtx_code code = GET_CODE (condition); 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 (reversed)
{ {
if (rx_float_compare_mode) if (rx_float_compare_mode)
...@@ -1063,7 +1057,7 @@ rx_get_stack_layout (unsigned int * lowest, ...@@ -1063,7 +1057,7 @@ rx_get_stack_layout (unsigned int * lowest,
return; 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) if (df_regs_ever_live_p (reg)
&& (! call_used_regs[reg] && (! call_used_regs[reg]
...@@ -1241,7 +1235,7 @@ rx_expand_prologue (void) ...@@ -1241,7 +1235,7 @@ rx_expand_prologue (void)
if (mask) if (mask)
{ {
/* Push registers in reverse order. */ /* Push registers in reverse order. */
for (reg = FIRST_PSEUDO_REGISTER; reg --;) for (reg = CC_REGNUM; reg --;)
if (mask & (1 << reg)) if (mask & (1 << reg))
{ {
insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg))); insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg)));
...@@ -1270,7 +1264,7 @@ rx_expand_prologue (void) ...@@ -1270,7 +1264,7 @@ rx_expand_prologue (void)
{ {
acc_low = acc_high = 0; 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 (mask & (1 << reg))
{ {
if (acc_low == 0) if (acc_low == 0)
...@@ -1543,7 +1537,8 @@ rx_expand_epilogue (bool is_sibcall) ...@@ -1543,7 +1537,8 @@ rx_expand_epilogue (bool is_sibcall)
if (register_mask) if (register_mask)
{ {
acc_low = acc_high = 0; 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 (register_mask & (1 << reg))
{ {
if (acc_low == 0) if (acc_low == 0)
...@@ -1574,7 +1569,7 @@ rx_expand_epilogue (bool is_sibcall) ...@@ -1574,7 +1569,7 @@ rx_expand_epilogue (bool is_sibcall)
if (register_mask) if (register_mask)
{ {
for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg ++) for (reg = 0; reg < CC_REGNUM; reg ++)
if (register_mask & (1 << reg)) if (register_mask & (1 << reg))
emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg))); emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg)));
} }
...@@ -1674,54 +1669,6 @@ rx_initial_elimination_offset (int from, int to) ...@@ -1674,54 +1669,6 @@ rx_initial_elimination_offset (int from, int to)
return stack_size; 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_DEST (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_ZSC:
/* Insn sets the Z,S and C flags, but not the O flag. */
CC_STATUS_INIT;
cc_status.flags |= CC_NO_OVERFLOW;
/* See comment above regarding cc_status.value1. */
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. */ /* Decide if a variable should go into one of the small data sections. */
static bool static bool
...@@ -2517,6 +2464,220 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain) ...@@ -2517,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 #undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE rx_function_value #define TARGET_FUNCTION_VALUE rx_function_value
...@@ -2610,6 +2771,12 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain) ...@@ -2610,6 +2771,12 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
#undef TARGET_PRINT_OPERAND_ADDRESS #undef TARGET_PRINT_OPERAND_ADDRESS
#define TARGET_PRINT_OPERAND_ADDRESS rx_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; struct gcc_target targetm = TARGET_INITIALIZER;
/* #include "gt-rx.h" */ /* #include "gt-rx.h" */
...@@ -207,7 +207,7 @@ enum reg_class ...@@ -207,7 +207,7 @@ enum reg_class
#define BASE_REG_CLASS GR_REGS #define BASE_REG_CLASS GR_REGS
#define INDEX_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 \ #define REGNO_REG_CLASS(REGNO) ((REGNO) < FIRST_PSEUDO_REGISTER \
? GR_REGS : NO_REGS) ? GR_REGS : NO_REGS)
...@@ -219,6 +219,7 @@ enum reg_class ...@@ -219,6 +219,7 @@ enum reg_class
#define STATIC_CHAIN_REGNUM 8 #define STATIC_CHAIN_REGNUM 8
#define TRAMPOLINE_TEMP_REGNUM 9 #define TRAMPOLINE_TEMP_REGNUM 9
#define STRUCT_VAL_REGNUM 15 #define STRUCT_VAL_REGNUM 15
#define CC_REGNUM 16
/* This is the register which is used to hold the address of the start /* 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 of the small data area, if that feature is being used. Note - this
...@@ -245,12 +246,12 @@ enum reg_class ...@@ -245,12 +246,12 @@ enum reg_class
#define FIXED_REGISTERS \ #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 \ #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 \ #define CONDITIONAL_REGISTER_USAGE \
...@@ -351,7 +352,7 @@ typedef unsigned int CUMULATIVE_ARGS; ...@@ -351,7 +352,7 @@ typedef unsigned int CUMULATIVE_ARGS;
#define REGISTER_NAMES \ #define REGISTER_NAMES \
{ \ { \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ "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 \ #define ADDITIONAL_REGISTER_NAMES \
...@@ -609,9 +610,6 @@ typedef unsigned int CUMULATIVE_ARGS; ...@@ -609,9 +610,6 @@ typedef unsigned int CUMULATIVE_ARGS;
they contain are always computed between two same-section symbols. */ they contain are always computed between two same-section symbols. */
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic) #define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
#define CC_NO_CARRY 0400
#define NOTICE_UPDATE_CC(EXP, INSN) rx_notice_update_cc (EXP, INSN)
extern int rx_float_compare_mode; extern int rx_float_compare_mode;
/* This is a version of REG_P that also returns TRUE for SUBREGs. */ /* This is a version of REG_P that also returns TRUE for SUBREGs. */
...@@ -646,3 +644,16 @@ extern int rx_float_compare_mode; ...@@ -646,3 +644,16 @@ extern int rx_float_compare_mode;
/* This macro is used to decide when RX FPU instructions can be used. */ /* This macro is used to decide when RX FPU instructions can be used. */
#define ALLOW_RX_FPU_INSNS (TARGET_USE_FPU) #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))))
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
(define_constants (define_constants
[ [
(SP_REG 0) (SP_REG 0)
(CC_REG 16)
(UNSPEC_LOW_REG 0) (UNSPEC_LOW_REG 0)
(UNSPEC_HIGH_REG 1) (UNSPEC_HIGH_REG 1)
...@@ -86,14 +87,6 @@ ...@@ -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,set_zsc,clobber" (const_string "none"))
(define_attr "length" "" (const_int 8)) (define_attr "length" "" (const_int 8))
(include "predicates.md") (include "predicates.md")
...@@ -156,77 +149,120 @@ ...@@ -156,77 +149,120 @@
;; Comparisons ;; 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" (define_expand "cbranchsi4"
[(set (cc0) (compare:CC (match_operand:SI 1 "register_operand") [(set (pc)
(match_operand:SI 2 "rx_source_operand"))) (if_then_else (match_operator:SI 0 "comparison_operator"
(set (pc) [(match_operand:SI 1 "register_operand")
(if_then_else (match_operator:SI 0 "comparison_operator" (match_operand:SI 2 "rx_source_operand")])
[(cc0) (const_int 0)])
(label_ref (match_operand 3 "")) (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" (define_expand "cbranchsf4"
[(set (cc0) (compare:CC (match_operand:SF 1 "register_operand") [(set (pc)
(match_operand:SF 2 "rx_source_operand"))) (if_then_else (match_operator:SF 0 "comparison_operator"
(set (pc) [(match_operand:SF 1 "register_operand")
(if_then_else (match_operator:SI 0 "comparison_operator" (match_operand:SF 2 "rx_source_operand")])
[(cc0) (const_int 0)])
(label_ref (match_operand 3 "")) (label_ref (match_operand 3 ""))
(pc)))] (pc)))
"ALLOW_RX_FPU_INSNS && (cfun == NULL || !cfun->can_throw_non_call_exceptions)" ]
"ALLOW_RX_FPU_INSNS"
"" ""
) )
;; The TST instruction is not used as it does not set the Carry flag, (define_insn_and_split "*cbranchsf4_<code>"
;; so for example, the LessThan comparison cannot be tested. [(set (pc)
;; (if_then_else (most_cond:SF (match_operand:SF 0 "register_operand" "r")
;; (define_insn "tstsi" (match_operand:SF 1 "rx_source_operand" "rFiQ"))
;; [(set (cc0) (label_ref (match_operand 2 "" ""))
;; (match_operand:SI 0 "rx_source_operand" "r,i,Q")))] (pc)))
;; "" ]
;; { "ALLOW_RX_FPU_INSNS"
;; rx_float_compare_mode = false; "#"
;; return "tst\t%Q0"; "&& reload_completed"
;; } [(const_int 0)]
;; [(set_attr "cc" "set_zs") "
;; (set_attr "timings" "11,11,33") /* We contstruct the split by hand as otherwise the JUMP_LABEL
;; (set_attr "length" "3,7,6")] 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" (define_insn "cmpsi"
[(set (cc0) (compare:CC [(set (reg:CC CC_REG)
(match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r") (compare:CC (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r")
(match_operand:SI 1 "rx_source_operand" (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
"r,Uint04,Int08,Sint16,Sint24,i,Q")))]
"" ""
{ {
rx_float_compare_mode = false; rx_float_compare_mode = false;
if (rx_compare_redundant (insn))
return "; Compare Eliminated: cmp %Q1, %0";
return "cmp\t%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")] (set_attr "length" "2,2,3,4,5,6,5")]
) )
;; This pattern is disabled if the function can throw non-call exceptions, ;; ??? g++.dg/eh/080514-1.C to see this happen.
;; because 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.
(define_insn "cmpsf" (define_insn "cmpsf"
[(set (cc0) [(set (reg:CC_ZSO CC_REG)
(compare:CC (match_operand:SF 0 "register_operand" "r,r,r") (compare:CC_ZSO (match_operand:SF 0 "register_operand" "r,r,r")
(match_operand:SF 1 "rx_source_operand" "r,i,Q")))] (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
"ALLOW_RX_FPU_INSNS && (cfun == NULL || !cfun->can_throw_non_call_exceptions)" "ALLOW_RX_FPU_INSNS"
{ {
rx_float_compare_mode = true; rx_float_compare_mode = true;
return "fcmp\t%1, %0"; 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")] (set_attr "length" "3,7,5")]
) )
...@@ -234,17 +270,17 @@ ...@@ -234,17 +270,17 @@
(define_expand "b<code>" (define_expand "b<code>"
[(set (pc) [(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)) (label_ref (match_operand 0))
(pc)))] (pc)))]
"" ""
"" ""
) )
(define_insn "*conditional_branch" (define_insn "conditional_branch"
[(set (pc) [(set (pc)
(if_then_else (match_operator 1 "comparison_operator" (if_then_else (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)]) [(reg:CC CC_REG) (const_int 0)])
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
...@@ -253,14 +289,13 @@ ...@@ -253,14 +289,13 @@
} }
[(set_attr "length" "8") ;; This length is wrong, but it is [(set_attr "length" "8") ;; This length is wrong, but it is
;; too hard to compute statically. ;; too hard to compute statically.
(set_attr "timings" "33") ;; The timing assumes that the branch is taken. (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
(set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
) )
(define_insn "*reveresed_conditional_branch" (define_insn "*reveresed_conditional_branch"
[(set (pc) [(set (pc)
(if_then_else (match_operator 1 "comparison_operator" (if_then_else (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)]) [(reg:CC CC_REG) (const_int 0)])
(pc) (pc)
(label_ref (match_operand 0 "" ""))))] (label_ref (match_operand 0 "" ""))))]
"" ""
...@@ -269,38 +304,37 @@ ...@@ -269,38 +304,37 @@
} }
[(set_attr "length" "8") ;; This length is wrong, but it is [(set_attr "length" "8") ;; This length is wrong, but it is
;; too hard to compute statically. ;; too hard to compute statically.
(set_attr "timings" "33") ;; The timing assumes that the branch is taken. (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
(set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
) )
(define_insn "jump" (define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))] [(set (pc)
(label_ref (match_operand 0 "" "")))]
"" ""
"bra\t%0" "bra\t%0"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "timings" "33") (set_attr "timings" "33")]
(set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
) )
(define_insn "indirect_jump" (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" "jmp\t%0"
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "timings" "33") (set_attr "timings" "33")]
(set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
) )
(define_insn "tablejump" (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 "" "")))] (use (label_ref (match_operand 1 "" "")))]
"" ""
{ return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0" { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
: "\n1:\tbra\t%0") : "\n1:\tbra\t%0")
: "jmp\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")] (set_attr "length" "2")]
) )
...@@ -324,11 +358,10 @@ ...@@ -324,11 +358,10 @@
) )
(define_insn "pop_and_return" (define_insn "pop_and_return"
[(match_parallel 1 "rx_rtsd_vector" [(match_parallel 1 "rx_rtsd_vector"
[(set:SI (reg:SI SP_REG) [(set:SI (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
(match_operand:SI (match_operand:SI 0 "const_int_operand" "n")))])]
0 "const_int_operand" "n")))])]
"reload_completed" "reload_completed"
{ {
rx_emit_stack_popm (operands, false); rx_emit_stack_popm (operands, false);
...@@ -385,13 +418,13 @@ ...@@ -385,13 +418,13 @@
(define_insn "call_internal" (define_insn "call_internal"
[(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol")) [(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 jsr\t%0
bsr\t%A0" bsr\t%A0"
[(set_attr "length" "2,4") [(set_attr "length" "2,4")
(set_attr "cc" "clobber")
(set_attr "timings" "33")] (set_attr "timings" "33")]
) )
...@@ -413,13 +446,13 @@ ...@@ -413,13 +446,13 @@
(define_insn "call_value_internal" (define_insn "call_value_internal"
[(set (match_operand 0 "register_operand" "=r,r") [(set (match_operand 0 "register_operand" "=r,r")
(call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol")) (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 jsr\t%1
bsr\t%A1" bsr\t%A1"
[(set_attr "length" "2,4") [(set_attr "length" "2,4")
(set_attr "cc" "clobber")
(set_attr "timings" "33")] (set_attr "timings" "33")]
) )
...@@ -564,11 +597,10 @@ ...@@ -564,11 +597,10 @@
) )
(define_insn "stack_pushm" (define_insn "stack_pushm"
[(match_parallel 1 "rx_store_multiple_vector" [(match_parallel 1 "rx_store_multiple_vector"
[(set:SI (reg:SI SP_REG) [(set:SI (reg:SI SP_REG)
(minus:SI (reg:SI SP_REG) (minus:SI (reg:SI SP_REG)
(match_operand:SI (match_operand:SI 0 "const_int_operand" "n")))])]
0 "const_int_operand" "n")))])]
"reload_completed" "reload_completed"
{ {
rx_emit_stack_pushm (operands); rx_emit_stack_pushm (operands);
...@@ -591,11 +623,10 @@ ...@@ -591,11 +623,10 @@
) )
(define_insn "stack_popm" (define_insn "stack_popm"
[(match_parallel 1 "rx_load_multiple_vector" [(match_parallel 1 "rx_load_multiple_vector"
[(set:SI (reg:SI SP_REG) [(set:SI (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
(match_operand:SI (match_operand:SI 0 "const_int_operand" "n")))])]
0 "const_int_operand" "n")))])]
"reload_completed" "reload_completed"
{ {
rx_emit_stack_popm (operands, true); rx_emit_stack_popm (operands, true);
...@@ -605,29 +636,29 @@ ...@@ -605,29 +636,29 @@
(set_attr "timings" "45")] ;; The timing is a guesstimate average timing. (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
) )
;; FIXME: Add memory destination options ?
(define_insn "cstoresi4" (define_insn "cstoresi4"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
(match_operator:SI (match_operator:SI 1 "comparison_operator"
1 "comparison_operator" [(match_operand:SI 2 "register_operand" "r,r,r,r,r,r,r")
[(match_operand:SI (match_operand:SI 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))
2 "register_operand" "r,r,r,r,r,r,r") (clobber (reg:CC CC_REG))] ;; Because the cc flags are set based on comparing ops 2 & 3 not the value in op 0.
(match_operand:SI
3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))]
"" ""
{ {
rx_float_compare_mode = false; rx_float_compare_mode = false;
return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0"; return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0";
} }
[(set_attr "cc" "clobber") ;; Because cc0 is set based on comparing ops 2 & 3 not the value in op 0. [(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")] (set_attr "length" "5,5,6,7,8,9,8")]
) )
(define_expand "movsicc" (define_expand "movsicc"
[(set (match_operand:SI 0 "register_operand") [(parallel
(if_then_else:SI (match_operand:SI 1 "comparison_operator") [(set (match_operand:SI 0 "register_operand")
(match_operand:SI 2 "nonmemory_operand") (if_then_else:SI (match_operand:SI 1 "comparison_operator")
(match_operand:SI 3 "immediate_operand")))] (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) if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
...@@ -638,22 +669,18 @@ ...@@ -638,22 +669,18 @@
) )
(define_insn "*movsieq" (define_insn "*movsieq"
[(set (match_operand:SI 0 "register_operand" "=r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r")
(if_then_else:SI (eq (match_operand:SI (if_then_else:SI (eq (match_operand:SI 3 "register_operand" "r,r,r")
3 "register_operand" "r,r,r") (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
(match_operand:SI (match_operand:SI 1 "nonmemory_operand" "0,i,r")
4 "rx_source_operand" "riQ,riQ,riQ")) (match_operand:SI 2 "immediate_operand" "i,i,i")))
(match_operand:SI (clobber (reg:CC CC_REG))] ;; See cstoresi4
1 "nonmemory_operand" "0,i,r")
(match_operand:SI
2 "immediate_operand" "i,i,i")))]
"" ""
"@ "@
cmp\t%Q4, %Q3\n\tstnz\t%2, %0 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%2, %0\n\tstz\t%1, %0
cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0" cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
[(set_attr "cc" "clobber") ;; See cstoresi4 [(set_attr "length" "13,19,15")
(set_attr "length" "13,19,15")
(set_attr "timings" "22,33,33")] (set_attr "timings" "22,33,33")]
) )
...@@ -662,14 +689,14 @@ ...@@ -662,14 +689,14 @@
(if_then_else:SI (ne (match_operand:SI 3 "register_operand" "r,r,r") (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 4 "rx_source_operand" "riQ,riQ,riQ"))
(match_operand:SI 1 "nonmemory_operand" "0,i,r") (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\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%2, %0\n\tstnz\t%1, %0
cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0" cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
[(set_attr "cc" "clobber") ;; See cstoresi4 [(set_attr "length" "13,19,15")
(set_attr "length" "13,19,15")
(set_attr "timings" "22,33,33")] (set_attr "timings" "22,33,33")]
) )
...@@ -677,24 +704,24 @@ ...@@ -677,24 +704,24 @@
(define_insn "abssi2" (define_insn "abssi2"
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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%0
abs\t%1, %0" abs\t%1, %0"
[(set_attr "cc" "set_zso") [(set_attr "length" "2,3")]
(set_attr "length" "2,3")]
) )
(define_insn "addsi3" (define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,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")
(plus:SI (match_operand:SI (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
1 "register_operand" (set (reg:CC_ZSC CC_REG) ;; See subsi3
"%0,0,0,0,0,0,0,r,r,r,r,r,0") (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2))
(match_operand:SI (const_int 0)))]
2 "rx_source_operand"
"r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,r,Sint08,Sint16,Sint24,i,Q")))]
"" ""
"@ "@
add\t%2, %0 add\t%2, %0
...@@ -704,35 +731,38 @@ ...@@ -704,35 +731,38 @@
add\t%2, %0 add\t%2, %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%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" add\t%Q2, %0"
[(set_attr "cc" "set_zsc") ;; See subsi3 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
(set_attr "timings" "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")]
(set_attr "length" "2,2,2,3,4,5,6,3,3,4,5,6,5")]
) )
(define_insn "adddi3" (define_insn "adddi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r") [(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") (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:DI 2 "rx_source_operand" (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" "add\t%L2, %L0\n\tadc\t%H2, %H0"
[(set_attr "cc" "set_zsc") ;; See subsi3 [(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")] (set_attr "length" "5,7,9,11,13,11")]
) )
(define_insn "andsi3" (define_insn "andsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") [(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,r,0") (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
(match_operand:SI (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
2 "rx_source_operand" (set (reg:CC_ZS CC_REG)
"r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))] (compare:CC_ZS (and:SI (match_dup 1) (match_dup 2))
(const_int 0)))]
"" ""
"@ "@
and\t%2, %0 and\t%2, %0
...@@ -744,8 +774,7 @@ ...@@ -744,8 +774,7 @@
and\t%1, %0 and\t%1, %0
and\t%2, %1, %0 and\t%2, %1, %0
and\t%Q2, %0" and\t%Q2, %0"
[(set_attr "cc" "set_zs") [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
(set_attr "timings" "11,11,11,11,11,11,11,33,33")
(set_attr "length" "2,2,3,4,5,6,2,5,5")] (set_attr "length" "2,2,3,4,5,6,2,5,5")]
) )
...@@ -770,12 +799,11 @@ ...@@ -770,12 +799,11 @@
(define_insn "divsi3" (define_insn "divsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") [(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") (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
(match_operand:SI (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))] (clobber (reg:CC CC_REG))]
"" ""
"div\t%Q2, %0" "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. ;; 2222, but that is a worst case sceanario.
(set_attr "length" "3,4,5,6,7,6")] (set_attr "length" "3,4,5,6,7,6")]
) )
...@@ -783,12 +811,11 @@ ...@@ -783,12 +811,11 @@
(define_insn "udivsi3" (define_insn "udivsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") [(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") (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
(match_operand:SI (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))] (clobber (reg:CC CC_REG))]
"" ""
"divu\t%Q2, %0" "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. ;; 2020, but that is a worst case sceanario.
(set_attr "length" "3,4,5,6,7,6")] (set_attr "length" "3,4,5,6,7,6")]
) )
...@@ -816,12 +843,9 @@ ...@@ -816,12 +843,9 @@
;; mulsidi3 pattern. Immediate mode addressing is not supported ;; mulsidi3 pattern. Immediate mode addressing is not supported
;; because gcc cannot handle the expression: (zero_extend (const_int)). ;; because gcc cannot handle the expression: (zero_extend (const_int)).
(define_insn "umulsidi3" (define_insn "umulsidi3"
[(set (match_operand:DI 0 "register_operand" [(set (match_operand:DI 0 "register_operand" "=r,r")
"=r,r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,0"))
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
"%0,0"))
(zero_extend:DI (match_operand:SI 2 "rx_compare_operand"
"r,Q"))))]
"! TARGET_BIG_ENDIAN_DATA" "! TARGET_BIG_ENDIAN_DATA"
"emulu\t%Q2, %0" "emulu\t%Q2, %0"
[(set_attr "length" "3,6") [(set_attr "length" "3,6")
...@@ -872,33 +896,39 @@ ...@@ -872,33 +896,39 @@
(define_insn "negsi2" (define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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. ;; The NEG instruction does not comply with -fwrapv semantics.
;; See gcc.c-torture/execute/pr22493-1.c for an example of this. ;; See gcc.c-torture/execute/pr22493-1.c for an example of this.
"! flag_wrapv" "! flag_wrapv"
"@ "@
neg\t%0 neg\t%0
neg\t%1, %0" neg\t%1, %0"
[(set_attr "length" "2,3") [(set_attr "length" "2,3")]
(set_attr "cc" "set_zsoc")]
) )
(define_insn "one_cmplsi2" (define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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%0
not\t%1, %0" not\t%1, %0"
[(set_attr "cc" "set_zs") [(set_attr "length" "2,3")]
(set_attr "length" "2,3")]
) )
(define_insn "iorsi3" (define_insn "iorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") [(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,r,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" (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
"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 or\t%2, %0
...@@ -910,74 +940,89 @@ ...@@ -910,74 +940,89 @@
or\t%1, %0 or\t%1, %0
or\t%2, %1, %0 or\t%2, %1, %0
or\t%Q2, %0" or\t%Q2, %0"
[(set_attr "cc" "set_zs") [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
(set_attr "timings" "11,11,11,11,11,11,11,11,33")
(set_attr "length" "2,2,3,4,5,6,2,3,5")] (set_attr "length" "2,2,3,4,5,6,2,3,5")]
) )
(define_insn "rotlsi3" (define_insn "rotlsi3"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(rotate:SI (match_operand:SI 1 "register_operand" "0") (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" "rotl\t%2, %0"
[(set_attr "cc" "set_zs") [(set_attr "length" "3")]
(set_attr "length" "3")]
) )
(define_insn "rotrsi3" (define_insn "rotrsi3"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(rotatert:SI (match_operand:SI 1 "register_operand" "0") (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" "rotr\t%2, %0"
[(set_attr "cc" "set_zs") [(set_attr "length" "3")]
(set_attr "length" "3")]
) )
(define_insn "ashrsi3" (define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,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, %0 shar\t%2, %0
shar\t%2, %1, %0" shar\t%2, %1, %0"
[(set_attr "cc" "set_zs") [(set_attr "length" "3,2,3")]
(set_attr "length" "3,2,3")]
) )
(define_insn "lshrsi3" (define_insn "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,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, %0 shlr\t%2, %0
shlr\t%2, %1, %0" shlr\t%2, %1, %0"
[(set_attr "cc" "set_zs") [(set_attr "length" "3,2,3")]
(set_attr "length" "3,2,3")]
) )
(define_insn "ashlsi3" (define_insn "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashift:SI (match_operand:SI 1 "register_operand" "0,0,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, %0 shll\t%2, %0
shll\t%2, %1, %0" shll\t%2, %1, %0"
[(set_attr "cc" "set_zs") [(set_attr "length" "3,2,3")]
(set_attr "length" "3,2,3")]
) )
(define_insn "subsi3" (define_insn "subsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") [(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") (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 sub\t%2, %0
...@@ -985,22 +1030,20 @@ ...@@ -985,22 +1030,20 @@
add\t%N2, %0 add\t%N2, %0
sub\t%2, %1, %0 sub\t%2, %1, %0
sub\t%Q2, %0" sub\t%Q2, %0"
[(set_attr "cc" "set_zsc") ;; Note - we do not acknowledge that the SUB [(set_attr "timings" "11,11,11,11,33")
;; 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.
(set_attr "timings" "11,11,11,11,33")
(set_attr "length" "2,2,6,3,5")] (set_attr "length" "2,2,6,3,5")]
) )
(define_insn "subdi3" (define_insn "subdi3"
[(set (match_operand:DI 0 "register_operand" "=r,r") [(set (match_operand:DI 0 "register_operand" "=r,r")
(minus:DI (match_operand:DI 1 "register_operand" "0,0") (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" "sub\t%L2, %L0\n\tsbb\t%H2, %H0"
[(set_attr "cc" "set_zsc") ;; See subsi3 [(set_attr "timings" "22,44")
(set_attr "timings" "22,44")
(set_attr "length" "5,11")] (set_attr "length" "5,11")]
) )
...@@ -1008,11 +1051,13 @@ ...@@ -1008,11 +1051,13 @@
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") [(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") (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:SI 2 "rx_source_operand" (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"
[(set_attr "cc" "set_zs") [(set_attr "timings" "11,11,11,11,11,33")
(set_attr "timings" "11,11,11,11,11,33")
(set_attr "length" "3,4,5,6,7,6")] (set_attr "length" "3,4,5,6,7,6")]
) )
...@@ -1021,64 +1066,76 @@ ...@@ -1021,64 +1066,76 @@
(define_insn "addsf3" (define_insn "addsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r") [(set (match_operand:SF 0 "register_operand" "=r,r,r")
(plus:SF (match_operand:SF 1 "register_operand" "%0,0,0") (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" "ALLOW_RX_FPU_INSNS"
"fadd\t%2, %0" "fadd\t%2, %0"
[(set_attr "cc" "set_zs") [(set_attr "timings" "44,44,66")
(set_attr "timings" "44,44,66")
(set_attr "length" "3,7,5")] (set_attr "length" "3,7,5")]
) )
(define_insn "divsf3" (define_insn "divsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r") [(set (match_operand:SF 0 "register_operand" "=r,r,r")
(div:SF (match_operand:SF 1 "register_operand" "0,0,0") (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" "ALLOW_RX_FPU_INSNS"
"fdiv\t%2, %0" "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")] (set_attr "length" "3,7,5")]
) )
(define_insn "mulsf3" (define_insn "mulsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r") [(set (match_operand:SF 0 "register_operand" "=r,r,r")
(mult:SF (match_operand:SF 1 "register_operand" "%0,0,0") (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" "ALLOW_RX_FPU_INSNS"
"fmul\t%2, %0" "fmul\t%2, %0"
[(set_attr "cc" "set_zs") [(set_attr "timings" "33,33,55")
(set_attr "timings" "33,33,55")
(set_attr "length" "3,7,5")] (set_attr "length" "3,7,5")]
) )
(define_insn "subsf3" (define_insn "subsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r") [(set (match_operand:SF 0 "register_operand" "=r,r,r")
(minus:SF (match_operand:SF 1 "register_operand" "0,0,0") (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" "ALLOW_RX_FPU_INSNS"
"fsub\t%Q2, %0" "fsub\t%Q2, %0"
[(set_attr "cc" "set_zs") [(set_attr "timings" "44,44,66")
(set_attr "timings" "44,44,66")
(set_attr "length" "3,7,5")] (set_attr "length" "3,7,5")]
) )
(define_insn "fix_truncsfsi2" (define_insn "fix_truncsfsi2"
[(set (match_operand:SI 0 "register_operand" "=r,r") [(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" "ALLOW_RX_FPU_INSNS"
"ftoi\t%Q1, %0" "ftoi\t%Q1, %0"
[(set_attr "cc" "set_zs") [(set_attr "timings" "22,44")
(set_attr "timings" "22,44")
(set_attr "length" "3,5")] (set_attr "length" "3,5")]
) )
(define_insn "floatsisf2" (define_insn "floatsisf2"
[(set (match_operand:SF 0 "register_operand" "=r,r") [(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" "ALLOW_RX_FPU_INSNS"
"itof\t%Q1, %0" "itof\t%Q1, %0"
[(set_attr "cc" "set_zs") [(set_attr "timings" "22,44")
(set_attr "timings" "22,44")
(set_attr "length" "3,6")] (set_attr "length" "3,6")]
) )
...@@ -1090,8 +1147,8 @@ ...@@ -1090,8 +1147,8 @@
;; of three instructions at a time. ;; of three instructions at a time.
(define_insn "bitset" (define_insn "bitset"
[(set:SI (match_operand:SI 0 "register_operand" "=r") [(set:SI (match_operand:SI 0 "register_operand" "=r")
(ior:SI (match_operand:SI 1 "register_operand" "0") (ior:SI (match_operand:SI 1 "register_operand" "0")
(ashift:SI (const_int 1) (ashift:SI (const_int 1)
(match_operand:SI 2 "nonmemory_operand" "ri"))))] (match_operand:SI 2 "nonmemory_operand" "ri"))))]
"" ""
...@@ -1100,8 +1157,8 @@ ...@@ -1100,8 +1157,8 @@
) )
(define_insn "bitset_in_memory" (define_insn "bitset_in_memory"
[(set:QI (match_operand:QI 0 "memory_operand" "=m") [(set:QI (match_operand:QI 0 "memory_operand" "=m")
(ior:QI (match_operand:QI 1 "memory_operand" "0") (ior:QI (match_operand:QI 1 "memory_operand" "0")
(ashift:QI (const_int 1) (ashift:QI (const_int 1)
(match_operand:QI 2 "nonmemory_operand" "ri"))))] (match_operand:QI 2 "nonmemory_operand" "ri"))))]
"" ""
...@@ -1275,14 +1332,10 @@ ...@@ -1275,14 +1332,10 @@
) )
(define_expand "insv" (define_expand "insv"
[(set:SI (zero_extract:SI (match_operand:SI [(set:SI (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand") ;; Destination
0 "nonimmediate_operand") ;; Destination (match_operand 1 "immediate_operand") ;; # of bits to set
(match_operand (match_operand 2 "immediate_operand")) ;; Starting bit
1 "immediate_operand") ;; # of bits to set (match_operand 3 "immediate_operand"))] ;; Bits to insert
(match_operand
2 "immediate_operand")) ;; Starting bit
(match_operand
3 "immediate_operand"))] ;; Bits to insert
"" ""
{ {
if (rx_expand_insv (operands)) if (rx_expand_insv (operands))
...@@ -1337,8 +1390,7 @@ ...@@ -1337,8 +1390,7 @@
(unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR) (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
(clobber (reg:SI 1)) (clobber (reg:SI 1))
(clobber (reg:SI 2)) (clobber (reg:SI 2))
(clobber (reg:SI 3)) (clobber (reg:SI 3))]
]
"" ""
"smovu" "smovu"
[(set_attr "length" "2") [(set_attr "length" "2")
...@@ -1352,11 +1404,11 @@ ...@@ -1352,11 +1404,11 @@
(clobber (reg:SI 1)) (clobber (reg:SI 1))
(clobber (reg:SI 2)) (clobber (reg:SI 2))
(clobber (reg:SI 3)) (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" "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 "length" "10")
(set_attr "cc" "clobber")
(set_attr "timings" "1111")] ;; The timing is a guesstimate. (set_attr "timings" "1111")] ;; The timing is a guesstimate.
) )
...@@ -1439,17 +1491,12 @@ ...@@ -1439,17 +1491,12 @@
) )
(define_expand "cmpstrnsi" (define_expand "cmpstrnsi"
[(set (match_operand:SI [(set (match_operand:SI 0 "register_operand") ;; Result
0 "register_operand") ;; Result (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
(unspec_volatile:SI [(match_operand:BLK (match_operand:BLK 2 "memory_operand")] ;; String2
1 "memory_operand") ;; String1
(match_operand:BLK
2 "memory_operand")] ;; String2
UNSPEC_CMPSTRN)) UNSPEC_CMPSTRN))
(use (match_operand:SI (use (match_operand:SI 3 "register_operand")) ;; Max Length
3 "register_operand")) ;; Max Length (match_operand:SI 4 "immediate_operand")] ;; Known Align
(match_operand:SI
4 "immediate_operand")] ;; Known Align
"" ""
{ {
rtx str1 = gen_rtx_REG (SImode, 1); rtx str1 = gen_rtx_REG (SImode, 1);
...@@ -1466,15 +1513,11 @@ ...@@ -1466,15 +1513,11 @@
) )
(define_expand "cmpstrsi" (define_expand "cmpstrsi"
[(set (match_operand:SI [(set (match_operand:SI 0 "register_operand") ;; Result
0 "register_operand") ;; Result (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
(unspec_volatile:SI [(match_operand:BLK (match_operand:BLK 2 "memory_operand")] ;; String2
1 "memory_operand") ;; String1
(match_operand:BLK
2 "memory_operand")] ;; String2
UNSPEC_CMPSTRN)) UNSPEC_CMPSTRN))
(match_operand:SI (match_operand:SI 3 "immediate_operand")] ;; Known Align
3 "immediate_operand")] ;; Known Align
"" ""
{ {
rtx str1 = gen_rtx_REG (SImode, 1); rtx str1 = gen_rtx_REG (SImode, 1);
...@@ -1498,7 +1541,8 @@ ...@@ -1498,7 +1541,8 @@
(use (match_operand:BLK 2 "memory_operand" "m")) (use (match_operand:BLK 2 "memory_operand" "m"))
(clobber (reg:SI 1)) (clobber (reg:SI 1))
(clobber (reg:SI 2)) (clobber (reg:SI 2))
(clobber (reg:SI 3))] (clobber (reg:SI 3))
(clobber (reg:CC CC_REG))]
"" ""
"scmpu ; Perform the string comparison "scmpu ; Perform the string comparison
mov #-1, %0 ; Set up -1 result (which cannot be created mov #-1, %0 ; Set up -1 result (which cannot be created
...@@ -1639,11 +1683,11 @@ ...@@ -1639,11 +1683,11 @@
(define_insn "lrintsf2" (define_insn "lrintsf2"
[(set (match_operand:SI 0 "register_operand" "=r,r") [(set (match_operand:SI 0 "register_operand" "=r,r")
(unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")] (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" "round\t%1, %0"
[(set_attr "cc" "clobber") [(set_attr "timings" "22,44")
(set_attr "timings" "22,44")
(set_attr "length" "3,5")] (set_attr "length" "3,5")]
) )
...@@ -1663,22 +1707,20 @@ ...@@ -1663,22 +1707,20 @@
(define_insn "clrpsw" (define_insn "clrpsw"
[(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")] [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
UNSPEC_BUILTIN_CLRPSW) UNSPEC_BUILTIN_CLRPSW)
(clobber (cc0))] (clobber (reg:CC CC_REG))]
"" ""
"clrpsw\t%F0" "clrpsw\t%F0"
[(set_attr "length" "2") [(set_attr "length" "2")]
(set_attr "cc" "clobber")]
) )
;; Set Processor Status Word ;; Set Processor Status Word
(define_insn "setpsw" (define_insn "setpsw"
[(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")] [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
UNSPEC_BUILTIN_SETPSW) UNSPEC_BUILTIN_SETPSW)
(clobber (cc0))] (clobber (reg:CC CC_REG))]
"" ""
"setpsw\t%F0" "setpsw\t%F0"
[(set_attr "length" "2") [(set_attr "length" "2")]
(set_attr "cc" "clobber")]
) )
;; Move from control register ;; Move from control register
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment