expr.h

来自「GCC编译器源代码」· C头文件 代码 · 共 944 行 · 第 1/3 页

H
944
字号
/* Definitions for code generation pass of GNU compiler.   Copyright (C) 1987, 91-96, 1997 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* The default branch cost is 1.  */#ifndef BRANCH_COST#define BRANCH_COST 1#endif/* Macros to access the slots of a QUEUED rtx.   Here rather than in rtl.h because only the expansion pass   should ever encounter a QUEUED.  *//* The variable for which an increment is queued.  */#define QUEUED_VAR(P) XEXP (P, 0)/* If the increment has been emitted, this is the insn   that does the increment.  It is zero before the increment is emitted.  */#define QUEUED_INSN(P) XEXP (P, 1)/* If a pre-increment copy has been generated, this is the copy   (it is a temporary reg).  Zero if no copy made yet.  */#define QUEUED_COPY(P) XEXP (P, 2)/* This is the body to use for the insn to do the increment.   It is used to emit the increment.  */#define QUEUED_BODY(P) XEXP (P, 3)/* Next QUEUED in the queue.  */#define QUEUED_NEXT(P) XEXP (P, 4)/* This is the 4th arg to `expand_expr'.   EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx.   EXPAND_INITIALIZER is similar but also record any labels on forced_labels.   EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address    is a constant that is not a legitimate address.   EXPAND_MEMORY_USE_* are explained below.  */enum expand_modifier {EXPAND_NORMAL, EXPAND_SUM,		      EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER,		      EXPAND_MEMORY_USE_WO, EXPAND_MEMORY_USE_RW,		      EXPAND_MEMORY_USE_BAD, EXPAND_MEMORY_USE_DONT};/* Argument for chkr_* functions.   MEMORY_USE_RO: the pointer reads memory.   MEMORY_USE_WO: the pointer writes to memory.   MEMORY_USE_RW: the pointer modifies memory (ie it reads and writes). An                  example is (*ptr)++   MEMORY_USE_BAD: use this if you don't know the behavior of the pointer, or                   if you know there are no pointers.  Using an INDIRECT_REF                   with MEMORY_USE_BAD will abort.   MEMORY_USE_TW: just test for writing, without update.  Special.   MEMORY_USE_DONT: the memory is neither read nor written.  This is used by   		   '->' and '.'.  */enum memory_use_mode {MEMORY_USE_BAD = 0, MEMORY_USE_RO = 1,		      MEMORY_USE_WO = 2, MEMORY_USE_RW = 3,		      MEMORY_USE_TW = 6, MEMORY_USE_DONT = 99};/* List of labels that must never be deleted.  */extern rtx forced_labels;/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.   So we can mark them all live at the end of the function, if stupid.  */extern rtx save_expr_regs;extern int current_function_calls_alloca;extern int current_function_outgoing_args_size;/* This is the offset from the arg pointer to the place where the first   anonymous arg can be found, if there is one.  */extern rtx current_function_arg_offset_rtx;/* This is nonzero if the current function uses the constant pool.  */extern int current_function_uses_const_pool;/* This is nonzero if the current function uses pic_offset_table_rtx.  */extern int current_function_uses_pic_offset_table;/* The arg pointer hard register, or the pseudo into which it was copied.  */extern rtx current_function_internal_arg_pointer;/* Nonzero means stack pops must not be deferred, and deferred stack   pops must not be output.  It is nonzero inside a function call,   inside a conditional expression, inside a statement expression,   and in other cases as well.  */extern int inhibit_defer_pop;/* Number of function calls seen so far in current function.  */extern int function_call_count;/* RTX for stack slot that holds the current handler for nonlocal gotos.   Zero when function does not have nonlocal labels.  */extern rtx nonlocal_goto_handler_slot;/* RTX for stack slot that holds the stack pointer value to restore   for a nonlocal goto.   Zero when function does not have nonlocal labels.  */extern rtx nonlocal_goto_stack_level;/* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels   (labels to which there can be nonlocal gotos from nested functions)   in this function.  */#ifdef TREE_CODE   /* Don't lose if tree.h not included.  */extern tree nonlocal_labels;#endif#define NO_DEFER_POP (inhibit_defer_pop += 1)#define OK_DEFER_POP (inhibit_defer_pop -= 1)/* Number of units that we should eventually pop off the stack.   These are the arguments to function calls that have already returned.  */extern int pending_stack_adjust;/* When temporaries are created by TARGET_EXPRs, they are created at   this level of temp_slot_level, so that they can remain allocated   until no longer needed.  CLEANUP_POINT_EXPRs define the lifetime   of TARGET_EXPRs.  */extern int target_temp_slot_level;#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.  */struct args_size{  int constant;  tree var;};#endif/* Add the value of the tree INC to the `struct args_size' TO.  */#define ADD_PARM_SIZE(TO, INC)	\{ tree inc = (INC);				\  if (TREE_CODE (inc) == INTEGER_CST)		\    (TO).constant += TREE_INT_CST_LOW (inc);	\  else if ((TO).var == 0)			\    (TO).var = inc;				\  else						\    (TO).var = size_binop (PLUS_EXPR, (TO).var, inc); }#define SUB_PARM_SIZE(TO, DEC)	\{ tree dec = (DEC);				\  if (TREE_CODE (dec) == INTEGER_CST)		\    (TO).constant -= TREE_INT_CST_LOW (dec);	\  else if ((TO).var == 0)			\    (TO).var = size_binop (MINUS_EXPR, integer_zero_node, 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.  */#define ARGS_SIZE_TREE(SIZE)						\((SIZE).var == 0 ? size_int ((SIZE).constant)				\ : size_binop (PLUS_EXPR, (SIZE).var, size_int ((SIZE).constant)))/* Supply a default definition for FUNCTION_ARG_PADDING:   usually pad upward, but pad short args downward on   big-endian machines.  */enum direction {none, upward, downward};  /* Value has this type.  */#ifndef FUNCTION_ARG_PADDING#define FUNCTION_ARG_PADDING(MODE, TYPE)				\  (! BYTES_BIG_ENDIAN							\   ? upward								\   : (((MODE) == BLKmode						\       ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST		\	  && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \       : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY)			\      ? downward : upward))#endif/* Supply a default definition for FUNCTION_ARG_BOUNDARY.  Normally, we let   FUNCTION_ARG_PADDING, which also pads the length, handle any needed   alignment.  */  #ifndef FUNCTION_ARG_BOUNDARY#define FUNCTION_ARG_BOUNDARY(MODE, TYPE)	PARM_BOUNDARY#endif/* Nonzero if we do not know how to pass TYPE solely in registers.   We cannot do so in the following cases:   - if the type has variable size   - if the type is marked as addressable (it is required to be constructed     into the stack)   - if the padding and mode of the type is such that a copy into a register     would put it into the wrong part of the register.   Which padding can't be supported depends on the byte endianness.   A value in a register is implicitly padded at the most significant end.   On a big-endian machine, that is the lower end in memory.   So a value padded in memory at the upper end can't go in a register.   For a little-endian machine, the reverse is true.  */#define MUST_PASS_IN_STACK(MODE,TYPE)			\  ((TYPE) != 0						\   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\       || TREE_ADDRESSABLE (TYPE)			\       || ((MODE) == BLKmode 				\	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \		 && 0 == (int_size_in_bytes (TYPE)	\			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\	       == (BYTES_BIG_ENDIAN ? upward : downward)))))/* Nonzero if type TYPE should be returned in memory.   Most machines can use the following default definition.  */#ifndef RETURN_IN_MEMORY#define RETURN_IN_MEMORY(TYPE) (TYPE_MODE (TYPE) == BLKmode)#endif/* Provide default values for the macros controlling stack checking.  */#ifndef STACK_CHECK_BUILTIN#define STACK_CHECK_BUILTIN 0#endif/* The default interval is one page.  */#ifndef STACK_CHECK_PROBE_INTERVAL#define STACK_CHECK_PROBE_INTERVAL 4096#endif/* The default is to do a store into the stack.  */#ifndef STACK_CHECK_PROBE_LOAD#define STACK_CHECK_PROBE_LOAD 0#endif/* This value is arbitrary, but should be sufficient for most machines.  */#ifndef STACK_CHECK_PROTECT#define STACK_CHECK_PROTECT (75 * UNITS_PER_WORD)#endif/* Make the maximum frame size be the largest we can and still only need   one probe per function.  */#ifndef STACK_CHECK_MAX_FRAME_SIZE#define STACK_CHECK_MAX_FRAME_SIZE \  (STACK_CHECK_PROBE_INTERVAL - UNITS_PER_WORD)#endif/* This is arbitrary, but should be large enough everywhere.  */#ifndef STACK_CHECK_FIXED_FRAME_SIZE#define STACK_CHECK_FIXED_FRAME_SIZE (4 * UNITS_PER_WORD)#endif/* Provide a reasonable default for the maximum size of an object to   allocate in the fixed frame.  We may need to be able to make this   controllable by the user at some point.  */#ifndef STACK_CHECK_MAX_VAR_SIZE#define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100)#endif/* Optabs are tables saying how to generate insn bodies   for various machine modes and numbers of operands.   Each optab applies to one operation.   For example, add_optab applies to addition.   The insn_code slot is the enum insn_code that says how to   generate an insn for this operation on a particular machine mode.   It is CODE_FOR_nothing if there is no such insn on the target machine.   The `lib_call' slot is the name of the library function that   can be used to perform the operation.   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;  struct {    enum insn_code insn_code;    rtx libfunc;  } handlers [NUM_MACHINE_MODES];} * optab;/* 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_gen_function[(int) (CODE)])#else#define GEN_FCN(CODE) (*insn_gen_function[(int) (CODE)])

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?