Commit c9a88190 by Kazu Hirata Committed by Kazu Hirata

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
parent 22a14e0d
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 * config/m32r/m32r-protos.h: Remove the prototypes for
call_address_operand, symbolic_operand, seth_add3_operand, call_address_operand, symbolic_operand, seth_add3_operand,
...@@ -26,6 +26,27 @@ ...@@ -26,6 +26,27 @@
* config/m32r/m32r.md: Include predicates.md. * config/m32r/m32r.md: Include predicates.md.
* config/m32r/predicates.md: New. * 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> 2005-03-18 Kazu Hirata <kazu@cs.umass.edu>
* hooks.c, hooks.h, intl.c, opts.h, prefix.c, tree-gimple.c, * 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 *, ...@@ -176,6 +176,9 @@ extern void pa_asm_output_aligned_local (FILE *, const char *,
unsigned int); unsigned int);
extern void pa_hpux_asm_output_external (FILE *, tree, const char *); 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. */ /* Functions in varasm.c used by pa.c. */
extern void som_readonly_data_section (void); extern void som_readonly_data_section (void);
extern void som_one_only_readonly_data_section (void); extern void som_one_only_readonly_data_section (void);
......
...@@ -91,7 +91,6 @@ static void pa_reorg (void); ...@@ -91,7 +91,6 @@ static void pa_reorg (void);
static void pa_combine_instructions (void); static void pa_combine_instructions (void);
static int pa_can_combine_p (rtx, rtx, rtx, int, rtx, rtx, rtx); static int pa_can_combine_p (rtx, rtx, rtx, int, rtx, rtx, rtx);
static int forward_branch_p (rtx); static int forward_branch_p (rtx);
static int shadd_constant_p (int);
static void compute_zdepwi_operands (unsigned HOST_WIDE_INT, unsigned *); static void compute_zdepwi_operands (unsigned HOST_WIDE_INT, unsigned *);
static int compute_movmem_length (rtx); static int compute_movmem_length (rtx);
static int compute_clrmem_length (rtx); static int compute_clrmem_length (rtx);
...@@ -550,26 +549,6 @@ copy_reg_pointer (rtx to, rtx from) ...@@ -550,26 +549,6 @@ copy_reg_pointer (rtx to, rtx from)
mark_reg_pointer (to, REGNO_POINTER_ALIGN (REGNO (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 /* Return 1 if X contains a symbolic expression. We know these
expressions will have one of a few well defined forms, so expressions will have one of a few well defined forms, so
we need only check those forms. */ we need only check those forms. */
...@@ -584,95 +563,6 @@ symbolic_expression_p (rtx x) ...@@ -584,95 +563,6 @@ symbolic_expression_p (rtx x)
return (symbolic_operand (x, VOIDmode)); 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 /* Accept any constant that can be moved in one instruction into a
general register. */ general register. */
int int
...@@ -683,198 +573,7 @@ cint_ok_for_move (HOST_WIDE_INT intval) ...@@ -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, 'N')
|| CONST_OK_FOR_LETTER_P (intval, 'K')); || 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 /* Return truth value of whether OP can be used as an operand in a
adddi3 insn. */ adddi3 insn. */
int int
...@@ -885,94 +584,6 @@ adddi3_operand (rtx op, enum machine_mode mode) ...@@ -885,94 +584,6 @@ adddi3_operand (rtx op, enum machine_mode mode)
&& (TARGET_64BIT ? INT_14_BITS (op) : INT_11_BITS (op)))); && (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. /* True iff zdepi can be used to generate this CONST_INT.
zdepi first sign extends a 5 bit signed number to a given field zdepi first sign extends a 5 bit signed number to a given field
length, then places this field anywhere in a zero. */ length, then places this field anywhere in a zero. */
...@@ -1002,14 +613,6 @@ and_mask_p (unsigned HOST_WIDE_INT mask) ...@@ -1002,14 +613,6 @@ and_mask_p (unsigned HOST_WIDE_INT mask)
return (mask & (mask - 1)) == 0; 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). */ /* True iff depi can be used to compute (reg | MASK). */
int int
ior_mask_p (unsigned HOST_WIDE_INT mask) ior_mask_p (unsigned HOST_WIDE_INT mask)
...@@ -1017,44 +620,6 @@ ior_mask_p (unsigned HOST_WIDE_INT mask) ...@@ -1017,44 +620,6 @@ ior_mask_p (unsigned HOST_WIDE_INT mask)
mask += mask & -mask; mask += mask & -mask;
return (mask & (mask - 1)) == 0; 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 /* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated position-independent, we return ORIG. Newly generated
...@@ -5741,8 +5306,7 @@ output_mul_insn (int unsignedp ATTRIBUTE_UNUSED, rtx insn) ...@@ -5741,8 +5306,7 @@ output_mul_insn (int unsignedp ATTRIBUTE_UNUSED, rtx insn)
/* Emit the rtl for doing a division by a constant. */ /* Emit the rtl for doing a division by a constant. */
/* Do magic division millicodes exist for this value? */ /* 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, const int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1};
1, 1};
/* We'll use an array to keep track of the magic millicodes and /* 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 whether or not we've used them already. [n][0] is signed, [n][1] is
...@@ -5751,15 +5315,6 @@ static const int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, ...@@ -5751,15 +5315,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]; static int div_milli[16][2];
int 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) emit_hpdiv_const (rtx *operands, int unsignedp)
{ {
if (GET_CODE (operands[2]) == CONST_INT if (GET_CODE (operands[2]) == CONST_INT
...@@ -8440,16 +7995,9 @@ fmpysuboperands (rtx *operands) ...@@ -8440,16 +7995,9 @@ fmpysuboperands (rtx *operands)
return 1; 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 /* Return 1 if the given constant is 2, 4, or 8. These are the valid
constants for shadd instructions. */ constants for shadd instructions. */
static int int
shadd_constant_p (int val) shadd_constant_p (int val)
{ {
if (val == 2 || val == 4 || val == 8) if (val == 2 || val == 4 || val == 8)
...@@ -8458,14 +8006,6 @@ shadd_constant_p (int val) ...@@ -8458,14 +8006,6 @@ shadd_constant_p (int val)
return 0; 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 /* Return 1 if OP is valid as a base or index register in a
REG+REG address. */ REG+REG address. */
...@@ -8528,14 +8068,6 @@ eq_neq_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -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 (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. */ /* Return 1 if INSN is in the delay slot of a call instruction. */
int int
jump_in_call_delay (rtx insn) jump_in_call_delay (rtx insn)
...@@ -9367,23 +8899,6 @@ pa_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -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. /* Return a string to output before text in the current function.
This function is only used with SOM. Because we don't support This function is only used with SOM. Because we don't support
......
...@@ -2128,49 +2128,6 @@ forget_section (void) \ ...@@ -2128,49 +2128,6 @@ forget_section (void) \
/* The number of Pmode words for the setjmp buffer. */ /* The number of Pmode words for the setjmp buffer. */
#define JMP_BUF_SIZE 50 #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. */ /* We need a libcall to canonicalize function pointers on TARGET_ELF32. */
#define CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL \ #define CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL \
"__canonicalize_funcptr_for_compare" "__canonicalize_funcptr_for_compare"
...@@ -561,7 +561,7 @@ ...@@ -561,7 +561,7 @@
(eq_attr "cpu" "8000")) (eq_attr "cpu" "8000"))
"inm_8000,fdivsqrt_8000*6,rnm_8000") "inm_8000,fdivsqrt_8000*6,rnm_8000")
(include "predicates.md")
;; Compare instructions. ;; Compare instructions.
;; This controls RTL generation and register allocation. ;; This controls RTL generation and register allocation.
......
;; 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);
})
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