1132718Skan/* Register Transfer Language (RTL) definitions for GCC 2169689Skan Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3169689Skan 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 2118334Speter 2290075Sobrien#ifndef GCC_RTL_H 2390075Sobrien#define GCC_RTL_H 2418334Speter 25223262Sbenl#include <sys/param.h> 26223262Sbenl#ifndef __PAST_END 27223262Sbenl# define __PAST_END(array, offset) (((typeof(*(array)) *)(array))[offset]) 28223262Sbenl#endif 29223262Sbenl 30169689Skan#include "statistics.h" 3118334Speter#include "machmode.h" 32132718Skan#include "input.h" 33169689Skan#include "real.h" 34169689Skan#include "vec.h" 3518334Speter 3618334Speter#undef FFS /* Some systems predefine this symbol; don't let it interfere. */ 3718334Speter#undef FLOAT /* Likewise. */ 3818334Speter#undef ABS /* Likewise. */ 3918334Speter#undef PC /* Likewise. */ 4018334Speter 4190075Sobrien/* Value used by some passes to "recognize" noop moves as valid 4290075Sobrien instructions. */ 4390075Sobrien#define NOOP_MOVE_INSN_CODE INT_MAX 4418334Speter 4518334Speter/* Register Transfer Language EXPRESSIONS CODES */ 4618334Speter 4718334Speter#define RTX_CODE enum rtx_code 4818334Speterenum rtx_code { 4918334Speter 5018334Speter#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM , 5118334Speter#include "rtl.def" /* rtl expressions are documented here */ 5218334Speter#undef DEF_RTL_EXPR 5318334Speter 5418334Speter LAST_AND_UNUSED_RTX_CODE}; /* A convenient way to get a value for 5518334Speter NUM_RTX_CODE. 5618334Speter Assumes default enum value assignment. */ 5718334Speter 5890075Sobrien#define NUM_RTX_CODE ((int) LAST_AND_UNUSED_RTX_CODE) 5918334Speter /* The cast here, saves many elsewhere. */ 6018334Speter 61169689Skan/* Register Transfer Language EXPRESSIONS CODE CLASSES */ 62169689Skan 63169689Skanenum rtx_class { 64169689Skan /* We check bit 0-1 of some rtx class codes in the predicates below. */ 65169689Skan 66169689Skan /* Bit 0 = comparison if 0, arithmetic is 1 67169689Skan Bit 1 = 1 if commutative. */ 68169689Skan RTX_COMPARE, /* 0 */ 69169689Skan RTX_COMM_COMPARE, 70169689Skan RTX_BIN_ARITH, 71169689Skan RTX_COMM_ARITH, 72169689Skan 73169689Skan /* Must follow the four preceding values. */ 74169689Skan RTX_UNARY, /* 4 */ 75169689Skan 76169689Skan RTX_EXTRA, 77169689Skan RTX_MATCH, 78169689Skan RTX_INSN, 79169689Skan 80169689Skan /* Bit 0 = 1 if constant. */ 81169689Skan RTX_OBJ, /* 8 */ 82169689Skan RTX_CONST_OBJ, 83169689Skan 84169689Skan RTX_TERNARY, 85169689Skan RTX_BITFIELD_OPS, 86169689Skan RTX_AUTOINC 87169689Skan}; 88169689Skan 89169689Skan#define RTX_OBJ_MASK (~1) 90169689Skan#define RTX_OBJ_RESULT (RTX_OBJ & RTX_OBJ_MASK) 91169689Skan#define RTX_COMPARE_MASK (~1) 92169689Skan#define RTX_COMPARE_RESULT (RTX_COMPARE & RTX_COMPARE_MASK) 93169689Skan#define RTX_ARITHMETIC_MASK (~1) 94169689Skan#define RTX_ARITHMETIC_RESULT (RTX_COMM_ARITH & RTX_ARITHMETIC_MASK) 95169689Skan#define RTX_BINARY_MASK (~3) 96169689Skan#define RTX_BINARY_RESULT (RTX_COMPARE & RTX_BINARY_MASK) 97169689Skan#define RTX_COMMUTATIVE_MASK (~2) 98169689Skan#define RTX_COMMUTATIVE_RESULT (RTX_COMM_COMPARE & RTX_COMMUTATIVE_MASK) 99169689Skan#define RTX_NON_COMMUTATIVE_RESULT (RTX_COMPARE & RTX_COMMUTATIVE_MASK) 100169689Skan 10190075Sobrienextern const unsigned char rtx_length[NUM_RTX_CODE]; 10250397Sobrien#define GET_RTX_LENGTH(CODE) (rtx_length[(int) (CODE)]) 10318334Speter 10490075Sobrienextern const char * const rtx_name[NUM_RTX_CODE]; 10550397Sobrien#define GET_RTX_NAME(CODE) (rtx_name[(int) (CODE)]) 10618334Speter 10790075Sobrienextern const char * const rtx_format[NUM_RTX_CODE]; 10850397Sobrien#define GET_RTX_FORMAT(CODE) (rtx_format[(int) (CODE)]) 10918334Speter 110169689Skanextern const enum rtx_class rtx_class[NUM_RTX_CODE]; 11150397Sobrien#define GET_RTX_CLASS(CODE) (rtx_class[(int) (CODE)]) 112117395Skan 113169689Skanextern const unsigned char rtx_code_size[NUM_RTX_CODE]; 114117395Skanextern const unsigned char rtx_next[NUM_RTX_CODE]; 11518334Speter 11650397Sobrien/* The flags and bitfields of an ADDR_DIFF_VEC. BASE is the base label 11750397Sobrien relative to which the offsets are calculated, as explained in rtl.def. */ 11850397Sobrientypedef struct 11950397Sobrien{ 12050397Sobrien /* Set at the start of shorten_branches - ONLY WHEN OPTIMIZING - : */ 12150397Sobrien unsigned min_align: 8; 12250397Sobrien /* Flags: */ 12350397Sobrien unsigned base_after_vec: 1; /* BASE is after the ADDR_DIFF_VEC. */ 12490075Sobrien unsigned min_after_vec: 1; /* minimum address target label is 12590075Sobrien after the ADDR_DIFF_VEC. */ 12690075Sobrien unsigned max_after_vec: 1; /* maximum address target label is 12790075Sobrien after the ADDR_DIFF_VEC. */ 12890075Sobrien unsigned min_after_base: 1; /* minimum address target label is 12990075Sobrien after BASE. */ 13090075Sobrien unsigned max_after_base: 1; /* maximum address target label is 13190075Sobrien after BASE. */ 13250397Sobrien /* Set by the actual branch shortening process - ONLY WHEN OPTIMIZING - : */ 13350397Sobrien unsigned offset_unsigned: 1; /* offsets have to be treated as unsigned. */ 13450397Sobrien unsigned : 2; 13550397Sobrien unsigned scale : 8; 13650397Sobrien} addr_diff_vec_flags; 13750397Sobrien 13890075Sobrien/* Structure used to describe the attributes of a MEM. These are hashed 13990075Sobrien so MEMs that the same attributes share a data structure. This means 14090075Sobrien they cannot be modified in place. If any element is nonzero, it means 14190075Sobrien the value of the corresponding attribute is unknown. */ 142117395Skan/* ALIGN and SIZE are the alignment and size of the MEM itself, 143117395Skan while EXPR can describe a larger underlying object, which might have a 144117395Skan stricter alignment; OFFSET is the offset of the MEM within that object. */ 145117395Skantypedef struct mem_attrs GTY(()) 14690075Sobrien{ 14790075Sobrien HOST_WIDE_INT alias; /* Memory alias set. */ 14890075Sobrien tree expr; /* expr corresponding to MEM. */ 14990075Sobrien rtx offset; /* Offset from start of DECL, as CONST_INT. */ 15090075Sobrien rtx size; /* Size in bytes, as a CONST_INT. */ 15190075Sobrien unsigned int align; /* Alignment of MEM in bits. */ 15290075Sobrien} mem_attrs; 15390075Sobrien 154132718Skan/* Structure used to describe the attributes of a REG in similar way as 155132718Skan mem_attrs does for MEM above. */ 156132718Skan 157132718Skantypedef struct reg_attrs GTY(()) 158132718Skan{ 159132718Skan tree decl; /* decl corresponding to REG. */ 160132718Skan HOST_WIDE_INT offset; /* Offset from start of DECL. */ 161132718Skan} reg_attrs; 162132718Skan 16318334Speter/* Common union for an element of an rtx. */ 16418334Speter 165117395Skanunion rtunion_def 16618334Speter{ 167169689Skan int rt_int; 168169689Skan unsigned int rt_uint; 169169689Skan const char *rt_str; 170169689Skan rtx rt_rtx; 171169689Skan rtvec rt_rtvec; 172169689Skan enum machine_mode rt_type; 17350397Sobrien addr_diff_vec_flags rt_addr_diff_vec_flags; 17490075Sobrien struct cselib_val_struct *rt_cselib; 175169689Skan struct bitmap_head_def *rt_bit; 176169689Skan tree rt_tree; 177169689Skan struct basic_block_def *rt_bb; 178169689Skan mem_attrs *rt_mem; 179169689Skan reg_attrs *rt_reg; 180169689Skan struct constant_descriptor_rtx *rt_constant; 181117395Skan}; 182117395Skantypedef union rtunion_def rtunion; 18318334Speter 184169689Skan/* This structure remembers the position of a SYMBOL_REF within an 185169689Skan object_block structure. A SYMBOL_REF only provides this information 186169689Skan if SYMBOL_REF_HAS_BLOCK_INFO_P is true. */ 187169689Skanstruct block_symbol GTY(()) { 188169689Skan /* The usual SYMBOL_REF fields. */ 189169689Skan rtunion GTY ((skip)) fld[3]; 190169689Skan 191169689Skan /* The block that contains this object. */ 192169689Skan struct object_block *block; 193169689Skan 194169689Skan /* The offset of this object from the start of its block. It is negative 195169689Skan if the symbol has not yet been assigned an offset. */ 196169689Skan HOST_WIDE_INT offset; 197169689Skan}; 198169689Skan 199169689SkanDEF_VEC_P(rtx); 200169689SkanDEF_VEC_ALLOC_P(rtx,heap); 201169689SkanDEF_VEC_ALLOC_P(rtx,gc); 202169689Skan 203169689Skan/* Describes a group of objects that are to be placed together in such 204169689Skan a way that their relative positions are known. */ 205169689Skanstruct object_block GTY(()) 206169689Skan{ 207169689Skan /* The section in which these objects should be placed. */ 208169689Skan section *sect; 209169689Skan 210169689Skan /* The alignment of the first object, measured in bits. */ 211169689Skan unsigned int alignment; 212169689Skan 213169689Skan /* The total size of the objects, measured in bytes. */ 214169689Skan HOST_WIDE_INT size; 215169689Skan 216169689Skan /* The SYMBOL_REFs for each object. The vector is sorted in 217169689Skan order of increasing offset and the following conditions will 218169689Skan hold for each element X: 219169689Skan 220169689Skan SYMBOL_REF_HAS_BLOCK_INFO_P (X) 221169689Skan !SYMBOL_REF_ANCHOR_P (X) 222169689Skan SYMBOL_REF_BLOCK (X) == [address of this structure] 223169689Skan SYMBOL_REF_BLOCK_OFFSET (X) >= 0. */ 224169689Skan VEC(rtx,gc) *objects; 225169689Skan 226169689Skan /* All the anchor SYMBOL_REFs used to address these objects, sorted 227169689Skan in order of increasing offset, and then increasing TLS model. 228169689Skan The following conditions will hold for each element X in this vector: 229169689Skan 230169689Skan SYMBOL_REF_HAS_BLOCK_INFO_P (X) 231169689Skan SYMBOL_REF_ANCHOR_P (X) 232169689Skan SYMBOL_REF_BLOCK (X) == [address of this structure] 233169689Skan SYMBOL_REF_BLOCK_OFFSET (X) >= 0. */ 234169689Skan VEC(rtx,gc) *anchors; 235169689Skan}; 236169689Skan 23718334Speter/* RTL expression ("rtx"). */ 23818334Speter 239132718Skanstruct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"), 240117395Skan chain_prev ("RTX_PREV (&%h)"))) 24118334Speter{ 24218334Speter /* The kind of expression this is. */ 24390075Sobrien ENUM_BITFIELD(rtx_code) code: 16; 24490075Sobrien 24518334Speter /* The kind of value the expression has. */ 24690075Sobrien ENUM_BITFIELD(machine_mode) mode : 8; 24790075Sobrien 248117395Skan /* 1 in a MEM if we should keep the alias set for this mem unchanged 249117395Skan when we access a component. 250117395Skan 1 in a CALL_INSN if it is a sibling call. 251117395Skan 1 in a SET that is for a return. 252117395Skan In a CODE_LABEL, part of the two-bit alternate entry field. */ 25318334Speter unsigned int jump : 1; 254117395Skan /* In a CODE_LABEL, part of the two-bit alternate entry field. 255117395Skan 1 in a MEM if it cannot trap. */ 25618334Speter unsigned int call : 1; 257117395Skan /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere. 258117395Skan 1 in a SUBREG if it references an unsigned object whose mode has been 259117395Skan from a promoted to a wider mode. 26018334Speter 1 in a SYMBOL_REF if it addresses something in the per-function 26118334Speter constants pool. 262117395Skan 1 in a CALL_INSN, NOTE, or EXPR_LIST for a const or pure call. 263117395Skan 1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch. */ 26418334Speter unsigned int unchanging : 1; 265117395Skan /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile. 266117395Skan 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE 267117395Skan if it has been deleted. 268117395Skan 1 in a REG expression if corresponds to a variable declared by the user, 26918334Speter 0 for an internally generated temporary. 270117395Skan 1 in a SUBREG with a negative value. 271117395Skan 1 in a LABEL_REF or in a REG_LABEL note for a non-local label. 272117395Skan In a SYMBOL_REF, this flag is used for machine-specific purposes. */ 27318334Speter unsigned int volatil : 1; 27450397Sobrien /* 1 in a MEM referring to a field of an aggregate. 27518334Speter 0 if the MEM was a variable or the result of a * operator in C; 27618334Speter 1 if it was the result of a . or -> operator (on a struct) in C. 27718334Speter 1 in a REG if the register is used only in exit code a loop. 27890075Sobrien 1 in a SUBREG expression if was generated from a variable with a 27918334Speter promoted mode. 28018334Speter 1 in a CODE_LABEL if the label is used for nonlocal gotos 28118334Speter and must not be deleted even if its count is zero. 282117395Skan 1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled 28318334Speter together with the preceding insn. Valid only within sched. 28418334Speter 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and 28518334Speter from the target of a branch. Valid from reorg until end of compilation; 286169689Skan cleared before used. */ 28718334Speter unsigned int in_struct : 1; 288117395Skan /* At the end of RTL generation, 1 if this rtx is used. This is used for 289117395Skan copying shared structure. See `unshare_all_rtl'. 29090075Sobrien In a REG, this is not needed for that purpose, and used instead 29118334Speter in `leaf_renumber_regs_insn'. 292117395Skan 1 in a SYMBOL_REF, means that emit_library_call 29318334Speter has used it as the function. */ 29418334Speter unsigned int used : 1; 29552284Sobrien /* 1 in an INSN or a SET if this rtx is related to the call frame, 29652284Sobrien either changing how we compute the frame address or saving and 29790075Sobrien restoring registers in the prologue and epilogue. 298169689Skan 1 in a REG or MEM if it is a pointer. 29990075Sobrien 1 in a SYMBOL_REF if it addresses something in the per-function 30090075Sobrien constant string pool. */ 30150397Sobrien unsigned frame_related : 1; 302169689Skan /* 1 in a REG or PARALLEL that is the current function's return value. 303169689Skan 1 in a MEM if it refers to a scalar. 304169689Skan 1 in a SYMBOL_REF for a weak symbol. */ 305169689Skan unsigned return_val : 1; 30690075Sobrien 30718334Speter /* The first element of the operands of this rtx. 30818334Speter The number of operands and their types are controlled 30918334Speter by the `code' field, according to rtl.def. */ 310132718Skan union u { 311132718Skan rtunion fld[1]; 312132718Skan HOST_WIDE_INT hwint[1]; 313169689Skan struct block_symbol block_sym; 314169689Skan struct real_value rv; 315132718Skan } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u; 31690075Sobrien}; 31718334Speter 318132718Skan/* The size in bytes of an rtx header (code, mode and flags). */ 319132718Skan#define RTX_HDR_SIZE offsetof (struct rtx_def, u) 320132718Skan 321132718Skan/* The size in bytes of an rtx with code CODE. */ 322169689Skan#define RTX_CODE_SIZE(CODE) rtx_code_size[CODE] 323132718Skan 32418334Speter#define NULL_RTX (rtx) 0 32518334Speter 326117395Skan/* The "next" and "previous" RTX, relative to this one. */ 327117395Skan 328117395Skan#define RTX_NEXT(X) (rtx_next[GET_CODE (X)] == 0 ? NULL \ 329117395Skan : *(rtx *)(((char *)X) + rtx_next[GET_CODE (X)])) 330117395Skan 331117395Skan/* FIXME: the "NEXT_INSN (PREV_INSN (X)) == X" condition shouldn't be needed. 332117395Skan */ 333169689Skan#define RTX_PREV(X) ((INSN_P (X) \ 334169689Skan || NOTE_P (X) \ 335169689Skan || BARRIER_P (X) \ 336169689Skan || LABEL_P (X)) \ 337117395Skan && PREV_INSN (X) != NULL \ 338117395Skan && NEXT_INSN (PREV_INSN (X)) == X \ 339117395Skan ? PREV_INSN (X) : NULL) 340117395Skan 34118334Speter/* Define macros to access the `code' field of the rtx. */ 34218334Speter 34390075Sobrien#define GET_CODE(RTX) ((enum rtx_code) (RTX)->code) 344132718Skan#define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE)) 34518334Speter 34690075Sobrien#define GET_MODE(RTX) ((enum machine_mode) (RTX)->mode) 347132718Skan#define PUT_MODE(RTX, MODE) ((RTX)->mode = (MODE)) 34818334Speter 34918334Speter/* RTL vector. These appear inside RTX's when there is a need 35018334Speter for a variable number of things. The principle use is inside 35118334Speter PARALLEL expressions. */ 35218334Speter 353117395Skanstruct rtvec_def GTY(()) { 35450397Sobrien int num_elem; /* number of elements */ 355117395Skan rtx GTY ((length ("%h.num_elem"))) elem[1]; 35690075Sobrien}; 35718334Speter 35818334Speter#define NULL_RTVEC (rtvec) 0 35918334Speter 36018334Speter#define GET_NUM_ELEM(RTVEC) ((RTVEC)->num_elem) 36150397Sobrien#define PUT_NUM_ELEM(RTVEC, NUM) ((RTVEC)->num_elem = (NUM)) 36218334Speter 363169689Skan/* Predicate yielding nonzero iff X is an rtx for a register. */ 36490075Sobrien#define REG_P(X) (GET_CODE (X) == REG) 36518334Speter 366169689Skan/* Predicate yielding nonzero iff X is an rtx for a memory location. */ 367169689Skan#define MEM_P(X) (GET_CODE (X) == MEM) 368169689Skan 369169689Skan/* Predicate yielding nonzero iff X is an rtx for a constant integer. */ 370169689Skan#define CONST_INT_P(X) (GET_CODE (X) == CONST_INT) 371169689Skan 37290075Sobrien/* Predicate yielding nonzero iff X is a label insn. */ 37390075Sobrien#define LABEL_P(X) (GET_CODE (X) == CODE_LABEL) 37418334Speter 37590075Sobrien/* Predicate yielding nonzero iff X is a jump insn. */ 37690075Sobrien#define JUMP_P(X) (GET_CODE (X) == JUMP_INSN) 37718334Speter 378169689Skan/* Predicate yielding nonzero iff X is a call insn. */ 379169689Skan#define CALL_P(X) (GET_CODE (X) == CALL_INSN) 380169689Skan 381169689Skan/* Predicate yielding nonzero iff X is an insn that cannot jump. */ 382169689Skan#define NONJUMP_INSN_P(X) (GET_CODE (X) == INSN) 383169689Skan 384169689Skan/* Predicate yielding nonzero iff X is a real insn. */ 385169689Skan#define INSN_P(X) \ 386169689Skan (NONJUMP_INSN_P (X) || JUMP_P (X) || CALL_P (X)) 387169689Skan 38890075Sobrien/* Predicate yielding nonzero iff X is a note insn. */ 38990075Sobrien#define NOTE_P(X) (GET_CODE (X) == NOTE) 39090075Sobrien 39190075Sobrien/* Predicate yielding nonzero iff X is a barrier insn. */ 39290075Sobrien#define BARRIER_P(X) (GET_CODE (X) == BARRIER) 39390075Sobrien 39490075Sobrien/* Predicate yielding nonzero iff X is a data for a jump table. */ 39590075Sobrien#define JUMP_TABLE_DATA_P(INSN) \ 39690075Sobrien (JUMP_P (INSN) && (GET_CODE (PATTERN (INSN)) == ADDR_VEC || \ 39790075Sobrien GET_CODE (PATTERN (INSN)) == ADDR_DIFF_VEC)) 39890075Sobrien 399169689Skan/* 1 if X is a unary operator. */ 400169689Skan 401169689Skan#define UNARY_P(X) \ 402169689Skan (GET_RTX_CLASS (GET_CODE (X)) == RTX_UNARY) 403169689Skan 404169689Skan/* 1 if X is a binary operator. */ 405169689Skan 406169689Skan#define BINARY_P(X) \ 407169689Skan ((GET_RTX_CLASS (GET_CODE (X)) & RTX_BINARY_MASK) == RTX_BINARY_RESULT) 408169689Skan 409169689Skan/* 1 if X is an arithmetic operator. */ 410169689Skan 411169689Skan#define ARITHMETIC_P(X) \ 412169689Skan ((GET_RTX_CLASS (GET_CODE (X)) & RTX_ARITHMETIC_MASK) \ 413169689Skan == RTX_ARITHMETIC_RESULT) 414169689Skan 415169689Skan/* 1 if X is an arithmetic operator. */ 416169689Skan 417169689Skan#define COMMUTATIVE_ARITH_P(X) \ 418169689Skan (GET_RTX_CLASS (GET_CODE (X)) == RTX_COMM_ARITH) 419169689Skan 420169689Skan/* 1 if X is a commutative arithmetic operator or a comparison operator. 421169689Skan These two are sometimes selected together because it is possible to 422169689Skan swap the two operands. */ 423169689Skan 424169689Skan#define SWAPPABLE_OPERANDS_P(X) \ 425169689Skan ((1 << GET_RTX_CLASS (GET_CODE (X))) \ 426169689Skan & ((1 << RTX_COMM_ARITH) | (1 << RTX_COMM_COMPARE) \ 427169689Skan | (1 << RTX_COMPARE))) 428169689Skan 429169689Skan/* 1 if X is a non-commutative operator. */ 430169689Skan 431169689Skan#define NON_COMMUTATIVE_P(X) \ 432169689Skan ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMMUTATIVE_MASK) \ 433169689Skan == RTX_NON_COMMUTATIVE_RESULT) 434169689Skan 435169689Skan/* 1 if X is a commutative operator on integers. */ 436169689Skan 437169689Skan#define COMMUTATIVE_P(X) \ 438169689Skan ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMMUTATIVE_MASK) \ 439169689Skan == RTX_COMMUTATIVE_RESULT) 440169689Skan 441169689Skan/* 1 if X is a relational operator. */ 442169689Skan 443169689Skan#define COMPARISON_P(X) \ 444169689Skan ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMPARE_MASK) == RTX_COMPARE_RESULT) 445169689Skan 44618334Speter/* 1 if X is a constant value that is an integer. */ 44718334Speter 44818334Speter#define CONSTANT_P(X) \ 449169689Skan (GET_RTX_CLASS (GET_CODE (X)) == RTX_CONST_OBJ) 45018334Speter 451169689Skan/* 1 if X can be used to represent an object. */ 452169689Skan#define OBJECT_P(X) \ 453169689Skan ((GET_RTX_CLASS (GET_CODE (X)) & RTX_OBJ_MASK) == RTX_OBJ_RESULT) 454169689Skan 45518334Speter/* General accessor macros for accessing the fields of an rtx. */ 45618334Speter 45790075Sobrien#if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) 45890075Sobrien/* The bit with a star outside the statement expr and an & inside is 45990075Sobrien so that N can be evaluated only once. */ 46090075Sobrien#define RTL_CHECK1(RTX, N, C1) __extension__ \ 461117395Skan(*({ rtx const _rtx = (RTX); const int _n = (N); \ 462117395Skan const enum rtx_code _code = GET_CODE (_rtx); \ 46390075Sobrien if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \ 46490075Sobrien rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \ 46590075Sobrien __FUNCTION__); \ 46690075Sobrien if (GET_RTX_FORMAT(_code)[_n] != C1) \ 46790075Sobrien rtl_check_failed_type1 (_rtx, _n, C1, __FILE__, __LINE__, \ 46890075Sobrien __FUNCTION__); \ 469132718Skan &_rtx->u.fld[_n]; })) 47050397Sobrien 47190075Sobrien#define RTL_CHECK2(RTX, N, C1, C2) __extension__ \ 472117395Skan(*({ rtx const _rtx = (RTX); const int _n = (N); \ 473117395Skan const enum rtx_code _code = GET_CODE (_rtx); \ 47490075Sobrien if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \ 47590075Sobrien rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \ 47690075Sobrien __FUNCTION__); \ 47790075Sobrien if (GET_RTX_FORMAT(_code)[_n] != C1 \ 47890075Sobrien && GET_RTX_FORMAT(_code)[_n] != C2) \ 47990075Sobrien rtl_check_failed_type2 (_rtx, _n, C1, C2, __FILE__, __LINE__, \ 48090075Sobrien __FUNCTION__); \ 481132718Skan &_rtx->u.fld[_n]; })) 48290075Sobrien 48390075Sobrien#define RTL_CHECKC1(RTX, N, C) __extension__ \ 484117395Skan(*({ rtx const _rtx = (RTX); const int _n = (N); \ 48590075Sobrien if (GET_CODE (_rtx) != (C)) \ 48690075Sobrien rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__, \ 48790075Sobrien __FUNCTION__); \ 488132718Skan &_rtx->u.fld[_n]; })) 48990075Sobrien 49090075Sobrien#define RTL_CHECKC2(RTX, N, C1, C2) __extension__ \ 491117395Skan(*({ rtx const _rtx = (RTX); const int _n = (N); \ 492117395Skan const enum rtx_code _code = GET_CODE (_rtx); \ 49390075Sobrien if (_code != (C1) && _code != (C2)) \ 49490075Sobrien rtl_check_failed_code2 (_rtx, (C1), (C2), __FILE__, __LINE__, \ 49590075Sobrien __FUNCTION__); \ 496132718Skan &_rtx->u.fld[_n]; })) 49790075Sobrien 49890075Sobrien#define RTVEC_ELT(RTVEC, I) __extension__ \ 499117395Skan(*({ rtvec const _rtvec = (RTVEC); const int _i = (I); \ 50090075Sobrien if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec)) \ 50190075Sobrien rtvec_check_failed_bounds (_rtvec, _i, __FILE__, __LINE__, \ 50290075Sobrien __FUNCTION__); \ 50390075Sobrien &_rtvec->elem[_i]; })) 50490075Sobrien 505132718Skan#define XWINT(RTX, N) __extension__ \ 506132718Skan(*({ rtx const _rtx = (RTX); const int _n = (N); \ 507132718Skan const enum rtx_code _code = GET_CODE (_rtx); \ 508132718Skan if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \ 509132718Skan rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \ 510132718Skan __FUNCTION__); \ 511132718Skan if (GET_RTX_FORMAT(_code)[_n] != 'w') \ 512132718Skan rtl_check_failed_type1 (_rtx, _n, 'w', __FILE__, __LINE__, \ 513132718Skan __FUNCTION__); \ 514132718Skan &_rtx->u.hwint[_n]; })) 515132718Skan 516132718Skan#define XCWINT(RTX, N, C) __extension__ \ 517132718Skan(*({ rtx const _rtx = (RTX); \ 518132718Skan if (GET_CODE (_rtx) != (C)) \ 519132718Skan rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__, \ 520132718Skan __FUNCTION__); \ 521132718Skan &_rtx->u.hwint[N]; })) 522132718Skan 523169689Skan#define XCMWINT(RTX, N, C, M) __extension__ \ 524169689Skan(*({ rtx const _rtx = (RTX); \ 525169689Skan if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) != (M)) \ 526169689Skan rtl_check_failed_code_mode (_rtx, (C), (M), false, __FILE__, \ 527169689Skan __LINE__, __FUNCTION__); \ 528169689Skan &_rtx->u.hwint[N]; })) 529169689Skan 530169689Skan#define XCNMPRV(RTX, C, M) __extension__ \ 531169689Skan({ rtx const _rtx = (RTX); \ 532169689Skan if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) == (M)) \ 533169689Skan rtl_check_failed_code_mode (_rtx, (C), (M), true, __FILE__, \ 534169689Skan __LINE__, __FUNCTION__); \ 535169689Skan &_rtx->u.rv; }) 536169689Skan 537169689Skan#define BLOCK_SYMBOL_CHECK(RTX) __extension__ \ 538169689Skan({ rtx const _symbol = (RTX); \ 539169689Skan unsigned int flags = RTL_CHECKC1 (_symbol, 1, SYMBOL_REF).rt_int; \ 540169689Skan if ((flags & SYMBOL_FLAG_HAS_BLOCK_INFO) == 0) \ 541169689Skan rtl_check_failed_block_symbol (__FILE__, __LINE__, \ 542169689Skan __FUNCTION__); \ 543169689Skan &_symbol->u.block_sym; }) 544169689Skan 545132718Skanextern void rtl_check_failed_bounds (rtx, int, const char *, int, 546132718Skan const char *) 54790075Sobrien ATTRIBUTE_NORETURN; 548132718Skanextern void rtl_check_failed_type1 (rtx, int, int, const char *, int, 549132718Skan const char *) 55090075Sobrien ATTRIBUTE_NORETURN; 551132718Skanextern void rtl_check_failed_type2 (rtx, int, int, int, const char *, 552132718Skan int, const char *) 55390075Sobrien ATTRIBUTE_NORETURN; 554132718Skanextern void rtl_check_failed_code1 (rtx, enum rtx_code, const char *, 555132718Skan int, const char *) 55690075Sobrien ATTRIBUTE_NORETURN; 557132718Skanextern void rtl_check_failed_code2 (rtx, enum rtx_code, enum rtx_code, 558132718Skan const char *, int, const char *) 55990075Sobrien ATTRIBUTE_NORETURN; 560169689Skanextern void rtl_check_failed_code_mode (rtx, enum rtx_code, enum machine_mode, 561169689Skan bool, const char *, int, const char *) 562169689Skan ATTRIBUTE_NORETURN; 563169689Skanextern void rtl_check_failed_block_symbol (const char *, int, const char *) 564169689Skan ATTRIBUTE_NORETURN; 565132718Skanextern void rtvec_check_failed_bounds (rtvec, int, const char *, int, 566132718Skan const char *) 56790075Sobrien ATTRIBUTE_NORETURN; 56890075Sobrien 56990075Sobrien#else /* not ENABLE_RTL_CHECKING */ 57090075Sobrien 571132718Skan#define RTL_CHECK1(RTX, N, C1) ((RTX)->u.fld[N]) 572132718Skan#define RTL_CHECK2(RTX, N, C1, C2) ((RTX)->u.fld[N]) 573223262Sbenl#define RTL_CHECKC1(RTX, N, C) __PAST_END((RTX)->u.fld, N) 574132718Skan#define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->u.fld[N]) 575223262Sbenl#define RTVEC_ELT(RTVEC, I) __PAST_END((RTVEC)->elem, I) 576132718Skan#define XWINT(RTX, N) ((RTX)->u.hwint[N]) 577132718Skan#define XCWINT(RTX, N, C) ((RTX)->u.hwint[N]) 578223262Sbenl#define XCMWINT(RTX, N, C, M) __PAST_END((RTX)->u.hwint, N) 579169689Skan#define XCNMWINT(RTX, N, C, M) ((RTX)->u.hwint[N]) 580169689Skan#define XCNMPRV(RTX, C, M) (&(RTX)->u.rv) 581169689Skan#define BLOCK_SYMBOL_CHECK(RTX) (&(RTX)->u.block_sym) 58290075Sobrien 58390075Sobrien#endif 58490075Sobrien 585117395Skan/* General accessor macros for accessing the flags of an rtx. */ 586117395Skan 587117395Skan/* Access an individual rtx flag, with no checking of any kind. */ 588117395Skan#define RTX_FLAG(RTX, FLAG) ((RTX)->FLAG) 589117395Skan 590117395Skan#if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION >= 2007) 591117395Skan#define RTL_FLAG_CHECK1(NAME, RTX, C1) __extension__ \ 592117395Skan({ rtx const _rtx = (RTX); \ 593117395Skan if (GET_CODE(_rtx) != C1) \ 594117395Skan rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \ 595132718Skan __FUNCTION__); \ 596117395Skan _rtx; }) 597117395Skan 598117395Skan#define RTL_FLAG_CHECK2(NAME, RTX, C1, C2) __extension__ \ 599117395Skan({ rtx const _rtx = (RTX); \ 600117395Skan if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2) \ 601117395Skan rtl_check_failed_flag (NAME,_rtx, __FILE__, __LINE__, \ 602132718Skan __FUNCTION__); \ 603117395Skan _rtx; }) 604117395Skan 605117395Skan#define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3) __extension__ \ 606117395Skan({ rtx const _rtx = (RTX); \ 607132718Skan if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \ 608117395Skan && GET_CODE(_rtx) != C3) \ 609117395Skan rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \ 610132718Skan __FUNCTION__); \ 611117395Skan _rtx; }) 612117395Skan 613117395Skan#define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4) __extension__ \ 614117395Skan({ rtx const _rtx = (RTX); \ 615132718Skan if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \ 616117395Skan && GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4) \ 617117395Skan rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \ 618132718Skan __FUNCTION__); \ 619117395Skan _rtx; }) 620117395Skan 621117395Skan#define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) __extension__ \ 622117395Skan({ rtx const _rtx = (RTX); \ 623132718Skan if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \ 624117395Skan && GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \ 625117395Skan && GET_CODE(_rtx) != C5) \ 626117395Skan rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \ 627132718Skan __FUNCTION__); \ 628117395Skan _rtx; }) 629117395Skan 630117395Skan#define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6) \ 631117395Skan __extension__ \ 632117395Skan({ rtx const _rtx = (RTX); \ 633132718Skan if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \ 634117395Skan && GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \ 635117395Skan && GET_CODE(_rtx) != C5 && GET_CODE(_rtx) != C6) \ 636117395Skan rtl_check_failed_flag (NAME,_rtx, __FILE__, __LINE__, \ 637132718Skan __FUNCTION__); \ 638117395Skan _rtx; }) 639117395Skan 640117395Skan#define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7) \ 641117395Skan __extension__ \ 642117395Skan({ rtx const _rtx = (RTX); \ 643132718Skan if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \ 644117395Skan && GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \ 645117395Skan && GET_CODE(_rtx) != C5 && GET_CODE(_rtx) != C6 \ 646117395Skan && GET_CODE(_rtx) != C7) \ 647117395Skan rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \ 648132718Skan __FUNCTION__); \ 649117395Skan _rtx; }) 650117395Skan 651117395Skan#define RTL_FLAG_CHECK8(NAME, RTX, C1, C2, C3, C4, C5, C6, C7, C8) \ 652117395Skan __extension__ \ 653117395Skan({ rtx const _rtx = (RTX); \ 654132718Skan if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \ 655117395Skan && GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \ 656117395Skan && GET_CODE(_rtx) != C5 && GET_CODE(_rtx) != C6 \ 657117395Skan && GET_CODE(_rtx) != C7 && GET_CODE(_rtx) != C8) \ 658117395Skan rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \ 659132718Skan __FUNCTION__); \ 660117395Skan _rtx; }) 661117395Skan 662132718Skanextern void rtl_check_failed_flag (const char *, rtx, const char *, 663132718Skan int, const char *) 664117395Skan ATTRIBUTE_NORETURN 665117395Skan ; 666117395Skan 667117395Skan#else /* not ENABLE_RTL_FLAG_CHECKING */ 668117395Skan 669117395Skan#define RTL_FLAG_CHECK1(NAME, RTX, C1) (RTX) 670117395Skan#define RTL_FLAG_CHECK2(NAME, RTX, C1, C2) (RTX) 671117395Skan#define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3) (RTX) 672117395Skan#define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4) (RTX) 673132718Skan#define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) (RTX) 674117395Skan#define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6) (RTX) 675117395Skan#define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7) (RTX) 676117395Skan#define RTL_FLAG_CHECK8(NAME, RTX, C1, C2, C3, C4, C5, C6, C7, C8) (RTX) 677117395Skan#endif 678117395Skan 679169689Skan#define XINT(RTX, N) (RTL_CHECK2 (RTX, N, 'i', 'n').rt_int) 680169689Skan#define XSTR(RTX, N) (RTL_CHECK2 (RTX, N, 's', 'S').rt_str) 681169689Skan#define XEXP(RTX, N) (RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx) 682169689Skan#define XVEC(RTX, N) (RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec) 683169689Skan#define XMODE(RTX, N) (RTL_CHECK1 (RTX, N, 'M').rt_type) 684169689Skan#define XBITMAP(RTX, N) (RTL_CHECK1 (RTX, N, 'b').rt_bit) 685169689Skan#define XTREE(RTX, N) (RTL_CHECK1 (RTX, N, 't').rt_tree) 686169689Skan#define XBBDEF(RTX, N) (RTL_CHECK1 (RTX, N, 'B').rt_bb) 687169689Skan#define XTMPL(RTX, N) (RTL_CHECK1 (RTX, N, 'T').rt_str) 688117395Skan 68990075Sobrien#define XVECEXP(RTX, N, M) RTVEC_ELT (XVEC (RTX, N), M) 69090075Sobrien#define XVECLEN(RTX, N) GET_NUM_ELEM (XVEC (RTX, N)) 69190075Sobrien 692132718Skan/* These are like XINT, etc. except that they expect a '0' field instead 69390075Sobrien of the normal type code. */ 69490075Sobrien 695169689Skan#define X0INT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_int) 696169689Skan#define X0UINT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_uint) 697169689Skan#define X0STR(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_str) 698169689Skan#define X0EXP(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_rtx) 699169689Skan#define X0VEC(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_rtvec) 700169689Skan#define X0MODE(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_type) 701169689Skan#define X0BITMAP(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_bit) 702169689Skan#define X0TREE(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_tree) 703169689Skan#define X0BBDEF(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_bb) 70490075Sobrien#define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags) 70590075Sobrien#define X0CSELIB(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_cselib) 706169689Skan#define X0MEMATTR(RTX, N) (RTL_CHECKC1 (RTX, N, MEM).rt_mem) 707169689Skan#define X0REGATTR(RTX, N) (RTL_CHECKC1 (RTX, N, REG).rt_reg) 708169689Skan#define X0CONSTANT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_constant) 70990075Sobrien 710132718Skan/* Access a '0' field with any type. */ 711132718Skan#define X0ANY(RTX, N) RTL_CHECK1 (RTX, N, '0') 712132718Skan 713169689Skan#define XCINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_int) 714169689Skan#define XCUINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_uint) 715169689Skan#define XCSTR(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_str) 716169689Skan#define XCEXP(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_rtx) 717169689Skan#define XCVEC(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_rtvec) 718169689Skan#define XCMODE(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_type) 719169689Skan#define XCBITMAP(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_bit) 720169689Skan#define XCTREE(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_tree) 721169689Skan#define XCBBDEF(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_bb) 72290075Sobrien#define XCCSELIB(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_cselib) 72390075Sobrien 72490075Sobrien#define XCVECEXP(RTX, N, M, C) RTVEC_ELT (XCVEC (RTX, N, C), M) 72590075Sobrien#define XCVECLEN(RTX, N, C) GET_NUM_ELEM (XCVEC (RTX, N, C)) 72690075Sobrien 727169689Skan#define XC2EXP(RTX, N, C1, C2) (RTL_CHECKC2 (RTX, N, C1, C2).rt_rtx) 72818334Speter 72918334Speter/* ACCESS MACROS for particular fields of insns. */ 73018334Speter 73118334Speter/* Holds a unique number for each insn. 73218334Speter These are not necessarily sequentially increasing. */ 73390075Sobrien#define INSN_UID(INSN) XINT (INSN, 0) 73418334Speter 73518334Speter/* Chain insns together in sequence. */ 73690075Sobrien#define PREV_INSN(INSN) XEXP (INSN, 1) 73790075Sobrien#define NEXT_INSN(INSN) XEXP (INSN, 2) 73818334Speter 739117395Skan#define BLOCK_FOR_INSN(INSN) XBBDEF (INSN, 3) 740132718Skan#define INSN_LOCATOR(INSN) XINT (INSN, 4) 74118334Speter/* The body of an insn. */ 742117395Skan#define PATTERN(INSN) XEXP (INSN, 5) 74318334Speter 74418334Speter/* Code number of instruction, from when it was recognized. 74518334Speter -1 means this instruction has not been recognized yet. */ 746117395Skan#define INSN_CODE(INSN) XINT (INSN, 6) 74718334Speter 74818334Speter/* Set up in flow.c; empty before then. 74918334Speter Holds a chain of INSN_LIST rtx's whose first operands point at 75018334Speter previous insns with direct data-flow connections to this one. 75118334Speter That means that those insns set variables whose next use is in this insn. 75218334Speter They are always in the same basic block as this insn. */ 753117395Skan#define LOG_LINKS(INSN) XEXP(INSN, 7) 75418334Speter 755117395Skan#define RTX_FRAME_RELATED_P(RTX) \ 756117395Skan (RTL_FLAG_CHECK5("RTX_FRAME_RELATED_P", (RTX), INSN, CALL_INSN, \ 757117395Skan JUMP_INSN, BARRIER, SET)->frame_related) 75818334Speter 759117395Skan/* 1 if RTX is an insn that has been deleted. */ 760117395Skan#define INSN_DELETED_P(RTX) \ 761117395Skan (RTL_FLAG_CHECK6("INSN_DELETED_P", (RTX), INSN, CALL_INSN, JUMP_INSN, \ 762117395Skan CODE_LABEL, BARRIER, NOTE)->volatil) 76318334Speter 764117395Skan/* 1 if RTX is a call to a const or pure function. */ 765117395Skan#define CONST_OR_PURE_CALL_P(RTX) \ 766117395Skan (RTL_FLAG_CHECK3("CONST_OR_PURE_CALL_P", (RTX), CALL_INSN, NOTE, \ 767117395Skan EXPR_LIST)->unchanging) 76890075Sobrien 769117395Skan/* 1 if RTX is a call_insn for a sibling call. */ 770117395Skan#define SIBLING_CALL_P(RTX) \ 771117395Skan (RTL_FLAG_CHECK1("SIBLING_CALL_P", (RTX), CALL_INSN)->jump) 77218334Speter 773117395Skan/* 1 if RTX is a jump_insn, call_insn, or insn that is an annulling branch. */ 774117395Skan#define INSN_ANNULLED_BRANCH_P(RTX) \ 775117395Skan (RTL_FLAG_CHECK3("INSN_ANNULLED_BRANCH_P", (RTX), JUMP_INSN, CALL_INSN, INSN)->unchanging) 77690075Sobrien 777117395Skan/* 1 if RTX is an insn in a delay slot and is from the target of the branch. 778117395Skan If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be 77918334Speter executed if the branch is taken. For annulled branches with this bit 78018334Speter clear, the insn should be executed only if the branch is not taken. */ 781117395Skan#define INSN_FROM_TARGET_P(RTX) \ 782117395Skan (RTL_FLAG_CHECK3("INSN_FROM_TARGET_P", (RTX), INSN, JUMP_INSN, CALL_INSN)->in_struct) 78318334Speter 784169689Skan/* In an ADDR_DIFF_VEC, the flags for RTX for use by branch shortening. 785169689Skan See the comments for ADDR_DIFF_VEC in rtl.def. */ 78690075Sobrien#define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS(RTX, 4) 78790075Sobrien 788169689Skan/* In a VALUE, the value cselib has assigned to RTX. 789169689Skan This is a "struct cselib_val_struct", see cselib.h. */ 79090075Sobrien#define CSELIB_VAL_PTR(RTX) X0CSELIB(RTX, 0) 79190075Sobrien 79218334Speter/* Holds a list of notes on what this insn does to various REGs. 79390075Sobrien It is a chain of EXPR_LIST rtx's, where the second operand is the 79490075Sobrien chain pointer and the first operand is the REG being described. 79518334Speter The mode field of the EXPR_LIST contains not a real machine mode 79690075Sobrien but a value from enum reg_note. */ 797117395Skan#define REG_NOTES(INSN) XEXP(INSN, 8) 79818334Speter 79990075Sobrienenum reg_note 80090075Sobrien{ 801169689Skan#define DEF_REG_NOTE(NAME) NAME, 802169689Skan#include "reg-notes.def" 803169689Skan#undef DEF_REG_NOTE 804169689Skan REG_NOTE_MAX 80590075Sobrien}; 80690075Sobrien 80718334Speter/* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */ 80818334Speter#define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK)) 80990075Sobrien#define PUT_REG_NOTE_KIND(LINK, KIND) \ 81090075Sobrien PUT_MODE (LINK, (enum machine_mode) (KIND)) 81118334Speter 81218334Speter/* Names for REG_NOTE's in EXPR_LIST insn's. */ 81318334Speter 81490075Sobrienextern const char * const reg_note_name[]; 81550397Sobrien#define GET_REG_NOTE_NAME(MODE) (reg_note_name[(int) (MODE)]) 81618334Speter 81718334Speter/* This field is only present on CALL_INSNs. It holds a chain of EXPR_LIST of 81818334Speter USE and CLOBBER expressions. 81918334Speter USE expressions list the registers filled with arguments that 82018334Speter are passed to the function. 82118334Speter CLOBBER expressions document the registers explicitly clobbered 82218334Speter by this CALL_INSN. 82318334Speter Pseudo registers can not be mentioned in this list. */ 824117395Skan#define CALL_INSN_FUNCTION_USAGE(INSN) XEXP(INSN, 9) 82518334Speter 82618334Speter/* The label-number of a code-label. The assembler label 82718334Speter is made from `L' and the label-number printed in decimal. 82818334Speter Label numbers are unique in a compilation. */ 829117395Skan#define CODE_LABEL_NUMBER(INSN) XINT (INSN, 6) 83018334Speter 83150397Sobrien/* In a NOTE that is a line number, this is a string for the file name that the 83250397Sobrien line is in. We use the same field to record block numbers temporarily in 83350397Sobrien NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes. (We avoid lots of casts 83450397Sobrien between ints and pointers if we use a different macro for the block number.) 835117395Skan */ 83618334Speter 837132718Skan/* Opaque data. */ 838132718Skan#define NOTE_DATA(INSN) RTL_CHECKC1 (INSN, 4, NOTE) 839169689Skan#define NOTE_DELETED_LABEL_NAME(INSN) XCSTR (INSN, 4, NOTE) 840169689Skan#ifdef USE_MAPPED_LOCATION 841169689Skan#define NOTE_SOURCE_LOCATION(INSN) XCUINT (INSN, 5, NOTE) 842169689Skan#define NOTE_EXPANDED_LOCATION(XLOC, INSN) \ 843169689Skan (XLOC) = expand_location (NOTE_SOURCE_LOCATION (INSN)) 844169689Skan#define SET_INSN_DELETED(INSN) \ 845169689Skan (PUT_CODE (INSN, NOTE), NOTE_LINE_NUMBER (INSN) = NOTE_INSN_DELETED) 846169689Skan#else 847169689Skan#define NOTE_EXPANDED_LOCATION(XLOC, INSN) \ 848169689Skan ((XLOC).file = NOTE_SOURCE_FILE (INSN), \ 849169689Skan (XLOC).line = NOTE_LINE_NUMBER (INSN)) 850132718Skan#define NOTE_SOURCE_FILE(INSN) XCSTR (INSN, 4, NOTE) 851169689Skan#define SET_INSN_DELETED(INSN) \ 852169689Skan (PUT_CODE (INSN, NOTE), NOTE_SOURCE_FILE (INSN) = 0, \ 853169689Skan NOTE_LINE_NUMBER (INSN) = NOTE_INSN_DELETED) 854169689Skan#endif 855117395Skan#define NOTE_BLOCK(INSN) XCTREE (INSN, 4, NOTE) 856117395Skan#define NOTE_EH_HANDLER(INSN) XCINT (INSN, 4, NOTE) 857117395Skan#define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 4, NOTE) 858117395Skan#define NOTE_EXPECTED_VALUE(INSN) XCEXP (INSN, 4, NOTE) 859169689Skan#define NOTE_VAR_LOCATION(INSN) XCEXP (INSN, 4, NOTE) 86018334Speter 86118334Speter/* In a NOTE that is a line number, this is the line number. 86218334Speter Other kinds of NOTEs are identified by negative numbers here. */ 863117395Skan#define NOTE_LINE_NUMBER(INSN) XCINT (INSN, 5, NOTE) 86418334Speter 86590075Sobrien/* Nonzero if INSN is a note marking the beginning of a basic block. */ 866132718Skan#define NOTE_INSN_BASIC_BLOCK_P(INSN) \ 86790075Sobrien (GET_CODE (INSN) == NOTE \ 86890075Sobrien && NOTE_LINE_NUMBER (INSN) == NOTE_INSN_BASIC_BLOCK) 86990075Sobrien 870169689Skan/* Variable declaration and the location of a variable. */ 871169689Skan#define NOTE_VAR_LOCATION_DECL(INSN) (XCTREE (XCEXP (INSN, 4, NOTE), \ 872169689Skan 0, VAR_LOCATION)) 873169689Skan#define NOTE_VAR_LOCATION_LOC(INSN) (XCEXP (XCEXP (INSN, 4, NOTE), \ 874169689Skan 1, VAR_LOCATION)) 875117395Skan 876169689Skan/* Codes that appear in the NOTE_LINE_NUMBER field for kinds of notes 877169689Skan that are not line numbers. These codes are all negative. 878169689Skan 87918334Speter Notice that we do not try to use zero here for any of 88018334Speter the special note codes because sometimes the source line 88118334Speter actually can be zero! This happens (for example) when we 88218334Speter are generating code for the per-translation-unit constructor 883169689Skan and destructor routines for some C++ translation unit. */ 88418334Speter 88590075Sobrienenum insn_note 88690075Sobrien{ 88790075Sobrien /* Keep all of these numbers negative. Adjust as needed. */ 88890075Sobrien NOTE_INSN_BIAS = -100, 88918334Speter 890169689Skan#define DEF_INSN_NOTE(NAME) NAME, 891169689Skan#include "insn-notes.def" 892169689Skan#undef DEF_INSN_NOTE 89318334Speter 89490075Sobrien NOTE_INSN_MAX 89590075Sobrien}; 89690075Sobrien 89718334Speter/* Names for NOTE insn's other than line numbers. */ 89818334Speter 89990075Sobrienextern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS]; 90090075Sobrien#define GET_NOTE_INSN_NAME(NOTE_CODE) \ 90190075Sobrien (note_insn_name[(NOTE_CODE) - (int) NOTE_INSN_BIAS]) 90218334Speter 90318334Speter/* The name of a label, in case it corresponds to an explicit label 90418334Speter in the input source code. */ 905117395Skan#define LABEL_NAME(RTX) XCSTR (RTX, 7, CODE_LABEL) 90618334Speter 90718334Speter/* In jump.c, each label contains a count of the number 90818334Speter of LABEL_REFs that point at it, so unused labels can be deleted. */ 909117395Skan#define LABEL_NUSES(RTX) XCINT (RTX, 4, CODE_LABEL) 91018334Speter 911260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 912260918Spfg/* The alignment of the label, as the log-base-2 of the alignment in bytes. */ 913260918Spfg#define LABEL_ALIGN_LOG(RTX) (XCUINT (RTX, 8, CODE_LABEL) & 0xFF) 914260918Spfg/* The maximum number of bytes to skip to achieve that alignment. */ 915260918Spfg#define LABEL_MAX_SKIP(RTX) (XCUINT (RTX, 8, CODE_LABEL) >> 8) 916260918Spfg#define SET_LABEL_ALIGN(RTX, ALIGN, MAX_SKIP) \ 917260918Spfg (XCUINT (RTX, 8, CODE_LABEL) = (ALIGN) | ((MAX_SKIP) << 8)) 918260918Spfg 919260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 920117395Skan/* Labels carry a two-bit field composed of the ->jump and ->call 921117395Skan bits. This field indicates whether the label is an alternate 922117395Skan entry point, and if so, what kind. */ 923117395Skanenum label_kind 924117395Skan{ 925117395Skan LABEL_NORMAL = 0, /* ordinary label */ 926117395Skan LABEL_STATIC_ENTRY, /* alternate entry point, not exported */ 927117395Skan LABEL_GLOBAL_ENTRY, /* alternate entry point, exported */ 928117395Skan LABEL_WEAK_ENTRY /* alternate entry point, exported as weak symbol */ 929117395Skan}; 93090075Sobrien 931117395Skan#if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION > 2007) 932117395Skan 933117395Skan/* Retrieve the kind of LABEL. */ 934117395Skan#define LABEL_KIND(LABEL) __extension__ \ 935117395Skan({ rtx const _label = (LABEL); \ 936117395Skan if (GET_CODE (_label) != CODE_LABEL) \ 937117395Skan rtl_check_failed_flag ("LABEL_KIND", _label, __FILE__, __LINE__, \ 938117395Skan __FUNCTION__); \ 939117395Skan (enum label_kind) ((_label->jump << 1) | _label->call); }) 940117395Skan 941117395Skan/* Set the kind of LABEL. */ 942117395Skan#define SET_LABEL_KIND(LABEL, KIND) do { \ 943117395Skan rtx _label = (LABEL); \ 944117395Skan unsigned int _kind = (KIND); \ 945117395Skan if (GET_CODE (_label) != CODE_LABEL) \ 946117395Skan rtl_check_failed_flag ("SET_LABEL_KIND", _label, __FILE__, __LINE__, \ 947117395Skan __FUNCTION__); \ 948117395Skan _label->jump = ((_kind >> 1) & 1); \ 949117395Skan _label->call = (_kind & 1); \ 950117395Skan} while (0) 951117395Skan 952117395Skan#else 953117395Skan 954117395Skan/* Retrieve the kind of LABEL. */ 955117395Skan#define LABEL_KIND(LABEL) \ 956117395Skan ((enum label_kind) (((LABEL)->jump << 1) | (LABEL)->call)) 957117395Skan 958117395Skan/* Set the kind of LABEL. */ 959117395Skan#define SET_LABEL_KIND(LABEL, KIND) do { \ 960117395Skan rtx _label = (LABEL); \ 961117395Skan unsigned int _kind = (KIND); \ 962117395Skan _label->jump = ((_kind >> 1) & 1); \ 963117395Skan _label->call = (_kind & 1); \ 964117395Skan} while (0) 965117395Skan 966117395Skan#endif /* rtl flag checking */ 967117395Skan 968117395Skan#define LABEL_ALT_ENTRY_P(LABEL) (LABEL_KIND (LABEL) != LABEL_NORMAL) 969117395Skan 97018334Speter/* In jump.c, each JUMP_INSN can point to a label that it can jump to, 97118334Speter so that if the JUMP_INSN is deleted, the label's LABEL_NUSES can 97218334Speter be decremented and possibly the label can be deleted. */ 973117395Skan#define JUMP_LABEL(INSN) XCEXP (INSN, 9, JUMP_INSN) 97418334Speter 97518334Speter/* Once basic blocks are found in flow.c, 97618334Speter each CODE_LABEL starts a chain that goes through 97718334Speter all the LABEL_REFs that jump to that label. 97890075Sobrien The chain eventually winds up at the CODE_LABEL: it is circular. */ 979117395Skan#define LABEL_REFS(LABEL) XCEXP (LABEL, 5, CODE_LABEL) 98018334Speter 98190075Sobrien/* For a REG rtx, REGNO extracts the register number. ORIGINAL_REGNO holds 98290075Sobrien the number the register originally had; for a pseudo register turned into 98390075Sobrien a hard reg this will hold the old pseudo register number. */ 98418334Speter 98590075Sobrien#define REGNO(RTX) XCUINT (RTX, 0, REG) 98690075Sobrien#define ORIGINAL_REGNO(RTX) X0UINT (RTX, 1) 98718334Speter 988117395Skan/* 1 if RTX is a reg or parallel that is the current function's return 989117395Skan value. */ 990117395Skan#define REG_FUNCTION_VALUE_P(RTX) \ 991169689Skan (RTL_FLAG_CHECK2("REG_FUNCTION_VALUE_P", (RTX), REG, PARALLEL)->return_val) 99218334Speter 993117395Skan/* 1 if RTX is a reg that corresponds to a variable declared by the user. */ 994117395Skan#define REG_USERVAR_P(RTX) \ 995117395Skan (RTL_FLAG_CHECK1("REG_USERVAR_P", (RTX), REG)->volatil) 99618334Speter 997117395Skan/* 1 if RTX is a reg that holds a pointer value. */ 998117395Skan#define REG_POINTER(RTX) \ 999117395Skan (RTL_FLAG_CHECK1("REG_POINTER", (RTX), REG)->frame_related) 100018334Speter 1001169689Skan/* 1 if RTX is a mem that holds a pointer value. */ 1002169689Skan#define MEM_POINTER(RTX) \ 1003169689Skan (RTL_FLAG_CHECK1("MEM_POINTER", (RTX), MEM)->frame_related) 1004169689Skan 100590075Sobrien/* 1 if the given register REG corresponds to a hard register. */ 100690075Sobrien#define HARD_REGISTER_P(REG) (HARD_REGISTER_NUM_P (REGNO (REG))) 100790075Sobrien 100890075Sobrien/* 1 if the given register number REG_NO corresponds to a hard register. */ 100990075Sobrien#define HARD_REGISTER_NUM_P(REG_NO) ((REG_NO) < FIRST_PSEUDO_REGISTER) 101090075Sobrien 101118334Speter/* For a CONST_INT rtx, INTVAL extracts the integer. */ 101290075Sobrien#define INTVAL(RTX) XCWINT(RTX, 0, CONST_INT) 1013169689Skan#define UINTVAL(RTX) ((unsigned HOST_WIDE_INT) INTVAL (RTX)) 101418334Speter 101590075Sobrien/* For a CONST_DOUBLE: 1016169689Skan For a VOIDmode, there are two integers CONST_DOUBLE_LOW is the 1017117395Skan low-order word and ..._HIGH the high-order. 1018132718Skan For a float, there is a REAL_VALUE_TYPE structure, and 1019117395Skan CONST_DOUBLE_REAL_VALUE(r) is a pointer to it. */ 1020169689Skan#define CONST_DOUBLE_LOW(r) XCMWINT (r, 0, CONST_DOUBLE, VOIDmode) 1021169689Skan#define CONST_DOUBLE_HIGH(r) XCMWINT (r, 1, CONST_DOUBLE, VOIDmode) 1022169689Skan#define CONST_DOUBLE_REAL_VALUE(r) \ 1023169689Skan ((const struct real_value *) XCNMPRV (r, CONST_DOUBLE, VOIDmode)) 102490075Sobrien 102596263Sobrien/* For a CONST_VECTOR, return element #n. */ 102696263Sobrien#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR) 102796263Sobrien 102896263Sobrien/* For a CONST_VECTOR, return the number of elements in a vector. */ 102996263Sobrien#define CONST_VECTOR_NUNITS(RTX) XCVECLEN (RTX, 0, CONST_VECTOR) 103096263Sobrien 103118334Speter/* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of. 103290075Sobrien SUBREG_BYTE extracts the byte-number. */ 103318334Speter 103490075Sobrien#define SUBREG_REG(RTX) XCEXP (RTX, 0, SUBREG) 103590075Sobrien#define SUBREG_BYTE(RTX) XCUINT (RTX, 1, SUBREG) 103618334Speter 103790075Sobrien/* in rtlanal.c */ 1038169689Skan/* Return the right cost to give to an operation 1039169689Skan to make the cost of the corresponding register-to-register instruction 1040169689Skan N times that of a fast register-to-register instruction. */ 1041169689Skan#define COSTS_N_INSNS(N) ((N) * 4) 1042169689Skan 1043169689Skan/* Maximum cost of an rtl expression. This value has the special meaning 1044169689Skan not to use an rtx with this cost under any circumstances. */ 1045169689Skan#define MAX_COST INT_MAX 1046169689Skan 1047169689Skanextern void init_rtlanal (void); 1048169689Skanextern int rtx_cost (rtx, enum rtx_code); 1049169689Skanextern int address_cost (rtx, enum machine_mode); 1050132718Skanextern unsigned int subreg_lsb (rtx); 1051169689Skanextern unsigned int subreg_lsb_1 (enum machine_mode, enum machine_mode, 1052169689Skan unsigned int); 1053132718Skanextern unsigned int subreg_regno_offset (unsigned int, enum machine_mode, 1054132718Skan unsigned int, enum machine_mode); 1055132718Skanextern bool subreg_offset_representable_p (unsigned int, enum machine_mode, 1056132718Skan unsigned int, enum machine_mode); 1057132718Skanextern unsigned int subreg_regno (rtx); 1058169689Skanextern unsigned HOST_WIDE_INT nonzero_bits (rtx, enum machine_mode); 1059169689Skanextern unsigned int num_sign_bit_copies (rtx, enum machine_mode); 1060169689Skanextern bool constant_pool_constant_p (rtx); 1061169689Skanextern bool truncated_to_mode (enum machine_mode, rtx); 106290075Sobrien 1063169689Skan 1064117395Skan/* 1 if RTX is a subreg containing a reg that is already known to be 1065117395Skan sign- or zero-extended from the mode of the subreg to the mode of 106618334Speter the reg. SUBREG_PROMOTED_UNSIGNED_P gives the signedness of the 106790075Sobrien extension. 106818334Speter 106918334Speter When used as a LHS, is means that this extension must be done 107018334Speter when assigning to SUBREG_REG. */ 107118334Speter 1072117395Skan#define SUBREG_PROMOTED_VAR_P(RTX) \ 1073117395Skan (RTL_FLAG_CHECK1("SUBREG_PROMOTED", (RTX), SUBREG)->in_struct) 107418334Speter 1075117395Skan#define SUBREG_PROMOTED_UNSIGNED_SET(RTX, VAL) \ 1076117395Skando { \ 1077117395Skan rtx const _rtx = RTL_FLAG_CHECK1("SUBREG_PROMOTED_UNSIGNED_SET", (RTX), SUBREG); \ 1078117395Skan if ((VAL) < 0) \ 1079117395Skan _rtx->volatil = 1; \ 1080117395Skan else { \ 1081117395Skan _rtx->volatil = 0; \ 1082117395Skan _rtx->unchanging = (VAL); \ 1083117395Skan } \ 1084117395Skan} while (0) 1085117395Skan#define SUBREG_PROMOTED_UNSIGNED_P(RTX) \ 1086117395Skan ((RTL_FLAG_CHECK1("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil) \ 1087117395Skan ? -1 : (RTX)->unchanging) 1088117395Skan 108918334Speter/* Access various components of an ASM_OPERANDS rtx. */ 109018334Speter 109190075Sobrien#define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS) 109290075Sobrien#define ASM_OPERANDS_OUTPUT_CONSTRAINT(RTX) XCSTR (RTX, 1, ASM_OPERANDS) 109390075Sobrien#define ASM_OPERANDS_OUTPUT_IDX(RTX) XCINT (RTX, 2, ASM_OPERANDS) 109490075Sobrien#define ASM_OPERANDS_INPUT_VEC(RTX) XCVEC (RTX, 3, ASM_OPERANDS) 109590075Sobrien#define ASM_OPERANDS_INPUT_CONSTRAINT_VEC(RTX) XCVEC (RTX, 4, ASM_OPERANDS) 109690075Sobrien#define ASM_OPERANDS_INPUT(RTX, N) XCVECEXP (RTX, 3, N, ASM_OPERANDS) 109790075Sobrien#define ASM_OPERANDS_INPUT_LENGTH(RTX) XCVECLEN (RTX, 3, ASM_OPERANDS) 109890075Sobrien#define ASM_OPERANDS_INPUT_CONSTRAINT_EXP(RTX, N) \ 109990075Sobrien XCVECEXP (RTX, 4, N, ASM_OPERANDS) 110090075Sobrien#define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) \ 110190075Sobrien XSTR (XCVECEXP (RTX, 4, N, ASM_OPERANDS), 0) 110290075Sobrien#define ASM_OPERANDS_INPUT_MODE(RTX, N) \ 110390075Sobrien GET_MODE (XCVECEXP (RTX, 4, N, ASM_OPERANDS)) 1104169689Skan#ifdef USE_MAPPED_LOCATION 1105169689Skan#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 5, ASM_OPERANDS) 1106169689Skan#else 110790075Sobrien#define ASM_OPERANDS_SOURCE_FILE(RTX) XCSTR (RTX, 5, ASM_OPERANDS) 110890075Sobrien#define ASM_OPERANDS_SOURCE_LINE(RTX) XCINT (RTX, 6, ASM_OPERANDS) 1109169689Skan#endif 111018334Speter 1111169689Skan/* 1 if RTX is a mem that is statically allocated in read-only memory. */ 1112169689Skan#define MEM_READONLY_P(RTX) \ 1113169689Skan (RTL_FLAG_CHECK1("MEM_READONLY_P", (RTX), MEM)->unchanging) 1114169689Skan 1115117395Skan/* 1 if RTX is a mem and we should keep the alias set for this mem 111690075Sobrien unchanged when we access a component. Set to 1, or example, when we 111790075Sobrien are already in a non-addressable component of an aggregate. */ 1118117395Skan#define MEM_KEEP_ALIAS_SET_P(RTX) \ 1119117395Skan (RTL_FLAG_CHECK1("MEM_KEEP_ALIAS_SET_P", (RTX), MEM)->jump) 112090075Sobrien 1121117395Skan/* 1 if RTX is a mem or asm_operand for a volatile reference. */ 1122117395Skan#define MEM_VOLATILE_P(RTX) \ 1123117395Skan (RTL_FLAG_CHECK3("MEM_VOLATILE_P", (RTX), MEM, ASM_OPERANDS, \ 1124117395Skan ASM_INPUT)->volatil) 112518334Speter 1126117395Skan/* 1 if RTX is a mem that refers to an aggregate, either to the 1127169689Skan aggregate itself or to a field of the aggregate. If zero, RTX may 112890075Sobrien or may not be such a reference. */ 1129117395Skan#define MEM_IN_STRUCT_P(RTX) \ 1130117395Skan (RTL_FLAG_CHECK1("MEM_IN_STRUCT_P", (RTX), MEM)->in_struct) 113118334Speter 1132169689Skan/* 1 if RTX is a MEM that refers to a scalar. If zero, RTX may or may 113390075Sobrien not refer to a scalar. */ 1134117395Skan#define MEM_SCALAR_P(RTX) \ 1135169689Skan (RTL_FLAG_CHECK1("MEM_SCALAR_P", (RTX), MEM)->return_val) 113652284Sobrien 1137117395Skan/* 1 if RTX is a mem that cannot trap. */ 1138117395Skan#define MEM_NOTRAP_P(RTX) \ 1139117395Skan (RTL_FLAG_CHECK1("MEM_NOTRAP_P", (RTX), MEM)->call) 1140117395Skan 1141117395Skan/* If VAL is nonzero, set MEM_IN_STRUCT_P and clear MEM_SCALAR_P in 114252284Sobrien RTX. Otherwise, vice versa. Use this macro only when you are 114352284Sobrien *sure* that you know that the MEM is in a structure, or is a 114452284Sobrien scalar. VAL is evaluated only once. */ 114590075Sobrien#define MEM_SET_IN_STRUCT_P(RTX, VAL) \ 114690075Sobriendo { \ 114790075Sobrien if (VAL) \ 114890075Sobrien { \ 114990075Sobrien MEM_IN_STRUCT_P (RTX) = 1; \ 115090075Sobrien MEM_SCALAR_P (RTX) = 0; \ 115190075Sobrien } \ 115290075Sobrien else \ 115390075Sobrien { \ 115490075Sobrien MEM_IN_STRUCT_P (RTX) = 0; \ 115590075Sobrien MEM_SCALAR_P (RTX) = 1; \ 115690075Sobrien } \ 115790075Sobrien} while (0) 115852284Sobrien 115990075Sobrien/* The memory attribute block. We provide access macros for each value 116090075Sobrien in the block and provide defaults if none specified. */ 116190075Sobrien#define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1) 116290075Sobrien 1163132718Skan/* The register attribute block. We provide access macros for each value 1164132718Skan in the block and provide defaults if none specified. */ 1165132718Skan#define REG_ATTRS(RTX) X0REGATTR (RTX, 2) 1166132718Skan 116750397Sobrien/* For a MEM rtx, the alias set. If 0, this MEM is not in any alias 116850397Sobrien set, and may alias anything. Otherwise, the MEM can only alias 1169132718Skan MEMs in a conflicting alias set. This value is set in a 117050397Sobrien language-dependent manner in the front-end, and should not be 1171132718Skan altered in the back-end. These set numbers are tested with 1172132718Skan alias_sets_conflict_p. */ 117390075Sobrien#define MEM_ALIAS_SET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->alias) 117450397Sobrien 117590075Sobrien/* For a MEM rtx, the decl it is known to refer to, if it is known to 117690075Sobrien refer to part of a DECL. It may also be a COMPONENT_REF. */ 117790075Sobrien#define MEM_EXPR(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->expr) 117890075Sobrien 117990075Sobrien/* For a MEM rtx, the offset from the start of MEM_EXPR, if known, as a 118090075Sobrien RTX that is always a CONST_INT. */ 118190075Sobrien#define MEM_OFFSET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->offset) 118290075Sobrien 118390075Sobrien/* For a MEM rtx, the size in bytes of the MEM, if known, as an RTX that 118490075Sobrien is always a CONST_INT. */ 118590075Sobrien#define MEM_SIZE(RTX) \ 118690075Sobrien(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->size \ 118790075Sobrien : GET_MODE (RTX) != BLKmode ? GEN_INT (GET_MODE_SIZE (GET_MODE (RTX))) \ 118890075Sobrien : 0) 118990075Sobrien 119090075Sobrien/* For a MEM rtx, the alignment in bits. We can use the alignment of the 119190075Sobrien mode as a default when STRICT_ALIGNMENT, but not if not. */ 119290075Sobrien#define MEM_ALIGN(RTX) \ 119390075Sobrien(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align \ 119490075Sobrien : (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode \ 119590075Sobrien ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT)) 119690075Sobrien 1197132718Skan/* For a REG rtx, the decl it is known to refer to, if it is known to 1198132718Skan refer to part of a DECL. */ 1199132718Skan#define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl) 1200132718Skan 1201235623Spfg/* For a REG rtx, the offset from the start of REG_EXPR, if known, as an 1202235623Spfg HOST_WIDE_INT. */ 1203132718Skan#define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset) 1204132718Skan 120590075Sobrien/* Copy the attributes that apply to memory locations from RHS to LHS. */ 120690075Sobrien#define MEM_COPY_ATTRIBUTES(LHS, RHS) \ 120790075Sobrien (MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS), \ 120890075Sobrien MEM_IN_STRUCT_P (LHS) = MEM_IN_STRUCT_P (RHS), \ 120990075Sobrien MEM_SCALAR_P (LHS) = MEM_SCALAR_P (RHS), \ 1210117395Skan MEM_NOTRAP_P (LHS) = MEM_NOTRAP_P (RHS), \ 1211169689Skan MEM_READONLY_P (LHS) = MEM_READONLY_P (RHS), \ 121290075Sobrien MEM_KEEP_ALIAS_SET_P (LHS) = MEM_KEEP_ALIAS_SET_P (RHS), \ 121390075Sobrien MEM_ATTRS (LHS) = MEM_ATTRS (RHS)) 121490075Sobrien 1215117395Skan/* 1 if RTX is a label_ref for a nonlocal label. */ 1216117395Skan/* Likewise in an expr_list for a reg_label note. */ 1217117395Skan#define LABEL_REF_NONLOCAL_P(RTX) \ 1218117395Skan (RTL_FLAG_CHECK2("LABEL_REF_NONLOCAL_P", (RTX), LABEL_REF, \ 1219117395Skan REG_LABEL)->volatil) 122018334Speter 1221117395Skan/* 1 if RTX is a code_label that should always be considered to be needed. */ 1222117395Skan#define LABEL_PRESERVE_P(RTX) \ 1223117395Skan (RTL_FLAG_CHECK2("LABEL_PRESERVE_P", (RTX), CODE_LABEL, NOTE)->in_struct) 122418334Speter 1225117395Skan/* During sched, 1 if RTX is an insn that must be scheduled together 122618334Speter with the preceding insn. */ 1227117395Skan#define SCHED_GROUP_P(RTX) \ 1228117395Skan (RTL_FLAG_CHECK3("SCHED_GROUP_P", (RTX), INSN, JUMP_INSN, CALL_INSN \ 1229117395Skan )->in_struct) 123018334Speter 123118334Speter/* For a SET rtx, SET_DEST is the place that is set 123218334Speter and SET_SRC is the value it is set to. */ 123390075Sobrien#define SET_DEST(RTX) XC2EXP(RTX, 0, SET, CLOBBER) 123490075Sobrien#define SET_SRC(RTX) XCEXP(RTX, 1, SET) 1235117395Skan#define SET_IS_RETURN_P(RTX) \ 1236117395Skan (RTL_FLAG_CHECK1("SET_IS_RETURN_P", (RTX), SET)->jump) 123718334Speter 123818334Speter/* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */ 123990075Sobrien#define TRAP_CONDITION(RTX) XCEXP (RTX, 0, TRAP_IF) 124090075Sobrien#define TRAP_CODE(RTX) XCEXP (RTX, 1, TRAP_IF) 124118334Speter 124290075Sobrien/* For a COND_EXEC rtx, COND_EXEC_TEST is the condition to base 124390075Sobrien conditionally executing the code on, COND_EXEC_CODE is the code 124490075Sobrien to execute if the condition is true. */ 124590075Sobrien#define COND_EXEC_TEST(RTX) XCEXP (RTX, 0, COND_EXEC) 124690075Sobrien#define COND_EXEC_CODE(RTX) XCEXP (RTX, 1, COND_EXEC) 124790075Sobrien 1248132718Skan/* 1 if RTX is a symbol_ref that addresses this function's rtl 1249132718Skan constants pool. */ 1250117395Skan#define CONSTANT_POOL_ADDRESS_P(RTX) \ 1251117395Skan (RTL_FLAG_CHECK1("CONSTANT_POOL_ADDRESS_P", (RTX), SYMBOL_REF)->unchanging) 125218334Speter 1253132718Skan/* 1 if RTX is a symbol_ref that addresses a value in the file's 1254132718Skan tree constant pool. This information is private to varasm.c. */ 1255132718Skan#define TREE_CONSTANT_POOL_ADDRESS_P(RTX) \ 1256132718Skan (RTL_FLAG_CHECK1("TREE_CONSTANT_POOL_ADDRESS_P", \ 1257132718Skan (RTX), SYMBOL_REF)->frame_related) 125890075Sobrien 1259117395Skan/* Used if RTX is a symbol_ref, for machine-specific purposes. */ 1260117395Skan#define SYMBOL_REF_FLAG(RTX) \ 1261117395Skan (RTL_FLAG_CHECK1("SYMBOL_REF_FLAG", (RTX), SYMBOL_REF)->volatil) 126218334Speter 1263117395Skan/* 1 if RTX is a symbol_ref that has been the library function in 1264117395Skan emit_library_call. */ 1265117395Skan#define SYMBOL_REF_USED(RTX) \ 1266117395Skan (RTL_FLAG_CHECK1("SYMBOL_REF_USED", (RTX), SYMBOL_REF)->used) 126718334Speter 1268117395Skan/* 1 if RTX is a symbol_ref for a weak symbol. */ 1269117395Skan#define SYMBOL_REF_WEAK(RTX) \ 1270169689Skan (RTL_FLAG_CHECK1("SYMBOL_REF_WEAK", (RTX), SYMBOL_REF)->return_val) 127118334Speter 1272169689Skan/* A pointer attached to the SYMBOL_REF; either SYMBOL_REF_DECL or 1273169689Skan SYMBOL_REF_CONSTANT. */ 1274169689Skan#define SYMBOL_REF_DATA(RTX) X0ANY ((RTX), 2) 1275169689Skan 1276169689Skan/* Set RTX's SYMBOL_REF_DECL to DECL. RTX must not be a constant 1277169689Skan pool symbol. */ 1278169689Skan#define SET_SYMBOL_REF_DECL(RTX, DECL) \ 1279169689Skan (gcc_assert (!CONSTANT_POOL_ADDRESS_P (RTX)), X0TREE ((RTX), 2) = (DECL)) 1280169689Skan 1281132718Skan/* The tree (decl or constant) associated with the symbol, or null. */ 1282169689Skan#define SYMBOL_REF_DECL(RTX) \ 1283169689Skan (CONSTANT_POOL_ADDRESS_P (RTX) ? NULL : X0TREE ((RTX), 2)) 1284132718Skan 1285169689Skan/* Set RTX's SYMBOL_REF_CONSTANT to C. RTX must be a constant pool symbol. */ 1286169689Skan#define SET_SYMBOL_REF_CONSTANT(RTX, C) \ 1287169689Skan (gcc_assert (CONSTANT_POOL_ADDRESS_P (RTX)), X0CONSTANT ((RTX), 2) = (C)) 1288169689Skan 1289169689Skan/* The rtx constant pool entry for a symbol, or null. */ 1290169689Skan#define SYMBOL_REF_CONSTANT(RTX) \ 1291169689Skan (CONSTANT_POOL_ADDRESS_P (RTX) ? X0CONSTANT ((RTX), 2) : NULL) 1292169689Skan 1293132718Skan/* A set of flags on a symbol_ref that are, in some respects, redundant with 1294132718Skan information derivable from the tree decl associated with this symbol. 1295132718Skan Except that we build a *lot* of SYMBOL_REFs that aren't associated with a 1296132718Skan decl. In some cases this is a bug. But beyond that, it's nice to cache 1297132718Skan this information to avoid recomputing it. Finally, this allows space for 1298132718Skan the target to store more than one bit of information, as with 1299132718Skan SYMBOL_REF_FLAG. */ 1300132718Skan#define SYMBOL_REF_FLAGS(RTX) X0INT ((RTX), 1) 1301132718Skan 1302132718Skan/* These flags are common enough to be defined for all targets. They 1303132718Skan are computed by the default version of targetm.encode_section_info. */ 1304132718Skan 1305132718Skan/* Set if this symbol is a function. */ 1306132718Skan#define SYMBOL_FLAG_FUNCTION (1 << 0) 1307132718Skan#define SYMBOL_REF_FUNCTION_P(RTX) \ 1308132718Skan ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_FUNCTION) != 0) 1309132718Skan/* Set if targetm.binds_local_p is true. */ 1310132718Skan#define SYMBOL_FLAG_LOCAL (1 << 1) 1311132718Skan#define SYMBOL_REF_LOCAL_P(RTX) \ 1312132718Skan ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_LOCAL) != 0) 1313132718Skan/* Set if targetm.in_small_data_p is true. */ 1314132718Skan#define SYMBOL_FLAG_SMALL (1 << 2) 1315132718Skan#define SYMBOL_REF_SMALL_P(RTX) \ 1316132718Skan ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_SMALL) != 0) 1317132718Skan/* The three-bit field at [5:3] is true for TLS variables; use 1318132718Skan SYMBOL_REF_TLS_MODEL to extract the field as an enum tls_model. */ 1319132718Skan#define SYMBOL_FLAG_TLS_SHIFT 3 1320132718Skan#define SYMBOL_REF_TLS_MODEL(RTX) \ 1321132718Skan ((enum tls_model) ((SYMBOL_REF_FLAGS (RTX) >> SYMBOL_FLAG_TLS_SHIFT) & 7)) 1322132718Skan/* Set if this symbol is not defined in this translation unit. */ 1323132718Skan#define SYMBOL_FLAG_EXTERNAL (1 << 6) 1324132718Skan#define SYMBOL_REF_EXTERNAL_P(RTX) \ 1325132718Skan ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_EXTERNAL) != 0) 1326169689Skan/* Set if this symbol has a block_symbol structure associated with it. */ 1327169689Skan#define SYMBOL_FLAG_HAS_BLOCK_INFO (1 << 7) 1328169689Skan#define SYMBOL_REF_HAS_BLOCK_INFO_P(RTX) \ 1329169689Skan ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_HAS_BLOCK_INFO) != 0) 1330169689Skan/* Set if this symbol is a section anchor. SYMBOL_REF_ANCHOR_P implies 1331169689Skan SYMBOL_REF_HAS_BLOCK_INFO_P. */ 1332169689Skan#define SYMBOL_FLAG_ANCHOR (1 << 8) 1333169689Skan#define SYMBOL_REF_ANCHOR_P(RTX) \ 1334169689Skan ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_ANCHOR) != 0) 1335132718Skan 1336132718Skan/* Subsequent bits are available for the target to use. */ 1337169689Skan#define SYMBOL_FLAG_MACH_DEP_SHIFT 9 1338132718Skan#define SYMBOL_FLAG_MACH_DEP (1 << SYMBOL_FLAG_MACH_DEP_SHIFT) 1339132718Skan 1340169689Skan/* If SYMBOL_REF_HAS_BLOCK_INFO_P (RTX), this is the object_block 1341169689Skan structure to which the symbol belongs, or NULL if it has not been 1342169689Skan assigned a block. */ 1343169689Skan#define SYMBOL_REF_BLOCK(RTX) (BLOCK_SYMBOL_CHECK (RTX)->block) 1344169689Skan 1345169689Skan/* If SYMBOL_REF_HAS_BLOCK_INFO_P (RTX), this is the offset of RTX from 1346169689Skan the first object in SYMBOL_REF_BLOCK (RTX). The value is negative if 1347169689Skan RTX has not yet been assigned to a block, or it has not been given an 1348169689Skan offset within that block. */ 1349169689Skan#define SYMBOL_REF_BLOCK_OFFSET(RTX) (BLOCK_SYMBOL_CHECK (RTX)->offset) 1350169689Skan 135118334Speter/* Define a macro to look for REG_INC notes, 135218334Speter but save time on machines where they never exist. */ 135318334Speter 135418334Speter#if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT)) 135590075Sobrien#define FIND_REG_INC_NOTE(INSN, REG) \ 135690075Sobrien ((REG) != NULL_RTX && REG_P ((REG)) \ 135790075Sobrien ? find_regno_note ((INSN), REG_INC, REGNO (REG)) \ 135890075Sobrien : find_reg_note ((INSN), REG_INC, (REG))) 135918334Speter#else 136090075Sobrien#define FIND_REG_INC_NOTE(INSN, REG) 0 136118334Speter#endif 136218334Speter 136318334Speter/* Indicate whether the machine has any sort of auto increment addressing. 136418334Speter If not, we can avoid checking for REG_INC notes. */ 136518334Speter 136618334Speter#if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT)) 136718334Speter#define AUTO_INC_DEC 136818334Speter#endif 136950397Sobrien 137052284Sobrien#ifndef HAVE_PRE_INCREMENT 137152284Sobrien#define HAVE_PRE_INCREMENT 0 137252284Sobrien#endif 137352284Sobrien 137452284Sobrien#ifndef HAVE_PRE_DECREMENT 137552284Sobrien#define HAVE_PRE_DECREMENT 0 137652284Sobrien#endif 137752284Sobrien 137852284Sobrien#ifndef HAVE_POST_INCREMENT 137952284Sobrien#define HAVE_POST_INCREMENT 0 138052284Sobrien#endif 138152284Sobrien 138252284Sobrien#ifndef HAVE_POST_DECREMENT 138352284Sobrien#define HAVE_POST_DECREMENT 0 138452284Sobrien#endif 138552284Sobrien 138690075Sobrien#ifndef HAVE_POST_MODIFY_DISP 138790075Sobrien#define HAVE_POST_MODIFY_DISP 0 138890075Sobrien#endif 138952284Sobrien 139090075Sobrien#ifndef HAVE_POST_MODIFY_REG 139190075Sobrien#define HAVE_POST_MODIFY_REG 0 139290075Sobrien#endif 139390075Sobrien 139490075Sobrien#ifndef HAVE_PRE_MODIFY_DISP 139590075Sobrien#define HAVE_PRE_MODIFY_DISP 0 139690075Sobrien#endif 139790075Sobrien 139890075Sobrien#ifndef HAVE_PRE_MODIFY_REG 139990075Sobrien#define HAVE_PRE_MODIFY_REG 0 140090075Sobrien#endif 140190075Sobrien 140290075Sobrien 140352284Sobrien/* Some architectures do not have complete pre/post increment/decrement 140452284Sobrien instruction sets, or only move some modes efficiently. These macros 140552284Sobrien allow us to tune autoincrement generation. */ 140652284Sobrien 140752284Sobrien#ifndef USE_LOAD_POST_INCREMENT 140852284Sobrien#define USE_LOAD_POST_INCREMENT(MODE) HAVE_POST_INCREMENT 140952284Sobrien#endif 141052284Sobrien 141152284Sobrien#ifndef USE_LOAD_POST_DECREMENT 141252284Sobrien#define USE_LOAD_POST_DECREMENT(MODE) HAVE_POST_DECREMENT 141352284Sobrien#endif 141452284Sobrien 141552284Sobrien#ifndef USE_LOAD_PRE_INCREMENT 141652284Sobrien#define USE_LOAD_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT 141752284Sobrien#endif 141852284Sobrien 141952284Sobrien#ifndef USE_LOAD_PRE_DECREMENT 142052284Sobrien#define USE_LOAD_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT 142152284Sobrien#endif 142252284Sobrien 142352284Sobrien#ifndef USE_STORE_POST_INCREMENT 142452284Sobrien#define USE_STORE_POST_INCREMENT(MODE) HAVE_POST_INCREMENT 142552284Sobrien#endif 142652284Sobrien 142752284Sobrien#ifndef USE_STORE_POST_DECREMENT 142852284Sobrien#define USE_STORE_POST_DECREMENT(MODE) HAVE_POST_DECREMENT 142952284Sobrien#endif 143052284Sobrien 143152284Sobrien#ifndef USE_STORE_PRE_INCREMENT 143252284Sobrien#define USE_STORE_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT 143352284Sobrien#endif 143452284Sobrien 143552284Sobrien#ifndef USE_STORE_PRE_DECREMENT 143652284Sobrien#define USE_STORE_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT 143752284Sobrien#endif 143818334Speter 143990075Sobrien/* Nonzero when we are generating CONCATs. */ 144090075Sobrienextern int generating_concat_p; 144118334Speter 1442169689Skan/* Nonzero when we are expanding trees to RTL. */ 1443169689Skanextern int currently_expanding_to_rtl; 1444169689Skan 144590075Sobrien/* Generally useful functions. */ 144618334Speter 144750397Sobrien/* In expmed.c */ 1448132718Skanextern int ceil_log2 (unsigned HOST_WIDE_INT); 144950397Sobrien 145090075Sobrien/* In builtins.c */ 1451132718Skanextern rtx expand_builtin_expect_jump (tree, rtx, rtx); 145218334Speter 145350397Sobrien/* In explow.c */ 1454132718Skanextern void set_stack_check_libfunc (rtx); 1455132718Skanextern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, enum machine_mode); 1456169689Skanextern rtx plus_constant (rtx, HOST_WIDE_INT); 145718334Speter 145890075Sobrien/* In emit-rtl.c */ 1459132718Skanextern rtvec gen_rtvec (int, ...); 1460132718Skanextern rtx copy_insn_1 (rtx); 1461132718Skanextern rtx copy_insn (rtx); 1462132718Skanextern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode); 1463132718Skanextern rtx emit_copy_of_insn_after (rtx, rtx); 1464132718Skanextern void set_reg_attrs_from_mem (rtx, rtx); 1465132718Skanextern void set_mem_attrs_from_reg (rtx, rtx); 1466132718Skanextern void set_reg_attrs_for_parm (rtx, rtx); 1467132718Skanextern int mem_expr_equal_p (tree, tree); 146818334Speter 146990075Sobrien/* In rtl.c */ 1470169689Skanextern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL); 1471169689Skan#define rtx_alloc(c) rtx_alloc_stat (c MEM_STAT_INFO) 1472169689Skan 1473132718Skanextern rtvec rtvec_alloc (int); 1474132718Skanextern rtx copy_rtx (rtx); 1475132718Skanextern void dump_rtx_statistics (void); 147618334Speter 147790075Sobrien/* In emit-rtl.c */ 1478132718Skanextern rtx copy_rtx_if_shared (rtx); 147990075Sobrien 148090075Sobrien/* In rtl.c */ 1481169689Skanextern unsigned int rtx_size (rtx); 1482169689Skanextern rtx shallow_copy_rtx_stat (rtx MEM_STAT_DECL); 1483169689Skan#define shallow_copy_rtx(a) shallow_copy_rtx_stat (a MEM_STAT_INFO) 1484132718Skanextern int rtx_equal_p (rtx, rtx); 148590075Sobrien 148690075Sobrien/* In emit-rtl.c */ 1487132718Skanextern rtvec gen_rtvec_v (int, rtx *); 1488132718Skanextern rtx gen_reg_rtx (enum machine_mode); 1489132718Skanextern rtx gen_rtx_REG_offset (rtx, enum machine_mode, unsigned int, int); 1490132718Skanextern rtx gen_label_rtx (void); 1491132718Skanextern rtx gen_lowpart_common (enum machine_mode, rtx); 149290075Sobrien 149390075Sobrien/* In cse.c */ 1494132718Skanextern rtx gen_lowpart_if_possible (enum machine_mode, rtx); 149590075Sobrien 149690075Sobrien/* In emit-rtl.c */ 1497132718Skanextern rtx gen_highpart (enum machine_mode, rtx); 1498132718Skanextern rtx gen_highpart_mode (enum machine_mode, enum machine_mode, rtx); 1499132718Skanextern rtx operand_subword (rtx, unsigned int, int, enum machine_mode); 150090075Sobrien 150190075Sobrien/* In emit-rtl.c */ 1502132718Skanextern rtx operand_subword_force (rtx, unsigned int, enum machine_mode); 1503132718Skanextern int subreg_lowpart_p (rtx); 1504132718Skanextern unsigned int subreg_lowpart_offset (enum machine_mode, 1505132718Skan enum machine_mode); 1506132718Skanextern unsigned int subreg_highpart_offset (enum machine_mode, 1507132718Skan enum machine_mode); 1508132718Skanextern rtx make_safe_from (rtx, rtx); 1509132718Skanextern rtx convert_memory_address (enum machine_mode, rtx); 1510132718Skanextern rtx get_insns (void); 1511132718Skanextern const char *get_insn_name (int); 1512132718Skanextern rtx get_last_insn (void); 1513132718Skanextern rtx get_last_insn_anywhere (void); 1514132718Skanextern rtx get_first_nonnote_insn (void); 1515132718Skanextern rtx get_last_nonnote_insn (void); 1516132718Skanextern void start_sequence (void); 1517132718Skanextern void push_to_sequence (rtx); 1518132718Skanextern void end_sequence (void); 1519132718Skanextern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT, 1520132718Skan enum machine_mode); 152190075Sobrien 1522169689Skan/* In loop-iv.c */ 1523169689Skan 1524169689Skanextern rtx lowpart_subreg (enum machine_mode, rtx, enum machine_mode); 1525169689Skan 152690075Sobrien/* In varasm.c */ 1527132718Skanextern rtx force_const_mem (enum machine_mode, rtx); 152890075Sobrien 152990075Sobrien/* In varasm.c */ 1530169689Skan 1531169689Skanstruct function; 1532132718Skanextern rtx get_pool_constant (rtx); 1533132718Skanextern rtx get_pool_constant_mark (rtx, bool *); 1534132718Skanextern enum machine_mode get_pool_mode (rtx); 1535132718Skanextern rtx simplify_subtraction (rtx); 153690075Sobrien 153790075Sobrien/* In function.c */ 1538132718Skanextern rtx assign_stack_local (enum machine_mode, HOST_WIDE_INT, int); 1539132718Skanextern rtx assign_stack_temp (enum machine_mode, HOST_WIDE_INT, int); 1540132718Skanextern rtx assign_stack_temp_for_type (enum machine_mode, 1541132718Skan HOST_WIDE_INT, int, tree); 1542132718Skanextern rtx assign_temp (tree, int, int, int); 1543132718Skan 154490075Sobrien/* In emit-rtl.c */ 1545132718Skanextern rtx emit_insn_before (rtx, rtx); 1546132718Skanextern rtx emit_insn_before_noloc (rtx, rtx); 1547132718Skanextern rtx emit_insn_before_setloc (rtx, rtx, int); 1548132718Skanextern rtx emit_jump_insn_before (rtx, rtx); 1549132718Skanextern rtx emit_jump_insn_before_noloc (rtx, rtx); 1550132718Skanextern rtx emit_jump_insn_before_setloc (rtx, rtx, int); 1551132718Skanextern rtx emit_call_insn_before (rtx, rtx); 1552132718Skanextern rtx emit_call_insn_before_noloc (rtx, rtx); 1553132718Skanextern rtx emit_call_insn_before_setloc (rtx, rtx, int); 1554132718Skanextern rtx emit_barrier_before (rtx); 1555132718Skanextern rtx emit_label_before (rtx, rtx); 1556132718Skanextern rtx emit_note_before (int, rtx); 1557132718Skanextern rtx emit_insn_after (rtx, rtx); 1558132718Skanextern rtx emit_insn_after_noloc (rtx, rtx); 1559132718Skanextern rtx emit_insn_after_setloc (rtx, rtx, int); 1560132718Skanextern rtx emit_jump_insn_after (rtx, rtx); 1561132718Skanextern rtx emit_jump_insn_after_noloc (rtx, rtx); 1562132718Skanextern rtx emit_jump_insn_after_setloc (rtx, rtx, int); 1563132718Skanextern rtx emit_call_insn_after (rtx, rtx); 1564132718Skanextern rtx emit_call_insn_after_noloc (rtx, rtx); 1565132718Skanextern rtx emit_call_insn_after_setloc (rtx, rtx, int); 1566132718Skanextern rtx emit_barrier_after (rtx); 1567132718Skanextern rtx emit_label_after (rtx, rtx); 1568132718Skanextern rtx emit_note_after (int, rtx); 1569132718Skanextern rtx emit_note_copy_after (rtx, rtx); 1570132718Skanextern rtx emit_insn (rtx); 1571132718Skanextern rtx emit_jump_insn (rtx); 1572132718Skanextern rtx emit_call_insn (rtx); 1573132718Skanextern rtx emit_label (rtx); 1574132718Skanextern rtx emit_barrier (void); 1575132718Skanextern rtx emit_note (int); 1576132718Skanextern rtx emit_note_copy (rtx); 1577132718Skanextern rtx emit_line_note (location_t); 1578132718Skanextern rtx make_insn_raw (rtx); 1579169689Skanextern rtx make_jump_insn_raw (rtx); 1580132718Skanextern void add_function_usage_to (rtx, rtx); 1581132718Skanextern rtx last_call_insn (void); 1582132718Skanextern rtx previous_insn (rtx); 1583132718Skanextern rtx next_insn (rtx); 1584132718Skanextern rtx prev_nonnote_insn (rtx); 1585132718Skanextern rtx next_nonnote_insn (rtx); 1586132718Skanextern rtx prev_real_insn (rtx); 1587132718Skanextern rtx next_real_insn (rtx); 1588132718Skanextern rtx prev_active_insn (rtx); 1589132718Skanextern rtx next_active_insn (rtx); 1590132718Skanextern int active_insn_p (rtx); 1591132718Skanextern rtx prev_label (rtx); 1592132718Skanextern rtx next_label (rtx); 1593169689Skanextern rtx skip_consecutive_labels (rtx); 1594132718Skanextern rtx next_cc0_user (rtx); 1595132718Skanextern rtx prev_cc0_setter (rtx); 159618334Speter 1597117395Skan/* In cfglayout.c */ 1598132718Skanextern int insn_line (rtx); 1599132718Skanextern const char * insn_file (rtx); 1600132718Skanextern int locator_line (int); 1601132718Skanextern const char * locator_file (int); 1602132718Skanextern int prologue_locator, epilogue_locator; 1603117395Skan 160490075Sobrien/* In jump.c */ 1605132718Skanextern enum rtx_code reverse_condition (enum rtx_code); 1606132718Skanextern enum rtx_code reverse_condition_maybe_unordered (enum rtx_code); 1607132718Skanextern enum rtx_code swap_condition (enum rtx_code); 1608132718Skanextern enum rtx_code unsigned_condition (enum rtx_code); 1609132718Skanextern enum rtx_code signed_condition (enum rtx_code); 1610132718Skanextern void mark_jump_label (rtx, rtx, int); 1611169689Skanextern unsigned int cleanup_barriers (void); 161290075Sobrien 161390075Sobrien/* In jump.c */ 1614132718Skanextern bool squeeze_notes (rtx *, rtx *); 1615132718Skanextern rtx delete_related_insns (rtx); 1616132718Skanextern void delete_jump (rtx); 1617132718Skanextern rtx get_label_before (rtx); 1618132718Skanextern rtx get_label_after (rtx); 1619132718Skanextern rtx follow_jumps (rtx); 162090075Sobrien 162190075Sobrien/* In recog.c */ 1622132718Skanextern rtx *find_constant_term_loc (rtx *); 162390075Sobrien 162490075Sobrien/* In emit-rtl.c */ 1625132718Skanextern rtx try_split (rtx, rtx, int); 162690075Sobrienextern int split_branch_probability; 162790075Sobrien 162890075Sobrien/* In unknown file */ 1629132718Skanextern rtx split_insns (rtx, rtx); 163090075Sobrien 163190075Sobrien/* In simplify-rtx.c */ 1632169689Skanextern rtx simplify_const_unary_operation (enum rtx_code, enum machine_mode, 1633169689Skan rtx, enum machine_mode); 1634132718Skanextern rtx simplify_unary_operation (enum rtx_code, enum machine_mode, rtx, 1635132718Skan enum machine_mode); 1636169689Skanextern rtx simplify_const_binary_operation (enum rtx_code, enum machine_mode, 1637169689Skan rtx, rtx); 1638132718Skanextern rtx simplify_binary_operation (enum rtx_code, enum machine_mode, rtx, 1639132718Skan rtx); 1640132718Skanextern rtx simplify_ternary_operation (enum rtx_code, enum machine_mode, 1641132718Skan enum machine_mode, rtx, rtx, rtx); 1642169689Skanextern rtx simplify_const_relational_operation (enum rtx_code, 1643169689Skan enum machine_mode, rtx, rtx); 1644132718Skanextern rtx simplify_relational_operation (enum rtx_code, enum machine_mode, 1645169689Skan enum machine_mode, rtx, rtx); 1646132718Skanextern rtx simplify_gen_binary (enum rtx_code, enum machine_mode, rtx, rtx); 1647132718Skanextern rtx simplify_gen_unary (enum rtx_code, enum machine_mode, rtx, 1648132718Skan enum machine_mode); 1649132718Skanextern rtx simplify_gen_ternary (enum rtx_code, enum machine_mode, 1650132718Skan enum machine_mode, rtx, rtx, rtx); 1651132718Skanextern rtx simplify_gen_relational (enum rtx_code, enum machine_mode, 1652132718Skan enum machine_mode, rtx, rtx); 1653132718Skanextern rtx simplify_subreg (enum machine_mode, rtx, enum machine_mode, 1654132718Skan unsigned int); 1655132718Skanextern rtx simplify_gen_subreg (enum machine_mode, rtx, enum machine_mode, 1656132718Skan unsigned int); 1657132718Skanextern rtx simplify_replace_rtx (rtx, rtx, rtx); 1658132718Skanextern rtx simplify_rtx (rtx); 1659132718Skanextern rtx avoid_constant_pool_reference (rtx); 1660169689Skanextern bool constant_pool_reference_p (rtx x); 1661169689Skanextern bool mode_signbit_p (enum machine_mode, rtx); 166290075Sobrien 166390075Sobrien/* In regclass.c */ 1664132718Skanextern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int, 1665132718Skan bool); 166690075Sobrien 166790075Sobrien/* In emit-rtl.c */ 1668132718Skanextern rtx set_unique_reg_note (rtx, enum reg_note, rtx); 166990075Sobrien 167050397Sobrien/* Functions in rtlanal.c */ 167150397Sobrien 167290075Sobrien/* Single set is implemented as macro for performance reasons. */ 167390075Sobrien#define single_set(I) (INSN_P (I) \ 167490075Sobrien ? (GET_CODE (PATTERN (I)) == SET \ 167590075Sobrien ? PATTERN (I) : single_set_1 (I)) \ 167690075Sobrien : NULL_RTX) 167790075Sobrien#define single_set_1(I) single_set_2 (I, PATTERN (I)) 167850397Sobrien 1679132718Skan/* Structure used for passing data to REPLACE_LABEL. */ 1680132718Skantypedef struct replace_label_data 1681132718Skan{ 1682132718Skan rtx r1; 1683132718Skan rtx r2; 1684132718Skan bool update_label_nuses; 1685132718Skan} replace_label_data; 168690075Sobrien 1687132718Skanextern int rtx_addr_can_trap_p (rtx); 1688132718Skanextern bool nonzero_address_p (rtx); 1689132718Skanextern int rtx_unstable_p (rtx); 1690132718Skanextern int rtx_varies_p (rtx, int); 1691132718Skanextern int rtx_addr_varies_p (rtx, int); 1692132718Skanextern HOST_WIDE_INT get_integer_term (rtx); 1693132718Skanextern rtx get_related_value (rtx); 1694132718Skanextern int reg_mentioned_p (rtx, rtx); 1695132718Skanextern int count_occurrences (rtx, rtx, int); 1696132718Skanextern int reg_referenced_p (rtx, rtx); 1697132718Skanextern int reg_used_between_p (rtx, rtx, rtx); 1698132718Skanextern int reg_set_between_p (rtx, rtx, rtx); 1699132718Skanextern int commutative_operand_precedence (rtx); 1700132718Skanextern int swap_commutative_operands_p (rtx, rtx); 1701132718Skanextern int modified_between_p (rtx, rtx, rtx); 1702132718Skanextern int no_labels_between_p (rtx, rtx); 1703132718Skanextern int modified_in_p (rtx, rtx); 1704132718Skanextern int reg_set_p (rtx, rtx); 1705132718Skanextern rtx single_set_2 (rtx, rtx); 1706132718Skanextern int multiple_sets (rtx); 1707132718Skanextern int set_noop_p (rtx); 1708132718Skanextern int noop_move_p (rtx); 1709132718Skanextern rtx find_last_value (rtx, rtx *, rtx, int); 1710132718Skanextern int refers_to_regno_p (unsigned int, unsigned int, rtx, rtx *); 1711132718Skanextern int reg_overlap_mentioned_p (rtx, rtx); 1712132718Skanextern rtx set_of (rtx, rtx); 1713132718Skanextern void note_stores (rtx, void (*) (rtx, rtx, void *), void *); 1714132718Skanextern void note_uses (rtx *, void (*) (rtx *, void *), void *); 1715132718Skanextern int dead_or_set_p (rtx, rtx); 1716132718Skanextern int dead_or_set_regno_p (rtx, unsigned int); 1717132718Skanextern rtx find_reg_note (rtx, enum reg_note, rtx); 1718132718Skanextern rtx find_regno_note (rtx, enum reg_note, unsigned int); 1719132718Skanextern rtx find_reg_equal_equiv_note (rtx); 1720132718Skanextern int find_reg_fusage (rtx, enum rtx_code, rtx); 1721132718Skanextern int find_regno_fusage (rtx, enum rtx_code, unsigned int); 1722132718Skanextern int pure_call_p (rtx); 1723132718Skanextern void remove_note (rtx, rtx); 1724132718Skanextern int side_effects_p (rtx); 1725132718Skanextern int volatile_refs_p (rtx); 1726132718Skanextern int volatile_insn_p (rtx); 1727132718Skanextern int may_trap_p (rtx); 1728169689Skanextern int may_trap_after_code_motion_p (rtx); 1729169689Skanextern int may_trap_or_fault_p (rtx); 1730132718Skanextern int inequality_comparisons_p (rtx); 1731132718Skanextern rtx replace_rtx (rtx, rtx, rtx); 1732132718Skanextern int replace_label (rtx *, void *); 1733132718Skanextern int rtx_referenced_p (rtx, rtx); 1734132718Skanextern bool tablejump_p (rtx, rtx *, rtx *); 1735132718Skanextern int computed_jump_p (rtx); 1736132718Skantypedef int (*rtx_function) (rtx *, void *); 1737132718Skanextern int for_each_rtx (rtx *, rtx_function, void *); 1738132718Skanextern rtx regno_use_in (unsigned int, rtx); 1739132718Skanextern int auto_inc_p (rtx); 1740132718Skanextern int in_expr_list_p (rtx, rtx); 1741132718Skanextern void remove_node_from_expr_list (rtx, rtx *); 1742132718Skanextern int loc_mentioned_in_p (rtx *, rtx); 1743132718Skanextern rtx find_first_parameter_load (rtx, rtx); 1744132718Skanextern bool keep_with_call_p (rtx); 1745132718Skanextern bool label_is_jump_target_p (rtx, rtx); 1746169689Skanextern int insn_rtx_cost (rtx); 1747132718Skan 1748169689Skan/* Given an insn and condition, return a canonical description of 1749169689Skan the test being made. */ 1750169689Skanextern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int, int); 1751169689Skan 1752169689Skan/* Given a JUMP_INSN, return a canonical description of the test 1753169689Skan being made. */ 1754169689Skanextern rtx get_condition (rtx, rtx *, int, int); 1755169689Skan 1756169689Skan 175752284Sobrien/* flow.c */ 175852284Sobrien 1759132718Skanextern rtx find_use_as_address (rtx, rtx, HOST_WIDE_INT); 1760117395Skan 1761117395Skan/* lists.c */ 1762117395Skan 1763132718Skanvoid free_EXPR_LIST_list (rtx *); 1764132718Skanvoid free_INSN_LIST_list (rtx *); 1765132718Skanvoid free_EXPR_LIST_node (rtx); 1766132718Skanvoid free_INSN_LIST_node (rtx); 1767132718Skanrtx alloc_INSN_LIST (rtx, rtx); 1768132718Skanrtx alloc_EXPR_LIST (int, rtx, rtx); 1769169689Skanvoid free_DEPS_LIST_list (rtx *); 1770169689Skanrtx alloc_DEPS_LIST (rtx, rtx, int); 1771169689Skanvoid remove_free_DEPS_LIST_elem (rtx, rtx *); 1772169689Skanvoid remove_free_INSN_LIST_elem (rtx, rtx *); 1773169689Skanrtx remove_list_elem (rtx, rtx *); 1774169689Skanrtx copy_DEPS_LIST_list (rtx); 177552284Sobrien 177652284Sobrien/* regclass.c */ 177752284Sobrien 177818334Speter/* Maximum number of parallel sets and clobbers in any insn in this fn. 1779132718Skan Always at least 3, since the combiner could put that many together 178018334Speter and we want this to remain correct for all the remaining passes. */ 178118334Speter 178218334Speterextern int max_parallel; 178318334Speter 178452284Sobrien/* Free up register info memory. */ 1785132718Skanextern void free_reg_info (void); 178652284Sobrien 178752284Sobrien/* recog.c */ 1788132718Skanextern int asm_noperands (rtx); 1789132718Skanextern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **, 1790132718Skan enum machine_mode *); 179118334Speter 1792132718Skanextern enum reg_class reg_preferred_class (int); 1793132718Skanextern enum reg_class reg_alternate_class (int); 179418334Speter 1795132718Skanextern void split_all_insns (int); 1796169689Skanextern unsigned int split_all_insns_noflow (void); 179752284Sobrien 179850397Sobrien#define MAX_SAVED_CONST_INT 64 1799117395Skanextern GTY(()) rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1]; 180050397Sobrien 180190075Sobrien#define const0_rtx (const_int_rtx[MAX_SAVED_CONST_INT]) 180290075Sobrien#define const1_rtx (const_int_rtx[MAX_SAVED_CONST_INT+1]) 180390075Sobrien#define const2_rtx (const_int_rtx[MAX_SAVED_CONST_INT+2]) 180490075Sobrien#define constm1_rtx (const_int_rtx[MAX_SAVED_CONST_INT-1]) 1805117395Skanextern GTY(()) rtx const_true_rtx; 180618334Speter 1807117395Skanextern GTY(()) rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE]; 180818334Speter 180990075Sobrien/* Returns a constant 0 rtx in mode MODE. Integer modes are treated the 181018334Speter same as VOIDmode. */ 181118334Speter 181218334Speter#define CONST0_RTX(MODE) (const_tiny_rtx[0][(int) (MODE)]) 181318334Speter 181418334Speter/* Likewise, for the constants 1 and 2. */ 181518334Speter 181618334Speter#define CONST1_RTX(MODE) (const_tiny_rtx[1][(int) (MODE)]) 181718334Speter#define CONST2_RTX(MODE) (const_tiny_rtx[2][(int) (MODE)]) 181818334Speter 181990075Sobrien/* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg 182090075Sobrien is used to represent the frame pointer. This is because the 182190075Sobrien hard frame pointer and the automatic variables are separated by an amount 182290075Sobrien that cannot be determined until after register allocation. We can assume 182390075Sobrien that in this case ELIMINABLE_REGS will be defined, one action of which 182490075Sobrien will be to eliminate FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. */ 182590075Sobrien#ifndef HARD_FRAME_POINTER_REGNUM 182690075Sobrien#define HARD_FRAME_POINTER_REGNUM FRAME_POINTER_REGNUM 182790075Sobrien#endif 182890075Sobrien 182990075Sobrien/* Index labels for global_rtl. */ 183090075Sobrienenum global_rtl_index 183150397Sobrien{ 183290075Sobrien GR_PC, 183390075Sobrien GR_CC0, 183490075Sobrien GR_STACK_POINTER, 183590075Sobrien GR_FRAME_POINTER, 183690075Sobrien/* For register elimination to work properly these hard_frame_pointer_rtx, 183790075Sobrien frame_pointer_rtx, and arg_pointer_rtx must be the same if they refer to 183890075Sobrien the same register. */ 183990075Sobrien#if FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM 184090075Sobrien GR_ARG_POINTER = GR_FRAME_POINTER, 184190075Sobrien#endif 184290075Sobrien#if HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM 184390075Sobrien GR_HARD_FRAME_POINTER = GR_FRAME_POINTER, 184490075Sobrien#else 184590075Sobrien GR_HARD_FRAME_POINTER, 184690075Sobrien#endif 184790075Sobrien#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM 184890075Sobrien#if HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM 184990075Sobrien GR_ARG_POINTER = GR_HARD_FRAME_POINTER, 185090075Sobrien#else 185190075Sobrien GR_ARG_POINTER, 185290075Sobrien#endif 185390075Sobrien#endif 185490075Sobrien GR_VIRTUAL_INCOMING_ARGS, 185590075Sobrien GR_VIRTUAL_STACK_ARGS, 185690075Sobrien GR_VIRTUAL_STACK_DYNAMIC, 185790075Sobrien GR_VIRTUAL_OUTGOING_ARGS, 185890075Sobrien GR_VIRTUAL_CFA, 185950397Sobrien 186090075Sobrien GR_MAX 186190075Sobrien}; 186290075Sobrien 186390075Sobrien/* Pointers to standard pieces of rtx are stored here. */ 1864117395Skanextern GTY(()) rtx global_rtl[GR_MAX]; 186590075Sobrien 186690075Sobrien/* Standard pieces of rtx, to be substituted directly into things. */ 186790075Sobrien#define pc_rtx (global_rtl[GR_PC]) 186890075Sobrien#define cc0_rtx (global_rtl[GR_CC0]) 186990075Sobrien 187018334Speter/* All references to certain hard regs, except those created 187118334Speter by allocating pseudo regs into them (when that's possible), 187218334Speter go through these unique rtx objects. */ 187390075Sobrien#define stack_pointer_rtx (global_rtl[GR_STACK_POINTER]) 187490075Sobrien#define frame_pointer_rtx (global_rtl[GR_FRAME_POINTER]) 187590075Sobrien#define hard_frame_pointer_rtx (global_rtl[GR_HARD_FRAME_POINTER]) 187690075Sobrien#define arg_pointer_rtx (global_rtl[GR_ARG_POINTER]) 187750397Sobrien 1878117395Skanextern GTY(()) rtx pic_offset_table_rtx; 1879117395Skanextern GTY(()) rtx static_chain_rtx; 1880117395Skanextern GTY(()) rtx static_chain_incoming_rtx; 1881117395Skanextern GTY(()) rtx return_address_pointer_rtx; 188218334Speter 188350397Sobrien/* Include the RTL generation functions. */ 188450397Sobrien 1885169689Skan#ifndef GENERATOR_FILE 188650397Sobrien#include "genrtl.h" 1887169689Skan#ifndef USE_MAPPED_LOCATION 1888169689Skan#undef gen_rtx_ASM_OPERANDS 1889169689Skan#define gen_rtx_ASM_OPERANDS(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, LOC) \ 1890169689Skan gen_rtx_fmt_ssiEEsi (ASM_OPERANDS, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (LOC).file, (LOC).line) 189150397Sobrien#endif 1892169689Skan#endif 189350397Sobrien 189450397Sobrien/* There are some RTL codes that require special attention; the 189550397Sobrien generation functions included above do the raw handling. If you 1896169689Skan add to this list, modify special_rtx in gengenrtl.c as well. */ 189750397Sobrien 1898132718Skanextern rtx gen_rtx_CONST_INT (enum machine_mode, HOST_WIDE_INT); 1899132718Skanextern rtx gen_rtx_CONST_VECTOR (enum machine_mode, rtvec); 1900132718Skanextern rtx gen_raw_REG (enum machine_mode, int); 1901132718Skanextern rtx gen_rtx_REG (enum machine_mode, unsigned); 1902132718Skanextern rtx gen_rtx_SUBREG (enum machine_mode, rtx, int); 1903132718Skanextern rtx gen_rtx_MEM (enum machine_mode, rtx); 190450397Sobrien 1905169689Skan#define GEN_INT(N) gen_rtx_CONST_INT (VOIDmode, (N)) 190690075Sobrien 190718334Speter/* Virtual registers are used during RTL generation to refer to locations into 190818334Speter the stack frame when the actual location isn't known until RTL generation 190918334Speter is complete. The routine instantiate_virtual_regs replaces these with 191018334Speter the proper value, which is normally {frame,arg,stack}_pointer_rtx plus 191118334Speter a constant. */ 191218334Speter 191318334Speter#define FIRST_VIRTUAL_REGISTER (FIRST_PSEUDO_REGISTER) 191418334Speter 191518334Speter/* This points to the first word of the incoming arguments passed on the stack, 191618334Speter either by the caller or by the callee when pretending it was passed by the 191718334Speter caller. */ 191818334Speter 191990075Sobrien#define virtual_incoming_args_rtx (global_rtl[GR_VIRTUAL_INCOMING_ARGS]) 192018334Speter 192118334Speter#define VIRTUAL_INCOMING_ARGS_REGNUM (FIRST_VIRTUAL_REGISTER) 192218334Speter 192318334Speter/* If FRAME_GROWS_DOWNWARD, this points to immediately above the first 192418334Speter variable on the stack. Otherwise, it points to the first variable on 192518334Speter the stack. */ 192618334Speter 192790075Sobrien#define virtual_stack_vars_rtx (global_rtl[GR_VIRTUAL_STACK_ARGS]) 192818334Speter 192918334Speter#define VIRTUAL_STACK_VARS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 1) 193018334Speter 193118334Speter/* This points to the location of dynamically-allocated memory on the stack 193218334Speter immediately after the stack pointer has been adjusted by the amount 193318334Speter desired. */ 193418334Speter 193590075Sobrien#define virtual_stack_dynamic_rtx (global_rtl[GR_VIRTUAL_STACK_DYNAMIC]) 193618334Speter 193718334Speter#define VIRTUAL_STACK_DYNAMIC_REGNUM ((FIRST_VIRTUAL_REGISTER) + 2) 193818334Speter 193918334Speter/* This points to the location in the stack at which outgoing arguments should 194018334Speter be written when the stack is pre-pushed (arguments pushed using push 194118334Speter insns always use sp). */ 194218334Speter 194390075Sobrien#define virtual_outgoing_args_rtx (global_rtl[GR_VIRTUAL_OUTGOING_ARGS]) 194418334Speter 194518334Speter#define VIRTUAL_OUTGOING_ARGS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 3) 194618334Speter 194752284Sobrien/* This points to the Canonical Frame Address of the function. This 1948132718Skan should correspond to the CFA produced by INCOMING_FRAME_SP_OFFSET, 194952284Sobrien but is calculated relative to the arg pointer for simplicity; the 195090075Sobrien frame pointer nor stack pointer are necessarily fixed relative to 195152284Sobrien the CFA until after reload. */ 195218334Speter 195390075Sobrien#define virtual_cfa_rtx (global_rtl[GR_VIRTUAL_CFA]) 195452284Sobrien 195552284Sobrien#define VIRTUAL_CFA_REGNUM ((FIRST_VIRTUAL_REGISTER) + 4) 195652284Sobrien 195752284Sobrien#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4) 195852284Sobrien 195990075Sobrien/* Nonzero if REGNUM is a pointer into the stack frame. */ 1960132718Skan#define REGNO_PTR_FRAME_P(REGNUM) \ 196190075Sobrien ((REGNUM) == STACK_POINTER_REGNUM \ 196290075Sobrien || (REGNUM) == FRAME_POINTER_REGNUM \ 196390075Sobrien || (REGNUM) == HARD_FRAME_POINTER_REGNUM \ 196490075Sobrien || (REGNUM) == ARG_POINTER_REGNUM \ 196590075Sobrien || ((REGNUM) >= FIRST_VIRTUAL_REGISTER \ 196690075Sobrien && (REGNUM) <= LAST_VIRTUAL_REGISTER)) 196718334Speter 196890075Sobrien/* REGNUM never really appearing in the INSN stream. */ 196990075Sobrien#define INVALID_REGNUM (~(unsigned int) 0) 197018334Speter 1971132718Skanextern rtx output_constant_def (tree, int); 1972132718Skanextern rtx lookup_constant_def (tree); 197390075Sobrien 197452284Sobrien/* Nonzero after the second flow pass has completed. 197552284Sobrien Set to 1 or 0 by toplev.c */ 197652284Sobrienextern int flow2_completed; 197752284Sobrien 197818334Speter/* Nonzero after end of reload pass. 197952284Sobrien Set to 1 or 0 by reload1.c. */ 198018334Speter 198118334Speterextern int reload_completed; 198218334Speter 1983132718Skan/* Nonzero after thread_prologue_and_epilogue_insns has run. */ 1984132718Skanextern int epilogue_completed; 1985132718Skan 198618334Speter/* Set to 1 while reload_as_needed is operating. 198718334Speter Required by some machines to handle any generated moves differently. */ 198818334Speter 198918334Speterextern int reload_in_progress; 199018334Speter 1991169689Skan#ifdef STACK_REGS 1992169689Skan/* Nonzero after end of regstack pass. 1993169689Skan Set to 1 or 0 by reg-stack.c. */ 1994169689Skanextern int regstack_completed; 1995169689Skan#endif 1996169689Skan 199718334Speter/* If this is nonzero, we do not bother generating VOLATILE 199818334Speter around volatile memory references, and we are willing to 199918334Speter output indirect addresses. If cse is to follow, we reject 200018334Speter indirect addresses so a useful potential cse is generated; 200118334Speter if it is used only once, instruction combination will produce 200218334Speter the same indirect address eventually. */ 200318334Speterextern int cse_not_expected; 200418334Speter 200552284Sobrien/* Set to nonzero before life analysis to indicate that it is unsafe to 200652284Sobrien generate any new pseudo registers. */ 200752284Sobrienextern int no_new_pseudos; 200852284Sobrien 200918334Speter/* Translates rtx code to tree code, for those codes needed by 201018334Speter REAL_ARITHMETIC. The function returns an int because the caller may not 201118334Speter know what `enum tree_code' means. */ 201218334Speter 2013132718Skanextern int rtx_to_tree_code (enum rtx_code); 201450397Sobrien 201550397Sobrien/* In cse.c */ 2016132718Skanextern int delete_trivially_dead_insns (rtx, int); 2017169689Skanextern int cse_main (rtx, int); 2018169689Skanextern int exp_equiv_p (rtx, rtx, int, bool); 2019169689Skanextern unsigned hash_rtx (rtx x, enum machine_mode, int *, int *, bool); 202050397Sobrien 202150397Sobrien/* In jump.c */ 2022132718Skanextern int comparison_dominates_p (enum rtx_code, enum rtx_code); 2023132718Skanextern int condjump_p (rtx); 2024132718Skanextern int any_condjump_p (rtx); 2025132718Skanextern int any_uncondjump_p (rtx); 2026132718Skanextern rtx pc_set (rtx); 2027132718Skanextern rtx condjump_label (rtx); 2028132718Skanextern int simplejump_p (rtx); 2029132718Skanextern int returnjump_p (rtx); 2030132718Skanextern int onlyjump_p (rtx); 2031132718Skanextern int only_sets_cc0_p (rtx); 2032132718Skanextern int sets_cc0_p (rtx); 2033132718Skanextern int invert_jump_1 (rtx, rtx); 2034132718Skanextern int invert_jump (rtx, rtx, int); 2035132718Skanextern int rtx_renumbered_equal_p (rtx, rtx); 2036132718Skanextern int true_regnum (rtx); 2037132718Skanextern unsigned int reg_or_subregno (rtx); 2038132718Skanextern int redirect_jump_1 (rtx, rtx); 2039169689Skanextern void redirect_jump_2 (rtx, rtx, rtx, int, int); 2040132718Skanextern int redirect_jump (rtx, rtx, int); 2041132718Skanextern void rebuild_jump_labels (rtx); 2042169689Skanextern rtx reversed_comparison (rtx, enum machine_mode); 2043132718Skanextern enum rtx_code reversed_comparison_code (rtx, rtx); 2044132718Skanextern enum rtx_code reversed_comparison_code_parts (enum rtx_code, 2045132718Skan rtx, rtx, rtx); 2046132718Skanextern void delete_for_peephole (rtx, rtx); 2047132718Skanextern int condjump_in_parallel_p (rtx); 2048169689Skanextern unsigned int purge_line_number_notes (void); 204950397Sobrien 205090075Sobrien/* In emit-rtl.c. */ 2051132718Skanextern int max_reg_num (void); 2052132718Skanextern int max_label_num (void); 2053132718Skanextern int get_first_label_num (void); 2054169689Skanextern void maybe_set_first_label_num (rtx); 2055132718Skanextern void delete_insns_since (rtx); 2056132718Skanextern void mark_reg_pointer (rtx, int); 2057132718Skanextern void mark_user_reg (rtx); 2058132718Skanextern void reset_used_flags (rtx); 2059132718Skanextern void set_used_flags (rtx); 2060132718Skanextern void reorder_insns (rtx, rtx, rtx); 2061132718Skanextern void reorder_insns_nobb (rtx, rtx, rtx); 2062132718Skanextern int get_max_uid (void); 2063132718Skanextern int in_sequence_p (void); 2064132718Skanextern void force_next_line_note (void); 2065132718Skanextern void init_emit (void); 2066132718Skanextern void init_emit_once (int); 2067132718Skanextern void push_topmost_sequence (void); 2068132718Skanextern void pop_topmost_sequence (void); 2069132718Skanextern void set_new_first_and_last_insn (rtx, rtx); 2070169689Skanextern unsigned int unshare_all_rtl (void); 2071132718Skanextern void unshare_all_rtl_again (rtx); 2072132718Skanextern void unshare_all_rtl_in_chain (rtx); 2073132718Skanextern void verify_rtl_sharing (void); 2074132718Skanextern void set_first_insn (rtx); 2075132718Skanextern void set_last_insn (rtx); 2076132718Skanextern void link_cc0_insns (rtx); 2077132718Skanextern void add_insn (rtx); 2078132718Skanextern void add_insn_before (rtx, rtx); 2079132718Skanextern void add_insn_after (rtx, rtx); 2080132718Skanextern void remove_insn (rtx); 2081132718Skanextern void emit_insn_after_with_line_notes (rtx, rtx, rtx); 2082132718Skanextern rtx emit (rtx); 2083169689Skanextern void renumber_insns (void); 2084132718Skanextern rtx delete_insn (rtx); 2085169689Skanextern rtx entry_of_function (void); 2086169689Skanextern void emit_insn_at_entry (rtx); 2087132718Skanextern void delete_insn_chain (rtx, rtx); 2088132718Skanextern rtx unlink_insn_chain (rtx, rtx); 2089132718Skanextern rtx delete_insn_and_edges (rtx); 2090132718Skanextern void delete_insn_chain_and_edges (rtx, rtx); 2091169689Skanextern rtx gen_lowpart_SUBREG (enum machine_mode, rtx); 2092169689Skanextern rtx gen_const_mem (enum machine_mode, rtx); 2093169689Skanextern rtx gen_frame_mem (enum machine_mode, rtx); 2094169689Skanextern rtx gen_tmp_stack_mem (enum machine_mode, rtx); 2095169689Skanextern bool validate_subreg (enum machine_mode, enum machine_mode, 2096169689Skan rtx, unsigned int); 209750397Sobrien 209850397Sobrien/* In combine.c */ 2099132718Skanextern unsigned int extended_count (rtx, enum machine_mode, int); 2100132718Skanextern rtx remove_death (unsigned int, rtx); 2101132718Skanextern void dump_combine_stats (FILE *); 2102132718Skanextern void dump_combine_total_stats (FILE *); 210350397Sobrien 2104169689Skan/* In sched-vis.c. */ 2105169689Skanextern void print_rtl_slim_with_bb (FILE *, rtx, int); 2106169689Skanextern void dump_insn_slim (FILE *f, rtx x); 2107169689Skanextern void debug_insn_slim (rtx x); 2108169689Skan 2109169689Skan/* In sched-rgn.c. */ 2110169689Skanextern void schedule_insns (void); 2111169689Skan 2112169689Skan/* In sched-ebb.c. */ 2113169689Skanextern void schedule_ebbs (void); 2114169689Skan 2115169689Skan/* In haifa-sched.c. */ 2116132718Skanextern void fix_sched_param (const char *, const char *); 211750397Sobrien 211850397Sobrien/* In print-rtl.c */ 211990075Sobrienextern const char *print_rtx_head; 2120132718Skanextern void debug_rtx (rtx); 2121132718Skanextern void debug_rtx_list (rtx, int); 2122132718Skanextern void debug_rtx_range (rtx, rtx); 2123132718Skanextern rtx debug_rtx_find (rtx, int); 2124132718Skanextern void print_mem_expr (FILE *, tree); 2125132718Skanextern void print_rtl (FILE *, rtx); 2126132718Skanextern void print_simple_rtl (FILE *, rtx); 2127132718Skanextern int print_rtl_single (FILE *, rtx); 2128132718Skanextern void print_inline_rtx (FILE *, rtx, int); 212950397Sobrien 2130169689Skan/* In bt-load.c */ 2131169689Skanextern void branch_target_load_optimize (bool); 213250397Sobrien 213350397Sobrien/* In function.c */ 2134132718Skanextern void reposition_prologue_and_epilogue_notes (rtx); 2135132718Skanextern void thread_prologue_and_epilogue_insns (rtx); 2136132718Skanextern int prologue_epilogue_contains (rtx); 2137132718Skanextern int sibcall_epilogue_contains (rtx); 2138132718Skanextern void mark_temp_addr_taken (rtx); 2139132718Skanextern void update_temp_slot_address (rtx, rtx); 214050397Sobrien 214150397Sobrien/* In stmt.c */ 2142132718Skanextern void expand_null_return (void); 2143132718Skanextern void expand_naked_return (void); 2144132718Skanextern void emit_jump (rtx); 214550397Sobrien 214650397Sobrien/* In expr.c */ 2147132718Skanextern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT, 2148132718Skan unsigned int, int); 214950397Sobrien 215050397Sobrien/* In flow.c */ 2151132718Skanextern void delete_dead_jumptables (void); 2152132718Skanextern void print_rtl_with_bb (FILE *, rtx); 2153169689Skanextern void dump_flow_info (FILE *, int); 215450397Sobrien 215550397Sobrien/* In expmed.c */ 2156132718Skanextern void init_expmed (void); 2157132718Skanextern void expand_inc (rtx, rtx); 2158132718Skanextern void expand_dec (rtx, rtx); 215950397Sobrien 216050397Sobrien/* In gcse.c */ 2161132718Skanextern bool can_copy_p (enum machine_mode); 2162132718Skanextern rtx fis_get_condition (rtx); 216350397Sobrien 216450397Sobrien/* In global.c */ 2165132718Skanextern void mark_elimination (int, int); 2166132718Skanextern void dump_global_regs (FILE *); 216750397Sobrien#ifdef HARD_CONST 2168117395Skan/* Yes, this ifdef is silly, but HARD_REG_SET is not always defined. */ 2169132718Skanextern void retry_global_alloc (int, HARD_REG_SET); 217050397Sobrien#endif 2171132718Skanextern void build_insn_chain (rtx); 217250397Sobrien 217350397Sobrien/* In regclass.c */ 2174132718Skanextern int reg_classes_intersect_p (enum reg_class, enum reg_class); 2175132718Skanextern int reg_class_subset_p (enum reg_class, enum reg_class); 2176132718Skanextern void globalize_reg (int); 2177132718Skanextern void init_reg_modes_once (void); 2178132718Skanextern void init_regs (void); 2179132718Skanextern void init_fake_stack_mems (void); 2180132718Skanextern void init_reg_sets (void); 2181132718Skanextern void regclass_init (void); 2182169689Skanextern void regclass (rtx, int); 2183169689Skanextern void reg_scan (rtx, unsigned int); 2184132718Skanextern void fix_register (const char *, int, int); 2185146895Skanextern void init_subregs_of_mode (void); 2186146895Skanextern void record_subregs_of_mode (rtx); 2187117395Skan#ifdef HARD_CONST 2188132718Skanextern void cannot_change_mode_set_regs (HARD_REG_SET *, 2189132718Skan enum machine_mode, unsigned int); 2190117395Skan#endif 2191132718Skanextern bool invalid_mode_change_p (unsigned int, enum reg_class, 2192132718Skan enum machine_mode); 219350397Sobrien 219450397Sobrien/* In reorg.c */ 2195169689Skanextern void dbr_schedule (rtx); 219650397Sobrien 219750397Sobrien/* In local-alloc.c */ 2198132718Skanextern void dump_local_alloc (FILE *); 2199169689Skan 2200169689Skan/* In reload1.c */ 2201132718Skanextern int function_invariant_p (rtx); 220250397Sobrien 220350397Sobrien/* In calls.c */ 220490075Sobrienenum libcall_type 220590075Sobrien{ 220690075Sobrien LCT_NORMAL = 0, 220790075Sobrien LCT_CONST = 1, 220890075Sobrien LCT_PURE = 2, 220990075Sobrien LCT_CONST_MAKE_BLOCK = 3, 221090075Sobrien LCT_PURE_MAKE_BLOCK = 4, 221190075Sobrien LCT_NORETURN = 5, 221290075Sobrien LCT_THROW = 6, 2213169689Skan LCT_RETURNS_TWICE = 7 221490075Sobrien}; 221550397Sobrien 2216132718Skanextern void emit_library_call (rtx, enum libcall_type, enum machine_mode, int, 2217132718Skan ...); 2218132718Skanextern rtx emit_library_call_value (rtx, rtx, enum libcall_type, 2219132718Skan enum machine_mode, int, ...); 222090075Sobrien 222150397Sobrien/* In varasm.c */ 2222132718Skanextern void init_varasm_once (void); 2223169689Skanextern enum tls_model decl_default_tls_model (tree); 2224169689Skan 222550397Sobrien/* In rtl.c */ 2226132718Skanextern void traverse_md_constants (int (*) (void **, void *), void *); 222790075Sobrienstruct md_constant { char *name, *value; }; 222850397Sobrien 2229169689Skan/* In read-rtl.c */ 2230132718Skanextern int read_skip_spaces (FILE *); 2231169689Skanextern bool read_rtx (FILE *, rtx *, int *); 2232169689Skanextern void copy_rtx_ptr_loc (const void *, const void *); 2233169689Skanextern void print_rtx_ptr_loc (const void *); 2234169689Skanextern const char *join_c_conditions (const char *, const char *); 2235169689Skanextern void print_c_condition (const char *); 223690075Sobrienextern const char *read_rtx_filename; 223790075Sobrienextern int read_rtx_lineno; 223890075Sobrien 223950397Sobrien/* In alias.c */ 2240132718Skanextern void clear_reg_alias_info (rtx); 2241132718Skanextern rtx canon_rtx (rtx); 2242132718Skanextern int true_dependence (rtx, enum machine_mode, rtx, int (*)(rtx, int)); 2243132718Skanextern rtx get_addr (rtx); 2244132718Skanextern int canon_true_dependence (rtx, enum machine_mode, rtx, rtx, 2245132718Skan int (*)(rtx, int)); 2246132718Skanextern int read_dependence (rtx, rtx); 2247132718Skanextern int anti_dependence (rtx, rtx); 2248132718Skanextern int output_dependence (rtx, rtx); 2249132718Skanextern void init_alias_once (void); 2250132718Skanextern void init_alias_analysis (void); 2251132718Skanextern void end_alias_analysis (void); 2252132718Skanextern bool memory_modified_in_insn_p (rtx, rtx); 2253132718Skanextern rtx find_base_term (rtx); 2254169689Skanextern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int); 2255132718Skanextern rtx get_reg_known_value (unsigned int); 2256132718Skanextern bool get_reg_known_equiv_p (unsigned int); 225750397Sobrien 225852284Sobrien#ifdef STACK_REGS 2259132718Skanextern int stack_regs_mentioned (rtx insn); 226052284Sobrien#endif 226152284Sobrien 226290075Sobrien/* In toplev.c */ 2263117395Skanextern GTY(()) rtx stack_limit_rtx; 226490075Sobrien 226590075Sobrien/* In predict.c */ 2266132718Skanextern void invert_br_probabilities (rtx); 2267132718Skanextern bool expensive_function_p (int); 2268117395Skan/* In tracer.c */ 2269132718Skanextern void tracer (unsigned int); 2270117395Skan 2271169689Skan/* In var-tracking.c */ 2272169689Skanextern unsigned int variable_tracking_main (void); 2273169689Skan 2274169689Skan/* In stor-layout.c. */ 2275169689Skanextern void get_mode_bounds (enum machine_mode, int, enum machine_mode, 2276169689Skan rtx *, rtx *); 2277169689Skan 2278169689Skan/* In loop-unswitch.c */ 2279169689Skanextern rtx reversed_condition (rtx); 2280169689Skanextern rtx compare_and_jump_seq (rtx, rtx, enum rtx_code, rtx, int, rtx); 2281169689Skan 2282169689Skan/* In loop-iv.c */ 2283169689Skanextern rtx canon_condition (rtx); 2284169689Skanextern void simplify_using_condition (rtx, rtx *, struct bitmap_head_def *); 2285169689Skan 2286169689Skanstruct rtl_hooks 2287169689Skan{ 2288169689Skan rtx (*gen_lowpart) (enum machine_mode, rtx); 2289169689Skan rtx (*gen_lowpart_no_emit) (enum machine_mode, rtx); 2290169689Skan rtx (*reg_nonzero_bits) (rtx, enum machine_mode, rtx, enum machine_mode, 2291169689Skan unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT *); 2292169689Skan rtx (*reg_num_sign_bit_copies) (rtx, enum machine_mode, rtx, enum machine_mode, 2293169689Skan unsigned int, unsigned int *); 2294169689Skan bool (*reg_truncated_to_mode) (enum machine_mode, rtx); 2295169689Skan 2296169689Skan /* Whenever you add entries here, make sure you adjust rtlhooks-def.h. */ 2297169689Skan}; 2298169689Skan 2299169689Skan/* Each pass can provide its own. */ 2300169689Skanextern struct rtl_hooks rtl_hooks; 2301169689Skan 2302169689Skan/* ... but then it has to restore these. */ 2303169689Skanextern const struct rtl_hooks general_rtl_hooks; 2304169689Skan 2305169689Skan/* Keep this for the nonce. */ 2306169689Skan#define gen_lowpart rtl_hooks.gen_lowpart 2307169689Skan 230890075Sobrien#endif /* ! GCC_RTL_H */ 2309