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