mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-28 22:34:03 +08:00
rx.md: Add peepholes and patterns to combine extending loads and simple arithmetic...
* config/rx/rx.md: Add peepholes and patterns to combine extending loads and simple arithmetic instructions. * config/rx/rx.h (ADJUST_INSN_LENGTH): Define. * config/rx/rx-protos.h (rx_adjust_insn_length): Prototype. * config/rx/rx.c (rx_is_legitimate_address): Allow QI and HI modes to use pre-decrement and post-increment addressing. (rx_is_restricted_memory_address): Add range checking of REG+INT addresses. (rx_print_operand): Add support for %Q. Fix handling of %Q. (rx_memory_move_cost): Adjust cost of stores. (rx_adjust_insn_length): New function. From-SVN: r171724
This commit is contained in:
parent
8a87e7abcb
commit
e9c0470ac5
@ -1,3 +1,18 @@
|
|||||||
|
2011-03-30 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* config/rx/rx.md: Add peepholes and patterns to combine
|
||||||
|
extending loads and simple arithmetic instructions.
|
||||||
|
* config/rx/rx.h (ADJUST_INSN_LENGTH): Define.
|
||||||
|
* config/rx/rx-protos.h (rx_adjust_insn_length): Prototype.
|
||||||
|
* config/rx/rx.c (rx_is_legitimate_address): Allow QI and HI
|
||||||
|
modes to use pre-decrement and post-increment addressing.
|
||||||
|
(rx_is_restricted_memory_address): Add range checking of REG+INT
|
||||||
|
addresses.
|
||||||
|
(rx_print_operand): Add support for %Q.
|
||||||
|
Fix handling of %Q.
|
||||||
|
(rx_memory_move_cost): Adjust cost of stores.
|
||||||
|
(rx_adjust_insn_length): New function.
|
||||||
|
|
||||||
2011-03-30 Jakub Jelinek <jakub@redhat.com>
|
2011-03-30 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c/48305
|
PR c/48305
|
||||||
|
@ -31,16 +31,17 @@ extern void rx_expand_prologue (void);
|
|||||||
extern int rx_initial_elimination_offset (int, int);
|
extern int rx_initial_elimination_offset (int, int);
|
||||||
|
|
||||||
#ifdef RTX_CODE
|
#ifdef RTX_CODE
|
||||||
|
extern int rx_adjust_insn_length (rtx, int);
|
||||||
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);
|
||||||
extern char * rx_gen_move_template (rtx *, bool);
|
extern char * rx_gen_move_template (rtx *, bool);
|
||||||
extern bool rx_is_legitimate_constant (rtx);
|
extern bool rx_is_legitimate_constant (rtx);
|
||||||
extern bool rx_is_restricted_memory_address (rtx, Mmode);
|
extern bool rx_is_restricted_memory_address (rtx, Mmode);
|
||||||
|
extern bool rx_match_ccmode (rtx, Mmode);
|
||||||
extern void rx_notice_update_cc (rtx body, rtx insn);
|
extern void rx_notice_update_cc (rtx body, rtx insn);
|
||||||
extern void rx_split_cbranch (Mmode, Rcode, rtx, rtx, rtx);
|
extern void rx_split_cbranch (Mmode, Rcode, rtx, rtx, rtx);
|
||||||
extern Mmode rx_select_cc_mode (Rcode, rtx, rtx);
|
extern Mmode rx_select_cc_mode (Rcode, rtx, rtx);
|
||||||
extern bool rx_match_ccmode (rtx, Mmode);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* GCC_RX_PROTOS_H */
|
#endif /* GCC_RX_PROTOS_H */
|
||||||
|
@ -86,7 +86,7 @@ rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
|
|||||||
/* Register Indirect. */
|
/* Register Indirect. */
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (GET_MODE_SIZE (mode) == 4
|
if (GET_MODE_SIZE (mode) <= 4
|
||||||
&& (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
|
&& (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
|
||||||
/* Pre-decrement Register Indirect or
|
/* Pre-decrement Register Indirect or
|
||||||
Post-increment Register Indirect. */
|
Post-increment Register Indirect. */
|
||||||
@ -117,7 +117,7 @@ rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (GET_MODE_SIZE (mode))
|
switch (GET_MODE_SIZE (mode))
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@ -126,7 +126,7 @@ rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
|
|||||||
case 1: factor = 1; break;
|
case 1: factor = 1; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val > (65535 * factor))
|
if (val >= (0x10000 * factor))
|
||||||
return false;
|
return false;
|
||||||
return (val % factor) == 0;
|
return (val % factor) == 0;
|
||||||
}
|
}
|
||||||
@ -167,8 +167,6 @@ rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
|
|||||||
bool
|
bool
|
||||||
rx_is_restricted_memory_address (rtx mem, enum machine_mode mode)
|
rx_is_restricted_memory_address (rtx mem, enum machine_mode mode)
|
||||||
{
|
{
|
||||||
rtx base, index;
|
|
||||||
|
|
||||||
if (! rx_is_legitimate_address
|
if (! rx_is_legitimate_address
|
||||||
(mode, mem, reload_in_progress || reload_completed))
|
(mode, mem, reload_in_progress || reload_completed))
|
||||||
return false;
|
return false;
|
||||||
@ -184,11 +182,18 @@ rx_is_restricted_memory_address (rtx mem, enum machine_mode mode)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
case PLUS:
|
case PLUS:
|
||||||
/* Only allow REG+INT addressing. */
|
{
|
||||||
base = XEXP (mem, 0);
|
rtx base, index;
|
||||||
index = XEXP (mem, 1);
|
|
||||||
|
/* Only allow REG+INT addressing. */
|
||||||
|
base = XEXP (mem, 0);
|
||||||
|
index = XEXP (mem, 1);
|
||||||
|
|
||||||
return RX_REG_P (base) && CONST_INT_P (index);
|
if (! RX_REG_P (base) || ! CONST_INT_P (index))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return IN_RANGE (INTVAL (index), 0, (0x10000 * GET_MODE_SIZE (mode)) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
case SYMBOL_REF:
|
case SYMBOL_REF:
|
||||||
/* Can happen when small data is being supported.
|
/* Can happen when small data is being supported.
|
||||||
@ -387,11 +392,14 @@ rx_assemble_integer (rtx x, unsigned int size, int is_aligned)
|
|||||||
%L Print low 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.
|
%N Print the negation of the immediate value.
|
||||||
%Q If the operand is a MEM, then correctly generate
|
%Q If the operand is a MEM, then correctly generate
|
||||||
register indirect or register relative addressing. */
|
register indirect or register relative addressing.
|
||||||
|
%R Like %Q but for zero-extending loads. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rx_print_operand (FILE * file, rtx op, int letter)
|
rx_print_operand (FILE * file, rtx op, int letter)
|
||||||
{
|
{
|
||||||
|
bool unsigned_load = false;
|
||||||
|
|
||||||
switch (letter)
|
switch (letter)
|
||||||
{
|
{
|
||||||
case 'A':
|
case 'A':
|
||||||
@ -451,6 +459,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int flags = flags_from_mode (mode);
|
unsigned int flags = flags_from_mode (mode);
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case LT:
|
case LT:
|
||||||
@ -589,10 +598,15 @@ rx_print_operand (FILE * file, rtx op, int letter)
|
|||||||
rx_print_integer (file, - INTVAL (op));
|
rx_print_integer (file, - INTVAL (op));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'R':
|
||||||
|
gcc_assert (GET_MODE_SIZE (GET_MODE (op)) < 4);
|
||||||
|
unsigned_load = true;
|
||||||
|
/* Fall through. */
|
||||||
case 'Q':
|
case 'Q':
|
||||||
if (MEM_P (op))
|
if (MEM_P (op))
|
||||||
{
|
{
|
||||||
HOST_WIDE_INT offset;
|
HOST_WIDE_INT offset;
|
||||||
|
rtx mem = op;
|
||||||
|
|
||||||
op = XEXP (op, 0);
|
op = XEXP (op, 0);
|
||||||
|
|
||||||
@ -627,22 +641,24 @@ rx_print_operand (FILE * file, rtx op, int letter)
|
|||||||
rx_print_operand (file, op, 0);
|
rx_print_operand (file, op, 0);
|
||||||
fprintf (file, "].");
|
fprintf (file, "].");
|
||||||
|
|
||||||
switch (GET_MODE_SIZE (GET_MODE (op)))
|
switch (GET_MODE_SIZE (GET_MODE (mem)))
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
gcc_assert (offset < 65535 * 1);
|
gcc_assert (offset <= 65535 * 1);
|
||||||
fprintf (file, "B");
|
fprintf (file, unsigned_load ? "UB" : "B");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
gcc_assert (offset % 2 == 0);
|
gcc_assert (offset % 2 == 0);
|
||||||
gcc_assert (offset < 65535 * 2);
|
gcc_assert (offset <= 65535 * 2);
|
||||||
fprintf (file, "W");
|
fprintf (file, unsigned_load ? "UW" : "W");
|
||||||
break;
|
break;
|
||||||
default:
|
case 4:
|
||||||
gcc_assert (offset % 4 == 0);
|
gcc_assert (offset % 4 == 0);
|
||||||
gcc_assert (offset < 65535 * 4);
|
gcc_assert (offset <= 65535 * 4);
|
||||||
fprintf (file, "L");
|
fprintf (file, "L");
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2449,8 +2465,7 @@ rx_is_legitimate_constant (rtx x)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
/* FIXME: Can this ever happen ? */
|
/* FIXME: Can this ever happen ? */
|
||||||
abort ();
|
gcc_unreachable ();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2593,7 +2608,7 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
|
|||||||
static int
|
static int
|
||||||
rx_memory_move_cost (enum machine_mode mode, reg_class_t regclass, bool in)
|
rx_memory_move_cost (enum machine_mode mode, reg_class_t regclass, bool in)
|
||||||
{
|
{
|
||||||
return 2 + memory_move_secondary_cost (mode, regclass, in);
|
return (in ? 2 : 0) + memory_move_secondary_cost (mode, regclass, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a CC_MODE to the set of flags that it represents. */
|
/* Convert a CC_MODE to the set of flags that it represents. */
|
||||||
@ -2778,6 +2793,113 @@ rx_max_skip_for_label (rtx lab)
|
|||||||
return opsize - 1;
|
return opsize - 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compute the real length of the extending load-and-op instructions. */
|
||||||
|
|
||||||
|
int
|
||||||
|
rx_adjust_insn_length (rtx insn, int current_length)
|
||||||
|
{
|
||||||
|
rtx extend, mem, offset;
|
||||||
|
bool zero;
|
||||||
|
int factor;
|
||||||
|
|
||||||
|
switch (INSN_CODE (insn))
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return current_length;
|
||||||
|
|
||||||
|
case CODE_FOR_plussi3_zero_extendhi:
|
||||||
|
case CODE_FOR_andsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_iorsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_xorsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_divsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_udivsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_minussi3_zero_extendhi:
|
||||||
|
case CODE_FOR_smaxsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_sminsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_multsi3_zero_extendhi:
|
||||||
|
case CODE_FOR_comparesi3_zero_extendqi:
|
||||||
|
zero = true;
|
||||||
|
factor = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CODE_FOR_plussi3_sign_extendhi:
|
||||||
|
case CODE_FOR_andsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_iorsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_xorsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_divsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_udivsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_minussi3_sign_extendhi:
|
||||||
|
case CODE_FOR_smaxsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_sminsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_multsi3_sign_extendhi:
|
||||||
|
case CODE_FOR_comparesi3_zero_extendhi:
|
||||||
|
zero = false;
|
||||||
|
factor = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CODE_FOR_plussi3_zero_extendqi:
|
||||||
|
case CODE_FOR_andsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_iorsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_xorsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_divsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_udivsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_minussi3_zero_extendqi:
|
||||||
|
case CODE_FOR_smaxsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_sminsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_multsi3_zero_extendqi:
|
||||||
|
case CODE_FOR_comparesi3_sign_extendqi:
|
||||||
|
zero = true;
|
||||||
|
factor = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CODE_FOR_plussi3_sign_extendqi:
|
||||||
|
case CODE_FOR_andsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_iorsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_xorsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_divsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_udivsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_minussi3_sign_extendqi:
|
||||||
|
case CODE_FOR_smaxsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_sminsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_multsi3_sign_extendqi:
|
||||||
|
case CODE_FOR_comparesi3_sign_extendhi:
|
||||||
|
zero = false;
|
||||||
|
factor = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are expecting: (SET (REG) (<OP> (REG) (<EXTEND> (MEM)))). */
|
||||||
|
extend = single_set (insn);
|
||||||
|
gcc_assert (extend != NULL_RTX);
|
||||||
|
|
||||||
|
extend = SET_SRC (extend);
|
||||||
|
if (GET_CODE (XEXP (extend, 0)) == ZERO_EXTEND
|
||||||
|
|| GET_CODE (XEXP (extend, 0)) == SIGN_EXTEND)
|
||||||
|
extend = XEXP (extend, 0);
|
||||||
|
else
|
||||||
|
extend = XEXP (extend, 1);
|
||||||
|
|
||||||
|
gcc_assert ((zero && (GET_CODE (extend) == ZERO_EXTEND))
|
||||||
|
|| (! zero && (GET_CODE (extend) == SIGN_EXTEND)));
|
||||||
|
|
||||||
|
mem = XEXP (extend, 0);
|
||||||
|
gcc_checking_assert (MEM_P (mem));
|
||||||
|
if (REG_P (XEXP (mem, 0)))
|
||||||
|
return (zero && factor == 1) ? 2 : 3;
|
||||||
|
|
||||||
|
/* We are expecting: (MEM (PLUS (REG) (CONST_INT))). */
|
||||||
|
gcc_checking_assert (GET_CODE (XEXP (mem, 0)) == PLUS);
|
||||||
|
gcc_checking_assert (REG_P (XEXP (XEXP (mem, 0), 0)));
|
||||||
|
|
||||||
|
offset = XEXP (XEXP (mem, 0), 1);
|
||||||
|
gcc_checking_assert (GET_CODE (offset) == CONST_INT);
|
||||||
|
|
||||||
|
if (IN_RANGE (INTVAL (offset), 0, 255 * factor))
|
||||||
|
return (zero && factor == 1) ? 3 : 4;
|
||||||
|
|
||||||
|
return (zero && factor == 1) ? 4 : 5;
|
||||||
|
}
|
||||||
|
|
||||||
#undef TARGET_ASM_JUMP_ALIGN_MAX_SKIP
|
#undef TARGET_ASM_JUMP_ALIGN_MAX_SKIP
|
||||||
#define TARGET_ASM_JUMP_ALIGN_MAX_SKIP rx_max_skip_for_label
|
#define TARGET_ASM_JUMP_ALIGN_MAX_SKIP rx_max_skip_for_label
|
||||||
|
@ -630,3 +630,10 @@ typedef unsigned int CUMULATIVE_ARGS;
|
|||||||
#define REGISTER_MOVE_COST(MODE,FROM,TO) 2
|
#define REGISTER_MOVE_COST(MODE,FROM,TO) 2
|
||||||
|
|
||||||
#define SELECT_CC_MODE(OP,X,Y) rx_select_cc_mode(OP, X, Y)
|
#define SELECT_CC_MODE(OP,X,Y) rx_select_cc_mode(OP, X, Y)
|
||||||
|
|
||||||
|
#define ADJUST_INSN_LENGTH(INSN,LENGTH) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
(LENGTH) = rx_adjust_insn_length ((INSN), (LENGTH)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
@ -1545,6 +1545,139 @@
|
|||||||
(set_attr "length" "3,4,5,6,7,6")]
|
(set_attr "length" "3,4,5,6,7,6")]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
;; A set of peepholes to catch extending loads followed by arithmetic operations.
|
||||||
|
;; We use iterators where possible to reduce the amount of typing and hence the
|
||||||
|
;; possibilities for typos.
|
||||||
|
|
||||||
|
(define_code_iterator extend_types [(zero_extend "") (sign_extend "")])
|
||||||
|
(define_code_attr letter [(zero_extend "R") (sign_extend "Q")])
|
||||||
|
|
||||||
|
(define_code_iterator memex_commutative [(plus "") (and "") (ior "") (xor "")])
|
||||||
|
(define_code_iterator memex_noncomm [(div "") (udiv "") (minus "")])
|
||||||
|
(define_code_iterator memex_nocc [(smax "") (smin "") (mult "")])
|
||||||
|
|
||||||
|
(define_code_attr op [(plus "add") (and "and") (div "div") (udiv "divu") (smax "max") (smin "min") (mult "mul") (ior "or") (minus "sub") (xor "xor")])
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (match_operand:SI 0 "register_operand")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
|
||||||
|
(parallel [(set (match_operand:SI 2 "register_operand")
|
||||||
|
(memex_commutative:SI (match_dup 0)
|
||||||
|
(match_dup 2)))
|
||||||
|
(clobber (reg:CC CC_REG))])]
|
||||||
|
"peep2_regno_dead_p (2, REGNO (operands[0]))"
|
||||||
|
[(parallel [(set:SI (match_dup 2)
|
||||||
|
(memex_commutative:SI (match_dup 2)
|
||||||
|
(extend_types:SI (match_dup 1))))
|
||||||
|
(clobber (reg:CC CC_REG))])]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (match_operand:SI 0 "register_operand")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
|
||||||
|
(parallel [(set (match_operand:SI 2 "register_operand")
|
||||||
|
(memex_commutative:SI (match_dup 2)
|
||||||
|
(match_dup 0)))
|
||||||
|
(clobber (reg:CC CC_REG))])]
|
||||||
|
"peep2_regno_dead_p (2, REGNO (operands[0]))"
|
||||||
|
[(parallel [(set:SI (match_dup 2)
|
||||||
|
(memex_commutative:SI (match_dup 2)
|
||||||
|
(extend_types:SI (match_dup 1))))
|
||||||
|
(clobber (reg:CC CC_REG))])]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (match_operand:SI 0 "register_operand")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
|
||||||
|
(parallel [(set (match_operand:SI 2 "register_operand")
|
||||||
|
(memex_noncomm:SI (match_dup 2)
|
||||||
|
(match_dup 0)))
|
||||||
|
(clobber (reg:CC CC_REG))])]
|
||||||
|
"peep2_regno_dead_p (2, REGNO (operands[0]))"
|
||||||
|
[(parallel [(set:SI (match_dup 2)
|
||||||
|
(memex_noncomm:SI (match_dup 2)
|
||||||
|
(extend_types:SI (match_dup 1))))
|
||||||
|
(clobber (reg:CC CC_REG))])]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (match_operand:SI 0 "register_operand")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
|
||||||
|
(set (match_operand:SI 2 "register_operand")
|
||||||
|
(memex_nocc:SI (match_dup 0)
|
||||||
|
(match_dup 2)))]
|
||||||
|
"peep2_regno_dead_p (2, REGNO (operands[0]))"
|
||||||
|
[(set:SI (match_dup 2)
|
||||||
|
(memex_nocc:SI (match_dup 2)
|
||||||
|
(extend_types:SI (match_dup 1))))]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (match_operand:SI 0 "register_operand")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
|
||||||
|
(set (match_operand:SI 2 "register_operand")
|
||||||
|
(memex_nocc:SI (match_dup 2)
|
||||||
|
(match_dup 0)))]
|
||||||
|
"peep2_regno_dead_p (2, REGNO (operands[0]))"
|
||||||
|
[(set:SI (match_dup 2)
|
||||||
|
(memex_nocc:SI (match_dup 2)
|
||||||
|
(extend_types:SI (match_dup 1))))]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "<memex_commutative:code>si3_<extend_types:code><small_int_modes:mode>"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(memex_commutative:SI (match_operand:SI 1 "register_operand" "%0")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))
|
||||||
|
(clobber (reg:CC CC_REG))]
|
||||||
|
""
|
||||||
|
"<memex_commutative:op>\t%<extend_types:letter>2, %0"
|
||||||
|
[(set_attr "timings" "33")
|
||||||
|
(set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "<memex_noncomm:code>si3_<extend_types:code><small_int_modes:mode>"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(memex_noncomm:SI (match_operand:SI 1 "register_operand" "0")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))
|
||||||
|
(clobber (reg:CC CC_REG))]
|
||||||
|
""
|
||||||
|
"<memex_noncomm:op>\t%<extend_types:letter>2, %0"
|
||||||
|
[(set_attr "timings" "33")
|
||||||
|
(set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "<memex_nocc:code>si3_<extend_types:code><small_int_modes:mode>"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(memex_nocc:SI (match_operand:SI 1 "register_operand" "%0")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))]
|
||||||
|
""
|
||||||
|
"<memex_nocc:op>\t%<extend_types:letter>2, %0"
|
||||||
|
[(set_attr "timings" "33")
|
||||||
|
(set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_peephole2
|
||||||
|
[(set (match_operand:SI 0 "register_operand")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
|
||||||
|
(set (reg:CC CC_REG)
|
||||||
|
(compare:CC (match_operand:SI 2 "register_operand")
|
||||||
|
(match_dup 0)))]
|
||||||
|
"peep2_regno_dead_p (2, REGNO (operands[0]))"
|
||||||
|
[(set (reg:CC CC_REG)
|
||||||
|
(compare:CC (match_dup 2)
|
||||||
|
(extend_types:SI (match_dup 1))))]
|
||||||
|
)
|
||||||
|
|
||||||
|
(define_insn "comparesi3_<extend_types:code><small_int_modes:mode>"
|
||||||
|
[(set (reg:CC CC_REG)
|
||||||
|
(compare:CC (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand" "Q"))))]
|
||||||
|
""
|
||||||
|
"cmp\t%<extend_types:letter>1, %0"
|
||||||
|
[(set_attr "timings" "33")
|
||||||
|
(set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
|
||||||
|
)
|
||||||
|
|
||||||
;; Floating Point Instructions
|
;; Floating Point Instructions
|
||||||
|
|
||||||
(define_insn "addsf3"
|
(define_insn "addsf3"
|
||||||
@ -1897,14 +2030,6 @@
|
|||||||
rtx addr2 = gen_rtx_REG (SImode, 2);
|
rtx addr2 = gen_rtx_REG (SImode, 2);
|
||||||
rtx len = gen_rtx_REG (SImode, 3);
|
rtx len = gen_rtx_REG (SImode, 3);
|
||||||
|
|
||||||
/* Do not use when the source or destination are volatile - the SMOVF
|
|
||||||
instruction will read and write in word sized blocks, which may be
|
|
||||||
outside of the valid address range. */
|
|
||||||
if (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
|
|
||||||
FAIL;
|
|
||||||
if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
|
|
||||||
FAIL;
|
|
||||||
|
|
||||||
if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
|
if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
|
||||||
|| REGNO (operands[0]) == 3))
|
|| REGNO (operands[0]) == 3))
|
||||||
FAIL;
|
FAIL;
|
||||||
|
Loading…
Reference in New Issue
Block a user