/* Definitions for code generation pass of GNU compiler.
- Copyright (C) 1987, 91-99, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
\f
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
/* Structure to record the size of a sequence of arguments
- as the sum of a tree-expression and a constant. */
+ as the sum of a tree-expression and a constant. This structure is
+ also used to store offsets from the stack, which might be negative,
+ so the variable part must be ssizetype, not sizetype. */
struct args_size
{
#define ADD_PARM_SIZE(TO, INC) \
{ tree inc = (INC); \
- if (TREE_CODE (inc) == INTEGER_CST) \
- (TO).constant += TREE_INT_CST_LOW (inc); \
+ if (host_integerp (inc, 0)) \
+ (TO).constant += tree_low_cst (inc, 0); \
else if ((TO).var == 0) \
(TO).var = inc; \
else \
#define SUB_PARM_SIZE(TO, DEC) \
{ tree dec = (DEC); \
- if (TREE_CODE (dec) == INTEGER_CST) \
- (TO).constant -= TREE_INT_CST_LOW (dec); \
+ if (host_integerp (dec, 0)) \
+ (TO).constant -= tree_low_cst (dec, 0); \
else if ((TO).var == 0) \
- (TO).var = size_binop (MINUS_EXPR, integer_zero_node, dec); \
+ (TO).var = size_binop (MINUS_EXPR, ssize_int (0), dec); \
else \
(TO).var = size_binop (MINUS_EXPR, (TO).var, dec); }
-/* Convert the implicit sum in a `struct args_size' into an rtx. */
-#define ARGS_SIZE_RTX(SIZE) \
-((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \
- : expand_expr (size_binop (PLUS_EXPR, (SIZE).var, \
- size_int ((SIZE).constant)), \
- NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD))
+/* Convert the implicit sum in a `struct args_size' into a tree
+ of type ssizetype. */
+#define ARGS_SIZE_TREE(SIZE) \
+((SIZE).var == 0 ? ssize_int ((SIZE).constant) \
+ : size_binop (PLUS_EXPR, (SIZE).var, ssize_int ((SIZE).constant)))
-/* Convert the implicit sum in a `struct args_size' into a tree. */
-#define ARGS_SIZE_TREE(SIZE) \
-((SIZE).var == 0 ? size_int ((SIZE).constant) \
- : size_binop (PLUS_EXPR, (SIZE).var, size_int ((SIZE).constant)))
+/* Convert the implicit sum in a `struct args_size' into an rtx. */
+#define ARGS_SIZE_RTX(SIZE) \
+((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \
+ : expand_expr (ARGS_SIZE_TREE (SIZE), NULL_RTX, VOIDmode, \
+ EXPAND_MEMORY_USE_BAD))
/* Supply a default definition for FUNCTION_ARG_PADDING:
usually pad upward, but pad short args downward on
A few optabs, such as move_optab and cmp_optab, are used
by special code. */
-/* Everything that uses expr.h needs to define enum insn_code
- but we don't list it in the Makefile dependencies just for that. */
-#include "insn-codes.h"
-
typedef struct optab
{
enum rtx_code code;
/* Given an enum insn_code, access the function to construct
the body of that kind of insn. */
-#ifdef FUNCTION_CONVERSION_BUG
-/* Some compilers fail to convert a function properly to a
- pointer-to-function when used as an argument.
- So produce the pointer-to-function directly.
- Luckily, these compilers seem to work properly when you
- call the pointer-to-function. */
-#define GEN_FCN(CODE) (insn_data[(int) (CODE)].genfun)
-#else
#define GEN_FCN(CODE) (*insn_data[(int) (CODE)].genfun)
-#endif
/* Enumeration of valid indexes into optab_table. */
enum optab_index
{
OTI_add,
+ OTI_addv,
OTI_sub,
+ OTI_subv,
/* Signed and fp multiply */
OTI_smul,
+ OTI_smulv,
/* Signed multiply, return high word */
OTI_smul_highpart,
OTI_umul_highpart,
/* Signed divide */
OTI_sdiv,
+ OTI_sdivv,
/* Signed divide-and-remainder in one */
OTI_sdivmod,
OTI_udiv,
/* Unary operations */
/* Negation */
OTI_neg,
+ OTI_negv,
/* Abs value */
OTI_abs,
+ OTI_absv,
/* Bitwise not */
OTI_one_cmpl,
/* Find first bit set */
#define add_optab (optab_table[OTI_add])
#define sub_optab (optab_table[OTI_sub])
#define smul_optab (optab_table[OTI_smul])
+#define addv_optab (optab_table[OTI_addv])
+#define subv_optab (optab_table[OTI_subv])
#define smul_highpart_optab (optab_table[OTI_smul_highpart])
#define umul_highpart_optab (optab_table[OTI_umul_highpart])
#define smul_widen_optab (optab_table[OTI_smul_widen])
#define umul_widen_optab (optab_table[OTI_umul_widen])
#define sdiv_optab (optab_table[OTI_sdiv])
+#define smulv_optab (optab_table[OTI_smulv])
+#define sdivv_optab (optab_table[OTI_sdivv])
#define sdivmod_optab (optab_table[OTI_sdivmod])
#define udiv_optab (optab_table[OTI_udiv])
#define udivmod_optab (optab_table[OTI_udivmod])
#define movstrict_optab (optab_table[OTI_movstrict])
#define neg_optab (optab_table[OTI_neg])
+#define negv_optab (optab_table[OTI_negv])
#define abs_optab (optab_table[OTI_abs])
+#define absv_optab (optab_table[OTI_absv])
#define one_cmpl_optab (optab_table[OTI_one_cmpl])
#define ffs_optab (optab_table[OTI_ffs])
#define sqrt_optab (optab_table[OTI_sqrt])
LTI_trunctfdf2,
LTI_memcpy,
+ LTI_memmove,
LTI_bcopy,
LTI_memcmp,
LTI_bcmp,
LTI_memset,
LTI_bzero,
- LTI_throw,
- LTI_rethrow,
- LTI_sjthrow,
- LTI_sjpopnthrow,
- LTI_terminate,
+ LTI_unwind_resume,
+ LTI_eh_personality,
LTI_setjmp,
LTI_longjmp,
- LTI_eh_rtime_match,
+ LTI_unwind_sjlj_register,
+ LTI_unwind_sjlj_unregister,
LTI_eqhf2,
LTI_nehf2,
#define trunctfdf2_libfunc (libfunc_table[LTI_trunctfdf2])
#define memcpy_libfunc (libfunc_table[LTI_memcpy])
+#define memmove_libfunc (libfunc_table[LTI_memmove])
#define bcopy_libfunc (libfunc_table[LTI_bcopy])
#define memcmp_libfunc (libfunc_table[LTI_memcmp])
#define bcmp_libfunc (libfunc_table[LTI_bcmp])
#define memset_libfunc (libfunc_table[LTI_memset])
#define bzero_libfunc (libfunc_table[LTI_bzero])
-#define throw_libfunc (libfunc_table[LTI_throw])
-#define rethrow_libfunc (libfunc_table[LTI_rethrow])
-#define sjthrow_libfunc (libfunc_table[LTI_sjthrow])
-#define sjpopnthrow_libfunc (libfunc_table[LTI_sjpopnthrow])
-#define terminate_libfunc (libfunc_table[LTI_terminate])
+#define unwind_resume_libfunc (libfunc_table[LTI_unwind_resume])
+#define eh_personality_libfunc (libfunc_table[LTI_eh_personality])
#define setjmp_libfunc (libfunc_table[LTI_setjmp])
#define longjmp_libfunc (libfunc_table[LTI_longjmp])
-#define eh_rtime_match_libfunc (libfunc_table[LTI_eh_rtime_match])
+#define unwind_sjlj_register_libfunc (libfunc_table[LTI_unwind_sjlj_register])
+#define unwind_sjlj_unregister_libfunc \
+ (libfunc_table[LTI_unwind_sjlj_unregister])
#define eqhf2_libfunc (libfunc_table[LTI_eqhf2])
#define nehf2_libfunc (libfunc_table[LTI_nehf2])
extern rtx expand_unop PARAMS ((enum machine_mode, optab, rtx, rtx, int));
/* Expand the absolute value operation. */
-extern rtx expand_abs PARAMS ((enum machine_mode, rtx, rtx, int));
+extern rtx expand_abs PARAMS ((enum machine_mode, rtx, rtx, int, int));
/* Expand the complex absolute value operation. */
extern rtx expand_complex_abs PARAMS ((enum machine_mode, rtx, rtx, int));
/* Emit one rtl insn to compare two rtx's. */
extern void emit_cmp_insn PARAMS ((rtx, rtx, enum rtx_code, rtx,
- enum machine_mode, int, int));
+ enum machine_mode, int, unsigned int));
/* Emit a pair of rtl insns to compare two rtx's and to jump
to a label if the comparison is true. */
extern void emit_cmp_and_jump_insns PARAMS ((rtx, rtx, enum rtx_code, rtx,
- enum machine_mode, int, int, rtx));
+ enum machine_mode, int,
+ unsigned int, rtx));
/* The various uses that a comparison can have; used by can_compare_p:
jumps, conditional moves, store flag operations. */
/* Functions from loop.c: */
-/* Given a JUMP_INSN, return a description of the test being made. */
+/* Given an insn and condition, return a canonical description of
+ the test being made. */
+extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx));
+
+/* Given a JUMP_INSN, return a canonical description of the test
+ being made. */
extern rtx get_condition PARAMS ((rtx, rtx *));
/* Generate a conditional trap instruction. */
/* Functions from builtins.c: */
#ifdef TREE_CODE
extern rtx expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
-extern tree expand_tree_builtin PARAMS ((tree, tree, tree));
extern void std_expand_builtin_va_start PARAMS ((int, tree, rtx));
extern rtx std_expand_builtin_va_arg PARAMS ((tree, tree));
extern rtx expand_builtin_va_arg PARAMS ((tree, tree));
#endif
-extern rtx expand_builtin_setjmp PARAMS ((rtx, rtx, rtx, rtx));
+extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
+extern void expand_builtin_setjmp_receiver PARAMS ((rtx));
extern void expand_builtin_longjmp PARAMS ((rtx, rtx));
extern rtx expand_builtin_saveregs PARAMS ((void));
-extern int get_varargs_alias_set PARAMS ((void));
+extern HOST_WIDE_INT get_varargs_alias_set PARAMS ((void));
+extern HOST_WIDE_INT get_frame_alias_set PARAMS ((void));
+extern void record_base_value PARAMS ((unsigned int, rtx, int));
+extern void record_alias_subset PARAMS ((HOST_WIDE_INT,
+ HOST_WIDE_INT));
+extern HOST_WIDE_INT new_alias_set PARAMS ((void));
\f
/* Functions from expr.c: */
extern rtx convert_to_mode PARAMS ((enum machine_mode, rtx, int));
/* Convert an rtx to MODE from OLDMODE and return the result. */
-extern rtx convert_modes PARAMS ((enum machine_mode, enum machine_mode, rtx, int));
+extern rtx convert_modes PARAMS ((enum machine_mode, enum machine_mode,
+ rtx, int));
/* Emit code to move a block Y to a block X. */
-extern rtx emit_block_move PARAMS ((rtx, rtx, rtx, int));
+extern rtx emit_block_move PARAMS ((rtx, rtx, rtx, unsigned int));
/* Copy all or part of a value X into registers starting at REGNO.
The number of registers to be filled is NREGS. */
/* Load a BLKmode value into non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_load PARAMS ((rtx, rtx, int, int));
+extern void emit_group_load PARAMS ((rtx, rtx, int, unsigned int));
+
/* Store a BLKmode value from non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_store PARAMS ((rtx, rtx, int, int));
+extern void emit_group_store PARAMS ((rtx, rtx, int, unsigned int));
#ifdef TREE_CODE
/* Copy BLKmode object from a set of registers. */
/* Mark REG as holding a parameter for the next CALL_INSN. */
extern void use_reg PARAMS ((rtx *, rtx));
+
/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
for the next CALL_INSN. */
extern void use_regs PARAMS ((rtx *, int, int));
+
/* Mark a PARALLEL as holding a parameter for the next CALL_INSN. */
extern void use_group_regs PARAMS ((rtx *, rtx));
/* Write zeros through the storage of OBJECT.
If OBJECT has BLKmode, SIZE is its length in bytes and ALIGN is its
alignment. */
-extern rtx clear_storage PARAMS ((rtx, rtx, int));
+extern rtx clear_storage PARAMS ((rtx, rtx, unsigned int));
+
+/* Return non-zero if it is desirable to store LEN bytes generated by
+ CONSTFUN with several move instructions by store_by_pieces
+ function. CONSTFUNDATA is a pointer which will be passed as argument
+ in every CONSTFUN call.
+ ALIGN is maximum alignment we can assume. */
+extern int can_store_by_pieces PARAMS ((unsigned HOST_WIDE_INT,
+ rtx (*) (PTR, HOST_WIDE_INT,
+ enum machine_mode),
+ PTR, unsigned int));
+
+/* Generate several move instructions to store LEN bytes generated by
+ CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
+ pointer which will be passed as argument in every CONSTFUN call.
+ ALIGN is maximum alignment we can assume. */
+extern void store_by_pieces PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ rtx (*) (PTR, HOST_WIDE_INT,
+ enum machine_mode),
+ PTR, unsigned int));
/* Emit insns to set X from Y. */
extern rtx emit_move_insn PARAMS ((rtx, rtx));
and return an rtx to address the beginning of the block. */
extern rtx push_block PARAMS ((rtx, int, int));
-/* Make an operand to push something on the stack. */
-extern rtx gen_push_operand PARAMS ((void));
-
#ifdef TREE_CODE
/* Generate code to push something onto the stack, given its mode and type. */
-extern void emit_push_insn PARAMS ((rtx, enum machine_mode, tree, rtx, int,
- int, rtx, int, rtx, rtx, int, rtx));
-
-/* Emit library call. */
-extern void emit_library_call PARAMS ((rtx orgfun, int no_queue,
- enum machine_mode outmode, int nargs, ...));
-extern rtx emit_library_call_value PARAMS ((rtx orgfun, rtx value, int no_queue,
- enum machine_mode outmode, int nargs, ...));
+extern void emit_push_insn PARAMS ((rtx, enum machine_mode, tree, rtx,
+ unsigned int, int, rtx, int, rtx, rtx,
+ int, rtx));
/* Expand an assignment that stores the value of FROM into TO. */
extern rtx expand_assignment PARAMS ((tree, tree, int, int));
/* Generate rtl to compare two rtx's, will call emit_cmp_insn. */
extern rtx compare_from_rtx PARAMS ((rtx, rtx, enum rtx_code, int,
- enum machine_mode, rtx, int));
+ enum machine_mode, rtx, unsigned int));
extern void do_compare_rtx_and_jump PARAMS ((rtx, rtx, enum rtx_code, int,
- enum machine_mode, rtx, int,
- rtx, rtx));
+ enum machine_mode, rtx,
+ unsigned int, rtx, rtx));
/* Generate a tablejump instruction (used for switch statements). */
extern void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx, rtx));
extern rtx expand_call PARAMS ((tree, rtx, int));
-extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree, rtx, int));
-extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int));
-extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *, struct args_size *));
+extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree,
+ rtx, int));
+extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx,
+ rtx, rtx, int));
+extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree,
+ struct args_size *,
+ struct args_size *,
+ struct args_size *,
+ struct args_size *));
extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx));
+
/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */
extern rtx label_rtx PARAMS ((tree));
#endif
/* Indicate how an input argument register was promoted. */
-extern rtx promoted_input_arg PARAMS ((int, enum machine_mode *, int *));
+extern rtx promoted_input_arg PARAMS ((unsigned int, enum machine_mode *,
+ int *));
/* Return an rtx like arg but sans any constant terms.
Returns the original rtx if it has no constant terms.
/* Return a memory reference like MEMREF, but which is known to have a
valid address. */
-
extern rtx validize_mem PARAMS ((rtx));
+#ifdef TREE_CODE
+/* Given REF, either a MEM or a REG, and T, either the type of X or
+ the expression corresponding to REF, set RTX_UNCHANGING_P if
+ appropriate. */
+extern void maybe_set_unchanging PARAMS ((rtx, tree));
+
+/* Given REF, a MEM, and T, either the type of X or the expression
+ corresponding to REF, set the memory attributes. OBJECTP is nonzero
+ if we are making a new object of this type. */
+extern void set_mem_attributes PARAMS ((rtx, tree, int));
+#endif
+
/* Assemble the static constant template for function entry trampolines. */
extern rtx assemble_trampoline_template PARAMS ((void));
-/* Return 1 if two rtx's are equivalent in structure and elements. */
-extern int rtx_equal_p PARAMS ((rtx, rtx));
-
/* Given rtx, return new rtx whose address won't be affected by
any side effects. It has been copied to a new temporary reg. */
extern rtx stabilize PARAMS ((rtx));
of STACK_BOUNDARY / BITS_PER_UNIT. */
extern rtx round_push PARAMS ((rtx));
-extern rtx store_bit_field PARAMS ((rtx, int, int, enum machine_mode, rtx, int, int));
-extern rtx extract_bit_field PARAMS ((rtx, int, int, int, rtx, enum machine_mode, enum machine_mode, int, int));
+extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ enum machine_mode, rtx,
+ unsigned int, HOST_WIDE_INT));
+extern rtx extract_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, int, rtx,
+ enum machine_mode, enum machine_mode,
+ unsigned int, HOST_WIDE_INT));
extern rtx expand_mult PARAMS ((enum machine_mode, rtx, rtx, rtx, int));
extern rtx expand_mult_add PARAMS ((rtx, rtx, rtx, rtx,enum machine_mode, int));
extern rtx expand_mult_highpart_adjust PARAMS ((enum machine_mode, rtx, rtx, rtx, rtx, int));
such codes that output_constant needs to know about. Returns a
language-independent constant equivalent to its input. */
extern tree (*lang_expand_constant) PARAMS ((tree));
+
+extern int safe_from_p PARAMS ((rtx, tree, int));
+
+/* Hook called by safe_from_p for language-specific tree codes. It is
+ up to the language front-end to install a hook if it has any such
+ codes that safe_from_p needs to know about. Since same_from_p will
+ recursively explore the TREE_OPERANDs of an expression, this hook
+ should not reexamine those pieces. This routine may recursively
+ call safe_from_p; it should always pass `0' as the TOP_P
+ parameter. */
+extern int (*lang_safe_from_p) PARAMS ((rtx, tree));
#endif
extern void init_all_optabs PARAMS ((void));
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
extern void mark_seen_cases PARAMS ((tree, unsigned char *,
- long, int));
+ HOST_WIDE_INT, int));
#endif