📄 rtl.h
字号:
/* Register Transfer Language (RTL) definitions for GNU C-Compiler Copyright (C) 1987, 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "machmode.h"#undef FFS /* Some systems predefine this symbol; don't let it interfere. */#undef FLOAT /* Likewise. *//* Register Transfer Language EXPRESSIONS CODES */#define RTX_CODE enum rtx_codeenum rtx_code {#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,#include "rtl.def" /* rtl expressions are documented here */#undef DEF_RTL_EXPR LAST_AND_UNUSED_RTX_CODE}; /* A convenient way to get a value for NUM_RTX_CODE. Assumes default enum value assignment. */#define NUM_RTX_CODE ((int)LAST_AND_UNUSED_RTX_CODE) /* The cast here, saves many elsewhere. */extern int rtx_length[];#define GET_RTX_LENGTH(CODE) (rtx_length[(int)(CODE)])extern char *rtx_name[];#define GET_RTX_NAME(CODE) (rtx_name[(int)(CODE)])extern char *rtx_format[];#define GET_RTX_FORMAT(CODE) (rtx_format[(int)(CODE)])extern char rtx_class[];#define GET_RTX_CLASS(CODE) (rtx_class[(int)(CODE)])/* Common union for an element of an rtx. */typedef union rtunion_def{ HOST_WIDE_INT rtwint; int rtint; char *rtstr; struct rtx_def *rtx; struct rtvec_def *rtvec; enum machine_mode rttype;} rtunion;/* RTL expression ("rtx"). */typedef struct rtx_def{#ifdef ONLY_INT_FIELDS#ifdef CODE_FIELD_BUG unsigned int code : 16;#else unsigned short code;#endif#else /* The kind of expression this is. */ enum rtx_code code : 16;#endif /* The kind of value the expression has. */#ifdef ONLY_INT_FIELDS int mode : 8;#else enum machine_mode mode : 8;#endif /* 1 in an INSN if it can alter flow of control within this function. Not yet used! */ unsigned int jump : 1; /* 1 in an INSN if it can call another function. Not yet used! */ unsigned int call : 1; /* 1 in a MEM or REG if value of this expression will never change during the current function, even though it is not manifestly constant. 1 in a SUBREG if it is from a promoted variable that is unsigned. 1 in a SYMBOL_REF if it addresses something in the per-function constants pool. 1 in a CALL_INSN if it is a const call. 1 in a JUMP_INSN if it is a branch that should be annulled. Valid from reorg until end of compilation; cleared before used. */ unsigned int unchanging : 1; /* 1 in a MEM expression if contents of memory are volatile. 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL or BARRIER if it is deleted. 1 in a REG expression if corresponds to a variable declared by the user. 0 for an internally generated temporary. In a SYMBOL_REF, this flag is used for machine-specific purposes. In a LABEL_REF or in a REG_LABEL note, this is LABEL_REF_NONLOCAL_P. */ unsigned int volatil : 1; /* 1 in a MEM referring to a field of a structure (not a union!). 0 if the MEM was a variable or the result of a * operator in C; 1 if it was the result of a . or -> operator (on a struct) in C. 1 in a REG if the register is used only in exit code a loop. 1 in a SUBREG expression if was generated from a variable with a promoted mode. 1 in a CODE_LABEL if the label is used for nonlocal gotos and must not be deleted even if its count is zero. 1 in a LABEL_REF if this is a reference to a label outside the current loop. 1 in an INSN, JUMP_INSN, or CALL_INSN if this insn must be scheduled together with the preceding insn. Valid only within sched. 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and from the target of a branch. Valid from reorg until end of compilation; cleared before used. */ unsigned int in_struct : 1; /* 1 if this rtx is used. This is used for copying shared structure. See `unshare_all_rtl'. In a REG, this is not needed for that purpose, and used instead in `leaf_renumber_regs_insn'. In a SYMBOL_REF, means that emit_library_call has used it as the function. */ unsigned int used : 1; /* Nonzero if this rtx came from procedure integration. In a REG, nonzero means this reg refers to the return value of the current function. */ unsigned integrated : 1; /* The first element of the operands of this rtx. The number of operands and their types are controlled by the `code' field, according to rtl.def. */ rtunion fld[1];} *rtx;/* Add prototype support. */#ifndef PROTO#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)#define PROTO(ARGS) ARGS#else#define PROTO(ARGS) ()#endif#endif#define NULL_RTX (rtx) 0/* Define a generic NULL if one hasn't already been defined. */#ifndef NULL#define NULL 0#endif#ifndef GENERIC_PTR#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)#define GENERIC_PTR void *#else#define GENERIC_PTR char *#endif#endif#ifndef NULL_PTR#define NULL_PTR ((GENERIC_PTR)0)#endif/* Define macros to access the `code' field of the rtx. */#ifdef SHORT_ENUM_BUG#define GET_CODE(RTX) ((enum rtx_code) ((RTX)->code))#define PUT_CODE(RTX, CODE) ((RTX)->code = ((short) (CODE)))#else#define GET_CODE(RTX) ((RTX)->code)#define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE))#endif#define GET_MODE(RTX) ((RTX)->mode)#define PUT_MODE(RTX, MODE) ((RTX)->mode = (MODE))#define RTX_INTEGRATED_P(RTX) ((RTX)->integrated)#define RTX_UNCHANGING_P(RTX) ((RTX)->unchanging)/* RTL vector. These appear inside RTX's when there is a need for a variable number of things. The principle use is inside PARALLEL expressions. */typedef struct rtvec_def{ unsigned num_elem; /* number of elements */ rtunion elem[1];} *rtvec;#define NULL_RTVEC (rtvec) 0#define GET_NUM_ELEM(RTVEC) ((RTVEC)->num_elem)#define PUT_NUM_ELEM(RTVEC, NUM) ((RTVEC)->num_elem = (unsigned) NUM)#define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[(I)].rtx)/* 1 if X is a REG. */#define REG_P(X) (GET_CODE (X) == REG)/* 1 if X is a constant value that is an integer. */#define CONSTANT_P(X) \ (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE \ || GET_CODE (X) == CONST || GET_CODE (X) == HIGH)/* General accessor macros for accessing the fields of an rtx. */#define XEXP(RTX, N) ((RTX)->fld[N].rtx)#define XINT(RTX, N) ((RTX)->fld[N].rtint)#define XWINT(RTX, N) ((RTX)->fld[N].rtwint)#define XSTR(RTX, N) ((RTX)->fld[N].rtstr)#define XVEC(RTX, N) ((RTX)->fld[N].rtvec)#define XVECLEN(RTX, N) ((RTX)->fld[N].rtvec->num_elem)#define XVECEXP(RTX,N,M)((RTX)->fld[N].rtvec->elem[M].rtx)/* ACCESS MACROS for particular fields of insns. *//* Holds a unique number for each insn. These are not necessarily sequentially increasing. */#define INSN_UID(INSN) ((INSN)->fld[0].rtint)/* Chain insns together in sequence. */#define PREV_INSN(INSN) ((INSN)->fld[1].rtx)#define NEXT_INSN(INSN) ((INSN)->fld[2].rtx)/* The body of an insn. */#define PATTERN(INSN) ((INSN)->fld[3].rtx)/* Code number of instruction, from when it was recognized. -1 means this instruction has not been recognized yet. */#define INSN_CODE(INSN) ((INSN)->fld[4].rtint)/* Set up in flow.c; empty before then. Holds a chain of INSN_LIST rtx's whose first operands point at previous insns with direct data-flow connections to this one. That means that those insns set variables whose next use is in this insn. They are always in the same basic block as this insn. */#define LOG_LINKS(INSN) ((INSN)->fld[5].rtx)/* 1 if insn has been deleted. */#define INSN_DELETED_P(INSN) ((INSN)->volatil)/* 1 if insn is a call to a const function. */#define CONST_CALL_P(INSN) ((INSN)->unchanging)/* 1 if insn is a branch that should not unconditionally execute its delay slots, i.e., it is an annulled branch. */#define INSN_ANNULLED_BRANCH_P(INSN) ((INSN)->unchanging)/* 1 if insn is in a delay slot and is from the target of the branch. If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be executed if the branch is taken. For annulled branches with this bit clear, the insn should be executed only if the branch is not taken. */#define INSN_FROM_TARGET_P(INSN) ((INSN)->in_struct)/* Holds a list of notes on what this insn does to various REGs. It is a chain of EXPR_LIST rtx's, where the second operand is the chain pointer and the first operand is the REG being described. The mode field of the EXPR_LIST contains not a real machine mode but a value that says what this note says about the REG: REG_DEAD means that the value in REG dies in this insn (i.e., it is not needed past this insn). If REG is set in this insn, the REG_DEAD note may, but need not, be omitted. REG_INC means that the REG is autoincremented or autodecremented. REG_EQUIV describes the insn as a whole; it says that the insn sets a register to a constant value or to be equivalent to a memory address. If the register is spilled to the stack then the constant value should be substituted for it. The contents of the REG_EQUIV is the constant value or memory address, which may be different from the source of the SET although it has the same value. REG_EQUAL is like REG_EQUIV except that the destination is only momentarily equal to the specified rtx. Therefore, it cannot be used for substitution; but it can be used for cse. REG_RETVAL means that this insn copies the return-value of a library call out of the hard reg for return values. This note is actually an INSN_LIST and it points to the first insn involved in setting up arguments for the call. flow.c uses this to delete the entire library call when its result is dead. REG_LIBCALL is the inverse of REG_RETVAL: it goes on the first insn of the library call and points at the one that has the REG_RETVAL. REG_WAS_0 says that the register set in this insn held 0 before the insn. The contents of the note is the insn that stored the 0. If that insn is deleted or patched to a NOTE, the REG_WAS_0 is inoperative. The REG_WAS_0 note is actually an INSN_LIST, not an EXPR_LIST. REG_NONNEG means that the register is always nonnegative during the containing loop. This is used in branches so that decrement and branch instructions terminating on zero can be matched. There must be an insn pattern in the md file named `decrement_and_branch_until_zero' or else this will never be added to any instructions. REG_NO_CONFLICT means there is no conflict *after this insn* between the register in the note and the destination of this insn. REG_UNUSED identifies a register set in this insn and never used.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -