pa-protos.h: Add prototypes for magic_milli and shadd_constant_p.
* config/pa/pa-protos.h: Add prototypes for magic_milli and shadd_constant_p. * config/pa/pa.c (reg_or_0_operand, call_operand_address, symbolic_operand, symbolic_memory_operand, reg_or_0_or_nonsymb_mem_operand, reg_before_reload_operand, indexed_memory_operand, move_dest_operand, move_src_operand, prefetch_cc_operand, prefetch_nocc_operand, reg_or_cint_move_operand, pic_label_operand, fp_reg_operand, arith_operand, arith11_operand, pre_cint_operand, post_cint_operan, arith_double_operand, ireg_or_int5_operand, ireg_operand, int5_operand, uint5_operand, int11_operand, uint32_operand, arith5_operand, and_operand, ior_operand, lhs_lshift_operand, lhs_lshift_cint_operand, arith32_operand, pc_or_label_operand, div_operand, plus_xor_ior_operator, shadd_operand, movb_comparison_operator, cmpib_comparison_operator): Move to predicates.md. (magic_milli, shadd_constant_p): Make it extern. * config/pa/pa.h (PREDICATE_CODES): Remove. * config/pa/pa.md: Include predicates.md. * config/pa/predicates.md: New. From-SVN: r96692
This commit is contained in:
parent
22a14e0dcc
commit
c9a8819075
|
@ -1,4 +1,4 @@
|
|||
2005-03-18 2005-03-18 Kazu Hirata <kazu@cs.umass.edu>
|
||||
2005-03-18 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* config/m32r/m32r-protos.h: Remove the prototypes for
|
||||
call_address_operand, symbolic_operand, seth_add3_operand,
|
||||
|
@ -26,6 +26,27 @@
|
|||
* config/m32r/m32r.md: Include predicates.md.
|
||||
* config/m32r/predicates.md: New.
|
||||
|
||||
* config/pa/pa-protos.h: Add prototypes for magic_milli and
|
||||
shadd_constant_p.
|
||||
* config/pa/pa.c (reg_or_0_operand, call_operand_address,
|
||||
symbolic_operand, symbolic_memory_operand,
|
||||
reg_or_0_or_nonsymb_mem_operand, reg_before_reload_operand,
|
||||
indexed_memory_operand, move_dest_operand, move_src_operand,
|
||||
prefetch_cc_operand, prefetch_nocc_operand,
|
||||
reg_or_cint_move_operand, pic_label_operand, fp_reg_operand,
|
||||
arith_operand, arith11_operand, pre_cint_operand,
|
||||
post_cint_operan, arith_double_operand, ireg_or_int5_operand,
|
||||
ireg_operand, int5_operand, uint5_operand, int11_operand,
|
||||
uint32_operand, arith5_operand, and_operand, ior_operand,
|
||||
lhs_lshift_operand, lhs_lshift_cint_operand, arith32_operand,
|
||||
pc_or_label_operand, div_operand, plus_xor_ior_operator,
|
||||
shadd_operand, movb_comparison_operator,
|
||||
cmpib_comparison_operator): Move to predicates.md.
|
||||
(magic_milli, shadd_constant_p): Make it extern.
|
||||
* config/pa/pa.h (PREDICATE_CODES): Remove.
|
||||
* config/pa/pa.md: Include predicates.md.
|
||||
* config/pa/predicates.md: New.
|
||||
|
||||
2005-03-18 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* hooks.c, hooks.h, intl.c, opts.h, prefix.c, tree-gimple.c,
|
||||
|
|
|
@ -176,6 +176,9 @@ extern void pa_asm_output_aligned_local (FILE *, const char *,
|
|||
unsigned int);
|
||||
extern void pa_hpux_asm_output_external (FILE *, tree, const char *);
|
||||
|
||||
extern const int magic_milli[];
|
||||
extern int shadd_constant_p (int);
|
||||
|
||||
/* Functions in varasm.c used by pa.c. */
|
||||
extern void som_readonly_data_section (void);
|
||||
extern void som_one_only_readonly_data_section (void);
|
||||
|
|
|
@ -91,7 +91,6 @@ static void pa_reorg (void);
|
|||
static void pa_combine_instructions (void);
|
||||
static int pa_can_combine_p (rtx, rtx, rtx, int, rtx, rtx, rtx);
|
||||
static int forward_branch_p (rtx);
|
||||
static int shadd_constant_p (int);
|
||||
static void compute_zdepwi_operands (unsigned HOST_WIDE_INT, unsigned *);
|
||||
static int compute_movmem_length (rtx);
|
||||
static int compute_clrmem_length (rtx);
|
||||
|
@ -550,26 +549,6 @@ copy_reg_pointer (rtx to, rtx from)
|
|||
mark_reg_pointer (to, REGNO_POINTER_ALIGN (REGNO (from)));
|
||||
}
|
||||
|
||||
/* Return nonzero only if OP is a register of mode MODE,
|
||||
or CONST0_RTX. */
|
||||
int
|
||||
reg_or_0_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return (op == CONST0_RTX (mode) || register_operand (op, mode));
|
||||
}
|
||||
|
||||
/* Return nonzero if OP is suitable for use in a call to a named
|
||||
function.
|
||||
|
||||
For 2.5 try to eliminate either call_operand_address or
|
||||
function_label_operand, they perform very similar functions. */
|
||||
int
|
||||
call_operand_address (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_MODE (op) == word_mode
|
||||
&& CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);
|
||||
}
|
||||
|
||||
/* Return 1 if X contains a symbolic expression. We know these
|
||||
expressions will have one of a few well defined forms, so
|
||||
we need only check those forms. */
|
||||
|
@ -584,95 +563,6 @@ symbolic_expression_p (rtx x)
|
|||
return (symbolic_operand (x, VOIDmode));
|
||||
}
|
||||
|
||||
int
|
||||
symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case SYMBOL_REF:
|
||||
case LABEL_REF:
|
||||
return 1;
|
||||
case CONST:
|
||||
op = XEXP (op, 0);
|
||||
return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|
||||
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
|
||||
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return truth value of statement that OP is a symbolic memory
|
||||
operand of mode MODE. */
|
||||
|
||||
int
|
||||
symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
op = XEXP (op, 0);
|
||||
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
|
||||
|| GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
|
||||
}
|
||||
|
||||
/* Return 1 if the operand is either a register, zero, or a memory operand
|
||||
that is not symbolic. */
|
||||
|
||||
int
|
||||
reg_or_0_or_nonsymb_mem_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (op == CONST0_RTX (mode))
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating move insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (XEXP (op, 0)) == PLUS
|
||||
&& REG_P (XEXP (XEXP (op, 0), 0))
|
||||
&& REG_P (XEXP (XEXP (op, 0), 1)))
|
||||
return 0;
|
||||
|
||||
return (!symbolic_memory_operand (op, mode)
|
||||
&& memory_address_p (mode, XEXP (op, 0)));
|
||||
}
|
||||
|
||||
/* Return 1 if the operand is a register operand or a non-symbolic memory
|
||||
operand after reload. This predicate is used for branch patterns that
|
||||
internally handle register reloading. We need to accept non-symbolic
|
||||
memory operands after reload to ensure that the pattern is still valid
|
||||
if reload didn't find a hard register for the operand. */
|
||||
|
||||
int
|
||||
reg_before_reload_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
/* Don't accept a SUBREG since it will need a reload. */
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
return 0;
|
||||
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (reload_completed
|
||||
&& memory_operand (op, mode)
|
||||
&& !symbolic_memory_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Accept any constant that can be moved in one instruction into a
|
||||
general register. */
|
||||
int
|
||||
|
@ -683,198 +573,7 @@ cint_ok_for_move (HOST_WIDE_INT intval)
|
|||
|| CONST_OK_FOR_LETTER_P (intval, 'N')
|
||||
|| CONST_OK_FOR_LETTER_P (intval, 'K'));
|
||||
}
|
||||
|
||||
/* Return 1 iff OP is an indexed memory operand. */
|
||||
int
|
||||
indexed_memory_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (GET_MODE (op) != mode)
|
||||
return 0;
|
||||
|
||||
/* Before reload, a (SUBREG (MEM...)) forces reloading into a register. */
|
||||
if (reload_completed && GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM || symbolic_memory_operand (op, mode))
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
return (memory_address_p (mode, op) && IS_INDEX_ADDR_P (op));
|
||||
}
|
||||
|
||||
/* Accept anything that can be used as a destination operand for a
|
||||
move instruction. We don't accept indexed memory operands since
|
||||
they are supported only for floating point stores. */
|
||||
int
|
||||
move_dest_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (GET_MODE (op) != mode)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM || symbolic_memory_operand (op, mode))
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
return (memory_address_p (mode, op)
|
||||
&& !IS_INDEX_ADDR_P (op)
|
||||
&& !IS_LO_SUM_DLT_ADDR_P (op));
|
||||
}
|
||||
|
||||
/* Accept anything that can be used as a source operand for a move
|
||||
instruction. */
|
||||
int
|
||||
move_src_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (op) == CONST_INT)
|
||||
return cint_ok_for_move (INTVAL (op));
|
||||
|
||||
if (GET_MODE (op) != mode)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating move insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (XEXP (op, 0)) == PLUS
|
||||
&& REG_P (XEXP (XEXP (op, 0), 0))
|
||||
&& REG_P (XEXP (XEXP (op, 0), 1)))
|
||||
return 0;
|
||||
|
||||
return memory_address_p (mode, XEXP (op, 0));
|
||||
}
|
||||
|
||||
/* Accept anything that can be used as the source operand for a prefetch
|
||||
instruction with a cache-control completer. */
|
||||
int
|
||||
prefetch_cc_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
/* We must reject virtual registers as we don't allow REG+D. */
|
||||
if (op == virtual_incoming_args_rtx
|
||||
|| op == virtual_stack_vars_rtx
|
||||
|| op == virtual_stack_dynamic_rtx
|
||||
|| op == virtual_outgoing_args_rtx
|
||||
|| op == virtual_cfa_rtx)
|
||||
return 0;
|
||||
|
||||
if (!REG_P (op) && !IS_INDEX_ADDR_P (op))
|
||||
return 0;
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating prefetch insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (op) == PLUS
|
||||
&& REG_P (XEXP (op, 0)))
|
||||
return 0;
|
||||
|
||||
return memory_address_p (mode, op);
|
||||
}
|
||||
|
||||
/* Accept anything that can be used as the source operand for a prefetch
|
||||
instruction with no cache-control completer. */
|
||||
int
|
||||
prefetch_nocc_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating prefetch insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (op) == PLUS
|
||||
&& REG_P (XEXP (op, 0))
|
||||
&& REG_P (XEXP (op, 1)))
|
||||
return 0;
|
||||
|
||||
return memory_address_p (mode, op);
|
||||
}
|
||||
|
||||
/* Accept REG and any CONST_INT that can be moved in one instruction into a
|
||||
general register. */
|
||||
int
|
||||
reg_or_cint_move_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
return (GET_CODE (op) == CONST_INT && cint_ok_for_move (INTVAL (op)));
|
||||
}
|
||||
|
||||
int
|
||||
pic_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (!flag_pic)
|
||||
return 0;
|
||||
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case LABEL_REF:
|
||||
return 1;
|
||||
case CONST:
|
||||
op = XEXP (op, 0);
|
||||
return (GET_CODE (XEXP (op, 0)) == LABEL_REF
|
||||
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
fp_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return reg_renumber && FP_REG_P (op);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return truth value of whether OP can be used as an operand in a
|
||||
three operand arithmetic insn that accepts registers of mode MODE
|
||||
or 14-bit signed integers. */
|
||||
int
|
||||
arith_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));
|
||||
}
|
||||
|
||||
/* Return truth value of whether OP can be used as an operand in a
|
||||
three operand arithmetic insn that accepts registers of mode MODE
|
||||
or 11-bit signed integers. */
|
||||
int
|
||||
arith11_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));
|
||||
}
|
||||
|
||||
/* Return truth value of whether OP can be used as an operand in a
|
||||
adddi3 insn. */
|
||||
int
|
||||
|
@ -885,94 +584,6 @@ adddi3_operand (rtx op, enum machine_mode mode)
|
|||
&& (TARGET_64BIT ? INT_14_BITS (op) : INT_11_BITS (op))));
|
||||
}
|
||||
|
||||
/* A constant integer suitable for use in a PRE_MODIFY memory
|
||||
reference. */
|
||||
int
|
||||
pre_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
|
||||
}
|
||||
|
||||
/* A constant integer suitable for use in a POST_MODIFY memory
|
||||
reference. */
|
||||
int
|
||||
post_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);
|
||||
}
|
||||
|
||||
int
|
||||
arith_double_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_DOUBLE
|
||||
&& GET_MODE (op) == mode
|
||||
&& VAL_14_BITS_P (CONST_DOUBLE_LOW (op))
|
||||
&& ((CONST_DOUBLE_HIGH (op) >= 0)
|
||||
== ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
|
||||
}
|
||||
|
||||
/* Return truth value of whether OP is an integer which fits the
|
||||
range constraining immediate operands in three-address insns, or
|
||||
is an integer register. */
|
||||
|
||||
int
|
||||
ireg_or_int5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return ((GET_CODE (op) == CONST_INT && INT_5_BITS (op))
|
||||
|| (GET_CODE (op) == REG && REGNO (op) > 0 && REGNO (op) < 32));
|
||||
}
|
||||
|
||||
/* Return nonzero if OP is an integer register, else return zero. */
|
||||
int
|
||||
ireg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == REG && REGNO (op) > 0 && REGNO (op) < 32);
|
||||
}
|
||||
|
||||
/* Return truth value of whether OP is an integer which fits the
|
||||
range constraining immediate operands in three-address insns. */
|
||||
|
||||
int
|
||||
int5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));
|
||||
}
|
||||
|
||||
int
|
||||
uint5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));
|
||||
}
|
||||
|
||||
int
|
||||
int11_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));
|
||||
}
|
||||
|
||||
int
|
||||
uint32_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
#if HOST_BITS_PER_WIDE_INT > 32
|
||||
/* All allowed constants will fit a CONST_INT. */
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& (INTVAL (op) >= 0 && INTVAL (op) < (HOST_WIDE_INT) 1 << 32));
|
||||
#else
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
|| (GET_CODE (op) == CONST_DOUBLE
|
||||
&& CONST_DOUBLE_HIGH (op) == 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
arith5_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return register_operand (op, mode) || int5_operand (op, mode);
|
||||
}
|
||||
|
||||
/* True iff zdepi can be used to generate this CONST_INT.
|
||||
zdepi first sign extends a 5 bit signed number to a given field
|
||||
length, then places this field anywhere in a zero. */
|
||||
|
@ -1002,14 +613,6 @@ and_mask_p (unsigned HOST_WIDE_INT mask)
|
|||
return (mask & (mask - 1)) == 0;
|
||||
}
|
||||
|
||||
/* True iff depi or extru can be used to compute (reg & OP). */
|
||||
int
|
||||
and_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
|
||||
}
|
||||
|
||||
/* True iff depi can be used to compute (reg | MASK). */
|
||||
int
|
||||
ior_mask_p (unsigned HOST_WIDE_INT mask)
|
||||
|
@ -1017,44 +620,6 @@ ior_mask_p (unsigned HOST_WIDE_INT mask)
|
|||
mask += mask & -mask;
|
||||
return (mask & (mask - 1)) == 0;
|
||||
}
|
||||
|
||||
/* True iff depi can be used to compute (reg | OP). */
|
||||
int
|
||||
ior_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));
|
||||
}
|
||||
|
||||
int
|
||||
lhs_lshift_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return register_operand (op, mode) || lhs_lshift_cint_operand (op, mode);
|
||||
}
|
||||
|
||||
/* True iff OP is a CONST_INT of the forms 0...0xxxx or 0...01...1xxxx.
|
||||
Such values can be the left hand side x in (x << r), using the zvdepi
|
||||
instruction. */
|
||||
int
|
||||
lhs_lshift_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
unsigned HOST_WIDE_INT x;
|
||||
if (GET_CODE (op) != CONST_INT)
|
||||
return 0;
|
||||
x = INTVAL (op) >> 4;
|
||||
return (x & (x + 1)) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
arith32_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
|
||||
}
|
||||
|
||||
int
|
||||
pc_or_label_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
|
||||
}
|
||||
|
||||
/* Legitimize PIC addresses. If the address is already
|
||||
position-independent, we return ORIG. Newly generated
|
||||
|
@ -5741,8 +5306,7 @@ output_mul_insn (int unsignedp ATTRIBUTE_UNUSED, rtx insn)
|
|||
/* Emit the rtl for doing a division by a constant. */
|
||||
|
||||
/* Do magic division millicodes exist for this value? */
|
||||
static const int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
|
||||
1, 1};
|
||||
const int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1};
|
||||
|
||||
/* We'll use an array to keep track of the magic millicodes and
|
||||
whether or not we've used them already. [n][0] is signed, [n][1] is
|
||||
|
@ -5750,15 +5314,6 @@ static const int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
|
|||
|
||||
static int div_milli[16][2];
|
||||
|
||||
int
|
||||
div_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return (mode == SImode
|
||||
&& ((GET_CODE (op) == REG && REGNO (op) == 25)
|
||||
|| (GET_CODE (op) == CONST_INT && INTVAL (op) > 0
|
||||
&& INTVAL (op) < 16 && magic_milli[INTVAL (op)])));
|
||||
}
|
||||
|
||||
int
|
||||
emit_hpdiv_const (rtx *operands, int unsignedp)
|
||||
{
|
||||
|
@ -8440,16 +7995,9 @@ fmpysuboperands (rtx *operands)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
plus_xor_ior_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == PLUS || GET_CODE (op) == XOR
|
||||
|| GET_CODE (op) == IOR);
|
||||
}
|
||||
|
||||
/* Return 1 if the given constant is 2, 4, or 8. These are the valid
|
||||
constants for shadd instructions. */
|
||||
static int
|
||||
int
|
||||
shadd_constant_p (int val)
|
||||
{
|
||||
if (val == 2 || val == 4 || val == 8)
|
||||
|
@ -8458,14 +8006,6 @@ shadd_constant_p (int val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Return 1 if OP is a CONST_INT with the value 2, 4, or 8. These are
|
||||
the valid constant for shadd instructions. */
|
||||
int
|
||||
shadd_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
|
||||
}
|
||||
|
||||
/* Return 1 if OP is valid as a base or index register in a
|
||||
REG+REG address. */
|
||||
|
||||
|
@ -8528,14 +8068,6 @@ eq_neq_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
|||
return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
|
||||
}
|
||||
|
||||
/* Return 1 if OP is an operator suitable for use in a movb instruction. */
|
||||
int
|
||||
movb_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (op) == EQ || GET_CODE (op) == NE
|
||||
|| GET_CODE (op) == LT || GET_CODE (op) == GE);
|
||||
}
|
||||
|
||||
/* Return 1 if INSN is in the delay slot of a call instruction. */
|
||||
int
|
||||
jump_in_call_delay (rtx insn)
|
||||
|
@ -9367,23 +8899,6 @@ pa_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
}
|
||||
|
||||
|
||||
/* Return 1 if this is a comparison operator. This allows the use of
|
||||
MATCH_OPERATOR to recognize all the branch insns. */
|
||||
|
||||
int
|
||||
cmpib_comparison_operator (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return ((mode == VOIDmode || GET_MODE (op) == mode)
|
||||
&& (GET_CODE (op) == EQ
|
||||
|| GET_CODE (op) == NE
|
||||
|| GET_CODE (op) == GT
|
||||
|| GET_CODE (op) == GTU
|
||||
|| GET_CODE (op) == GE
|
||||
|| GET_CODE (op) == LT
|
||||
|| GET_CODE (op) == LE
|
||||
|| GET_CODE (op) == LEU));
|
||||
}
|
||||
|
||||
/* Return a string to output before text in the current function.
|
||||
|
||||
This function is only used with SOM. Because we don't support
|
||||
|
|
|
@ -2128,49 +2128,6 @@ forget_section (void) \
|
|||
/* The number of Pmode words for the setjmp buffer. */
|
||||
#define JMP_BUF_SIZE 50
|
||||
|
||||
#define PREDICATE_CODES \
|
||||
{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
|
||||
{"call_operand_address", {LABEL_REF, SYMBOL_REF, CONST_INT, \
|
||||
CONST_DOUBLE, CONST, HIGH}}, \
|
||||
{"indexed_memory_operand", {SUBREG, MEM}}, \
|
||||
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
|
||||
{"symbolic_memory_operand", {SUBREG, MEM}}, \
|
||||
{"reg_before_reload_operand", {REG, MEM}}, \
|
||||
{"reg_or_0_or_nonsymb_mem_operand", {SUBREG, REG, MEM, CONST_INT, \
|
||||
CONST_DOUBLE}}, \
|
||||
{"move_dest_operand", {SUBREG, REG, MEM}}, \
|
||||
{"move_src_operand", {SUBREG, REG, CONST_INT, MEM}}, \
|
||||
{"prefetch_cc_operand", {MEM}}, \
|
||||
{"prefetch_nocc_operand", {MEM}}, \
|
||||
{"reg_or_cint_move_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"pic_label_operand", {LABEL_REF, CONST}}, \
|
||||
{"fp_reg_operand", {REG}}, \
|
||||
{"arith_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"arith11_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"pre_cint_operand", {CONST_INT}}, \
|
||||
{"post_cint_operand", {CONST_INT}}, \
|
||||
{"arith_double_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"ireg_or_int5_operand", {CONST_INT, REG}}, \
|
||||
{"int5_operand", {CONST_INT}}, \
|
||||
{"uint5_operand", {CONST_INT}}, \
|
||||
{"int11_operand", {CONST_INT}}, \
|
||||
{"uint32_operand", {CONST_INT, \
|
||||
HOST_BITS_PER_WIDE_INT > 32 ? 0 : CONST_DOUBLE}}, \
|
||||
{"arith5_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"and_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"ior_operand", {CONST_INT}}, \
|
||||
{"lhs_lshift_cint_operand", {CONST_INT}}, \
|
||||
{"lhs_lshift_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"arith32_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"pc_or_label_operand", {PC, LABEL_REF}}, \
|
||||
{"plus_xor_ior_operator", {PLUS, XOR, IOR}}, \
|
||||
{"shadd_operand", {CONST_INT}}, \
|
||||
{"div_operand", {REG, CONST_INT}}, \
|
||||
{"ireg_operand", {REG}}, \
|
||||
{"cmpib_comparison_operator", {EQ, NE, LT, LE, LEU, \
|
||||
GT, GTU, GE}}, \
|
||||
{"movb_comparison_operator", {EQ, NE, LT, GE}},
|
||||
|
||||
/* We need a libcall to canonicalize function pointers on TARGET_ELF32. */
|
||||
#define CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL \
|
||||
"__canonicalize_funcptr_for_compare"
|
||||
|
|
|
@ -561,7 +561,7 @@
|
|||
(eq_attr "cpu" "8000"))
|
||||
"inm_8000,fdivsqrt_8000*6,rnm_8000")
|
||||
|
||||
|
||||
(include "predicates.md")
|
||||
|
||||
;; Compare instructions.
|
||||
;; This controls RTL generation and register allocation.
|
||||
|
|
|
@ -0,0 +1,550 @@
|
|||
;; Predicate definitions for HP PA-RISC.
|
||||
;; Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; 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 2, 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 COPYING. If not, write to
|
||||
;; the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
;; Return nonzero only if OP is a register of mode MODE, or
|
||||
;; CONST0_RTX.
|
||||
|
||||
(define_predicate "reg_or_0_operand"
|
||||
(match_code "subreg,reg,const_int,const_double")
|
||||
{
|
||||
return (op == CONST0_RTX (mode) || register_operand (op, mode));
|
||||
})
|
||||
|
||||
;; Return nonzero if OP is suitable for use in a call to a named
|
||||
;; function.
|
||||
;;
|
||||
;; For 2.5 try to eliminate either call_operand_address or
|
||||
;; function_label_operand, they perform very similar functions.
|
||||
|
||||
(define_predicate "call_operand_address"
|
||||
(match_code "label_ref,symbol_ref,const_int,const_double,const,high")
|
||||
{
|
||||
return (GET_MODE (op) == word_mode
|
||||
&& CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);
|
||||
})
|
||||
|
||||
;; Return 1 iff OP is an indexed memory operand.
|
||||
|
||||
(define_predicate "indexed_memory_operand"
|
||||
(match_code "subreg,mem")
|
||||
{
|
||||
if (GET_MODE (op) != mode)
|
||||
return 0;
|
||||
|
||||
/* Before reload, a (SUBREG (MEM...)) forces reloading into a register. */
|
||||
if (reload_completed && GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM || symbolic_memory_operand (op, mode))
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
return (memory_address_p (mode, op) && IS_INDEX_ADDR_P (op));
|
||||
})
|
||||
|
||||
;; TODO: Add a comment.
|
||||
|
||||
(define_predicate "symbolic_operand"
|
||||
(match_code "symbol_ref,label_ref,const")
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case SYMBOL_REF:
|
||||
case LABEL_REF:
|
||||
return 1;
|
||||
case CONST:
|
||||
op = XEXP (op, 0);
|
||||
return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|
||||
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
|
||||
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
|
||||
;; Return truth value of statement that OP is a symbolic memory
|
||||
;; operand of mode MODE.
|
||||
|
||||
(define_predicate "symbolic_memory_operand"
|
||||
(match_code "subreg,mem")
|
||||
{
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
op = XEXP (op, 0);
|
||||
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
|
||||
|| GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
|
||||
})
|
||||
|
||||
;; Return 1 if the operand is a register operand or a non-symbolic
|
||||
;; memory operand after reload. This predicate is used for branch
|
||||
;; patterns that internally handle register reloading. We need to
|
||||
;; accept non-symbolic memory operands after reload to ensure that the
|
||||
;; pattern is still valid if reload didn't find a hard register for
|
||||
;; the operand.
|
||||
|
||||
(define_predicate "reg_before_reload_operand"
|
||||
(match_code "reg,mem")
|
||||
{
|
||||
/* Don't accept a SUBREG since it will need a reload. */
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
return 0;
|
||||
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (reload_completed
|
||||
&& memory_operand (op, mode)
|
||||
&& !symbolic_memory_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
})
|
||||
|
||||
;; Return 1 if the operand is either a register, zero, or a memory
|
||||
;; operand that is not symbolic.
|
||||
|
||||
(define_predicate "reg_or_0_or_nonsymb_mem_operand"
|
||||
(match_code "subreg,reg,mem,const_int,const_double")
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (op == CONST0_RTX (mode))
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating move insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (XEXP (op, 0)) == PLUS
|
||||
&& REG_P (XEXP (XEXP (op, 0), 0))
|
||||
&& REG_P (XEXP (XEXP (op, 0), 1)))
|
||||
return 0;
|
||||
|
||||
return (!symbolic_memory_operand (op, mode)
|
||||
&& memory_address_p (mode, XEXP (op, 0)));
|
||||
})
|
||||
|
||||
;; Accept anything that can be used as a destination operand for a
|
||||
;; move instruction. We don't accept indexed memory operands since
|
||||
;; they are supported only for floating point stores.
|
||||
|
||||
(define_predicate "move_dest_operand"
|
||||
(match_code "subreg,reg,mem")
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (GET_MODE (op) != mode)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM || symbolic_memory_operand (op, mode))
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
return (memory_address_p (mode, op)
|
||||
&& !IS_INDEX_ADDR_P (op)
|
||||
&& !IS_LO_SUM_DLT_ADDR_P (op));
|
||||
})
|
||||
|
||||
;; Accept anything that can be used as a source operand for a move
|
||||
;; instruction.
|
||||
|
||||
(define_predicate "move_src_operand"
|
||||
(match_code "subreg,reg,const_int,mem")
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (op) == CONST_INT)
|
||||
return cint_ok_for_move (INTVAL (op));
|
||||
|
||||
if (GET_MODE (op) != mode)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating move insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (XEXP (op, 0)) == PLUS
|
||||
&& REG_P (XEXP (XEXP (op, 0), 0))
|
||||
&& REG_P (XEXP (XEXP (op, 0), 1)))
|
||||
return 0;
|
||||
|
||||
return memory_address_p (mode, XEXP (op, 0));
|
||||
})
|
||||
|
||||
;; Accept anything that can be used as the source operand for a
|
||||
;; prefetch instruction with a cache-control completer.
|
||||
|
||||
(define_predicate "prefetch_cc_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
/* We must reject virtual registers as we don't allow REG+D. */
|
||||
if (op == virtual_incoming_args_rtx
|
||||
|| op == virtual_stack_vars_rtx
|
||||
|| op == virtual_stack_dynamic_rtx
|
||||
|| op == virtual_outgoing_args_rtx
|
||||
|| op == virtual_cfa_rtx)
|
||||
return 0;
|
||||
|
||||
if (!REG_P (op) && !IS_INDEX_ADDR_P (op))
|
||||
return 0;
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating prefetch insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (op) == PLUS
|
||||
&& REG_P (XEXP (op, 0)))
|
||||
return 0;
|
||||
|
||||
return memory_address_p (mode, op);
|
||||
})
|
||||
|
||||
;; Accept anything that can be used as the source operand for a
|
||||
;; prefetch instruction with no cache-control completer.
|
||||
|
||||
(define_predicate "prefetch_nocc_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
op = XEXP (op, 0);
|
||||
|
||||
/* Until problems with management of the REG_POINTER flag are resolved,
|
||||
we need to delay creating prefetch insns with unscaled indexed addresses
|
||||
until CSE is not expected. */
|
||||
if (!TARGET_NO_SPACE_REGS
|
||||
&& !cse_not_expected
|
||||
&& GET_CODE (op) == PLUS
|
||||
&& REG_P (XEXP (op, 0))
|
||||
&& REG_P (XEXP (op, 1)))
|
||||
return 0;
|
||||
|
||||
return memory_address_p (mode, op);
|
||||
})
|
||||
|
||||
;; Accept REG and any CONST_INT that can be moved in one instruction
|
||||
;; into a general register.
|
||||
|
||||
(define_predicate "reg_or_cint_move_operand"
|
||||
(match_code "subreg,reg,const_int")
|
||||
{
|
||||
if (register_operand (op, mode))
|
||||
return 1;
|
||||
|
||||
return (GET_CODE (op) == CONST_INT && cint_ok_for_move (INTVAL (op)));
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "pic_label_operand"
|
||||
(match_code "label_ref,const")
|
||||
{
|
||||
if (!flag_pic)
|
||||
return 0;
|
||||
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case LABEL_REF:
|
||||
return 1;
|
||||
case CONST:
|
||||
op = XEXP (op, 0);
|
||||
return (GET_CODE (XEXP (op, 0)) == LABEL_REF
|
||||
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "fp_reg_operand"
|
||||
(match_code "reg")
|
||||
{
|
||||
return reg_renumber && FP_REG_P (op);
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP can be used as an operand in a
|
||||
;; three operand arithmetic insn that accepts registers of mode MODE
|
||||
;; or 14-bit signed integers.
|
||||
|
||||
(define_predicate "arith_operand"
|
||||
(match_code "subreg,reg,const_int")
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP can be used as an operand in a
|
||||
;; three operand arithmetic insn that accepts registers of mode MODE
|
||||
;; or 11-bit signed integers.
|
||||
|
||||
(define_predicate "arith11_operand"
|
||||
(match_code "subreg,reg,const_int")
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));
|
||||
})
|
||||
|
||||
;; A constant integer suitable for use in a PRE_MODIFY memory
|
||||
;; reference.
|
||||
|
||||
(define_predicate "pre_cint_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
|
||||
})
|
||||
|
||||
;; A constant integer suitable for use in a POST_MODIFY memory
|
||||
;; reference.
|
||||
|
||||
(define_predicate "post_cint_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "arith_double_operand"
|
||||
(match_code "subreg,reg,const_double")
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_DOUBLE
|
||||
&& GET_MODE (op) == mode
|
||||
&& VAL_14_BITS_P (CONST_DOUBLE_LOW (op))
|
||||
&& ((CONST_DOUBLE_HIGH (op) >= 0)
|
||||
== ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP is an integer which fits the range
|
||||
;; constraining immediate operands in three-address insns, or is an
|
||||
;; integer register.
|
||||
|
||||
(define_predicate "ireg_or_int5_operand"
|
||||
(match_code "const_int,reg")
|
||||
{
|
||||
return ((GET_CODE (op) == CONST_INT && INT_5_BITS (op))
|
||||
|| (GET_CODE (op) == REG && REGNO (op) > 0 && REGNO (op) < 32));
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP is an integer which fits the range
|
||||
;; constraining immediate operands in three-address insns.
|
||||
|
||||
(define_predicate "int5_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP is an integer which fits the range
|
||||
;; constraining immediate operands in three-address insns.
|
||||
|
||||
(define_predicate "uint5_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP is an integer which fits the range
|
||||
;; constraining immediate operands in three-address insns.
|
||||
|
||||
(define_predicate "int11_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP is an integer which fits the range
|
||||
;; constraining immediate operands in three-address insns.
|
||||
|
||||
(define_predicate "uint32_operand"
|
||||
(match_code "const_int,const_double")
|
||||
{
|
||||
#if HOST_BITS_PER_WIDE_INT > 32
|
||||
/* All allowed constants will fit a CONST_INT. */
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& (INTVAL (op) >= 0 && INTVAL (op) < (HOST_WIDE_INT) 1 << 32));
|
||||
#else
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
|| (GET_CODE (op) == CONST_DOUBLE
|
||||
&& CONST_DOUBLE_HIGH (op) == 0));
|
||||
#endif
|
||||
})
|
||||
|
||||
;; Return truth value of whether OP is an integer which fits the range
|
||||
;; constraining immediate operands in three-address insns.
|
||||
|
||||
(define_predicate "arith5_operand"
|
||||
(match_code "subreg,reg,const_int")
|
||||
{
|
||||
return register_operand (op, mode) || int5_operand (op, mode);
|
||||
})
|
||||
|
||||
;; True iff depi or extru can be used to compute (reg & OP).
|
||||
|
||||
(define_predicate "and_operand"
|
||||
(match_code "subreg,reg,const_int")
|
||||
{
|
||||
return (register_operand (op, mode)
|
||||
|| (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
|
||||
})
|
||||
|
||||
;; True iff depi can be used to compute (reg | OP).
|
||||
|
||||
(define_predicate "ior_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));
|
||||
})
|
||||
|
||||
;; True iff OP is a CONST_INT of the forms 0...0xxxx or
|
||||
;; 0...01...1xxxx. Such values can be the left hand side x in (x <<
|
||||
;; r), using the zvdepi instruction.
|
||||
|
||||
(define_predicate "lhs_lshift_cint_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
unsigned HOST_WIDE_INT x;
|
||||
if (GET_CODE (op) != CONST_INT)
|
||||
return 0;
|
||||
x = INTVAL (op) >> 4;
|
||||
return (x & (x + 1)) == 0;
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "lhs_lshift_operand"
|
||||
(match_code "subreg,reg,const_int")
|
||||
{
|
||||
return register_operand (op, mode) || lhs_lshift_cint_operand (op, mode);
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "arith32_operand"
|
||||
(match_code "subreg,reg,const_int")
|
||||
{
|
||||
return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "pc_or_label_operand"
|
||||
(match_code "pc,label_ref")
|
||||
{
|
||||
return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "plus_xor_ior_operator"
|
||||
(match_code "plus,xor,ior")
|
||||
{
|
||||
return (GET_CODE (op) == PLUS || GET_CODE (op) == XOR
|
||||
|| GET_CODE (op) == IOR);
|
||||
})
|
||||
|
||||
;; Return 1 if OP is a CONST_INT with the value 2, 4, or 8. These are
|
||||
;; the valid constant for shadd instructions.
|
||||
|
||||
(define_predicate "shadd_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
|
||||
})
|
||||
|
||||
;; TODO: Add a comment here.
|
||||
|
||||
(define_predicate "div_operand"
|
||||
(match_code "reg,const_int")
|
||||
{
|
||||
return (mode == SImode
|
||||
&& ((GET_CODE (op) == REG && REGNO (op) == 25)
|
||||
|| (GET_CODE (op) == CONST_INT && INTVAL (op) > 0
|
||||
&& INTVAL (op) < 16 && magic_milli[INTVAL (op)])));
|
||||
})
|
||||
|
||||
;; Return nonzero if OP is an integer register, else return zero.
|
||||
|
||||
(define_predicate "ireg_operand"
|
||||
(match_code "reg")
|
||||
{
|
||||
return (GET_CODE (op) == REG && REGNO (op) > 0 && REGNO (op) < 32);
|
||||
})
|
||||
|
||||
;; Return 1 if this is a comparison operator. This allows the use of
|
||||
;; MATCH_OPERATOR to recognize all the branch insns.
|
||||
|
||||
(define_predicate "cmpib_comparison_operator"
|
||||
(match_code "eq,ne,lt,le,leu,gt,gtu,ge")
|
||||
{
|
||||
return ((mode == VOIDmode || GET_MODE (op) == mode)
|
||||
&& (GET_CODE (op) == EQ
|
||||
|| GET_CODE (op) == NE
|
||||
|| GET_CODE (op) == GT
|
||||
|| GET_CODE (op) == GTU
|
||||
|| GET_CODE (op) == GE
|
||||
|| GET_CODE (op) == LT
|
||||
|| GET_CODE (op) == LE
|
||||
|| GET_CODE (op) == LEU));
|
||||
})
|
||||
|
||||
;; Return 1 if OP is an operator suitable for use in a movb
|
||||
;; instruction.
|
||||
|
||||
(define_predicate "movb_comparison_operator"
|
||||
(match_code "eq,ne,lt,ge")
|
||||
{
|
||||
return (GET_CODE (op) == EQ || GET_CODE (op) == NE
|
||||
|| GET_CODE (op) == LT || GET_CODE (op) == GE);
|
||||
})
|
Loading…
Reference in New Issue