138fd1498Szrj /* Register Transfer Language (RTL) definitions for GCC
238fd1498Szrj Copyright (C) 1987-2018 Free Software Foundation, Inc.
338fd1498Szrj
438fd1498Szrj This file is part of GCC.
538fd1498Szrj
638fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
738fd1498Szrj the terms of the GNU General Public License as published by the Free
838fd1498Szrj Software Foundation; either version 3, or (at your option) any later
938fd1498Szrj version.
1038fd1498Szrj
1138fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1238fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
1338fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1438fd1498Szrj for more details.
1538fd1498Szrj
1638fd1498Szrj You should have received a copy of the GNU General Public License
1738fd1498Szrj along with GCC; see the file COPYING3. If not see
1838fd1498Szrj <http://www.gnu.org/licenses/>. */
1938fd1498Szrj
2038fd1498Szrj #ifndef GCC_RTL_H
2138fd1498Szrj #define GCC_RTL_H
2238fd1498Szrj
2338fd1498Szrj /* This file is occasionally included by generator files which expect
2438fd1498Szrj machmode.h and other files to exist and would not normally have been
2538fd1498Szrj included by coretypes.h. */
2638fd1498Szrj #ifdef GENERATOR_FILE
2738fd1498Szrj #include "real.h"
2838fd1498Szrj #include "fixed-value.h"
2938fd1498Szrj #include "statistics.h"
3038fd1498Szrj #include "vec.h"
3138fd1498Szrj #include "hash-table.h"
3238fd1498Szrj #include "hash-set.h"
3338fd1498Szrj #include "input.h"
3438fd1498Szrj #include "is-a.h"
3538fd1498Szrj #endif /* GENERATOR_FILE */
3638fd1498Szrj
3738fd1498Szrj #include "hard-reg-set.h"
3838fd1498Szrj
3938fd1498Szrj /* Value used by some passes to "recognize" noop moves as valid
4038fd1498Szrj instructions. */
4138fd1498Szrj #define NOOP_MOVE_INSN_CODE INT_MAX
4238fd1498Szrj
4338fd1498Szrj /* Register Transfer Language EXPRESSIONS CODES */
4438fd1498Szrj
4538fd1498Szrj #define RTX_CODE enum rtx_code
4638fd1498Szrj enum rtx_code {
4738fd1498Szrj
4838fd1498Szrj #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
4938fd1498Szrj #include "rtl.def" /* rtl expressions are documented here */
5038fd1498Szrj #undef DEF_RTL_EXPR
5138fd1498Szrj
5238fd1498Szrj LAST_AND_UNUSED_RTX_CODE}; /* A convenient way to get a value for
5338fd1498Szrj NUM_RTX_CODE.
5438fd1498Szrj Assumes default enum value assignment. */
5538fd1498Szrj
5638fd1498Szrj /* The cast here, saves many elsewhere. */
5738fd1498Szrj #define NUM_RTX_CODE ((int) LAST_AND_UNUSED_RTX_CODE)
5838fd1498Szrj
5938fd1498Szrj /* Similar, but since generator files get more entries... */
6038fd1498Szrj #ifdef GENERATOR_FILE
6138fd1498Szrj # define NON_GENERATOR_NUM_RTX_CODE ((int) MATCH_OPERAND)
6238fd1498Szrj #endif
6338fd1498Szrj
6438fd1498Szrj /* Register Transfer Language EXPRESSIONS CODE CLASSES */
6538fd1498Szrj
6638fd1498Szrj enum rtx_class {
6738fd1498Szrj /* We check bit 0-1 of some rtx class codes in the predicates below. */
6838fd1498Szrj
6938fd1498Szrj /* Bit 0 = comparison if 0, arithmetic is 1
7038fd1498Szrj Bit 1 = 1 if commutative. */
7138fd1498Szrj RTX_COMPARE, /* 0 */
7238fd1498Szrj RTX_COMM_COMPARE,
7338fd1498Szrj RTX_BIN_ARITH,
7438fd1498Szrj RTX_COMM_ARITH,
7538fd1498Szrj
7638fd1498Szrj /* Must follow the four preceding values. */
7738fd1498Szrj RTX_UNARY, /* 4 */
7838fd1498Szrj
7938fd1498Szrj RTX_EXTRA,
8038fd1498Szrj RTX_MATCH,
8138fd1498Szrj RTX_INSN,
8238fd1498Szrj
8338fd1498Szrj /* Bit 0 = 1 if constant. */
8438fd1498Szrj RTX_OBJ, /* 8 */
8538fd1498Szrj RTX_CONST_OBJ,
8638fd1498Szrj
8738fd1498Szrj RTX_TERNARY,
8838fd1498Szrj RTX_BITFIELD_OPS,
8938fd1498Szrj RTX_AUTOINC
9038fd1498Szrj };
9138fd1498Szrj
9238fd1498Szrj #define RTX_OBJ_MASK (~1)
9338fd1498Szrj #define RTX_OBJ_RESULT (RTX_OBJ & RTX_OBJ_MASK)
9438fd1498Szrj #define RTX_COMPARE_MASK (~1)
9538fd1498Szrj #define RTX_COMPARE_RESULT (RTX_COMPARE & RTX_COMPARE_MASK)
9638fd1498Szrj #define RTX_ARITHMETIC_MASK (~1)
9738fd1498Szrj #define RTX_ARITHMETIC_RESULT (RTX_COMM_ARITH & RTX_ARITHMETIC_MASK)
9838fd1498Szrj #define RTX_BINARY_MASK (~3)
9938fd1498Szrj #define RTX_BINARY_RESULT (RTX_COMPARE & RTX_BINARY_MASK)
10038fd1498Szrj #define RTX_COMMUTATIVE_MASK (~2)
10138fd1498Szrj #define RTX_COMMUTATIVE_RESULT (RTX_COMM_COMPARE & RTX_COMMUTATIVE_MASK)
10238fd1498Szrj #define RTX_NON_COMMUTATIVE_RESULT (RTX_COMPARE & RTX_COMMUTATIVE_MASK)
10338fd1498Szrj
10438fd1498Szrj extern const unsigned char rtx_length[NUM_RTX_CODE];
10538fd1498Szrj #define GET_RTX_LENGTH(CODE) (rtx_length[(int) (CODE)])
10638fd1498Szrj
10738fd1498Szrj extern const char * const rtx_name[NUM_RTX_CODE];
10838fd1498Szrj #define GET_RTX_NAME(CODE) (rtx_name[(int) (CODE)])
10938fd1498Szrj
11038fd1498Szrj extern const char * const rtx_format[NUM_RTX_CODE];
11138fd1498Szrj #define GET_RTX_FORMAT(CODE) (rtx_format[(int) (CODE)])
11238fd1498Szrj
11338fd1498Szrj extern const enum rtx_class rtx_class[NUM_RTX_CODE];
11438fd1498Szrj #define GET_RTX_CLASS(CODE) (rtx_class[(int) (CODE)])
11538fd1498Szrj
11638fd1498Szrj /* True if CODE is part of the insn chain (i.e. has INSN_UID, PREV_INSN
11738fd1498Szrj and NEXT_INSN fields). */
11838fd1498Szrj #define INSN_CHAIN_CODE_P(CODE) IN_RANGE (CODE, DEBUG_INSN, NOTE)
11938fd1498Szrj
12038fd1498Szrj extern const unsigned char rtx_code_size[NUM_RTX_CODE];
12138fd1498Szrj extern const unsigned char rtx_next[NUM_RTX_CODE];
12238fd1498Szrj
12338fd1498Szrj /* The flags and bitfields of an ADDR_DIFF_VEC. BASE is the base label
12438fd1498Szrj relative to which the offsets are calculated, as explained in rtl.def. */
12538fd1498Szrj struct addr_diff_vec_flags
12638fd1498Szrj {
12738fd1498Szrj /* Set at the start of shorten_branches - ONLY WHEN OPTIMIZING - : */
12838fd1498Szrj unsigned min_align: 8;
12938fd1498Szrj /* Flags: */
13038fd1498Szrj unsigned base_after_vec: 1; /* BASE is after the ADDR_DIFF_VEC. */
13138fd1498Szrj unsigned min_after_vec: 1; /* minimum address target label is
13238fd1498Szrj after the ADDR_DIFF_VEC. */
13338fd1498Szrj unsigned max_after_vec: 1; /* maximum address target label is
13438fd1498Szrj after the ADDR_DIFF_VEC. */
13538fd1498Szrj unsigned min_after_base: 1; /* minimum address target label is
13638fd1498Szrj after BASE. */
13738fd1498Szrj unsigned max_after_base: 1; /* maximum address target label is
13838fd1498Szrj after BASE. */
13938fd1498Szrj /* Set by the actual branch shortening process - ONLY WHEN OPTIMIZING - : */
14038fd1498Szrj unsigned offset_unsigned: 1; /* offsets have to be treated as unsigned. */
14138fd1498Szrj unsigned : 2;
14238fd1498Szrj unsigned scale : 8;
14338fd1498Szrj };
14438fd1498Szrj
14538fd1498Szrj /* Structure used to describe the attributes of a MEM. These are hashed
14638fd1498Szrj so MEMs that the same attributes share a data structure. This means
14738fd1498Szrj they cannot be modified in place. */
14838fd1498Szrj struct GTY(()) mem_attrs
14938fd1498Szrj {
15038fd1498Szrj mem_attrs ();
15138fd1498Szrj
15238fd1498Szrj /* The expression that the MEM accesses, or null if not known.
15338fd1498Szrj This expression might be larger than the memory reference itself.
15438fd1498Szrj (In other words, the MEM might access only part of the object.) */
15538fd1498Szrj tree expr;
15638fd1498Szrj
15738fd1498Szrj /* The offset of the memory reference from the start of EXPR.
15838fd1498Szrj Only valid if OFFSET_KNOWN_P. */
15938fd1498Szrj poly_int64 offset;
16038fd1498Szrj
16138fd1498Szrj /* The size of the memory reference in bytes. Only valid if
16238fd1498Szrj SIZE_KNOWN_P. */
16338fd1498Szrj poly_int64 size;
16438fd1498Szrj
16538fd1498Szrj /* The alias set of the memory reference. */
16638fd1498Szrj alias_set_type alias;
16738fd1498Szrj
16838fd1498Szrj /* The alignment of the reference in bits. Always a multiple of
16938fd1498Szrj BITS_PER_UNIT. Note that EXPR may have a stricter alignment
17038fd1498Szrj than the memory reference itself. */
17138fd1498Szrj unsigned int align;
17238fd1498Szrj
17338fd1498Szrj /* The address space that the memory reference uses. */
17438fd1498Szrj unsigned char addrspace;
17538fd1498Szrj
17638fd1498Szrj /* True if OFFSET is known. */
17738fd1498Szrj bool offset_known_p;
17838fd1498Szrj
17938fd1498Szrj /* True if SIZE is known. */
18038fd1498Szrj bool size_known_p;
18138fd1498Szrj };
18238fd1498Szrj
18338fd1498Szrj /* Structure used to describe the attributes of a REG in similar way as
18438fd1498Szrj mem_attrs does for MEM above. Note that the OFFSET field is calculated
18538fd1498Szrj in the same way as for mem_attrs, rather than in the same way as a
18638fd1498Szrj SUBREG_BYTE. For example, if a big-endian target stores a byte
18738fd1498Szrj object in the low part of a 4-byte register, the OFFSET field
18838fd1498Szrj will be -3 rather than 0. */
18938fd1498Szrj
19038fd1498Szrj struct GTY((for_user)) reg_attrs {
19138fd1498Szrj tree decl; /* decl corresponding to REG. */
19238fd1498Szrj poly_int64 offset; /* Offset from start of DECL. */
19338fd1498Szrj };
19438fd1498Szrj
19538fd1498Szrj /* Common union for an element of an rtx. */
19638fd1498Szrj
19738fd1498Szrj union rtunion
19838fd1498Szrj {
19938fd1498Szrj int rt_int;
20038fd1498Szrj unsigned int rt_uint;
20138fd1498Szrj poly_uint16_pod rt_subreg;
20238fd1498Szrj const char *rt_str;
20338fd1498Szrj rtx rt_rtx;
20438fd1498Szrj rtvec rt_rtvec;
20538fd1498Szrj machine_mode rt_type;
20638fd1498Szrj addr_diff_vec_flags rt_addr_diff_vec_flags;
20738fd1498Szrj struct cselib_val *rt_cselib;
20838fd1498Szrj tree rt_tree;
20938fd1498Szrj basic_block rt_bb;
21038fd1498Szrj mem_attrs *rt_mem;
21138fd1498Szrj struct constant_descriptor_rtx *rt_constant;
21238fd1498Szrj struct dw_cfi_node *rt_cfi;
21338fd1498Szrj };
21438fd1498Szrj
21538fd1498Szrj /* Describes the properties of a REG. */
21638fd1498Szrj struct GTY(()) reg_info {
21738fd1498Szrj /* The value of REGNO. */
21838fd1498Szrj unsigned int regno;
21938fd1498Szrj
22038fd1498Szrj /* The value of REG_NREGS. */
22138fd1498Szrj unsigned int nregs : 8;
22238fd1498Szrj unsigned int unused : 24;
22338fd1498Szrj
22438fd1498Szrj /* The value of REG_ATTRS. */
22538fd1498Szrj reg_attrs *attrs;
22638fd1498Szrj };
22738fd1498Szrj
22838fd1498Szrj /* This structure remembers the position of a SYMBOL_REF within an
22938fd1498Szrj object_block structure. A SYMBOL_REF only provides this information
23038fd1498Szrj if SYMBOL_REF_HAS_BLOCK_INFO_P is true. */
23138fd1498Szrj struct GTY(()) block_symbol {
23238fd1498Szrj /* The usual SYMBOL_REF fields. */
23338fd1498Szrj rtunion GTY ((skip)) fld[2];
23438fd1498Szrj
23538fd1498Szrj /* The block that contains this object. */
23638fd1498Szrj struct object_block *block;
23738fd1498Szrj
23838fd1498Szrj /* The offset of this object from the start of its block. It is negative
23938fd1498Szrj if the symbol has not yet been assigned an offset. */
24038fd1498Szrj HOST_WIDE_INT offset;
24138fd1498Szrj };
24238fd1498Szrj
24338fd1498Szrj /* Describes a group of objects that are to be placed together in such
24438fd1498Szrj a way that their relative positions are known. */
24538fd1498Szrj struct GTY((for_user)) object_block {
24638fd1498Szrj /* The section in which these objects should be placed. */
24738fd1498Szrj section *sect;
24838fd1498Szrj
24938fd1498Szrj /* The alignment of the first object, measured in bits. */
25038fd1498Szrj unsigned int alignment;
25138fd1498Szrj
25238fd1498Szrj /* The total size of the objects, measured in bytes. */
25338fd1498Szrj HOST_WIDE_INT size;
25438fd1498Szrj
25538fd1498Szrj /* The SYMBOL_REFs for each object. The vector is sorted in
25638fd1498Szrj order of increasing offset and the following conditions will
25738fd1498Szrj hold for each element X:
25838fd1498Szrj
25938fd1498Szrj SYMBOL_REF_HAS_BLOCK_INFO_P (X)
26038fd1498Szrj !SYMBOL_REF_ANCHOR_P (X)
26138fd1498Szrj SYMBOL_REF_BLOCK (X) == [address of this structure]
26238fd1498Szrj SYMBOL_REF_BLOCK_OFFSET (X) >= 0. */
26338fd1498Szrj vec<rtx, va_gc> *objects;
26438fd1498Szrj
26538fd1498Szrj /* All the anchor SYMBOL_REFs used to address these objects, sorted
26638fd1498Szrj in order of increasing offset, and then increasing TLS model.
26738fd1498Szrj The following conditions will hold for each element X in this vector:
26838fd1498Szrj
26938fd1498Szrj SYMBOL_REF_HAS_BLOCK_INFO_P (X)
27038fd1498Szrj SYMBOL_REF_ANCHOR_P (X)
27138fd1498Szrj SYMBOL_REF_BLOCK (X) == [address of this structure]
27238fd1498Szrj SYMBOL_REF_BLOCK_OFFSET (X) >= 0. */
27338fd1498Szrj vec<rtx, va_gc> *anchors;
27438fd1498Szrj };
27538fd1498Szrj
27638fd1498Szrj struct GTY((variable_size)) hwivec_def {
27738fd1498Szrj HOST_WIDE_INT elem[1];
27838fd1498Szrj };
27938fd1498Szrj
28038fd1498Szrj /* Number of elements of the HWIVEC if RTX is a CONST_WIDE_INT. */
28138fd1498Szrj #define CWI_GET_NUM_ELEM(RTX) \
28238fd1498Szrj ((int)RTL_FLAG_CHECK1("CWI_GET_NUM_ELEM", (RTX), CONST_WIDE_INT)->u2.num_elem)
28338fd1498Szrj #define CWI_PUT_NUM_ELEM(RTX, NUM) \
28438fd1498Szrj (RTL_FLAG_CHECK1("CWI_PUT_NUM_ELEM", (RTX), CONST_WIDE_INT)->u2.num_elem = (NUM))
28538fd1498Szrj
28638fd1498Szrj struct GTY((variable_size)) const_poly_int_def {
28738fd1498Szrj trailing_wide_ints<NUM_POLY_INT_COEFFS> coeffs;
28838fd1498Szrj };
28938fd1498Szrj
29038fd1498Szrj /* RTL expression ("rtx"). */
29138fd1498Szrj
29238fd1498Szrj /* The GTY "desc" and "tag" options below are a kludge: we need a desc
29338fd1498Szrj field for gengtype to recognize that inheritance is occurring,
29438fd1498Szrj so that all subclasses are redirected to the traversal hook for the
29538fd1498Szrj base class.
29638fd1498Szrj However, all of the fields are in the base class, and special-casing
29738fd1498Szrj is at work. Hence we use desc and tag of 0, generating a switch
29838fd1498Szrj statement of the form:
29938fd1498Szrj switch (0)
30038fd1498Szrj {
30138fd1498Szrj case 0: // all the work happens here
30238fd1498Szrj }
30338fd1498Szrj in order to work with the existing special-casing in gengtype. */
30438fd1498Szrj
30538fd1498Szrj struct GTY((desc("0"), tag("0"),
30638fd1498Szrj chain_next ("RTX_NEXT (&%h)"),
30738fd1498Szrj chain_prev ("RTX_PREV (&%h)"))) rtx_def {
30838fd1498Szrj /* The kind of expression this is. */
30938fd1498Szrj ENUM_BITFIELD(rtx_code) code: 16;
31038fd1498Szrj
31138fd1498Szrj /* The kind of value the expression has. */
31238fd1498Szrj ENUM_BITFIELD(machine_mode) mode : 8;
31338fd1498Szrj
31438fd1498Szrj /* 1 in a MEM if we should keep the alias set for this mem unchanged
31538fd1498Szrj when we access a component.
31638fd1498Szrj 1 in a JUMP_INSN if it is a crossing jump.
31738fd1498Szrj 1 in a CALL_INSN if it is a sibling call.
31838fd1498Szrj 1 in a SET that is for a return.
31938fd1498Szrj In a CODE_LABEL, part of the two-bit alternate entry field.
32038fd1498Szrj 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c.
32138fd1498Szrj 1 in a VALUE is SP_BASED_VALUE_P in cselib.c.
32238fd1498Szrj 1 in a SUBREG generated by LRA for reload insns.
32338fd1498Szrj 1 in a REG if this is a static chain register.
32438fd1498Szrj 1 in a CALL for calls instrumented by Pointer Bounds Checker.
32538fd1498Szrj Dumped as "/j" in RTL dumps. */
32638fd1498Szrj unsigned int jump : 1;
32738fd1498Szrj /* In a CODE_LABEL, part of the two-bit alternate entry field.
32838fd1498Szrj 1 in a MEM if it cannot trap.
32938fd1498Szrj 1 in a CALL_INSN logically equivalent to
33038fd1498Szrj ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P.
33138fd1498Szrj Dumped as "/c" in RTL dumps. */
33238fd1498Szrj unsigned int call : 1;
33338fd1498Szrj /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
33438fd1498Szrj 1 in a SUBREG used for SUBREG_PROMOTED_UNSIGNED_P.
33538fd1498Szrj 1 in a SYMBOL_REF if it addresses something in the per-function
33638fd1498Szrj constants pool.
33738fd1498Szrj 1 in a CALL_INSN logically equivalent to ECF_CONST and TREE_READONLY.
33838fd1498Szrj 1 in a NOTE, or EXPR_LIST for a const call.
33938fd1498Szrj 1 in a JUMP_INSN of an annulling branch.
34038fd1498Szrj 1 in a CONCAT is VAL_EXPR_IS_CLOBBERED in var-tracking.c.
34138fd1498Szrj 1 in a preserved VALUE is PRESERVED_VALUE_P in cselib.c.
34238fd1498Szrj 1 in a clobber temporarily created for LRA.
34338fd1498Szrj Dumped as "/u" in RTL dumps. */
34438fd1498Szrj unsigned int unchanging : 1;
34538fd1498Szrj /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile.
34638fd1498Szrj 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE
34738fd1498Szrj if it has been deleted.
34838fd1498Szrj 1 in a REG expression if corresponds to a variable declared by the user,
34938fd1498Szrj 0 for an internally generated temporary.
35038fd1498Szrj 1 in a SUBREG used for SUBREG_PROMOTED_UNSIGNED_P.
35138fd1498Szrj 1 in a LABEL_REF, REG_LABEL_TARGET or REG_LABEL_OPERAND note for a
35238fd1498Szrj non-local label.
35338fd1498Szrj In a SYMBOL_REF, this flag is used for machine-specific purposes.
35438fd1498Szrj In a PREFETCH, this flag indicates that it should be considered a
35538fd1498Szrj scheduling barrier.
35638fd1498Szrj 1 in a CONCAT is VAL_NEEDS_RESOLUTION in var-tracking.c.
35738fd1498Szrj Dumped as "/v" in RTL dumps. */
35838fd1498Szrj unsigned int volatil : 1;
35938fd1498Szrj /* 1 in a REG if the register is used only in exit code a loop.
36038fd1498Szrj 1 in a SUBREG expression if was generated from a variable with a
36138fd1498Szrj promoted mode.
36238fd1498Szrj 1 in a CODE_LABEL if the label is used for nonlocal gotos
36338fd1498Szrj and must not be deleted even if its count is zero.
36438fd1498Szrj 1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled
36538fd1498Szrj together with the preceding insn. Valid only within sched.
36638fd1498Szrj 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and
36738fd1498Szrj from the target of a branch. Valid from reorg until end of compilation;
36838fd1498Szrj cleared before used.
36938fd1498Szrj
37038fd1498Szrj The name of the field is historical. It used to be used in MEMs
37138fd1498Szrj to record whether the MEM accessed part of a structure.
37238fd1498Szrj Dumped as "/s" in RTL dumps. */
37338fd1498Szrj unsigned int in_struct : 1;
37438fd1498Szrj /* At the end of RTL generation, 1 if this rtx is used. This is used for
37538fd1498Szrj copying shared structure. See `unshare_all_rtl'.
37638fd1498Szrj In a REG, this is not needed for that purpose, and used instead
37738fd1498Szrj in `leaf_renumber_regs_insn'.
37838fd1498Szrj 1 in a SYMBOL_REF, means that emit_library_call
37938fd1498Szrj has used it as the function.
38038fd1498Szrj 1 in a CONCAT is VAL_HOLDS_TRACK_EXPR in var-tracking.c.
38138fd1498Szrj 1 in a VALUE or DEBUG_EXPR is VALUE_RECURSED_INTO in var-tracking.c. */
38238fd1498Szrj unsigned int used : 1;
38338fd1498Szrj /* 1 in an INSN or a SET if this rtx is related to the call frame,
38438fd1498Szrj either changing how we compute the frame address or saving and
38538fd1498Szrj restoring registers in the prologue and epilogue.
38638fd1498Szrj 1 in a REG or MEM if it is a pointer.
38738fd1498Szrj 1 in a SYMBOL_REF if it addresses something in the per-function
38838fd1498Szrj constant string pool.
38938fd1498Szrj 1 in a VALUE is VALUE_CHANGED in var-tracking.c.
39038fd1498Szrj Dumped as "/f" in RTL dumps. */
39138fd1498Szrj unsigned frame_related : 1;
39238fd1498Szrj /* 1 in a REG or PARALLEL that is the current function's return value.
39338fd1498Szrj 1 in a SYMBOL_REF for a weak symbol.
39438fd1498Szrj 1 in a CALL_INSN logically equivalent to ECF_PURE and DECL_PURE_P.
39538fd1498Szrj 1 in a CONCAT is VAL_EXPR_HAS_REVERSE in var-tracking.c.
39638fd1498Szrj 1 in a VALUE or DEBUG_EXPR is NO_LOC_P in var-tracking.c.
39738fd1498Szrj Dumped as "/i" in RTL dumps. */
39838fd1498Szrj unsigned return_val : 1;
39938fd1498Szrj
40038fd1498Szrj union {
40138fd1498Szrj /* The final union field is aligned to 64 bits on LP64 hosts,
40238fd1498Szrj giving a 32-bit gap after the fields above. We optimize the
40338fd1498Szrj layout for that case and use the gap for extra code-specific
40438fd1498Szrj information. */
40538fd1498Szrj
40638fd1498Szrj /* The ORIGINAL_REGNO of a REG. */
40738fd1498Szrj unsigned int original_regno;
40838fd1498Szrj
40938fd1498Szrj /* The INSN_UID of an RTX_INSN-class code. */
41038fd1498Szrj int insn_uid;
41138fd1498Szrj
41238fd1498Szrj /* The SYMBOL_REF_FLAGS of a SYMBOL_REF. */
41338fd1498Szrj unsigned int symbol_ref_flags;
41438fd1498Szrj
41538fd1498Szrj /* The PAT_VAR_LOCATION_STATUS of a VAR_LOCATION. */
41638fd1498Szrj enum var_init_status var_location_status;
41738fd1498Szrj
41838fd1498Szrj /* In a CONST_WIDE_INT (aka hwivec_def), this is the number of
41938fd1498Szrj HOST_WIDE_INTs in the hwivec_def. */
42038fd1498Szrj unsigned int num_elem;
42138fd1498Szrj
42238fd1498Szrj /* Information about a CONST_VECTOR. */
42338fd1498Szrj struct
42438fd1498Szrj {
42538fd1498Szrj /* The value of CONST_VECTOR_NPATTERNS. */
42638fd1498Szrj unsigned int npatterns : 16;
42738fd1498Szrj
42838fd1498Szrj /* The value of CONST_VECTOR_NELTS_PER_PATTERN. */
42938fd1498Szrj unsigned int nelts_per_pattern : 8;
43038fd1498Szrj
43138fd1498Szrj /* For future expansion. */
43238fd1498Szrj unsigned int unused : 8;
43338fd1498Szrj } const_vector;
43438fd1498Szrj } GTY ((skip)) u2;
43538fd1498Szrj
43638fd1498Szrj /* The first element of the operands of this rtx.
43738fd1498Szrj The number of operands and their types are controlled
43838fd1498Szrj by the `code' field, according to rtl.def. */
43938fd1498Szrj union u {
44038fd1498Szrj rtunion fld[1];
44138fd1498Szrj HOST_WIDE_INT hwint[1];
44238fd1498Szrj struct reg_info reg;
44338fd1498Szrj struct block_symbol block_sym;
44438fd1498Szrj struct real_value rv;
44538fd1498Szrj struct fixed_value fv;
44638fd1498Szrj struct hwivec_def hwiv;
44738fd1498Szrj struct const_poly_int_def cpi;
44838fd1498Szrj } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u;
44938fd1498Szrj };
45038fd1498Szrj
45138fd1498Szrj /* A node for constructing singly-linked lists of rtx. */
45238fd1498Szrj
class()45338fd1498Szrj class GTY(()) rtx_expr_list : public rtx_def
45438fd1498Szrj {
45538fd1498Szrj /* No extra fields, but adds invariant: (GET_CODE (X) == EXPR_LIST). */
45638fd1498Szrj
45738fd1498Szrj public:
45838fd1498Szrj /* Get next in list. */
45938fd1498Szrj rtx_expr_list *next () const;
46038fd1498Szrj
46138fd1498Szrj /* Get at the underlying rtx. */
46238fd1498Szrj rtx element () const;
46338fd1498Szrj };
46438fd1498Szrj
46538fd1498Szrj template <>
46638fd1498Szrj template <>
46738fd1498Szrj inline bool
test(rtx rt)46838fd1498Szrj is_a_helper <rtx_expr_list *>::test (rtx rt)
46938fd1498Szrj {
47038fd1498Szrj return rt->code == EXPR_LIST;
47138fd1498Szrj }
47238fd1498Szrj
class()47338fd1498Szrj class GTY(()) rtx_insn_list : public rtx_def
47438fd1498Szrj {
47538fd1498Szrj /* No extra fields, but adds invariant: (GET_CODE (X) == INSN_LIST).
47638fd1498Szrj
47738fd1498Szrj This is an instance of:
47838fd1498Szrj
47938fd1498Szrj DEF_RTL_EXPR(INSN_LIST, "insn_list", "ue", RTX_EXTRA)
48038fd1498Szrj
48138fd1498Szrj i.e. a node for constructing singly-linked lists of rtx_insn *, where
48238fd1498Szrj the list is "external" to the insn (as opposed to the doubly-linked
48338fd1498Szrj list embedded within rtx_insn itself). */
48438fd1498Szrj
48538fd1498Szrj public:
48638fd1498Szrj /* Get next in list. */
48738fd1498Szrj rtx_insn_list *next () const;
48838fd1498Szrj
48938fd1498Szrj /* Get at the underlying instruction. */
49038fd1498Szrj rtx_insn *insn () const;
49138fd1498Szrj
49238fd1498Szrj };
49338fd1498Szrj
49438fd1498Szrj template <>
49538fd1498Szrj template <>
49638fd1498Szrj inline bool
test(rtx rt)49738fd1498Szrj is_a_helper <rtx_insn_list *>::test (rtx rt)
49838fd1498Szrj {
49938fd1498Szrj return rt->code == INSN_LIST;
50038fd1498Szrj }
50138fd1498Szrj
50238fd1498Szrj /* A node with invariant GET_CODE (X) == SEQUENCE i.e. a vector of rtx,
50338fd1498Szrj typically (but not always) of rtx_insn *, used in the late passes. */
50438fd1498Szrj
class()50538fd1498Szrj class GTY(()) rtx_sequence : public rtx_def
50638fd1498Szrj {
50738fd1498Szrj /* No extra fields, but adds invariant: (GET_CODE (X) == SEQUENCE). */
50838fd1498Szrj
50938fd1498Szrj public:
51038fd1498Szrj /* Get number of elements in sequence. */
51138fd1498Szrj int len () const;
51238fd1498Szrj
51338fd1498Szrj /* Get i-th element of the sequence. */
51438fd1498Szrj rtx element (int index) const;
51538fd1498Szrj
51638fd1498Szrj /* Get i-th element of the sequence, with a checked cast to
51738fd1498Szrj rtx_insn *. */
51838fd1498Szrj rtx_insn *insn (int index) const;
51938fd1498Szrj };
52038fd1498Szrj
52138fd1498Szrj template <>
52238fd1498Szrj template <>
52338fd1498Szrj inline bool
test(rtx rt)52438fd1498Szrj is_a_helper <rtx_sequence *>::test (rtx rt)
52538fd1498Szrj {
52638fd1498Szrj return rt->code == SEQUENCE;
52738fd1498Szrj }
52838fd1498Szrj
52938fd1498Szrj template <>
53038fd1498Szrj template <>
53138fd1498Szrj inline bool
test(const_rtx rt)53238fd1498Szrj is_a_helper <const rtx_sequence *>::test (const_rtx rt)
53338fd1498Szrj {
53438fd1498Szrj return rt->code == SEQUENCE;
53538fd1498Szrj }
53638fd1498Szrj
class()53738fd1498Szrj class GTY(()) rtx_insn : public rtx_def
53838fd1498Szrj {
53938fd1498Szrj public:
54038fd1498Szrj /* No extra fields, but adds the invariant:
54138fd1498Szrj
54238fd1498Szrj (INSN_P (X)
54338fd1498Szrj || NOTE_P (X)
54438fd1498Szrj || JUMP_TABLE_DATA_P (X)
54538fd1498Szrj || BARRIER_P (X)
54638fd1498Szrj || LABEL_P (X))
54738fd1498Szrj
54838fd1498Szrj i.e. that we must be able to use the following:
54938fd1498Szrj INSN_UID ()
55038fd1498Szrj NEXT_INSN ()
55138fd1498Szrj PREV_INSN ()
55238fd1498Szrj i.e. we have an rtx that has an INSN_UID field and can be part of
55338fd1498Szrj a linked list of insns.
55438fd1498Szrj */
55538fd1498Szrj
55638fd1498Szrj /* Returns true if this insn has been deleted. */
55738fd1498Szrj
55838fd1498Szrj bool deleted () const { return volatil; }
55938fd1498Szrj
56038fd1498Szrj /* Mark this insn as deleted. */
56138fd1498Szrj
56238fd1498Szrj void set_deleted () { volatil = true; }
56338fd1498Szrj
56438fd1498Szrj /* Mark this insn as not deleted. */
56538fd1498Szrj
56638fd1498Szrj void set_undeleted () { volatil = false; }
56738fd1498Szrj };
56838fd1498Szrj
56938fd1498Szrj /* Subclasses of rtx_insn. */
57038fd1498Szrj
class()57138fd1498Szrj class GTY(()) rtx_debug_insn : public rtx_insn
57238fd1498Szrj {
57338fd1498Szrj /* No extra fields, but adds the invariant:
57438fd1498Szrj DEBUG_INSN_P (X) aka (GET_CODE (X) == DEBUG_INSN)
57538fd1498Szrj i.e. an annotation for tracking variable assignments.
57638fd1498Szrj
57738fd1498Szrj This is an instance of:
57838fd1498Szrj DEF_RTL_EXPR(DEBUG_INSN, "debug_insn", "uuBeiie", RTX_INSN)
57938fd1498Szrj from rtl.def. */
58038fd1498Szrj };
58138fd1498Szrj
class()58238fd1498Szrj class GTY(()) rtx_nonjump_insn : public rtx_insn
58338fd1498Szrj {
58438fd1498Szrj /* No extra fields, but adds the invariant:
58538fd1498Szrj NONJUMP_INSN_P (X) aka (GET_CODE (X) == INSN)
58638fd1498Szrj i.e an instruction that cannot jump.
58738fd1498Szrj
58838fd1498Szrj This is an instance of:
58938fd1498Szrj DEF_RTL_EXPR(INSN, "insn", "uuBeiie", RTX_INSN)
59038fd1498Szrj from rtl.def. */
59138fd1498Szrj };
59238fd1498Szrj
class()59338fd1498Szrj class GTY(()) rtx_jump_insn : public rtx_insn
59438fd1498Szrj {
59538fd1498Szrj public:
59638fd1498Szrj /* No extra fields, but adds the invariant:
59738fd1498Szrj JUMP_P (X) aka (GET_CODE (X) == JUMP_INSN)
59838fd1498Szrj i.e. an instruction that can possibly jump.
59938fd1498Szrj
60038fd1498Szrj This is an instance of:
60138fd1498Szrj DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeiie0", RTX_INSN)
60238fd1498Szrj from rtl.def. */
60338fd1498Szrj
60438fd1498Szrj /* Returns jump target of this instruction. The returned value is not
60538fd1498Szrj necessarily a code label: it may also be a RETURN or SIMPLE_RETURN
60638fd1498Szrj expression. Also, when the code label is marked "deleted", it is
60738fd1498Szrj replaced by a NOTE. In some cases the value is NULL_RTX. */
60838fd1498Szrj
60938fd1498Szrj inline rtx jump_label () const;
61038fd1498Szrj
61138fd1498Szrj /* Returns jump target cast to rtx_code_label *. */
61238fd1498Szrj
61338fd1498Szrj inline rtx_code_label *jump_target () const;
61438fd1498Szrj
61538fd1498Szrj /* Set jump target. */
61638fd1498Szrj
61738fd1498Szrj inline void set_jump_target (rtx_code_label *);
61838fd1498Szrj };
61938fd1498Szrj
class()62038fd1498Szrj class GTY(()) rtx_call_insn : public rtx_insn
62138fd1498Szrj {
62238fd1498Szrj /* No extra fields, but adds the invariant:
62338fd1498Szrj CALL_P (X) aka (GET_CODE (X) == CALL_INSN)
62438fd1498Szrj i.e. an instruction that can possibly call a subroutine
62538fd1498Szrj but which will not change which instruction comes next
62638fd1498Szrj in the current function.
62738fd1498Szrj
62838fd1498Szrj This is an instance of:
62938fd1498Szrj DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeiiee", RTX_INSN)
63038fd1498Szrj from rtl.def. */
63138fd1498Szrj };
63238fd1498Szrj
class()63338fd1498Szrj class GTY(()) rtx_jump_table_data : public rtx_insn
63438fd1498Szrj {
63538fd1498Szrj /* No extra fields, but adds the invariant:
63638fd1498Szrj JUMP_TABLE_DATA_P (X) aka (GET_CODE (INSN) == JUMP_TABLE_DATA)
63738fd1498Szrj i.e. a data for a jump table, considered an instruction for
63838fd1498Szrj historical reasons.
63938fd1498Szrj
64038fd1498Szrj This is an instance of:
64138fd1498Szrj DEF_RTL_EXPR(JUMP_TABLE_DATA, "jump_table_data", "uuBe0000", RTX_INSN)
64238fd1498Szrj from rtl.def. */
64338fd1498Szrj
64438fd1498Szrj public:
64538fd1498Szrj
64638fd1498Szrj /* This can be either:
64738fd1498Szrj
64838fd1498Szrj (a) a table of absolute jumps, in which case PATTERN (this) is an
64938fd1498Szrj ADDR_VEC with arg 0 a vector of labels, or
65038fd1498Szrj
65138fd1498Szrj (b) a table of relative jumps (e.g. for -fPIC), in which case
65238fd1498Szrj PATTERN (this) is an ADDR_DIFF_VEC, with arg 0 a LABEL_REF and
65338fd1498Szrj arg 1 the vector of labels.
65438fd1498Szrj
65538fd1498Szrj This method gets the underlying vec. */
65638fd1498Szrj
65738fd1498Szrj inline rtvec get_labels () const;
65838fd1498Szrj inline scalar_int_mode get_data_mode () const;
65938fd1498Szrj };
66038fd1498Szrj
class()66138fd1498Szrj class GTY(()) rtx_barrier : public rtx_insn
66238fd1498Szrj {
66338fd1498Szrj /* No extra fields, but adds the invariant:
66438fd1498Szrj BARRIER_P (X) aka (GET_CODE (X) == BARRIER)
66538fd1498Szrj i.e. a marker that indicates that control will not flow through.
66638fd1498Szrj
66738fd1498Szrj This is an instance of:
66838fd1498Szrj DEF_RTL_EXPR(BARRIER, "barrier", "uu00000", RTX_EXTRA)
66938fd1498Szrj from rtl.def. */
67038fd1498Szrj };
67138fd1498Szrj
class()67238fd1498Szrj class GTY(()) rtx_code_label : public rtx_insn
67338fd1498Szrj {
67438fd1498Szrj /* No extra fields, but adds the invariant:
67538fd1498Szrj LABEL_P (X) aka (GET_CODE (X) == CODE_LABEL)
67638fd1498Szrj i.e. a label in the assembler.
67738fd1498Szrj
67838fd1498Szrj This is an instance of:
67938fd1498Szrj DEF_RTL_EXPR(CODE_LABEL, "code_label", "uuB00is", RTX_EXTRA)
68038fd1498Szrj from rtl.def. */
68138fd1498Szrj };
68238fd1498Szrj
class()68338fd1498Szrj class GTY(()) rtx_note : public rtx_insn
68438fd1498Szrj {
68538fd1498Szrj /* No extra fields, but adds the invariant:
68638fd1498Szrj NOTE_P(X) aka (GET_CODE (X) == NOTE)
68738fd1498Szrj i.e. a note about the corresponding source code.
68838fd1498Szrj
68938fd1498Szrj This is an instance of:
69038fd1498Szrj DEF_RTL_EXPR(NOTE, "note", "uuB0ni", RTX_EXTRA)
69138fd1498Szrj from rtl.def. */
69238fd1498Szrj };
69338fd1498Szrj
69438fd1498Szrj /* The size in bytes of an rtx header (code, mode and flags). */
69538fd1498Szrj #define RTX_HDR_SIZE offsetof (struct rtx_def, u)
69638fd1498Szrj
69738fd1498Szrj /* The size in bytes of an rtx with code CODE. */
69838fd1498Szrj #define RTX_CODE_SIZE(CODE) rtx_code_size[CODE]
69938fd1498Szrj
70038fd1498Szrj #define NULL_RTX (rtx) 0
70138fd1498Szrj
70238fd1498Szrj /* The "next" and "previous" RTX, relative to this one. */
70338fd1498Szrj
70438fd1498Szrj #define RTX_NEXT(X) (rtx_next[GET_CODE (X)] == 0 ? NULL \
70538fd1498Szrj : *(rtx *)(((char *)X) + rtx_next[GET_CODE (X)]))
70638fd1498Szrj
70738fd1498Szrj /* FIXME: the "NEXT_INSN (PREV_INSN (X)) == X" condition shouldn't be needed.
70838fd1498Szrj */
70938fd1498Szrj #define RTX_PREV(X) ((INSN_P (X) \
71038fd1498Szrj || NOTE_P (X) \
71138fd1498Szrj || JUMP_TABLE_DATA_P (X) \
71238fd1498Szrj || BARRIER_P (X) \
71338fd1498Szrj || LABEL_P (X)) \
71438fd1498Szrj && PREV_INSN (as_a <rtx_insn *> (X)) != NULL \
71538fd1498Szrj && NEXT_INSN (PREV_INSN (as_a <rtx_insn *> (X))) == X \
71638fd1498Szrj ? PREV_INSN (as_a <rtx_insn *> (X)) : NULL)
71738fd1498Szrj
71838fd1498Szrj /* Define macros to access the `code' field of the rtx. */
71938fd1498Szrj
72038fd1498Szrj #define GET_CODE(RTX) ((enum rtx_code) (RTX)->code)
72138fd1498Szrj #define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE))
72238fd1498Szrj
72338fd1498Szrj #define GET_MODE(RTX) ((machine_mode) (RTX)->mode)
72438fd1498Szrj #define PUT_MODE_RAW(RTX, MODE) ((RTX)->mode = (MODE))
72538fd1498Szrj
72638fd1498Szrj /* RTL vector. These appear inside RTX's when there is a need
72738fd1498Szrj for a variable number of things. The principle use is inside
72838fd1498Szrj PARALLEL expressions. */
72938fd1498Szrj
73038fd1498Szrj struct GTY(()) rtvec_def {
73138fd1498Szrj int num_elem; /* number of elements */
73238fd1498Szrj rtx GTY ((length ("%h.num_elem"))) elem[1];
73338fd1498Szrj };
73438fd1498Szrj
73538fd1498Szrj #define NULL_RTVEC (rtvec) 0
73638fd1498Szrj
73738fd1498Szrj #define GET_NUM_ELEM(RTVEC) ((RTVEC)->num_elem)
73838fd1498Szrj #define PUT_NUM_ELEM(RTVEC, NUM) ((RTVEC)->num_elem = (NUM))
73938fd1498Szrj
74038fd1498Szrj /* Predicate yielding nonzero iff X is an rtx for a register. */
74138fd1498Szrj #define REG_P(X) (GET_CODE (X) == REG)
74238fd1498Szrj
74338fd1498Szrj /* Predicate yielding nonzero iff X is an rtx for a memory location. */
74438fd1498Szrj #define MEM_P(X) (GET_CODE (X) == MEM)
74538fd1498Szrj
74638fd1498Szrj #if TARGET_SUPPORTS_WIDE_INT
74738fd1498Szrj
74838fd1498Szrj /* Match CONST_*s that can represent compile-time constant integers. */
74938fd1498Szrj #define CASE_CONST_SCALAR_INT \
75038fd1498Szrj case CONST_INT: \
75138fd1498Szrj case CONST_WIDE_INT
75238fd1498Szrj
75338fd1498Szrj /* Match CONST_*s for which pointer equality corresponds to value
75438fd1498Szrj equality. */
75538fd1498Szrj #define CASE_CONST_UNIQUE \
75638fd1498Szrj case CONST_INT: \
75738fd1498Szrj case CONST_WIDE_INT: \
75838fd1498Szrj case CONST_POLY_INT: \
75938fd1498Szrj case CONST_DOUBLE: \
76038fd1498Szrj case CONST_FIXED
76138fd1498Szrj
76238fd1498Szrj /* Match all CONST_* rtxes. */
76338fd1498Szrj #define CASE_CONST_ANY \
76438fd1498Szrj case CONST_INT: \
76538fd1498Szrj case CONST_WIDE_INT: \
76638fd1498Szrj case CONST_POLY_INT: \
76738fd1498Szrj case CONST_DOUBLE: \
76838fd1498Szrj case CONST_FIXED: \
76938fd1498Szrj case CONST_VECTOR
77038fd1498Szrj
77138fd1498Szrj #else
77238fd1498Szrj
77338fd1498Szrj /* Match CONST_*s that can represent compile-time constant integers. */
77438fd1498Szrj #define CASE_CONST_SCALAR_INT \
77538fd1498Szrj case CONST_INT: \
77638fd1498Szrj case CONST_DOUBLE
77738fd1498Szrj
77838fd1498Szrj /* Match CONST_*s for which pointer equality corresponds to value
77938fd1498Szrj equality. */
78038fd1498Szrj #define CASE_CONST_UNIQUE \
78138fd1498Szrj case CONST_INT: \
78238fd1498Szrj case CONST_DOUBLE: \
78338fd1498Szrj case CONST_FIXED
78438fd1498Szrj
78538fd1498Szrj /* Match all CONST_* rtxes. */
78638fd1498Szrj #define CASE_CONST_ANY \
78738fd1498Szrj case CONST_INT: \
78838fd1498Szrj case CONST_DOUBLE: \
78938fd1498Szrj case CONST_FIXED: \
79038fd1498Szrj case CONST_VECTOR
79138fd1498Szrj #endif
79238fd1498Szrj
79338fd1498Szrj /* Predicate yielding nonzero iff X is an rtx for a constant integer. */
79438fd1498Szrj #define CONST_INT_P(X) (GET_CODE (X) == CONST_INT)
79538fd1498Szrj
79638fd1498Szrj /* Predicate yielding nonzero iff X is an rtx for a constant integer. */
79738fd1498Szrj #define CONST_WIDE_INT_P(X) (GET_CODE (X) == CONST_WIDE_INT)
79838fd1498Szrj
79938fd1498Szrj /* Predicate yielding nonzero iff X is an rtx for a polynomial constant
80038fd1498Szrj integer. */
80138fd1498Szrj #define CONST_POLY_INT_P(X) \
80238fd1498Szrj (NUM_POLY_INT_COEFFS > 1 && GET_CODE (X) == CONST_POLY_INT)
80338fd1498Szrj
80438fd1498Szrj /* Predicate yielding nonzero iff X is an rtx for a constant fixed-point. */
80538fd1498Szrj #define CONST_FIXED_P(X) (GET_CODE (X) == CONST_FIXED)
80638fd1498Szrj
80738fd1498Szrj /* Predicate yielding true iff X is an rtx for a double-int
80838fd1498Szrj or floating point constant. */
80938fd1498Szrj #define CONST_DOUBLE_P(X) (GET_CODE (X) == CONST_DOUBLE)
81038fd1498Szrj
81138fd1498Szrj /* Predicate yielding true iff X is an rtx for a double-int. */
81238fd1498Szrj #define CONST_DOUBLE_AS_INT_P(X) \
81338fd1498Szrj (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == VOIDmode)
81438fd1498Szrj
81538fd1498Szrj /* Predicate yielding true iff X is an rtx for a integer const. */
81638fd1498Szrj #if TARGET_SUPPORTS_WIDE_INT
81738fd1498Szrj #define CONST_SCALAR_INT_P(X) \
81838fd1498Szrj (CONST_INT_P (X) || CONST_WIDE_INT_P (X))
81938fd1498Szrj #else
82038fd1498Szrj #define CONST_SCALAR_INT_P(X) \
82138fd1498Szrj (CONST_INT_P (X) || CONST_DOUBLE_AS_INT_P (X))
82238fd1498Szrj #endif
82338fd1498Szrj
82438fd1498Szrj /* Predicate yielding true iff X is an rtx for a double-int. */
82538fd1498Szrj #define CONST_DOUBLE_AS_FLOAT_P(X) \
82638fd1498Szrj (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode)
82738fd1498Szrj
82838fd1498Szrj /* Predicate yielding nonzero iff X is a label insn. */
82938fd1498Szrj #define LABEL_P(X) (GET_CODE (X) == CODE_LABEL)
83038fd1498Szrj
83138fd1498Szrj /* Predicate yielding nonzero iff X is a jump insn. */
83238fd1498Szrj #define JUMP_P(X) (GET_CODE (X) == JUMP_INSN)
83338fd1498Szrj
83438fd1498Szrj /* Predicate yielding nonzero iff X is a call insn. */
83538fd1498Szrj #define CALL_P(X) (GET_CODE (X) == CALL_INSN)
83638fd1498Szrj
83738fd1498Szrj /* Predicate yielding nonzero iff X is an insn that cannot jump. */
83838fd1498Szrj #define NONJUMP_INSN_P(X) (GET_CODE (X) == INSN)
83938fd1498Szrj
84038fd1498Szrj /* Predicate yielding nonzero iff X is a debug note/insn. */
84138fd1498Szrj #define DEBUG_INSN_P(X) (GET_CODE (X) == DEBUG_INSN)
84238fd1498Szrj
84338fd1498Szrj /* Predicate yielding nonzero iff X is an insn that is not a debug insn. */
84438fd1498Szrj #define NONDEBUG_INSN_P(X) (INSN_P (X) && !DEBUG_INSN_P (X))
84538fd1498Szrj
84638fd1498Szrj /* Nonzero if DEBUG_MARKER_INSN_P may possibly hold. */
84738fd1498Szrj #define MAY_HAVE_DEBUG_MARKER_INSNS debug_nonbind_markers_p
84838fd1498Szrj /* Nonzero if DEBUG_BIND_INSN_P may possibly hold. */
84938fd1498Szrj #define MAY_HAVE_DEBUG_BIND_INSNS flag_var_tracking_assignments
85038fd1498Szrj /* Nonzero if DEBUG_INSN_P may possibly hold. */
85138fd1498Szrj #define MAY_HAVE_DEBUG_INSNS \
85238fd1498Szrj (MAY_HAVE_DEBUG_MARKER_INSNS || MAY_HAVE_DEBUG_BIND_INSNS)
85338fd1498Szrj
85438fd1498Szrj /* Predicate yielding nonzero iff X is a real insn. */
85538fd1498Szrj #define INSN_P(X) \
85638fd1498Szrj (NONJUMP_INSN_P (X) || DEBUG_INSN_P (X) || JUMP_P (X) || CALL_P (X))
85738fd1498Szrj
85838fd1498Szrj /* Predicate yielding nonzero iff X is a note insn. */
85938fd1498Szrj #define NOTE_P(X) (GET_CODE (X) == NOTE)
86038fd1498Szrj
86138fd1498Szrj /* Predicate yielding nonzero iff X is a barrier insn. */
86238fd1498Szrj #define BARRIER_P(X) (GET_CODE (X) == BARRIER)
86338fd1498Szrj
86438fd1498Szrj /* Predicate yielding nonzero iff X is a data for a jump table. */
86538fd1498Szrj #define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA)
86638fd1498Szrj
86738fd1498Szrj /* Predicate yielding nonzero iff RTX is a subreg. */
86838fd1498Szrj #define SUBREG_P(RTX) (GET_CODE (RTX) == SUBREG)
86938fd1498Szrj
87038fd1498Szrj /* Predicate yielding true iff RTX is a symbol ref. */
87138fd1498Szrj #define SYMBOL_REF_P(RTX) (GET_CODE (RTX) == SYMBOL_REF)
87238fd1498Szrj
87338fd1498Szrj template <>
87438fd1498Szrj template <>
87538fd1498Szrj inline bool
test(rtx rt)87638fd1498Szrj is_a_helper <rtx_insn *>::test (rtx rt)
87738fd1498Szrj {
87838fd1498Szrj return (INSN_P (rt)
87938fd1498Szrj || NOTE_P (rt)
88038fd1498Szrj || JUMP_TABLE_DATA_P (rt)
88138fd1498Szrj || BARRIER_P (rt)
88238fd1498Szrj || LABEL_P (rt));
88338fd1498Szrj }
88438fd1498Szrj
88538fd1498Szrj template <>
88638fd1498Szrj template <>
88738fd1498Szrj inline bool
test(const_rtx rt)88838fd1498Szrj is_a_helper <const rtx_insn *>::test (const_rtx rt)
88938fd1498Szrj {
89038fd1498Szrj return (INSN_P (rt)
89138fd1498Szrj || NOTE_P (rt)
89238fd1498Szrj || JUMP_TABLE_DATA_P (rt)
89338fd1498Szrj || BARRIER_P (rt)
89438fd1498Szrj || LABEL_P (rt));
89538fd1498Szrj }
89638fd1498Szrj
89738fd1498Szrj template <>
89838fd1498Szrj template <>
89938fd1498Szrj inline bool
test(rtx rt)90038fd1498Szrj is_a_helper <rtx_debug_insn *>::test (rtx rt)
90138fd1498Szrj {
90238fd1498Szrj return DEBUG_INSN_P (rt);
90338fd1498Szrj }
90438fd1498Szrj
90538fd1498Szrj template <>
90638fd1498Szrj template <>
90738fd1498Szrj inline bool
test(rtx rt)90838fd1498Szrj is_a_helper <rtx_nonjump_insn *>::test (rtx rt)
90938fd1498Szrj {
91038fd1498Szrj return NONJUMP_INSN_P (rt);
91138fd1498Szrj }
91238fd1498Szrj
91338fd1498Szrj template <>
91438fd1498Szrj template <>
91538fd1498Szrj inline bool
test(rtx rt)91638fd1498Szrj is_a_helper <rtx_jump_insn *>::test (rtx rt)
91738fd1498Szrj {
91838fd1498Szrj return JUMP_P (rt);
91938fd1498Szrj }
92038fd1498Szrj
92138fd1498Szrj template <>
92238fd1498Szrj template <>
92338fd1498Szrj inline bool
test(rtx_insn * insn)92438fd1498Szrj is_a_helper <rtx_jump_insn *>::test (rtx_insn *insn)
92538fd1498Szrj {
92638fd1498Szrj return JUMP_P (insn);
92738fd1498Szrj }
92838fd1498Szrj
92938fd1498Szrj template <>
93038fd1498Szrj template <>
93138fd1498Szrj inline bool
test(rtx rt)93238fd1498Szrj is_a_helper <rtx_call_insn *>::test (rtx rt)
93338fd1498Szrj {
93438fd1498Szrj return CALL_P (rt);
93538fd1498Szrj }
93638fd1498Szrj
93738fd1498Szrj template <>
93838fd1498Szrj template <>
93938fd1498Szrj inline bool
test(rtx_insn * insn)94038fd1498Szrj is_a_helper <rtx_call_insn *>::test (rtx_insn *insn)
94138fd1498Szrj {
94238fd1498Szrj return CALL_P (insn);
94338fd1498Szrj }
94438fd1498Szrj
94538fd1498Szrj template <>
94638fd1498Szrj template <>
94738fd1498Szrj inline bool
test(rtx rt)94838fd1498Szrj is_a_helper <rtx_jump_table_data *>::test (rtx rt)
94938fd1498Szrj {
95038fd1498Szrj return JUMP_TABLE_DATA_P (rt);
95138fd1498Szrj }
95238fd1498Szrj
95338fd1498Szrj template <>
95438fd1498Szrj template <>
95538fd1498Szrj inline bool
test(rtx_insn * insn)95638fd1498Szrj is_a_helper <rtx_jump_table_data *>::test (rtx_insn *insn)
95738fd1498Szrj {
95838fd1498Szrj return JUMP_TABLE_DATA_P (insn);
95938fd1498Szrj }
96038fd1498Szrj
96138fd1498Szrj template <>
96238fd1498Szrj template <>
96338fd1498Szrj inline bool
test(rtx rt)96438fd1498Szrj is_a_helper <rtx_barrier *>::test (rtx rt)
96538fd1498Szrj {
96638fd1498Szrj return BARRIER_P (rt);
96738fd1498Szrj }
96838fd1498Szrj
96938fd1498Szrj template <>
97038fd1498Szrj template <>
97138fd1498Szrj inline bool
test(rtx rt)97238fd1498Szrj is_a_helper <rtx_code_label *>::test (rtx rt)
97338fd1498Szrj {
97438fd1498Szrj return LABEL_P (rt);
97538fd1498Szrj }
97638fd1498Szrj
97738fd1498Szrj template <>
97838fd1498Szrj template <>
97938fd1498Szrj inline bool
test(rtx_insn * insn)98038fd1498Szrj is_a_helper <rtx_code_label *>::test (rtx_insn *insn)
98138fd1498Szrj {
98238fd1498Szrj return LABEL_P (insn);
98338fd1498Szrj }
98438fd1498Szrj
98538fd1498Szrj template <>
98638fd1498Szrj template <>
98738fd1498Szrj inline bool
test(rtx rt)98838fd1498Szrj is_a_helper <rtx_note *>::test (rtx rt)
98938fd1498Szrj {
99038fd1498Szrj return NOTE_P (rt);
99138fd1498Szrj }
99238fd1498Szrj
99338fd1498Szrj template <>
99438fd1498Szrj template <>
99538fd1498Szrj inline bool
test(rtx_insn * insn)99638fd1498Szrj is_a_helper <rtx_note *>::test (rtx_insn *insn)
99738fd1498Szrj {
99838fd1498Szrj return NOTE_P (insn);
99938fd1498Szrj }
100038fd1498Szrj
100138fd1498Szrj /* Predicate yielding nonzero iff X is a return or simple_return. */
100238fd1498Szrj #define ANY_RETURN_P(X) \
100338fd1498Szrj (GET_CODE (X) == RETURN || GET_CODE (X) == SIMPLE_RETURN)
100438fd1498Szrj
100538fd1498Szrj /* 1 if X is a unary operator. */
100638fd1498Szrj
100738fd1498Szrj #define UNARY_P(X) \
100838fd1498Szrj (GET_RTX_CLASS (GET_CODE (X)) == RTX_UNARY)
100938fd1498Szrj
101038fd1498Szrj /* 1 if X is a binary operator. */
101138fd1498Szrj
101238fd1498Szrj #define BINARY_P(X) \
101338fd1498Szrj ((GET_RTX_CLASS (GET_CODE (X)) & RTX_BINARY_MASK) == RTX_BINARY_RESULT)
101438fd1498Szrj
101538fd1498Szrj /* 1 if X is an arithmetic operator. */
101638fd1498Szrj
101738fd1498Szrj #define ARITHMETIC_P(X) \
101838fd1498Szrj ((GET_RTX_CLASS (GET_CODE (X)) & RTX_ARITHMETIC_MASK) \
101938fd1498Szrj == RTX_ARITHMETIC_RESULT)
102038fd1498Szrj
102138fd1498Szrj /* 1 if X is an arithmetic operator. */
102238fd1498Szrj
102338fd1498Szrj #define COMMUTATIVE_ARITH_P(X) \
102438fd1498Szrj (GET_RTX_CLASS (GET_CODE (X)) == RTX_COMM_ARITH)
102538fd1498Szrj
102638fd1498Szrj /* 1 if X is a commutative arithmetic operator or a comparison operator.
102738fd1498Szrj These two are sometimes selected together because it is possible to
102838fd1498Szrj swap the two operands. */
102938fd1498Szrj
103038fd1498Szrj #define SWAPPABLE_OPERANDS_P(X) \
103138fd1498Szrj ((1 << GET_RTX_CLASS (GET_CODE (X))) \
103238fd1498Szrj & ((1 << RTX_COMM_ARITH) | (1 << RTX_COMM_COMPARE) \
103338fd1498Szrj | (1 << RTX_COMPARE)))
103438fd1498Szrj
103538fd1498Szrj /* 1 if X is a non-commutative operator. */
103638fd1498Szrj
103738fd1498Szrj #define NON_COMMUTATIVE_P(X) \
103838fd1498Szrj ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMMUTATIVE_MASK) \
103938fd1498Szrj == RTX_NON_COMMUTATIVE_RESULT)
104038fd1498Szrj
104138fd1498Szrj /* 1 if X is a commutative operator on integers. */
104238fd1498Szrj
104338fd1498Szrj #define COMMUTATIVE_P(X) \
104438fd1498Szrj ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMMUTATIVE_MASK) \
104538fd1498Szrj == RTX_COMMUTATIVE_RESULT)
104638fd1498Szrj
104738fd1498Szrj /* 1 if X is a relational operator. */
104838fd1498Szrj
104938fd1498Szrj #define COMPARISON_P(X) \
105038fd1498Szrj ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMPARE_MASK) == RTX_COMPARE_RESULT)
105138fd1498Szrj
105238fd1498Szrj /* 1 if X is a constant value that is an integer. */
105338fd1498Szrj
105438fd1498Szrj #define CONSTANT_P(X) \
105538fd1498Szrj (GET_RTX_CLASS (GET_CODE (X)) == RTX_CONST_OBJ)
105638fd1498Szrj
105738fd1498Szrj /* 1 if X can be used to represent an object. */
105838fd1498Szrj #define OBJECT_P(X) \
105938fd1498Szrj ((GET_RTX_CLASS (GET_CODE (X)) & RTX_OBJ_MASK) == RTX_OBJ_RESULT)
106038fd1498Szrj
106138fd1498Szrj /* General accessor macros for accessing the fields of an rtx. */
106238fd1498Szrj
106338fd1498Szrj #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
106438fd1498Szrj /* The bit with a star outside the statement expr and an & inside is
106538fd1498Szrj so that N can be evaluated only once. */
106638fd1498Szrj #define RTL_CHECK1(RTX, N, C1) __extension__ \
106738fd1498Szrj (*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N); \
106838fd1498Szrj const enum rtx_code _code = GET_CODE (_rtx); \
106938fd1498Szrj if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \
107038fd1498Szrj rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \
107138fd1498Szrj __FUNCTION__); \
107238fd1498Szrj if (GET_RTX_FORMAT (_code)[_n] != C1) \
107338fd1498Szrj rtl_check_failed_type1 (_rtx, _n, C1, __FILE__, __LINE__, \
107438fd1498Szrj __FUNCTION__); \
107538fd1498Szrj &_rtx->u.fld[_n]; }))
107638fd1498Szrj
107738fd1498Szrj #define RTL_CHECK2(RTX, N, C1, C2) __extension__ \
107838fd1498Szrj (*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N); \
107938fd1498Szrj const enum rtx_code _code = GET_CODE (_rtx); \
108038fd1498Szrj if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \
108138fd1498Szrj rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \
108238fd1498Szrj __FUNCTION__); \
108338fd1498Szrj if (GET_RTX_FORMAT (_code)[_n] != C1 \
108438fd1498Szrj && GET_RTX_FORMAT (_code)[_n] != C2) \
108538fd1498Szrj rtl_check_failed_type2 (_rtx, _n, C1, C2, __FILE__, __LINE__, \
108638fd1498Szrj __FUNCTION__); \
108738fd1498Szrj &_rtx->u.fld[_n]; }))
108838fd1498Szrj
108938fd1498Szrj #define RTL_CHECKC1(RTX, N, C) __extension__ \
109038fd1498Szrj (*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N); \
109138fd1498Szrj if (GET_CODE (_rtx) != (C)) \
109238fd1498Szrj rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__, \
109338fd1498Szrj __FUNCTION__); \
109438fd1498Szrj &_rtx->u.fld[_n]; }))
109538fd1498Szrj
109638fd1498Szrj #define RTL_CHECKC2(RTX, N, C1, C2) __extension__ \
109738fd1498Szrj (*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N); \
109838fd1498Szrj const enum rtx_code _code = GET_CODE (_rtx); \
109938fd1498Szrj if (_code != (C1) && _code != (C2)) \
110038fd1498Szrj rtl_check_failed_code2 (_rtx, (C1), (C2), __FILE__, __LINE__, \
110138fd1498Szrj __FUNCTION__); \
110238fd1498Szrj &_rtx->u.fld[_n]; }))
110338fd1498Szrj
110438fd1498Szrj #define RTVEC_ELT(RTVEC, I) __extension__ \
110538fd1498Szrj (*({ __typeof (RTVEC) const _rtvec = (RTVEC); const int _i = (I); \
110638fd1498Szrj if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec)) \
110738fd1498Szrj rtvec_check_failed_bounds (_rtvec, _i, __FILE__, __LINE__, \
110838fd1498Szrj __FUNCTION__); \
110938fd1498Szrj &_rtvec->elem[_i]; }))
111038fd1498Szrj
111138fd1498Szrj #define XWINT(RTX, N) __extension__ \
111238fd1498Szrj (*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N); \
111338fd1498Szrj const enum rtx_code _code = GET_CODE (_rtx); \
111438fd1498Szrj if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \
111538fd1498Szrj rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \
111638fd1498Szrj __FUNCTION__); \
111738fd1498Szrj if (GET_RTX_FORMAT (_code)[_n] != 'w') \
111838fd1498Szrj rtl_check_failed_type1 (_rtx, _n, 'w', __FILE__, __LINE__, \
111938fd1498Szrj __FUNCTION__); \
112038fd1498Szrj &_rtx->u.hwint[_n]; }))
112138fd1498Szrj
112238fd1498Szrj #define CWI_ELT(RTX, I) __extension__ \
112338fd1498Szrj (*({ __typeof (RTX) const _cwi = (RTX); \
112438fd1498Szrj int _max = CWI_GET_NUM_ELEM (_cwi); \
112538fd1498Szrj const int _i = (I); \
112638fd1498Szrj if (_i < 0 || _i >= _max) \
112738fd1498Szrj cwi_check_failed_bounds (_cwi, _i, __FILE__, __LINE__, \
112838fd1498Szrj __FUNCTION__); \
112938fd1498Szrj &_cwi->u.hwiv.elem[_i]; }))
113038fd1498Szrj
113138fd1498Szrj #define XCWINT(RTX, N, C) __extension__ \
113238fd1498Szrj (*({ __typeof (RTX) const _rtx = (RTX); \
113338fd1498Szrj if (GET_CODE (_rtx) != (C)) \
113438fd1498Szrj rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__, \
113538fd1498Szrj __FUNCTION__); \
113638fd1498Szrj &_rtx->u.hwint[N]; }))
113738fd1498Szrj
113838fd1498Szrj #define XCMWINT(RTX, N, C, M) __extension__ \
113938fd1498Szrj (*({ __typeof (RTX) const _rtx = (RTX); \
114038fd1498Szrj if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) != (M)) \
114138fd1498Szrj rtl_check_failed_code_mode (_rtx, (C), (M), false, __FILE__, \
114238fd1498Szrj __LINE__, __FUNCTION__); \
114338fd1498Szrj &_rtx->u.hwint[N]; }))
114438fd1498Szrj
114538fd1498Szrj #define XCNMPRV(RTX, C, M) __extension__ \
114638fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
114738fd1498Szrj if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) == (M)) \
114838fd1498Szrj rtl_check_failed_code_mode (_rtx, (C), (M), true, __FILE__, \
114938fd1498Szrj __LINE__, __FUNCTION__); \
115038fd1498Szrj &_rtx->u.rv; })
115138fd1498Szrj
115238fd1498Szrj #define XCNMPFV(RTX, C, M) __extension__ \
115338fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
115438fd1498Szrj if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) == (M)) \
115538fd1498Szrj rtl_check_failed_code_mode (_rtx, (C), (M), true, __FILE__, \
115638fd1498Szrj __LINE__, __FUNCTION__); \
115738fd1498Szrj &_rtx->u.fv; })
115838fd1498Szrj
115938fd1498Szrj #define REG_CHECK(RTX) __extension__ \
116038fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
116138fd1498Szrj if (GET_CODE (_rtx) != REG) \
116238fd1498Szrj rtl_check_failed_code1 (_rtx, REG, __FILE__, __LINE__, \
116338fd1498Szrj __FUNCTION__); \
116438fd1498Szrj &_rtx->u.reg; })
116538fd1498Szrj
116638fd1498Szrj #define BLOCK_SYMBOL_CHECK(RTX) __extension__ \
116738fd1498Szrj ({ __typeof (RTX) const _symbol = (RTX); \
116838fd1498Szrj const unsigned int flags = SYMBOL_REF_FLAGS (_symbol); \
116938fd1498Szrj if ((flags & SYMBOL_FLAG_HAS_BLOCK_INFO) == 0) \
117038fd1498Szrj rtl_check_failed_block_symbol (__FILE__, __LINE__, \
117138fd1498Szrj __FUNCTION__); \
117238fd1498Szrj &_symbol->u.block_sym; })
117338fd1498Szrj
117438fd1498Szrj #define HWIVEC_CHECK(RTX,C) __extension__ \
117538fd1498Szrj ({ __typeof (RTX) const _symbol = (RTX); \
117638fd1498Szrj RTL_CHECKC1 (_symbol, 0, C); \
117738fd1498Szrj &_symbol->u.hwiv; })
117838fd1498Szrj
117938fd1498Szrj extern void rtl_check_failed_bounds (const_rtx, int, const char *, int,
118038fd1498Szrj const char *)
118138fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
118238fd1498Szrj extern void rtl_check_failed_type1 (const_rtx, int, int, const char *, int,
118338fd1498Szrj const char *)
118438fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
118538fd1498Szrj extern void rtl_check_failed_type2 (const_rtx, int, int, int, const char *,
118638fd1498Szrj int, const char *)
118738fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
118838fd1498Szrj extern void rtl_check_failed_code1 (const_rtx, enum rtx_code, const char *,
118938fd1498Szrj int, const char *)
119038fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
119138fd1498Szrj extern void rtl_check_failed_code2 (const_rtx, enum rtx_code, enum rtx_code,
119238fd1498Szrj const char *, int, const char *)
119338fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
119438fd1498Szrj extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, machine_mode,
119538fd1498Szrj bool, const char *, int, const char *)
119638fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
119738fd1498Szrj extern void rtl_check_failed_block_symbol (const char *, int, const char *)
119838fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
119938fd1498Szrj extern void cwi_check_failed_bounds (const_rtx, int, const char *, int,
120038fd1498Szrj const char *)
120138fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
120238fd1498Szrj extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int,
120338fd1498Szrj const char *)
120438fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
120538fd1498Szrj
120638fd1498Szrj #else /* not ENABLE_RTL_CHECKING */
120738fd1498Szrj
120838fd1498Szrj #define RTL_CHECK1(RTX, N, C1) ((RTX)->u.fld[N])
120938fd1498Szrj #define RTL_CHECK2(RTX, N, C1, C2) ((RTX)->u.fld[N])
121038fd1498Szrj #define RTL_CHECKC1(RTX, N, C) ((RTX)->u.fld[N])
121138fd1498Szrj #define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->u.fld[N])
121238fd1498Szrj #define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[I])
121338fd1498Szrj #define XWINT(RTX, N) ((RTX)->u.hwint[N])
121438fd1498Szrj #define CWI_ELT(RTX, I) ((RTX)->u.hwiv.elem[I])
121538fd1498Szrj #define XCWINT(RTX, N, C) ((RTX)->u.hwint[N])
121638fd1498Szrj #define XCMWINT(RTX, N, C, M) ((RTX)->u.hwint[N])
121738fd1498Szrj #define XCNMWINT(RTX, N, C, M) ((RTX)->u.hwint[N])
121838fd1498Szrj #define XCNMPRV(RTX, C, M) (&(RTX)->u.rv)
121938fd1498Szrj #define XCNMPFV(RTX, C, M) (&(RTX)->u.fv)
122038fd1498Szrj #define REG_CHECK(RTX) (&(RTX)->u.reg)
122138fd1498Szrj #define BLOCK_SYMBOL_CHECK(RTX) (&(RTX)->u.block_sym)
122238fd1498Szrj #define HWIVEC_CHECK(RTX,C) (&(RTX)->u.hwiv)
122338fd1498Szrj
122438fd1498Szrj #endif
122538fd1498Szrj
122638fd1498Szrj /* General accessor macros for accessing the flags of an rtx. */
122738fd1498Szrj
122838fd1498Szrj /* Access an individual rtx flag, with no checking of any kind. */
122938fd1498Szrj #define RTX_FLAG(RTX, FLAG) ((RTX)->FLAG)
123038fd1498Szrj
123138fd1498Szrj #if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION >= 2007)
123238fd1498Szrj #define RTL_FLAG_CHECK1(NAME, RTX, C1) __extension__ \
123338fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
123438fd1498Szrj if (GET_CODE (_rtx) != C1) \
123538fd1498Szrj rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
123638fd1498Szrj __FUNCTION__); \
123738fd1498Szrj _rtx; })
123838fd1498Szrj
123938fd1498Szrj #define RTL_FLAG_CHECK2(NAME, RTX, C1, C2) __extension__ \
124038fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
124138fd1498Szrj if (GET_CODE (_rtx) != C1 && GET_CODE(_rtx) != C2) \
124238fd1498Szrj rtl_check_failed_flag (NAME,_rtx, __FILE__, __LINE__, \
124338fd1498Szrj __FUNCTION__); \
124438fd1498Szrj _rtx; })
124538fd1498Szrj
124638fd1498Szrj #define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3) __extension__ \
124738fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
124838fd1498Szrj if (GET_CODE (_rtx) != C1 && GET_CODE(_rtx) != C2 \
124938fd1498Szrj && GET_CODE (_rtx) != C3) \
125038fd1498Szrj rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
125138fd1498Szrj __FUNCTION__); \
125238fd1498Szrj _rtx; })
125338fd1498Szrj
125438fd1498Szrj #define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4) __extension__ \
125538fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
125638fd1498Szrj if (GET_CODE (_rtx) != C1 && GET_CODE(_rtx) != C2 \
125738fd1498Szrj && GET_CODE (_rtx) != C3 && GET_CODE(_rtx) != C4) \
125838fd1498Szrj rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
125938fd1498Szrj __FUNCTION__); \
126038fd1498Szrj _rtx; })
126138fd1498Szrj
126238fd1498Szrj #define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) __extension__ \
126338fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
126438fd1498Szrj if (GET_CODE (_rtx) != C1 && GET_CODE (_rtx) != C2 \
126538fd1498Szrj && GET_CODE (_rtx) != C3 && GET_CODE (_rtx) != C4 \
126638fd1498Szrj && GET_CODE (_rtx) != C5) \
126738fd1498Szrj rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
126838fd1498Szrj __FUNCTION__); \
126938fd1498Szrj _rtx; })
127038fd1498Szrj
127138fd1498Szrj #define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6) \
127238fd1498Szrj __extension__ \
127338fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
127438fd1498Szrj if (GET_CODE (_rtx) != C1 && GET_CODE (_rtx) != C2 \
127538fd1498Szrj && GET_CODE (_rtx) != C3 && GET_CODE (_rtx) != C4 \
127638fd1498Szrj && GET_CODE (_rtx) != C5 && GET_CODE (_rtx) != C6) \
127738fd1498Szrj rtl_check_failed_flag (NAME,_rtx, __FILE__, __LINE__, \
127838fd1498Szrj __FUNCTION__); \
127938fd1498Szrj _rtx; })
128038fd1498Szrj
128138fd1498Szrj #define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7) \
128238fd1498Szrj __extension__ \
128338fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
128438fd1498Szrj if (GET_CODE (_rtx) != C1 && GET_CODE (_rtx) != C2 \
128538fd1498Szrj && GET_CODE (_rtx) != C3 && GET_CODE (_rtx) != C4 \
128638fd1498Szrj && GET_CODE (_rtx) != C5 && GET_CODE (_rtx) != C6 \
128738fd1498Szrj && GET_CODE (_rtx) != C7) \
128838fd1498Szrj rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
128938fd1498Szrj __FUNCTION__); \
129038fd1498Szrj _rtx; })
129138fd1498Szrj
129238fd1498Szrj #define RTL_INSN_CHAIN_FLAG_CHECK(NAME, RTX) \
129338fd1498Szrj __extension__ \
129438fd1498Szrj ({ __typeof (RTX) const _rtx = (RTX); \
129538fd1498Szrj if (!INSN_CHAIN_CODE_P (GET_CODE (_rtx))) \
129638fd1498Szrj rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
129738fd1498Szrj __FUNCTION__); \
129838fd1498Szrj _rtx; })
129938fd1498Szrj
130038fd1498Szrj extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
130138fd1498Szrj int, const char *)
130238fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD
130338fd1498Szrj ;
130438fd1498Szrj
130538fd1498Szrj #else /* not ENABLE_RTL_FLAG_CHECKING */
130638fd1498Szrj
130738fd1498Szrj #define RTL_FLAG_CHECK1(NAME, RTX, C1) (RTX)
130838fd1498Szrj #define RTL_FLAG_CHECK2(NAME, RTX, C1, C2) (RTX)
130938fd1498Szrj #define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3) (RTX)
131038fd1498Szrj #define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4) (RTX)
131138fd1498Szrj #define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) (RTX)
131238fd1498Szrj #define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6) (RTX)
131338fd1498Szrj #define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7) (RTX)
131438fd1498Szrj #define RTL_INSN_CHAIN_FLAG_CHECK(NAME, RTX) (RTX)
131538fd1498Szrj #endif
131638fd1498Szrj
131738fd1498Szrj #define XINT(RTX, N) (RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
131838fd1498Szrj #define XUINT(RTX, N) (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
131938fd1498Szrj #define XSTR(RTX, N) (RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
132038fd1498Szrj #define XEXP(RTX, N) (RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
132138fd1498Szrj #define XVEC(RTX, N) (RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
132238fd1498Szrj #define XMODE(RTX, N) (RTL_CHECK1 (RTX, N, 'M').rt_type)
132338fd1498Szrj #define XTREE(RTX, N) (RTL_CHECK1 (RTX, N, 't').rt_tree)
132438fd1498Szrj #define XBBDEF(RTX, N) (RTL_CHECK1 (RTX, N, 'B').rt_bb)
132538fd1498Szrj #define XTMPL(RTX, N) (RTL_CHECK1 (RTX, N, 'T').rt_str)
132638fd1498Szrj #define XCFI(RTX, N) (RTL_CHECK1 (RTX, N, 'C').rt_cfi)
132738fd1498Szrj
132838fd1498Szrj #define XVECEXP(RTX, N, M) RTVEC_ELT (XVEC (RTX, N), M)
132938fd1498Szrj #define XVECLEN(RTX, N) GET_NUM_ELEM (XVEC (RTX, N))
133038fd1498Szrj
133138fd1498Szrj /* These are like XINT, etc. except that they expect a '0' field instead
133238fd1498Szrj of the normal type code. */
133338fd1498Szrj
133438fd1498Szrj #define X0INT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_int)
133538fd1498Szrj #define X0UINT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_uint)
133638fd1498Szrj #define X0STR(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_str)
133738fd1498Szrj #define X0EXP(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_rtx)
133838fd1498Szrj #define X0VEC(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_rtvec)
133938fd1498Szrj #define X0MODE(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_type)
134038fd1498Szrj #define X0TREE(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_tree)
134138fd1498Szrj #define X0BBDEF(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_bb)
134238fd1498Szrj #define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags)
134338fd1498Szrj #define X0CSELIB(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_cselib)
134438fd1498Szrj #define X0MEMATTR(RTX, N) (RTL_CHECKC1 (RTX, N, MEM).rt_mem)
134538fd1498Szrj #define X0CONSTANT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_constant)
134638fd1498Szrj
134738fd1498Szrj /* Access a '0' field with any type. */
134838fd1498Szrj #define X0ANY(RTX, N) RTL_CHECK1 (RTX, N, '0')
134938fd1498Szrj
135038fd1498Szrj #define XCINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_int)
135138fd1498Szrj #define XCUINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_uint)
135238fd1498Szrj #define XCSUBREG(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_subreg)
135338fd1498Szrj #define XCSTR(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_str)
135438fd1498Szrj #define XCEXP(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_rtx)
135538fd1498Szrj #define XCVEC(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_rtvec)
135638fd1498Szrj #define XCMODE(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_type)
135738fd1498Szrj #define XCTREE(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_tree)
135838fd1498Szrj #define XCBBDEF(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_bb)
135938fd1498Szrj #define XCCFI(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_cfi)
136038fd1498Szrj #define XCCSELIB(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_cselib)
136138fd1498Szrj
136238fd1498Szrj #define XCVECEXP(RTX, N, M, C) RTVEC_ELT (XCVEC (RTX, N, C), M)
136338fd1498Szrj #define XCVECLEN(RTX, N, C) GET_NUM_ELEM (XCVEC (RTX, N, C))
136438fd1498Szrj
136538fd1498Szrj #define XC2EXP(RTX, N, C1, C2) (RTL_CHECKC2 (RTX, N, C1, C2).rt_rtx)
136638fd1498Szrj
136738fd1498Szrj
136838fd1498Szrj /* Methods of rtx_expr_list. */
136938fd1498Szrj
next()137038fd1498Szrj inline rtx_expr_list *rtx_expr_list::next () const
137138fd1498Szrj {
137238fd1498Szrj rtx tmp = XEXP (this, 1);
137338fd1498Szrj return safe_as_a <rtx_expr_list *> (tmp);
137438fd1498Szrj }
137538fd1498Szrj
element()137638fd1498Szrj inline rtx rtx_expr_list::element () const
137738fd1498Szrj {
137838fd1498Szrj return XEXP (this, 0);
137938fd1498Szrj }
138038fd1498Szrj
138138fd1498Szrj /* Methods of rtx_insn_list. */
138238fd1498Szrj
next()138338fd1498Szrj inline rtx_insn_list *rtx_insn_list::next () const
138438fd1498Szrj {
138538fd1498Szrj rtx tmp = XEXP (this, 1);
138638fd1498Szrj return safe_as_a <rtx_insn_list *> (tmp);
138738fd1498Szrj }
138838fd1498Szrj
insn()138938fd1498Szrj inline rtx_insn *rtx_insn_list::insn () const
139038fd1498Szrj {
139138fd1498Szrj rtx tmp = XEXP (this, 0);
139238fd1498Szrj return safe_as_a <rtx_insn *> (tmp);
139338fd1498Szrj }
139438fd1498Szrj
139538fd1498Szrj /* Methods of rtx_sequence. */
139638fd1498Szrj
len()139738fd1498Szrj inline int rtx_sequence::len () const
139838fd1498Szrj {
139938fd1498Szrj return XVECLEN (this, 0);
140038fd1498Szrj }
140138fd1498Szrj
element(int index)140238fd1498Szrj inline rtx rtx_sequence::element (int index) const
140338fd1498Szrj {
140438fd1498Szrj return XVECEXP (this, 0, index);
140538fd1498Szrj }
140638fd1498Szrj
insn(int index)140738fd1498Szrj inline rtx_insn *rtx_sequence::insn (int index) const
140838fd1498Szrj {
140938fd1498Szrj return as_a <rtx_insn *> (XVECEXP (this, 0, index));
141038fd1498Szrj }
141138fd1498Szrj
141238fd1498Szrj /* ACCESS MACROS for particular fields of insns. */
141338fd1498Szrj
141438fd1498Szrj /* Holds a unique number for each insn.
141538fd1498Szrj These are not necessarily sequentially increasing. */
INSN_UID(const_rtx insn)141638fd1498Szrj inline int INSN_UID (const_rtx insn)
141738fd1498Szrj {
141838fd1498Szrj return RTL_INSN_CHAIN_FLAG_CHECK ("INSN_UID",
141938fd1498Szrj (insn))->u2.insn_uid;
142038fd1498Szrj }
INSN_UID(rtx insn)142138fd1498Szrj inline int& INSN_UID (rtx insn)
142238fd1498Szrj {
142338fd1498Szrj return RTL_INSN_CHAIN_FLAG_CHECK ("INSN_UID",
142438fd1498Szrj (insn))->u2.insn_uid;
142538fd1498Szrj }
142638fd1498Szrj
142738fd1498Szrj /* Chain insns together in sequence. */
142838fd1498Szrj
142938fd1498Szrj /* For now these are split in two: an rvalue form:
143038fd1498Szrj PREV_INSN/NEXT_INSN
143138fd1498Szrj and an lvalue form:
143238fd1498Szrj SET_NEXT_INSN/SET_PREV_INSN. */
143338fd1498Szrj
PREV_INSN(const rtx_insn * insn)143438fd1498Szrj inline rtx_insn *PREV_INSN (const rtx_insn *insn)
143538fd1498Szrj {
143638fd1498Szrj rtx prev = XEXP (insn, 0);
143738fd1498Szrj return safe_as_a <rtx_insn *> (prev);
143838fd1498Szrj }
143938fd1498Szrj
SET_PREV_INSN(rtx_insn * insn)144038fd1498Szrj inline rtx& SET_PREV_INSN (rtx_insn *insn)
144138fd1498Szrj {
144238fd1498Szrj return XEXP (insn, 0);
144338fd1498Szrj }
144438fd1498Szrj
NEXT_INSN(const rtx_insn * insn)144538fd1498Szrj inline rtx_insn *NEXT_INSN (const rtx_insn *insn)
144638fd1498Szrj {
144738fd1498Szrj rtx next = XEXP (insn, 1);
144838fd1498Szrj return safe_as_a <rtx_insn *> (next);
144938fd1498Szrj }
145038fd1498Szrj
SET_NEXT_INSN(rtx_insn * insn)145138fd1498Szrj inline rtx& SET_NEXT_INSN (rtx_insn *insn)
145238fd1498Szrj {
145338fd1498Szrj return XEXP (insn, 1);
145438fd1498Szrj }
145538fd1498Szrj
BLOCK_FOR_INSN(const_rtx insn)145638fd1498Szrj inline basic_block BLOCK_FOR_INSN (const_rtx insn)
145738fd1498Szrj {
145838fd1498Szrj return XBBDEF (insn, 2);
145938fd1498Szrj }
146038fd1498Szrj
BLOCK_FOR_INSN(rtx insn)146138fd1498Szrj inline basic_block& BLOCK_FOR_INSN (rtx insn)
146238fd1498Szrj {
146338fd1498Szrj return XBBDEF (insn, 2);
146438fd1498Szrj }
146538fd1498Szrj
set_block_for_insn(rtx_insn * insn,basic_block bb)146638fd1498Szrj inline void set_block_for_insn (rtx_insn *insn, basic_block bb)
146738fd1498Szrj {
146838fd1498Szrj BLOCK_FOR_INSN (insn) = bb;
146938fd1498Szrj }
147038fd1498Szrj
147138fd1498Szrj /* The body of an insn. */
PATTERN(const_rtx insn)147238fd1498Szrj inline rtx PATTERN (const_rtx insn)
147338fd1498Szrj {
147438fd1498Szrj return XEXP (insn, 3);
147538fd1498Szrj }
147638fd1498Szrj
PATTERN(rtx insn)147738fd1498Szrj inline rtx& PATTERN (rtx insn)
147838fd1498Szrj {
147938fd1498Szrj return XEXP (insn, 3);
148038fd1498Szrj }
148138fd1498Szrj
INSN_LOCATION(const rtx_insn * insn)148238fd1498Szrj inline unsigned int INSN_LOCATION (const rtx_insn *insn)
148338fd1498Szrj {
148438fd1498Szrj return XUINT (insn, 4);
148538fd1498Szrj }
148638fd1498Szrj
INSN_LOCATION(rtx_insn * insn)148738fd1498Szrj inline unsigned int& INSN_LOCATION (rtx_insn *insn)
148838fd1498Szrj {
148938fd1498Szrj return XUINT (insn, 4);
149038fd1498Szrj }
149138fd1498Szrj
INSN_HAS_LOCATION(const rtx_insn * insn)149238fd1498Szrj inline bool INSN_HAS_LOCATION (const rtx_insn *insn)
149338fd1498Szrj {
149438fd1498Szrj return LOCATION_LOCUS (INSN_LOCATION (insn)) != UNKNOWN_LOCATION;
149538fd1498Szrj }
149638fd1498Szrj
149738fd1498Szrj /* LOCATION of an RTX if relevant. */
149838fd1498Szrj #define RTL_LOCATION(X) (INSN_P (X) ? \
149938fd1498Szrj INSN_LOCATION (as_a <rtx_insn *> (X)) \
150038fd1498Szrj : UNKNOWN_LOCATION)
150138fd1498Szrj
150238fd1498Szrj /* Code number of instruction, from when it was recognized.
150338fd1498Szrj -1 means this instruction has not been recognized yet. */
150438fd1498Szrj #define INSN_CODE(INSN) XINT (INSN, 5)
150538fd1498Szrj
get_labels()150638fd1498Szrj inline rtvec rtx_jump_table_data::get_labels () const
150738fd1498Szrj {
150838fd1498Szrj rtx pat = PATTERN (this);
150938fd1498Szrj if (GET_CODE (pat) == ADDR_VEC)
151038fd1498Szrj return XVEC (pat, 0);
151138fd1498Szrj else
151238fd1498Szrj return XVEC (pat, 1); /* presumably an ADDR_DIFF_VEC */
151338fd1498Szrj }
151438fd1498Szrj
151538fd1498Szrj /* Return the mode of the data in the table, which is always a scalar
151638fd1498Szrj integer. */
151738fd1498Szrj
151838fd1498Szrj inline scalar_int_mode
get_data_mode()151938fd1498Szrj rtx_jump_table_data::get_data_mode () const
152038fd1498Szrj {
152138fd1498Szrj return as_a <scalar_int_mode> (GET_MODE (PATTERN (this)));
152238fd1498Szrj }
152338fd1498Szrj
152438fd1498Szrj /* If LABEL is followed by a jump table, return the table, otherwise
152538fd1498Szrj return null. */
152638fd1498Szrj
152738fd1498Szrj inline rtx_jump_table_data *
jump_table_for_label(const rtx_code_label * label)152838fd1498Szrj jump_table_for_label (const rtx_code_label *label)
152938fd1498Szrj {
153038fd1498Szrj return safe_dyn_cast <rtx_jump_table_data *> (NEXT_INSN (label));
153138fd1498Szrj }
153238fd1498Szrj
153338fd1498Szrj #define RTX_FRAME_RELATED_P(RTX) \
153438fd1498Szrj (RTL_FLAG_CHECK6 ("RTX_FRAME_RELATED_P", (RTX), DEBUG_INSN, INSN, \
153538fd1498Szrj CALL_INSN, JUMP_INSN, BARRIER, SET)->frame_related)
153638fd1498Szrj
153738fd1498Szrj /* 1 if JUMP RTX is a crossing jump. */
153838fd1498Szrj #define CROSSING_JUMP_P(RTX) \
153938fd1498Szrj (RTL_FLAG_CHECK1 ("CROSSING_JUMP_P", (RTX), JUMP_INSN)->jump)
154038fd1498Szrj
154138fd1498Szrj /* 1 if RTX is a call to a const function. Built from ECF_CONST and
154238fd1498Szrj TREE_READONLY. */
154338fd1498Szrj #define RTL_CONST_CALL_P(RTX) \
154438fd1498Szrj (RTL_FLAG_CHECK1 ("RTL_CONST_CALL_P", (RTX), CALL_INSN)->unchanging)
154538fd1498Szrj
154638fd1498Szrj /* 1 if RTX is a call to a pure function. Built from ECF_PURE and
154738fd1498Szrj DECL_PURE_P. */
154838fd1498Szrj #define RTL_PURE_CALL_P(RTX) \
154938fd1498Szrj (RTL_FLAG_CHECK1 ("RTL_PURE_CALL_P", (RTX), CALL_INSN)->return_val)
155038fd1498Szrj
155138fd1498Szrj /* 1 if RTX is a call to a const or pure function. */
155238fd1498Szrj #define RTL_CONST_OR_PURE_CALL_P(RTX) \
155338fd1498Szrj (RTL_CONST_CALL_P (RTX) || RTL_PURE_CALL_P (RTX))
155438fd1498Szrj
155538fd1498Szrj /* 1 if RTX is a call to a looping const or pure function. Built from
155638fd1498Szrj ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P. */
155738fd1498Szrj #define RTL_LOOPING_CONST_OR_PURE_CALL_P(RTX) \
155838fd1498Szrj (RTL_FLAG_CHECK1 ("CONST_OR_PURE_CALL_P", (RTX), CALL_INSN)->call)
155938fd1498Szrj
156038fd1498Szrj /* 1 if RTX is a call_insn for a sibling call. */
156138fd1498Szrj #define SIBLING_CALL_P(RTX) \
156238fd1498Szrj (RTL_FLAG_CHECK1 ("SIBLING_CALL_P", (RTX), CALL_INSN)->jump)
156338fd1498Szrj
156438fd1498Szrj /* 1 if RTX is a jump_insn, call_insn, or insn that is an annulling branch. */
156538fd1498Szrj #define INSN_ANNULLED_BRANCH_P(RTX) \
156638fd1498Szrj (RTL_FLAG_CHECK1 ("INSN_ANNULLED_BRANCH_P", (RTX), JUMP_INSN)->unchanging)
156738fd1498Szrj
156838fd1498Szrj /* 1 if RTX is an insn in a delay slot and is from the target of the branch.
156938fd1498Szrj If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be
157038fd1498Szrj executed if the branch is taken. For annulled branches with this bit
157138fd1498Szrj clear, the insn should be executed only if the branch is not taken. */
157238fd1498Szrj #define INSN_FROM_TARGET_P(RTX) \
157338fd1498Szrj (RTL_FLAG_CHECK3 ("INSN_FROM_TARGET_P", (RTX), INSN, JUMP_INSN, \
157438fd1498Szrj CALL_INSN)->in_struct)
157538fd1498Szrj
157638fd1498Szrj /* In an ADDR_DIFF_VEC, the flags for RTX for use by branch shortening.
157738fd1498Szrj See the comments for ADDR_DIFF_VEC in rtl.def. */
157838fd1498Szrj #define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS (RTX, 4)
157938fd1498Szrj
158038fd1498Szrj /* In a VALUE, the value cselib has assigned to RTX.
158138fd1498Szrj This is a "struct cselib_val", see cselib.h. */
158238fd1498Szrj #define CSELIB_VAL_PTR(RTX) X0CSELIB (RTX, 0)
158338fd1498Szrj
158438fd1498Szrj /* Holds a list of notes on what this insn does to various REGs.
158538fd1498Szrj It is a chain of EXPR_LIST rtx's, where the second operand is the
158638fd1498Szrj chain pointer and the first operand is the REG being described.
158738fd1498Szrj The mode field of the EXPR_LIST contains not a real machine mode
158838fd1498Szrj but a value from enum reg_note. */
158938fd1498Szrj #define REG_NOTES(INSN) XEXP(INSN, 6)
159038fd1498Szrj
159138fd1498Szrj /* In an ENTRY_VALUE this is the DECL_INCOMING_RTL of the argument in
159238fd1498Szrj question. */
159338fd1498Szrj #define ENTRY_VALUE_EXP(RTX) (RTL_CHECKC1 (RTX, 0, ENTRY_VALUE).rt_rtx)
159438fd1498Szrj
159538fd1498Szrj enum reg_note
159638fd1498Szrj {
159738fd1498Szrj #define DEF_REG_NOTE(NAME) NAME,
159838fd1498Szrj #include "reg-notes.def"
159938fd1498Szrj #undef DEF_REG_NOTE
160038fd1498Szrj REG_NOTE_MAX
160138fd1498Szrj };
160238fd1498Szrj
160338fd1498Szrj /* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */
160438fd1498Szrj #define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
160538fd1498Szrj #define PUT_REG_NOTE_KIND(LINK, KIND) \
160638fd1498Szrj PUT_MODE_RAW (LINK, (machine_mode) (KIND))
160738fd1498Szrj
160838fd1498Szrj /* Names for REG_NOTE's in EXPR_LIST insn's. */
160938fd1498Szrj
161038fd1498Szrj extern const char * const reg_note_name[];
161138fd1498Szrj #define GET_REG_NOTE_NAME(MODE) (reg_note_name[(int) (MODE)])
161238fd1498Szrj
161338fd1498Szrj /* This field is only present on CALL_INSNs. It holds a chain of EXPR_LIST of
161438fd1498Szrj USE and CLOBBER expressions.
161538fd1498Szrj USE expressions list the registers filled with arguments that
161638fd1498Szrj are passed to the function.
161738fd1498Szrj CLOBBER expressions document the registers explicitly clobbered
161838fd1498Szrj by this CALL_INSN.
161938fd1498Szrj Pseudo registers can not be mentioned in this list. */
162038fd1498Szrj #define CALL_INSN_FUNCTION_USAGE(INSN) XEXP(INSN, 7)
162138fd1498Szrj
162238fd1498Szrj /* The label-number of a code-label. The assembler label
162338fd1498Szrj is made from `L' and the label-number printed in decimal.
162438fd1498Szrj Label numbers are unique in a compilation. */
162538fd1498Szrj #define CODE_LABEL_NUMBER(INSN) XINT (INSN, 5)
162638fd1498Szrj
162738fd1498Szrj /* In a NOTE that is a line number, this is a string for the file name that the
162838fd1498Szrj line is in. We use the same field to record block numbers temporarily in
162938fd1498Szrj NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes. (We avoid lots of casts
163038fd1498Szrj between ints and pointers if we use a different macro for the block number.)
163138fd1498Szrj */
163238fd1498Szrj
163338fd1498Szrj /* Opaque data. */
163438fd1498Szrj #define NOTE_DATA(INSN) RTL_CHECKC1 (INSN, 3, NOTE)
163538fd1498Szrj #define NOTE_DELETED_LABEL_NAME(INSN) XCSTR (INSN, 3, NOTE)
163638fd1498Szrj #define SET_INSN_DELETED(INSN) set_insn_deleted (INSN);
163738fd1498Szrj #define NOTE_BLOCK(INSN) XCTREE (INSN, 3, NOTE)
163838fd1498Szrj #define NOTE_EH_HANDLER(INSN) XCINT (INSN, 3, NOTE)
163938fd1498Szrj #define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 3, NOTE)
164038fd1498Szrj #define NOTE_VAR_LOCATION(INSN) XCEXP (INSN, 3, NOTE)
164138fd1498Szrj #define NOTE_MARKER_LOCATION(INSN) XCUINT (INSN, 3, NOTE)
164238fd1498Szrj #define NOTE_CFI(INSN) XCCFI (INSN, 3, NOTE)
164338fd1498Szrj #define NOTE_LABEL_NUMBER(INSN) XCINT (INSN, 3, NOTE)
164438fd1498Szrj
164538fd1498Szrj /* In a NOTE that is a line number, this is the line number.
164638fd1498Szrj Other kinds of NOTEs are identified by negative numbers here. */
164738fd1498Szrj #define NOTE_KIND(INSN) XCINT (INSN, 4, NOTE)
164838fd1498Szrj
164938fd1498Szrj /* Nonzero if INSN is a note marking the beginning of a basic block. */
165038fd1498Szrj #define NOTE_INSN_BASIC_BLOCK_P(INSN) \
165138fd1498Szrj (NOTE_P (INSN) && NOTE_KIND (INSN) == NOTE_INSN_BASIC_BLOCK)
165238fd1498Szrj
165338fd1498Szrj /* Nonzero if INSN is a debug nonbind marker note,
165438fd1498Szrj for which NOTE_MARKER_LOCATION can be used. */
165538fd1498Szrj #define NOTE_MARKER_P(INSN) \
165638fd1498Szrj (NOTE_P (INSN) && \
165738fd1498Szrj (NOTE_KIND (INSN) == NOTE_INSN_BEGIN_STMT \
165838fd1498Szrj || NOTE_KIND (INSN) == NOTE_INSN_INLINE_ENTRY))
165938fd1498Szrj
166038fd1498Szrj /* Variable declaration and the location of a variable. */
166138fd1498Szrj #define PAT_VAR_LOCATION_DECL(PAT) (XCTREE ((PAT), 0, VAR_LOCATION))
166238fd1498Szrj #define PAT_VAR_LOCATION_LOC(PAT) (XCEXP ((PAT), 1, VAR_LOCATION))
166338fd1498Szrj
166438fd1498Szrj /* Initialization status of the variable in the location. Status
166538fd1498Szrj can be unknown, uninitialized or initialized. See enumeration
166638fd1498Szrj type below. */
166738fd1498Szrj #define PAT_VAR_LOCATION_STATUS(PAT) \
166838fd1498Szrj (RTL_FLAG_CHECK1 ("PAT_VAR_LOCATION_STATUS", PAT, VAR_LOCATION) \
166938fd1498Szrj ->u2.var_location_status)
167038fd1498Szrj
167138fd1498Szrj /* Accessors for a NOTE_INSN_VAR_LOCATION. */
167238fd1498Szrj #define NOTE_VAR_LOCATION_DECL(NOTE) \
167338fd1498Szrj PAT_VAR_LOCATION_DECL (NOTE_VAR_LOCATION (NOTE))
167438fd1498Szrj #define NOTE_VAR_LOCATION_LOC(NOTE) \
167538fd1498Szrj PAT_VAR_LOCATION_LOC (NOTE_VAR_LOCATION (NOTE))
167638fd1498Szrj #define NOTE_VAR_LOCATION_STATUS(NOTE) \
167738fd1498Szrj PAT_VAR_LOCATION_STATUS (NOTE_VAR_LOCATION (NOTE))
167838fd1498Szrj
167938fd1498Szrj /* Evaluate to TRUE if INSN is a debug insn that denotes a variable
168038fd1498Szrj location/value tracking annotation. */
168138fd1498Szrj #define DEBUG_BIND_INSN_P(INSN) \
168238fd1498Szrj (DEBUG_INSN_P (INSN) \
168338fd1498Szrj && (GET_CODE (PATTERN (INSN)) \
168438fd1498Szrj == VAR_LOCATION))
168538fd1498Szrj /* Evaluate to TRUE if INSN is a debug insn that denotes a program
168638fd1498Szrj source location marker. */
168738fd1498Szrj #define DEBUG_MARKER_INSN_P(INSN) \
168838fd1498Szrj (DEBUG_INSN_P (INSN) \
168938fd1498Szrj && (GET_CODE (PATTERN (INSN)) \
169038fd1498Szrj != VAR_LOCATION))
169138fd1498Szrj /* Evaluate to the marker kind. */
169238fd1498Szrj #define INSN_DEBUG_MARKER_KIND(INSN) \
169338fd1498Szrj (GET_CODE (PATTERN (INSN)) == DEBUG_MARKER \
169438fd1498Szrj ? (GET_MODE (PATTERN (INSN)) == VOIDmode \
169538fd1498Szrj ? NOTE_INSN_BEGIN_STMT \
169638fd1498Szrj : GET_MODE (PATTERN (INSN)) == BLKmode \
169738fd1498Szrj ? NOTE_INSN_INLINE_ENTRY \
169838fd1498Szrj : (enum insn_note)-1) \
169938fd1498Szrj : (enum insn_note)-1)
170038fd1498Szrj /* Create patterns for debug markers. These and the above abstract
170138fd1498Szrj the representation, so that it's easier to get rid of the abuse of
170238fd1498Szrj the mode to hold the marker kind. Other marker types are
170338fd1498Szrj envisioned, so a single bit flag won't do; maybe separate RTL codes
170438fd1498Szrj wouldn't be a problem. */
170538fd1498Szrj #define GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT() \
170638fd1498Szrj gen_rtx_DEBUG_MARKER (VOIDmode)
170738fd1498Szrj #define GEN_RTX_DEBUG_MARKER_INLINE_ENTRY_PAT() \
170838fd1498Szrj gen_rtx_DEBUG_MARKER (BLKmode)
170938fd1498Szrj
171038fd1498Szrj /* The VAR_LOCATION rtx in a DEBUG_INSN. */
171138fd1498Szrj #define INSN_VAR_LOCATION(INSN) \
171238fd1498Szrj (RTL_FLAG_CHECK1 ("INSN_VAR_LOCATION", PATTERN (INSN), VAR_LOCATION))
171338fd1498Szrj /* A pointer to the VAR_LOCATION rtx in a DEBUG_INSN. */
171438fd1498Szrj #define INSN_VAR_LOCATION_PTR(INSN) \
171538fd1498Szrj (&PATTERN (INSN))
171638fd1498Szrj
171738fd1498Szrj /* Accessors for a tree-expanded var location debug insn. */
171838fd1498Szrj #define INSN_VAR_LOCATION_DECL(INSN) \
171938fd1498Szrj PAT_VAR_LOCATION_DECL (INSN_VAR_LOCATION (INSN))
172038fd1498Szrj #define INSN_VAR_LOCATION_LOC(INSN) \
172138fd1498Szrj PAT_VAR_LOCATION_LOC (INSN_VAR_LOCATION (INSN))
172238fd1498Szrj #define INSN_VAR_LOCATION_STATUS(INSN) \
172338fd1498Szrj PAT_VAR_LOCATION_STATUS (INSN_VAR_LOCATION (INSN))
172438fd1498Szrj
172538fd1498Szrj /* Expand to the RTL that denotes an unknown variable location in a
172638fd1498Szrj DEBUG_INSN. */
172738fd1498Szrj #define gen_rtx_UNKNOWN_VAR_LOC() (gen_rtx_CLOBBER (VOIDmode, const0_rtx))
172838fd1498Szrj
172938fd1498Szrj /* Determine whether X is such an unknown location. */
173038fd1498Szrj #define VAR_LOC_UNKNOWN_P(X) \
173138fd1498Szrj (GET_CODE (X) == CLOBBER && XEXP ((X), 0) == const0_rtx)
173238fd1498Szrj
173338fd1498Szrj /* 1 if RTX is emitted after a call, but it should take effect before
173438fd1498Szrj the call returns. */
173538fd1498Szrj #define NOTE_DURING_CALL_P(RTX) \
173638fd1498Szrj (RTL_FLAG_CHECK1 ("NOTE_VAR_LOCATION_DURING_CALL_P", (RTX), NOTE)->call)
173738fd1498Szrj
173838fd1498Szrj /* DEBUG_EXPR_DECL corresponding to a DEBUG_EXPR RTX. */
173938fd1498Szrj #define DEBUG_EXPR_TREE_DECL(RTX) XCTREE (RTX, 0, DEBUG_EXPR)
174038fd1498Szrj
174138fd1498Szrj /* VAR_DECL/PARM_DECL DEBUG_IMPLICIT_PTR takes address of. */
174238fd1498Szrj #define DEBUG_IMPLICIT_PTR_DECL(RTX) XCTREE (RTX, 0, DEBUG_IMPLICIT_PTR)
174338fd1498Szrj
174438fd1498Szrj /* PARM_DECL DEBUG_PARAMETER_REF references. */
174538fd1498Szrj #define DEBUG_PARAMETER_REF_DECL(RTX) XCTREE (RTX, 0, DEBUG_PARAMETER_REF)
174638fd1498Szrj
174738fd1498Szrj /* Codes that appear in the NOTE_KIND field for kinds of notes
174838fd1498Szrj that are not line numbers. These codes are all negative.
174938fd1498Szrj
175038fd1498Szrj Notice that we do not try to use zero here for any of
175138fd1498Szrj the special note codes because sometimes the source line
175238fd1498Szrj actually can be zero! This happens (for example) when we
175338fd1498Szrj are generating code for the per-translation-unit constructor
175438fd1498Szrj and destructor routines for some C++ translation unit. */
175538fd1498Szrj
175638fd1498Szrj enum insn_note
175738fd1498Szrj {
175838fd1498Szrj #define DEF_INSN_NOTE(NAME) NAME,
175938fd1498Szrj #include "insn-notes.def"
176038fd1498Szrj #undef DEF_INSN_NOTE
176138fd1498Szrj
176238fd1498Szrj NOTE_INSN_MAX
176338fd1498Szrj };
176438fd1498Szrj
176538fd1498Szrj /* Names for NOTE insn's other than line numbers. */
176638fd1498Szrj
176738fd1498Szrj extern const char * const note_insn_name[NOTE_INSN_MAX];
176838fd1498Szrj #define GET_NOTE_INSN_NAME(NOTE_CODE) \
176938fd1498Szrj (note_insn_name[(NOTE_CODE)])
177038fd1498Szrj
177138fd1498Szrj /* The name of a label, in case it corresponds to an explicit label
177238fd1498Szrj in the input source code. */
177338fd1498Szrj #define LABEL_NAME(RTX) XCSTR (RTX, 6, CODE_LABEL)
177438fd1498Szrj
177538fd1498Szrj /* In jump.c, each label contains a count of the number
177638fd1498Szrj of LABEL_REFs that point at it, so unused labels can be deleted. */
177738fd1498Szrj #define LABEL_NUSES(RTX) XCINT (RTX, 4, CODE_LABEL)
177838fd1498Szrj
177938fd1498Szrj /* Labels carry a two-bit field composed of the ->jump and ->call
178038fd1498Szrj bits. This field indicates whether the label is an alternate
178138fd1498Szrj entry point, and if so, what kind. */
178238fd1498Szrj enum label_kind
178338fd1498Szrj {
178438fd1498Szrj LABEL_NORMAL = 0, /* ordinary label */
178538fd1498Szrj LABEL_STATIC_ENTRY, /* alternate entry point, not exported */
178638fd1498Szrj LABEL_GLOBAL_ENTRY, /* alternate entry point, exported */
178738fd1498Szrj LABEL_WEAK_ENTRY /* alternate entry point, exported as weak symbol */
178838fd1498Szrj };
178938fd1498Szrj
179038fd1498Szrj #if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION > 2007)
179138fd1498Szrj
179238fd1498Szrj /* Retrieve the kind of LABEL. */
179338fd1498Szrj #define LABEL_KIND(LABEL) __extension__ \
179438fd1498Szrj ({ __typeof (LABEL) const _label = (LABEL); \
179538fd1498Szrj if (! LABEL_P (_label)) \
179638fd1498Szrj rtl_check_failed_flag ("LABEL_KIND", _label, __FILE__, __LINE__, \
179738fd1498Szrj __FUNCTION__); \
179838fd1498Szrj (enum label_kind) ((_label->jump << 1) | _label->call); })
179938fd1498Szrj
180038fd1498Szrj /* Set the kind of LABEL. */
180138fd1498Szrj #define SET_LABEL_KIND(LABEL, KIND) do { \
180238fd1498Szrj __typeof (LABEL) const _label = (LABEL); \
180338fd1498Szrj const unsigned int _kind = (KIND); \
180438fd1498Szrj if (! LABEL_P (_label)) \
180538fd1498Szrj rtl_check_failed_flag ("SET_LABEL_KIND", _label, __FILE__, __LINE__, \
180638fd1498Szrj __FUNCTION__); \
180738fd1498Szrj _label->jump = ((_kind >> 1) & 1); \
180838fd1498Szrj _label->call = (_kind & 1); \
180938fd1498Szrj } while (0)
181038fd1498Szrj
181138fd1498Szrj #else
181238fd1498Szrj
181338fd1498Szrj /* Retrieve the kind of LABEL. */
181438fd1498Szrj #define LABEL_KIND(LABEL) \
181538fd1498Szrj ((enum label_kind) (((LABEL)->jump << 1) | (LABEL)->call))
181638fd1498Szrj
181738fd1498Szrj /* Set the kind of LABEL. */
181838fd1498Szrj #define SET_LABEL_KIND(LABEL, KIND) do { \
181938fd1498Szrj rtx const _label = (LABEL); \
182038fd1498Szrj const unsigned int _kind = (KIND); \
182138fd1498Szrj _label->jump = ((_kind >> 1) & 1); \
182238fd1498Szrj _label->call = (_kind & 1); \
182338fd1498Szrj } while (0)
182438fd1498Szrj
182538fd1498Szrj #endif /* rtl flag checking */
182638fd1498Szrj
182738fd1498Szrj #define LABEL_ALT_ENTRY_P(LABEL) (LABEL_KIND (LABEL) != LABEL_NORMAL)
182838fd1498Szrj
182938fd1498Szrj /* In jump.c, each JUMP_INSN can point to a label that it can jump to,
183038fd1498Szrj so that if the JUMP_INSN is deleted, the label's LABEL_NUSES can
183138fd1498Szrj be decremented and possibly the label can be deleted. */
183238fd1498Szrj #define JUMP_LABEL(INSN) XCEXP (INSN, 7, JUMP_INSN)
183338fd1498Szrj
JUMP_LABEL_AS_INSN(const rtx_insn * insn)183438fd1498Szrj inline rtx_insn *JUMP_LABEL_AS_INSN (const rtx_insn *insn)
183538fd1498Szrj {
183638fd1498Szrj return safe_as_a <rtx_insn *> (JUMP_LABEL (insn));
183738fd1498Szrj }
183838fd1498Szrj
183938fd1498Szrj /* Methods of rtx_jump_insn. */
184038fd1498Szrj
jump_label()184138fd1498Szrj inline rtx rtx_jump_insn::jump_label () const
184238fd1498Szrj {
184338fd1498Szrj return JUMP_LABEL (this);
184438fd1498Szrj }
184538fd1498Szrj
jump_target()184638fd1498Szrj inline rtx_code_label *rtx_jump_insn::jump_target () const
184738fd1498Szrj {
184838fd1498Szrj return safe_as_a <rtx_code_label *> (JUMP_LABEL (this));
184938fd1498Szrj }
185038fd1498Szrj
set_jump_target(rtx_code_label * target)185138fd1498Szrj inline void rtx_jump_insn::set_jump_target (rtx_code_label *target)
185238fd1498Szrj {
185338fd1498Szrj JUMP_LABEL (this) = target;
185438fd1498Szrj }
185538fd1498Szrj
185638fd1498Szrj /* Once basic blocks are found, each CODE_LABEL starts a chain that
185738fd1498Szrj goes through all the LABEL_REFs that jump to that label. The chain
185838fd1498Szrj eventually winds up at the CODE_LABEL: it is circular. */
185938fd1498Szrj #define LABEL_REFS(LABEL) XCEXP (LABEL, 3, CODE_LABEL)
186038fd1498Szrj
186138fd1498Szrj /* Get the label that a LABEL_REF references. */
186238fd1498Szrj static inline rtx_insn *
label_ref_label(const_rtx ref)186338fd1498Szrj label_ref_label (const_rtx ref)
186438fd1498Szrj {
186538fd1498Szrj return as_a<rtx_insn *> (XCEXP (ref, 0, LABEL_REF));
186638fd1498Szrj }
186738fd1498Szrj
186838fd1498Szrj /* Set the label that LABEL_REF ref refers to. */
186938fd1498Szrj
187038fd1498Szrj static inline void
set_label_ref_label(rtx ref,rtx_insn * label)187138fd1498Szrj set_label_ref_label (rtx ref, rtx_insn *label)
187238fd1498Szrj {
187338fd1498Szrj XCEXP (ref, 0, LABEL_REF) = label;
187438fd1498Szrj }
187538fd1498Szrj
187638fd1498Szrj /* For a REG rtx, REGNO extracts the register number. REGNO can only
187738fd1498Szrj be used on RHS. Use SET_REGNO to change the value. */
187838fd1498Szrj #define REGNO(RTX) (rhs_regno(RTX))
187938fd1498Szrj #define SET_REGNO(RTX, N) (df_ref_change_reg_with_loc (RTX, N))
188038fd1498Szrj
188138fd1498Szrj /* Return the number of consecutive registers in a REG. This is always
188238fd1498Szrj 1 for pseudo registers and is determined by TARGET_HARD_REGNO_NREGS for
188338fd1498Szrj hard registers. */
188438fd1498Szrj #define REG_NREGS(RTX) (REG_CHECK (RTX)->nregs)
188538fd1498Szrj
188638fd1498Szrj /* ORIGINAL_REGNO holds the number the register originally had; for a
188738fd1498Szrj pseudo register turned into a hard reg this will hold the old pseudo
188838fd1498Szrj register number. */
188938fd1498Szrj #define ORIGINAL_REGNO(RTX) \
189038fd1498Szrj (RTL_FLAG_CHECK1 ("ORIGINAL_REGNO", (RTX), REG)->u2.original_regno)
189138fd1498Szrj
189238fd1498Szrj /* Force the REGNO macro to only be used on the lhs. */
189338fd1498Szrj static inline unsigned int
rhs_regno(const_rtx x)189438fd1498Szrj rhs_regno (const_rtx x)
189538fd1498Szrj {
189638fd1498Szrj return REG_CHECK (x)->regno;
189738fd1498Szrj }
189838fd1498Szrj
189938fd1498Szrj /* Return the final register in REG X plus one. */
190038fd1498Szrj static inline unsigned int
END_REGNO(const_rtx x)190138fd1498Szrj END_REGNO (const_rtx x)
190238fd1498Szrj {
190338fd1498Szrj return REGNO (x) + REG_NREGS (x);
190438fd1498Szrj }
190538fd1498Szrj
190638fd1498Szrj /* Change the REGNO and REG_NREGS of REG X to the specified values,
190738fd1498Szrj bypassing the df machinery. */
190838fd1498Szrj static inline void
set_regno_raw(rtx x,unsigned int regno,unsigned int nregs)190938fd1498Szrj set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
191038fd1498Szrj {
191138fd1498Szrj reg_info *reg = REG_CHECK (x);
191238fd1498Szrj reg->regno = regno;
191338fd1498Szrj reg->nregs = nregs;
191438fd1498Szrj }
191538fd1498Szrj
191638fd1498Szrj /* 1 if RTX is a reg or parallel that is the current function's return
191738fd1498Szrj value. */
191838fd1498Szrj #define REG_FUNCTION_VALUE_P(RTX) \
191938fd1498Szrj (RTL_FLAG_CHECK2 ("REG_FUNCTION_VALUE_P", (RTX), REG, PARALLEL)->return_val)
192038fd1498Szrj
192138fd1498Szrj /* 1 if RTX is a reg that corresponds to a variable declared by the user. */
192238fd1498Szrj #define REG_USERVAR_P(RTX) \
192338fd1498Szrj (RTL_FLAG_CHECK1 ("REG_USERVAR_P", (RTX), REG)->volatil)
192438fd1498Szrj
192538fd1498Szrj /* 1 if RTX is a reg that holds a pointer value. */
192638fd1498Szrj #define REG_POINTER(RTX) \
192738fd1498Szrj (RTL_FLAG_CHECK1 ("REG_POINTER", (RTX), REG)->frame_related)
192838fd1498Szrj
192938fd1498Szrj /* 1 if RTX is a mem that holds a pointer value. */
193038fd1498Szrj #define MEM_POINTER(RTX) \
193138fd1498Szrj (RTL_FLAG_CHECK1 ("MEM_POINTER", (RTX), MEM)->frame_related)
193238fd1498Szrj
193338fd1498Szrj /* 1 if the given register REG corresponds to a hard register. */
193438fd1498Szrj #define HARD_REGISTER_P(REG) (HARD_REGISTER_NUM_P (REGNO (REG)))
193538fd1498Szrj
193638fd1498Szrj /* 1 if the given register number REG_NO corresponds to a hard register. */
193738fd1498Szrj #define HARD_REGISTER_NUM_P(REG_NO) ((REG_NO) < FIRST_PSEUDO_REGISTER)
193838fd1498Szrj
193938fd1498Szrj /* For a CONST_INT rtx, INTVAL extracts the integer. */
194038fd1498Szrj #define INTVAL(RTX) XCWINT (RTX, 0, CONST_INT)
194138fd1498Szrj #define UINTVAL(RTX) ((unsigned HOST_WIDE_INT) INTVAL (RTX))
194238fd1498Szrj
194338fd1498Szrj /* For a CONST_WIDE_INT, CONST_WIDE_INT_NUNITS is the number of
194438fd1498Szrj elements actually needed to represent the constant.
194538fd1498Szrj CONST_WIDE_INT_ELT gets one of the elements. 0 is the least
194638fd1498Szrj significant HOST_WIDE_INT. */
194738fd1498Szrj #define CONST_WIDE_INT_VEC(RTX) HWIVEC_CHECK (RTX, CONST_WIDE_INT)
194838fd1498Szrj #define CONST_WIDE_INT_NUNITS(RTX) CWI_GET_NUM_ELEM (RTX)
194938fd1498Szrj #define CONST_WIDE_INT_ELT(RTX, N) CWI_ELT (RTX, N)
195038fd1498Szrj
195138fd1498Szrj /* For a CONST_POLY_INT, CONST_POLY_INT_COEFFS gives access to the
195238fd1498Szrj individual coefficients, in the form of a trailing_wide_ints structure. */
195338fd1498Szrj #define CONST_POLY_INT_COEFFS(RTX) \
195438fd1498Szrj (RTL_FLAG_CHECK1("CONST_POLY_INT_COEFFS", (RTX), \
195538fd1498Szrj CONST_POLY_INT)->u.cpi.coeffs)
195638fd1498Szrj
195738fd1498Szrj /* For a CONST_DOUBLE:
195838fd1498Szrj #if TARGET_SUPPORTS_WIDE_INT == 0
195938fd1498Szrj For a VOIDmode, there are two integers CONST_DOUBLE_LOW is the
196038fd1498Szrj low-order word and ..._HIGH the high-order.
196138fd1498Szrj #endif
196238fd1498Szrj For a float, there is a REAL_VALUE_TYPE structure, and
196338fd1498Szrj CONST_DOUBLE_REAL_VALUE(r) is a pointer to it. */
196438fd1498Szrj #define CONST_DOUBLE_LOW(r) XCMWINT (r, 0, CONST_DOUBLE, VOIDmode)
196538fd1498Szrj #define CONST_DOUBLE_HIGH(r) XCMWINT (r, 1, CONST_DOUBLE, VOIDmode)
196638fd1498Szrj #define CONST_DOUBLE_REAL_VALUE(r) \
196738fd1498Szrj ((const struct real_value *) XCNMPRV (r, CONST_DOUBLE, VOIDmode))
196838fd1498Szrj
196938fd1498Szrj #define CONST_FIXED_VALUE(r) \
197038fd1498Szrj ((const struct fixed_value *) XCNMPFV (r, CONST_FIXED, VOIDmode))
197138fd1498Szrj #define CONST_FIXED_VALUE_HIGH(r) \
197238fd1498Szrj ((HOST_WIDE_INT) (CONST_FIXED_VALUE (r)->data.high))
197338fd1498Szrj #define CONST_FIXED_VALUE_LOW(r) \
197438fd1498Szrj ((HOST_WIDE_INT) (CONST_FIXED_VALUE (r)->data.low))
197538fd1498Szrj
197638fd1498Szrj /* For a CONST_VECTOR, return element #n. */
197738fd1498Szrj #define CONST_VECTOR_ELT(RTX, N) const_vector_elt (RTX, N)
197838fd1498Szrj
197938fd1498Szrj /* See rtl.texi for a description of these macros. */
198038fd1498Szrj #define CONST_VECTOR_NPATTERNS(RTX) \
198138fd1498Szrj (RTL_FLAG_CHECK1 ("CONST_VECTOR_NPATTERNS", (RTX), CONST_VECTOR) \
198238fd1498Szrj ->u2.const_vector.npatterns)
198338fd1498Szrj
198438fd1498Szrj #define CONST_VECTOR_NELTS_PER_PATTERN(RTX) \
198538fd1498Szrj (RTL_FLAG_CHECK1 ("CONST_VECTOR_NELTS_PER_PATTERN", (RTX), CONST_VECTOR) \
198638fd1498Szrj ->u2.const_vector.nelts_per_pattern)
198738fd1498Szrj
198838fd1498Szrj #define CONST_VECTOR_DUPLICATE_P(RTX) \
198938fd1498Szrj (CONST_VECTOR_NELTS_PER_PATTERN (RTX) == 1)
199038fd1498Szrj
199138fd1498Szrj #define CONST_VECTOR_STEPPED_P(RTX) \
199238fd1498Szrj (CONST_VECTOR_NELTS_PER_PATTERN (RTX) == 3)
199338fd1498Szrj
199438fd1498Szrj #define CONST_VECTOR_ENCODED_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)
199538fd1498Szrj
199638fd1498Szrj /* Return the number of elements encoded directly in a CONST_VECTOR. */
199738fd1498Szrj
199838fd1498Szrj inline unsigned int
const_vector_encoded_nelts(const_rtx x)199938fd1498Szrj const_vector_encoded_nelts (const_rtx x)
200038fd1498Szrj {
200138fd1498Szrj return CONST_VECTOR_NPATTERNS (x) * CONST_VECTOR_NELTS_PER_PATTERN (x);
200238fd1498Szrj }
200338fd1498Szrj
200438fd1498Szrj /* For a CONST_VECTOR, return the number of elements in a vector. */
200538fd1498Szrj #define CONST_VECTOR_NUNITS(RTX) GET_MODE_NUNITS (GET_MODE (RTX))
200638fd1498Szrj
200738fd1498Szrj /* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of.
200838fd1498Szrj SUBREG_BYTE extracts the byte-number. */
200938fd1498Szrj
201038fd1498Szrj #define SUBREG_REG(RTX) XCEXP (RTX, 0, SUBREG)
201138fd1498Szrj #define SUBREG_BYTE(RTX) XCSUBREG (RTX, 1, SUBREG)
201238fd1498Szrj
201338fd1498Szrj /* in rtlanal.c */
201438fd1498Szrj /* Return the right cost to give to an operation
201538fd1498Szrj to make the cost of the corresponding register-to-register instruction
201638fd1498Szrj N times that of a fast register-to-register instruction. */
201738fd1498Szrj #define COSTS_N_INSNS(N) ((N) * 4)
201838fd1498Szrj
201938fd1498Szrj /* Maximum cost of an rtl expression. This value has the special meaning
202038fd1498Szrj not to use an rtx with this cost under any circumstances. */
202138fd1498Szrj #define MAX_COST INT_MAX
202238fd1498Szrj
202338fd1498Szrj /* Return true if CODE always has VOIDmode. */
202438fd1498Szrj
202538fd1498Szrj static inline bool
always_void_p(enum rtx_code code)202638fd1498Szrj always_void_p (enum rtx_code code)
202738fd1498Szrj {
202838fd1498Szrj return code == SET;
202938fd1498Szrj }
203038fd1498Szrj
203138fd1498Szrj /* A structure to hold all available cost information about an rtl
203238fd1498Szrj expression. */
203338fd1498Szrj struct full_rtx_costs
203438fd1498Szrj {
203538fd1498Szrj int speed;
203638fd1498Szrj int size;
203738fd1498Szrj };
203838fd1498Szrj
203938fd1498Szrj /* Initialize a full_rtx_costs structure C to the maximum cost. */
204038fd1498Szrj static inline void
init_costs_to_max(struct full_rtx_costs * c)204138fd1498Szrj init_costs_to_max (struct full_rtx_costs *c)
204238fd1498Szrj {
204338fd1498Szrj c->speed = MAX_COST;
204438fd1498Szrj c->size = MAX_COST;
204538fd1498Szrj }
204638fd1498Szrj
204738fd1498Szrj /* Initialize a full_rtx_costs structure C to zero cost. */
204838fd1498Szrj static inline void
init_costs_to_zero(struct full_rtx_costs * c)204938fd1498Szrj init_costs_to_zero (struct full_rtx_costs *c)
205038fd1498Szrj {
205138fd1498Szrj c->speed = 0;
205238fd1498Szrj c->size = 0;
205338fd1498Szrj }
205438fd1498Szrj
205538fd1498Szrj /* Compare two full_rtx_costs structures A and B, returning true
205638fd1498Szrj if A < B when optimizing for speed. */
205738fd1498Szrj static inline bool
costs_lt_p(struct full_rtx_costs * a,struct full_rtx_costs * b,bool speed)205838fd1498Szrj costs_lt_p (struct full_rtx_costs *a, struct full_rtx_costs *b,
205938fd1498Szrj bool speed)
206038fd1498Szrj {
206138fd1498Szrj if (speed)
206238fd1498Szrj return (a->speed < b->speed
206338fd1498Szrj || (a->speed == b->speed && a->size < b->size));
206438fd1498Szrj else
206538fd1498Szrj return (a->size < b->size
206638fd1498Szrj || (a->size == b->size && a->speed < b->speed));
206738fd1498Szrj }
206838fd1498Szrj
206938fd1498Szrj /* Increase both members of the full_rtx_costs structure C by the
207038fd1498Szrj cost of N insns. */
207138fd1498Szrj static inline void
costs_add_n_insns(struct full_rtx_costs * c,int n)207238fd1498Szrj costs_add_n_insns (struct full_rtx_costs *c, int n)
207338fd1498Szrj {
207438fd1498Szrj c->speed += COSTS_N_INSNS (n);
207538fd1498Szrj c->size += COSTS_N_INSNS (n);
207638fd1498Szrj }
207738fd1498Szrj
207838fd1498Szrj /* Describes the shape of a subreg:
207938fd1498Szrj
208038fd1498Szrj inner_mode == the mode of the SUBREG_REG
208138fd1498Szrj offset == the SUBREG_BYTE
208238fd1498Szrj outer_mode == the mode of the SUBREG itself. */
208338fd1498Szrj struct subreg_shape {
208438fd1498Szrj subreg_shape (machine_mode, poly_uint16, machine_mode);
208538fd1498Szrj bool operator == (const subreg_shape &) const;
208638fd1498Szrj bool operator != (const subreg_shape &) const;
208738fd1498Szrj unsigned HOST_WIDE_INT unique_id () const;
208838fd1498Szrj
208938fd1498Szrj machine_mode inner_mode;
209038fd1498Szrj poly_uint16 offset;
209138fd1498Szrj machine_mode outer_mode;
209238fd1498Szrj };
209338fd1498Szrj
209438fd1498Szrj inline
subreg_shape(machine_mode inner_mode_in,poly_uint16 offset_in,machine_mode outer_mode_in)209538fd1498Szrj subreg_shape::subreg_shape (machine_mode inner_mode_in,
209638fd1498Szrj poly_uint16 offset_in,
209738fd1498Szrj machine_mode outer_mode_in)
209838fd1498Szrj : inner_mode (inner_mode_in), offset (offset_in), outer_mode (outer_mode_in)
209938fd1498Szrj {}
210038fd1498Szrj
210138fd1498Szrj inline bool
210238fd1498Szrj subreg_shape::operator == (const subreg_shape &other) const
210338fd1498Szrj {
210438fd1498Szrj return (inner_mode == other.inner_mode
210538fd1498Szrj && known_eq (offset, other.offset)
210638fd1498Szrj && outer_mode == other.outer_mode);
210738fd1498Szrj }
210838fd1498Szrj
210938fd1498Szrj inline bool
211038fd1498Szrj subreg_shape::operator != (const subreg_shape &other) const
211138fd1498Szrj {
211238fd1498Szrj return !operator == (other);
211338fd1498Szrj }
211438fd1498Szrj
211538fd1498Szrj /* Return an integer that uniquely identifies this shape. Structures
211638fd1498Szrj like rtx_def assume that a mode can fit in an 8-bit bitfield and no
211738fd1498Szrj current mode is anywhere near being 65536 bytes in size, so the
211838fd1498Szrj id comfortably fits in an int. */
211938fd1498Szrj
212038fd1498Szrj inline unsigned HOST_WIDE_INT
unique_id()212138fd1498Szrj subreg_shape::unique_id () const
212238fd1498Szrj {
212338fd1498Szrj { STATIC_ASSERT (MAX_MACHINE_MODE <= 256); }
212438fd1498Szrj { STATIC_ASSERT (NUM_POLY_INT_COEFFS <= 3); }
212538fd1498Szrj { STATIC_ASSERT (sizeof (offset.coeffs[0]) <= 2); }
212638fd1498Szrj int res = (int) inner_mode + ((int) outer_mode << 8);
212738fd1498Szrj for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
212838fd1498Szrj res += (HOST_WIDE_INT) offset.coeffs[i] << ((1 + i) * 16);
212938fd1498Szrj return res;
213038fd1498Szrj }
213138fd1498Szrj
213238fd1498Szrj /* Return the shape of a SUBREG rtx. */
213338fd1498Szrj
213438fd1498Szrj static inline subreg_shape
shape_of_subreg(const_rtx x)213538fd1498Szrj shape_of_subreg (const_rtx x)
213638fd1498Szrj {
213738fd1498Szrj return subreg_shape (GET_MODE (SUBREG_REG (x)),
213838fd1498Szrj SUBREG_BYTE (x), GET_MODE (x));
213938fd1498Szrj }
214038fd1498Szrj
214138fd1498Szrj /* Information about an address. This structure is supposed to be able
214238fd1498Szrj to represent all supported target addresses. Please extend it if it
214338fd1498Szrj is not yet general enough. */
214438fd1498Szrj struct address_info {
214538fd1498Szrj /* The mode of the value being addressed, or VOIDmode if this is
214638fd1498Szrj a load-address operation with no known address mode. */
214738fd1498Szrj machine_mode mode;
214838fd1498Szrj
214938fd1498Szrj /* The address space. */
215038fd1498Szrj addr_space_t as;
215138fd1498Szrj
215238fd1498Szrj /* True if this is an RTX_AUTOINC address. */
215338fd1498Szrj bool autoinc_p;
215438fd1498Szrj
215538fd1498Szrj /* A pointer to the top-level address. */
215638fd1498Szrj rtx *outer;
215738fd1498Szrj
215838fd1498Szrj /* A pointer to the inner address, after all address mutations
215938fd1498Szrj have been stripped from the top-level address. It can be one
216038fd1498Szrj of the following:
216138fd1498Szrj
216238fd1498Szrj - A {PRE,POST}_{INC,DEC} of *BASE. SEGMENT, INDEX and DISP are null.
216338fd1498Szrj
216438fd1498Szrj - A {PRE,POST}_MODIFY of *BASE. In this case either INDEX or DISP
216538fd1498Szrj points to the step value, depending on whether the step is variable
216638fd1498Szrj or constant respectively. SEGMENT is null.
216738fd1498Szrj
216838fd1498Szrj - A plain sum of the form SEGMENT + BASE + INDEX + DISP,
216938fd1498Szrj with null fields evaluating to 0. */
217038fd1498Szrj rtx *inner;
217138fd1498Szrj
217238fd1498Szrj /* Components that make up *INNER. Each one may be null or nonnull.
217338fd1498Szrj When nonnull, their meanings are as follows:
217438fd1498Szrj
217538fd1498Szrj - *SEGMENT is the "segment" of memory to which the address refers.
217638fd1498Szrj This value is entirely target-specific and is only called a "segment"
217738fd1498Szrj because that's its most typical use. It contains exactly one UNSPEC,
217838fd1498Szrj pointed to by SEGMENT_TERM. The contents of *SEGMENT do not need
217938fd1498Szrj reloading.
218038fd1498Szrj
218138fd1498Szrj - *BASE is a variable expression representing a base address.
218238fd1498Szrj It contains exactly one REG, SUBREG or MEM, pointed to by BASE_TERM.
218338fd1498Szrj
218438fd1498Szrj - *INDEX is a variable expression representing an index value.
218538fd1498Szrj It may be a scaled expression, such as a MULT. It has exactly
218638fd1498Szrj one REG, SUBREG or MEM, pointed to by INDEX_TERM.
218738fd1498Szrj
218838fd1498Szrj - *DISP is a constant, possibly mutated. DISP_TERM points to the
218938fd1498Szrj unmutated RTX_CONST_OBJ. */
219038fd1498Szrj rtx *segment;
219138fd1498Szrj rtx *base;
219238fd1498Szrj rtx *index;
219338fd1498Szrj rtx *disp;
219438fd1498Szrj
219538fd1498Szrj rtx *segment_term;
219638fd1498Szrj rtx *base_term;
219738fd1498Szrj rtx *index_term;
219838fd1498Szrj rtx *disp_term;
219938fd1498Szrj
220038fd1498Szrj /* In a {PRE,POST}_MODIFY address, this points to a second copy
220138fd1498Szrj of BASE_TERM, otherwise it is null. */
220238fd1498Szrj rtx *base_term2;
220338fd1498Szrj
220438fd1498Szrj /* ADDRESS if this structure describes an address operand, MEM if
220538fd1498Szrj it describes a MEM address. */
220638fd1498Szrj enum rtx_code addr_outer_code;
220738fd1498Szrj
220838fd1498Szrj /* If BASE is nonnull, this is the code of the rtx that contains it. */
220938fd1498Szrj enum rtx_code base_outer_code;
221038fd1498Szrj };
221138fd1498Szrj
221238fd1498Szrj /* This is used to bundle an rtx and a mode together so that the pair
221338fd1498Szrj can be used with the wi:: routines. If we ever put modes into rtx
221438fd1498Szrj integer constants, this should go away and then just pass an rtx in. */
221538fd1498Szrj typedef std::pair <rtx, machine_mode> rtx_mode_t;
221638fd1498Szrj
221738fd1498Szrj namespace wi
221838fd1498Szrj {
221938fd1498Szrj template <>
222038fd1498Szrj struct int_traits <rtx_mode_t>
222138fd1498Szrj {
222238fd1498Szrj static const enum precision_type precision_type = VAR_PRECISION;
222338fd1498Szrj static const bool host_dependent_precision = false;
222438fd1498Szrj /* This ought to be true, except for the special case that BImode
222538fd1498Szrj is canonicalized to STORE_FLAG_VALUE, which might be 1. */
222638fd1498Szrj static const bool is_sign_extended = false;
222738fd1498Szrj static unsigned int get_precision (const rtx_mode_t &);
222838fd1498Szrj static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
222938fd1498Szrj const rtx_mode_t &);
223038fd1498Szrj };
223138fd1498Szrj }
223238fd1498Szrj
223338fd1498Szrj inline unsigned int
223438fd1498Szrj wi::int_traits <rtx_mode_t>::get_precision (const rtx_mode_t &x)
223538fd1498Szrj {
223638fd1498Szrj return GET_MODE_PRECISION (as_a <scalar_mode> (x.second));
223738fd1498Szrj }
223838fd1498Szrj
223938fd1498Szrj inline wi::storage_ref
224038fd1498Szrj wi::int_traits <rtx_mode_t>::decompose (HOST_WIDE_INT *,
224138fd1498Szrj unsigned int precision,
224238fd1498Szrj const rtx_mode_t &x)
224338fd1498Szrj {
224438fd1498Szrj gcc_checking_assert (precision == get_precision (x));
224538fd1498Szrj switch (GET_CODE (x.first))
224638fd1498Szrj {
224738fd1498Szrj case CONST_INT:
224838fd1498Szrj if (precision < HOST_BITS_PER_WIDE_INT)
224938fd1498Szrj /* Nonzero BImodes are stored as STORE_FLAG_VALUE, which on many
225038fd1498Szrj targets is 1 rather than -1. */
225138fd1498Szrj gcc_checking_assert (INTVAL (x.first)
225238fd1498Szrj == sext_hwi (INTVAL (x.first), precision)
225338fd1498Szrj || (x.second == BImode && INTVAL (x.first) == 1));
225438fd1498Szrj
225538fd1498Szrj return wi::storage_ref (&INTVAL (x.first), 1, precision);
225638fd1498Szrj
225738fd1498Szrj case CONST_WIDE_INT:
225838fd1498Szrj return wi::storage_ref (&CONST_WIDE_INT_ELT (x.first, 0),
225938fd1498Szrj CONST_WIDE_INT_NUNITS (x.first), precision);
226038fd1498Szrj
226138fd1498Szrj #if TARGET_SUPPORTS_WIDE_INT == 0
226238fd1498Szrj case CONST_DOUBLE:
226338fd1498Szrj return wi::storage_ref (&CONST_DOUBLE_LOW (x.first), 2, precision);
226438fd1498Szrj #endif
226538fd1498Szrj
226638fd1498Szrj default:
226738fd1498Szrj gcc_unreachable ();
226838fd1498Szrj }
226938fd1498Szrj }
227038fd1498Szrj
227138fd1498Szrj namespace wi
227238fd1498Szrj {
227338fd1498Szrj hwi_with_prec shwi (HOST_WIDE_INT, machine_mode mode);
227438fd1498Szrj wide_int min_value (machine_mode, signop);
227538fd1498Szrj wide_int max_value (machine_mode, signop);
227638fd1498Szrj }
227738fd1498Szrj
227838fd1498Szrj inline wi::hwi_with_prec
227938fd1498Szrj wi::shwi (HOST_WIDE_INT val, machine_mode mode)
228038fd1498Szrj {
228138fd1498Szrj return shwi (val, GET_MODE_PRECISION (as_a <scalar_mode> (mode)));
228238fd1498Szrj }
228338fd1498Szrj
228438fd1498Szrj /* Produce the smallest number that is represented in MODE. The precision
228538fd1498Szrj is taken from MODE and the sign from SGN. */
228638fd1498Szrj inline wide_int
228738fd1498Szrj wi::min_value (machine_mode mode, signop sgn)
228838fd1498Szrj {
228938fd1498Szrj return min_value (GET_MODE_PRECISION (as_a <scalar_mode> (mode)), sgn);
229038fd1498Szrj }
229138fd1498Szrj
229238fd1498Szrj /* Produce the largest number that is represented in MODE. The precision
229338fd1498Szrj is taken from MODE and the sign from SGN. */
229438fd1498Szrj inline wide_int
229538fd1498Szrj wi::max_value (machine_mode mode, signop sgn)
229638fd1498Szrj {
229738fd1498Szrj return max_value (GET_MODE_PRECISION (as_a <scalar_mode> (mode)), sgn);
229838fd1498Szrj }
229938fd1498Szrj
230038fd1498Szrj namespace wi
230138fd1498Szrj {
230238fd1498Szrj typedef poly_int<NUM_POLY_INT_COEFFS,
230338fd1498Szrj generic_wide_int <wide_int_ref_storage <false, false> > >
230438fd1498Szrj rtx_to_poly_wide_ref;
230538fd1498Szrj rtx_to_poly_wide_ref to_poly_wide (const_rtx, machine_mode);
230638fd1498Szrj }
230738fd1498Szrj
230838fd1498Szrj /* Return the value of a CONST_POLY_INT in its native precision. */
230938fd1498Szrj
231038fd1498Szrj inline wi::rtx_to_poly_wide_ref
231138fd1498Szrj const_poly_int_value (const_rtx x)
231238fd1498Szrj {
231338fd1498Szrj poly_int<NUM_POLY_INT_COEFFS, WIDE_INT_REF_FOR (wide_int)> res;
231438fd1498Szrj for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
231538fd1498Szrj res.coeffs[i] = CONST_POLY_INT_COEFFS (x)[i];
231638fd1498Szrj return res;
231738fd1498Szrj }
231838fd1498Szrj
231938fd1498Szrj /* Return true if X is a scalar integer or a CONST_POLY_INT. The value
232038fd1498Szrj can then be extracted using wi::to_poly_wide. */
232138fd1498Szrj
232238fd1498Szrj inline bool
232338fd1498Szrj poly_int_rtx_p (const_rtx x)
232438fd1498Szrj {
232538fd1498Szrj return CONST_SCALAR_INT_P (x) || CONST_POLY_INT_P (x);
232638fd1498Szrj }
232738fd1498Szrj
232838fd1498Szrj /* Access X (which satisfies poly_int_rtx_p) as a poly_wide_int.
232938fd1498Szrj MODE is the mode of X. */
233038fd1498Szrj
233138fd1498Szrj inline wi::rtx_to_poly_wide_ref
233238fd1498Szrj wi::to_poly_wide (const_rtx x, machine_mode mode)
233338fd1498Szrj {
233438fd1498Szrj if (CONST_POLY_INT_P (x))
233538fd1498Szrj return const_poly_int_value (x);
233638fd1498Szrj return rtx_mode_t (const_cast<rtx> (x), mode);
233738fd1498Szrj }
233838fd1498Szrj
233938fd1498Szrj /* Return the value of X as a poly_int64. */
234038fd1498Szrj
234138fd1498Szrj inline poly_int64
234238fd1498Szrj rtx_to_poly_int64 (const_rtx x)
234338fd1498Szrj {
234438fd1498Szrj if (CONST_POLY_INT_P (x))
234538fd1498Szrj {
234638fd1498Szrj poly_int64 res;
234738fd1498Szrj for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
234838fd1498Szrj res.coeffs[i] = CONST_POLY_INT_COEFFS (x)[i].to_shwi ();
234938fd1498Szrj return res;
235038fd1498Szrj }
235138fd1498Szrj return INTVAL (x);
235238fd1498Szrj }
235338fd1498Szrj
235438fd1498Szrj /* Return true if arbitrary value X is an integer constant that can
235538fd1498Szrj be represented as a poly_int64. Store the value in *RES if so,
235638fd1498Szrj otherwise leave it unmodified. */
235738fd1498Szrj
235838fd1498Szrj inline bool
235938fd1498Szrj poly_int_rtx_p (const_rtx x, poly_int64_pod *res)
236038fd1498Szrj {
236138fd1498Szrj if (CONST_INT_P (x))
236238fd1498Szrj {
236338fd1498Szrj *res = INTVAL (x);
236438fd1498Szrj return true;
236538fd1498Szrj }
236638fd1498Szrj if (CONST_POLY_INT_P (x))
236738fd1498Szrj {
236838fd1498Szrj for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
236938fd1498Szrj if (!wi::fits_shwi_p (CONST_POLY_INT_COEFFS (x)[i]))
237038fd1498Szrj return false;
237138fd1498Szrj for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
237238fd1498Szrj res->coeffs[i] = CONST_POLY_INT_COEFFS (x)[i].to_shwi ();
237338fd1498Szrj return true;
237438fd1498Szrj }
237538fd1498Szrj return false;
237638fd1498Szrj }
237738fd1498Szrj
237838fd1498Szrj extern void init_rtlanal (void);
237938fd1498Szrj extern int rtx_cost (rtx, machine_mode, enum rtx_code, int, bool);
238038fd1498Szrj extern int address_cost (rtx, machine_mode, addr_space_t, bool);
238138fd1498Szrj extern void get_full_rtx_cost (rtx, machine_mode, enum rtx_code, int,
238238fd1498Szrj struct full_rtx_costs *);
238338fd1498Szrj extern poly_uint64 subreg_lsb (const_rtx);
238438fd1498Szrj extern poly_uint64 subreg_lsb_1 (machine_mode, machine_mode, poly_uint64);
238538fd1498Szrj extern poly_uint64 subreg_size_offset_from_lsb (poly_uint64, poly_uint64,
238638fd1498Szrj poly_uint64);
238738fd1498Szrj extern bool read_modify_subreg_p (const_rtx);
238838fd1498Szrj
238938fd1498Szrj /* Return the subreg byte offset for a subreg whose outer mode is
239038fd1498Szrj OUTER_MODE, whose inner mode is INNER_MODE, and where there are
239138fd1498Szrj LSB_SHIFT *bits* between the lsb of the outer value and the lsb of
239238fd1498Szrj the inner value. This is the inverse of subreg_lsb_1 (which converts
239338fd1498Szrj byte offsets to bit shifts). */
239438fd1498Szrj
239538fd1498Szrj inline poly_uint64
239638fd1498Szrj subreg_offset_from_lsb (machine_mode outer_mode,
239738fd1498Szrj machine_mode inner_mode,
239838fd1498Szrj poly_uint64 lsb_shift)
239938fd1498Szrj {
240038fd1498Szrj return subreg_size_offset_from_lsb (GET_MODE_SIZE (outer_mode),
240138fd1498Szrj GET_MODE_SIZE (inner_mode), lsb_shift);
240238fd1498Szrj }
240338fd1498Szrj
240438fd1498Szrj extern unsigned int subreg_regno_offset (unsigned int, machine_mode,
240538fd1498Szrj poly_uint64, machine_mode);
240638fd1498Szrj extern bool subreg_offset_representable_p (unsigned int, machine_mode,
240738fd1498Szrj poly_uint64, machine_mode);
240838fd1498Szrj extern unsigned int subreg_regno (const_rtx);
240938fd1498Szrj extern int simplify_subreg_regno (unsigned int, machine_mode,
241038fd1498Szrj poly_uint64, machine_mode);
241138fd1498Szrj extern unsigned int subreg_nregs (const_rtx);
241238fd1498Szrj extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
241338fd1498Szrj extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, machine_mode);
241438fd1498Szrj extern unsigned int num_sign_bit_copies (const_rtx, machine_mode);
241538fd1498Szrj extern bool constant_pool_constant_p (rtx);
241638fd1498Szrj extern bool truncated_to_mode (machine_mode, const_rtx);
241738fd1498Szrj extern int low_bitmask_len (machine_mode, unsigned HOST_WIDE_INT);
241838fd1498Szrj extern void split_double (rtx, rtx *, rtx *);
241938fd1498Szrj extern rtx *strip_address_mutations (rtx *, enum rtx_code * = 0);
242038fd1498Szrj extern void decompose_address (struct address_info *, rtx *,
242138fd1498Szrj machine_mode, addr_space_t, enum rtx_code);
242238fd1498Szrj extern void decompose_lea_address (struct address_info *, rtx *);
242338fd1498Szrj extern void decompose_mem_address (struct address_info *, rtx);
242438fd1498Szrj extern void update_address (struct address_info *);
242538fd1498Szrj extern HOST_WIDE_INT get_index_scale (const struct address_info *);
242638fd1498Szrj extern enum rtx_code get_index_code (const struct address_info *);
242738fd1498Szrj
242838fd1498Szrj /* 1 if RTX is a subreg containing a reg that is already known to be
242938fd1498Szrj sign- or zero-extended from the mode of the subreg to the mode of
243038fd1498Szrj the reg. SUBREG_PROMOTED_UNSIGNED_P gives the signedness of the
243138fd1498Szrj extension.
243238fd1498Szrj
243338fd1498Szrj When used as a LHS, is means that this extension must be done
243438fd1498Szrj when assigning to SUBREG_REG. */
243538fd1498Szrj
243638fd1498Szrj #define SUBREG_PROMOTED_VAR_P(RTX) \
243738fd1498Szrj (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED", (RTX), SUBREG)->in_struct)
243838fd1498Szrj
243938fd1498Szrj /* Valid for subregs which are SUBREG_PROMOTED_VAR_P(). In that case
244038fd1498Szrj this gives the necessary extensions:
244138fd1498Szrj 0 - signed (SPR_SIGNED)
244238fd1498Szrj 1 - normal unsigned (SPR_UNSIGNED)
244338fd1498Szrj 2 - value is both sign and unsign extended for mode
244438fd1498Szrj (SPR_SIGNED_AND_UNSIGNED).
244538fd1498Szrj -1 - pointer unsigned, which most often can be handled like unsigned
244638fd1498Szrj extension, except for generating instructions where we need to
244738fd1498Szrj emit special code (ptr_extend insns) on some architectures
244838fd1498Szrj (SPR_POINTER). */
244938fd1498Szrj
245038fd1498Szrj const int SRP_POINTER = -1;
245138fd1498Szrj const int SRP_SIGNED = 0;
245238fd1498Szrj const int SRP_UNSIGNED = 1;
245338fd1498Szrj const int SRP_SIGNED_AND_UNSIGNED = 2;
245438fd1498Szrj
245538fd1498Szrj /* Sets promoted mode for SUBREG_PROMOTED_VAR_P(). */
245638fd1498Szrj #define SUBREG_PROMOTED_SET(RTX, VAL) \
245738fd1498Szrj do { \
245838fd1498Szrj rtx const _rtx = RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SET", \
245938fd1498Szrj (RTX), SUBREG); \
246038fd1498Szrj switch (VAL) \
246138fd1498Szrj { \
246238fd1498Szrj case SRP_POINTER: \
246338fd1498Szrj _rtx->volatil = 0; \
246438fd1498Szrj _rtx->unchanging = 0; \
246538fd1498Szrj break; \
246638fd1498Szrj case SRP_SIGNED: \
246738fd1498Szrj _rtx->volatil = 0; \
246838fd1498Szrj _rtx->unchanging = 1; \
246938fd1498Szrj break; \
247038fd1498Szrj case SRP_UNSIGNED: \
247138fd1498Szrj _rtx->volatil = 1; \
247238fd1498Szrj _rtx->unchanging = 0; \
247338fd1498Szrj break; \
247438fd1498Szrj case SRP_SIGNED_AND_UNSIGNED: \
247538fd1498Szrj _rtx->volatil = 1; \
247638fd1498Szrj _rtx->unchanging = 1; \
247738fd1498Szrj break; \
247838fd1498Szrj } \
247938fd1498Szrj } while (0)
248038fd1498Szrj
248138fd1498Szrj /* Gets the value stored in promoted mode for SUBREG_PROMOTED_VAR_P(),
248238fd1498Szrj including SRP_SIGNED_AND_UNSIGNED if promoted for
248338fd1498Szrj both signed and unsigned. */
248438fd1498Szrj #define SUBREG_PROMOTED_GET(RTX) \
248538fd1498Szrj (2 * (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_GET", (RTX), SUBREG)->volatil)\
248638fd1498Szrj + (RTX)->unchanging - 1)
248738fd1498Szrj
248838fd1498Szrj /* Returns sign of promoted mode for SUBREG_PROMOTED_VAR_P(). */
248938fd1498Szrj #define SUBREG_PROMOTED_SIGN(RTX) \
249038fd1498Szrj ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGN", (RTX), SUBREG)->volatil) ? 1\
249138fd1498Szrj : (RTX)->unchanging - 1)
249238fd1498Szrj
249338fd1498Szrj /* Predicate to check if RTX of SUBREG_PROMOTED_VAR_P() is promoted
249438fd1498Szrj for SIGNED type. */
249538fd1498Szrj #define SUBREG_PROMOTED_SIGNED_P(RTX) \
249638fd1498Szrj (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGNED_P", (RTX), SUBREG)->unchanging)
249738fd1498Szrj
249838fd1498Szrj /* Predicate to check if RTX of SUBREG_PROMOTED_VAR_P() is promoted
249938fd1498Szrj for UNSIGNED type. */
250038fd1498Szrj #define SUBREG_PROMOTED_UNSIGNED_P(RTX) \
250138fd1498Szrj (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil)
250238fd1498Szrj
250338fd1498Szrj /* Checks if RTX of SUBREG_PROMOTED_VAR_P() is promoted for given SIGN. */
250438fd1498Szrj #define SUBREG_CHECK_PROMOTED_SIGN(RTX, SIGN) \
250538fd1498Szrj ((SIGN) == SRP_POINTER ? SUBREG_PROMOTED_GET (RTX) == SRP_POINTER \
250638fd1498Szrj : (SIGN) == SRP_SIGNED ? SUBREG_PROMOTED_SIGNED_P (RTX) \
250738fd1498Szrj : SUBREG_PROMOTED_UNSIGNED_P (RTX))
250838fd1498Szrj
250938fd1498Szrj /* True if the REG is the static chain register for some CALL_INSN. */
251038fd1498Szrj #define STATIC_CHAIN_REG_P(RTX) \
251138fd1498Szrj (RTL_FLAG_CHECK1 ("STATIC_CHAIN_REG_P", (RTX), REG)->jump)
251238fd1498Szrj
251338fd1498Szrj /* True if the subreg was generated by LRA for reload insns. Such
251438fd1498Szrj subregs are valid only during LRA. */
251538fd1498Szrj #define LRA_SUBREG_P(RTX) \
251638fd1498Szrj (RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump)
251738fd1498Szrj
251838fd1498Szrj /* True if call is instrumented by Pointer Bounds Checker. */
251938fd1498Szrj #define CALL_EXPR_WITH_BOUNDS_P(RTX) \
252038fd1498Szrj (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump)
252138fd1498Szrj
252238fd1498Szrj /* Access various components of an ASM_OPERANDS rtx. */
252338fd1498Szrj
252438fd1498Szrj #define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS)
252538fd1498Szrj #define ASM_OPERANDS_OUTPUT_CONSTRAINT(RTX) XCSTR (RTX, 1, ASM_OPERANDS)
252638fd1498Szrj #define ASM_OPERANDS_OUTPUT_IDX(RTX) XCINT (RTX, 2, ASM_OPERANDS)
252738fd1498Szrj #define ASM_OPERANDS_INPUT_VEC(RTX) XCVEC (RTX, 3, ASM_OPERANDS)
252838fd1498Szrj #define ASM_OPERANDS_INPUT_CONSTRAINT_VEC(RTX) XCVEC (RTX, 4, ASM_OPERANDS)
252938fd1498Szrj #define ASM_OPERANDS_INPUT(RTX, N) XCVECEXP (RTX, 3, N, ASM_OPERANDS)
253038fd1498Szrj #define ASM_OPERANDS_INPUT_LENGTH(RTX) XCVECLEN (RTX, 3, ASM_OPERANDS)
253138fd1498Szrj #define ASM_OPERANDS_INPUT_CONSTRAINT_EXP(RTX, N) \
253238fd1498Szrj XCVECEXP (RTX, 4, N, ASM_OPERANDS)
253338fd1498Szrj #define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) \
253438fd1498Szrj XSTR (XCVECEXP (RTX, 4, N, ASM_OPERANDS), 0)
253538fd1498Szrj #define ASM_OPERANDS_INPUT_MODE(RTX, N) \
253638fd1498Szrj GET_MODE (XCVECEXP (RTX, 4, N, ASM_OPERANDS))
253738fd1498Szrj #define ASM_OPERANDS_LABEL_VEC(RTX) XCVEC (RTX, 5, ASM_OPERANDS)
253838fd1498Szrj #define ASM_OPERANDS_LABEL_LENGTH(RTX) XCVECLEN (RTX, 5, ASM_OPERANDS)
253938fd1498Szrj #define ASM_OPERANDS_LABEL(RTX, N) XCVECEXP (RTX, 5, N, ASM_OPERANDS)
254038fd1498Szrj #define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 6, ASM_OPERANDS)
254138fd1498Szrj #define ASM_INPUT_SOURCE_LOCATION(RTX) XCUINT (RTX, 1, ASM_INPUT)
254238fd1498Szrj
254338fd1498Szrj /* 1 if RTX is a mem that is statically allocated in read-only memory. */
254438fd1498Szrj #define MEM_READONLY_P(RTX) \
254538fd1498Szrj (RTL_FLAG_CHECK1 ("MEM_READONLY_P", (RTX), MEM)->unchanging)
254638fd1498Szrj
254738fd1498Szrj /* 1 if RTX is a mem and we should keep the alias set for this mem
254838fd1498Szrj unchanged when we access a component. Set to 1, or example, when we
254938fd1498Szrj are already in a non-addressable component of an aggregate. */
255038fd1498Szrj #define MEM_KEEP_ALIAS_SET_P(RTX) \
255138fd1498Szrj (RTL_FLAG_CHECK1 ("MEM_KEEP_ALIAS_SET_P", (RTX), MEM)->jump)
255238fd1498Szrj
255338fd1498Szrj /* 1 if RTX is a mem or asm_operand for a volatile reference. */
255438fd1498Szrj #define MEM_VOLATILE_P(RTX) \
255538fd1498Szrj (RTL_FLAG_CHECK3 ("MEM_VOLATILE_P", (RTX), MEM, ASM_OPERANDS, \
255638fd1498Szrj ASM_INPUT)->volatil)
255738fd1498Szrj
255838fd1498Szrj /* 1 if RTX is a mem that cannot trap. */
255938fd1498Szrj #define MEM_NOTRAP_P(RTX) \
256038fd1498Szrj (RTL_FLAG_CHECK1 ("MEM_NOTRAP_P", (RTX), MEM)->call)
256138fd1498Szrj
256238fd1498Szrj /* The memory attribute block. We provide access macros for each value
256338fd1498Szrj in the block and provide defaults if none specified. */
256438fd1498Szrj #define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1)
256538fd1498Szrj
256638fd1498Szrj /* The register attribute block. We provide access macros for each value
256738fd1498Szrj in the block and provide defaults if none specified. */
256838fd1498Szrj #define REG_ATTRS(RTX) (REG_CHECK (RTX)->attrs)
256938fd1498Szrj
257038fd1498Szrj #ifndef GENERATOR_FILE
257138fd1498Szrj /* For a MEM rtx, the alias set. If 0, this MEM is not in any alias
257238fd1498Szrj set, and may alias anything. Otherwise, the MEM can only alias
257338fd1498Szrj MEMs in a conflicting alias set. This value is set in a
257438fd1498Szrj language-dependent manner in the front-end, and should not be
257538fd1498Szrj altered in the back-end. These set numbers are tested with
257638fd1498Szrj alias_sets_conflict_p. */
257738fd1498Szrj #define MEM_ALIAS_SET(RTX) (get_mem_attrs (RTX)->alias)
257838fd1498Szrj
257938fd1498Szrj /* For a MEM rtx, the decl it is known to refer to, if it is known to
258038fd1498Szrj refer to part of a DECL. It may also be a COMPONENT_REF. */
258138fd1498Szrj #define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr)
258238fd1498Szrj
258338fd1498Szrj /* For a MEM rtx, true if its MEM_OFFSET is known. */
258438fd1498Szrj #define MEM_OFFSET_KNOWN_P(RTX) (get_mem_attrs (RTX)->offset_known_p)
258538fd1498Szrj
258638fd1498Szrj /* For a MEM rtx, the offset from the start of MEM_EXPR. */
258738fd1498Szrj #define MEM_OFFSET(RTX) (get_mem_attrs (RTX)->offset)
258838fd1498Szrj
258938fd1498Szrj /* For a MEM rtx, the address space. */
259038fd1498Szrj #define MEM_ADDR_SPACE(RTX) (get_mem_attrs (RTX)->addrspace)
259138fd1498Szrj
259238fd1498Szrj /* For a MEM rtx, true if its MEM_SIZE is known. */
259338fd1498Szrj #define MEM_SIZE_KNOWN_P(RTX) (get_mem_attrs (RTX)->size_known_p)
259438fd1498Szrj
259538fd1498Szrj /* For a MEM rtx, the size in bytes of the MEM. */
259638fd1498Szrj #define MEM_SIZE(RTX) (get_mem_attrs (RTX)->size)
259738fd1498Szrj
259838fd1498Szrj /* For a MEM rtx, the alignment in bits. We can use the alignment of the
259938fd1498Szrj mode as a default when STRICT_ALIGNMENT, but not if not. */
260038fd1498Szrj #define MEM_ALIGN(RTX) (get_mem_attrs (RTX)->align)
260138fd1498Szrj #else
260238fd1498Szrj #define MEM_ADDR_SPACE(RTX) ADDR_SPACE_GENERIC
260338fd1498Szrj #endif
260438fd1498Szrj
260538fd1498Szrj /* For a REG rtx, the decl it is known to refer to, if it is known to
260638fd1498Szrj refer to part of a DECL. */
260738fd1498Szrj #define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
260838fd1498Szrj
260938fd1498Szrj /* For a REG rtx, the offset from the start of REG_EXPR, if known, as an
261038fd1498Szrj HOST_WIDE_INT. */
261138fd1498Szrj #define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset)
261238fd1498Szrj
261338fd1498Szrj /* Copy the attributes that apply to memory locations from RHS to LHS. */
261438fd1498Szrj #define MEM_COPY_ATTRIBUTES(LHS, RHS) \
261538fd1498Szrj (MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS), \
261638fd1498Szrj MEM_NOTRAP_P (LHS) = MEM_NOTRAP_P (RHS), \
261738fd1498Szrj MEM_READONLY_P (LHS) = MEM_READONLY_P (RHS), \
261838fd1498Szrj MEM_KEEP_ALIAS_SET_P (LHS) = MEM_KEEP_ALIAS_SET_P (RHS), \
261938fd1498Szrj MEM_POINTER (LHS) = MEM_POINTER (RHS), \
262038fd1498Szrj MEM_ATTRS (LHS) = MEM_ATTRS (RHS))
262138fd1498Szrj
262238fd1498Szrj /* 1 if RTX is a label_ref for a nonlocal label. */
262338fd1498Szrj /* Likewise in an expr_list for a REG_LABEL_OPERAND or
262438fd1498Szrj REG_LABEL_TARGET note. */
262538fd1498Szrj #define LABEL_REF_NONLOCAL_P(RTX) \
262638fd1498Szrj (RTL_FLAG_CHECK1 ("LABEL_REF_NONLOCAL_P", (RTX), LABEL_REF)->volatil)
262738fd1498Szrj
262838fd1498Szrj /* 1 if RTX is a code_label that should always be considered to be needed. */
262938fd1498Szrj #define LABEL_PRESERVE_P(RTX) \
263038fd1498Szrj (RTL_FLAG_CHECK2 ("LABEL_PRESERVE_P", (RTX), CODE_LABEL, NOTE)->in_struct)
263138fd1498Szrj
263238fd1498Szrj /* During sched, 1 if RTX is an insn that must be scheduled together
263338fd1498Szrj with the preceding insn. */
263438fd1498Szrj #define SCHED_GROUP_P(RTX) \
263538fd1498Szrj (RTL_FLAG_CHECK4 ("SCHED_GROUP_P", (RTX), DEBUG_INSN, INSN, \
263638fd1498Szrj JUMP_INSN, CALL_INSN)->in_struct)
263738fd1498Szrj
263838fd1498Szrj /* For a SET rtx, SET_DEST is the place that is set
263938fd1498Szrj and SET_SRC is the value it is set to. */
264038fd1498Szrj #define SET_DEST(RTX) XC2EXP (RTX, 0, SET, CLOBBER)
264138fd1498Szrj #define SET_SRC(RTX) XCEXP (RTX, 1, SET)
264238fd1498Szrj #define SET_IS_RETURN_P(RTX) \
264338fd1498Szrj (RTL_FLAG_CHECK1 ("SET_IS_RETURN_P", (RTX), SET)->jump)
264438fd1498Szrj
264538fd1498Szrj /* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */
264638fd1498Szrj #define TRAP_CONDITION(RTX) XCEXP (RTX, 0, TRAP_IF)
264738fd1498Szrj #define TRAP_CODE(RTX) XCEXP (RTX, 1, TRAP_IF)
264838fd1498Szrj
264938fd1498Szrj /* For a COND_EXEC rtx, COND_EXEC_TEST is the condition to base
265038fd1498Szrj conditionally executing the code on, COND_EXEC_CODE is the code
265138fd1498Szrj to execute if the condition is true. */
265238fd1498Szrj #define COND_EXEC_TEST(RTX) XCEXP (RTX, 0, COND_EXEC)
265338fd1498Szrj #define COND_EXEC_CODE(RTX) XCEXP (RTX, 1, COND_EXEC)
265438fd1498Szrj
265538fd1498Szrj /* 1 if RTX is a symbol_ref that addresses this function's rtl
265638fd1498Szrj constants pool. */
265738fd1498Szrj #define CONSTANT_POOL_ADDRESS_P(RTX) \
265838fd1498Szrj (RTL_FLAG_CHECK1 ("CONSTANT_POOL_ADDRESS_P", (RTX), SYMBOL_REF)->unchanging)
265938fd1498Szrj
266038fd1498Szrj /* 1 if RTX is a symbol_ref that addresses a value in the file's
266138fd1498Szrj tree constant pool. This information is private to varasm.c. */
266238fd1498Szrj #define TREE_CONSTANT_POOL_ADDRESS_P(RTX) \
266338fd1498Szrj (RTL_FLAG_CHECK1 ("TREE_CONSTANT_POOL_ADDRESS_P", \
266438fd1498Szrj (RTX), SYMBOL_REF)->frame_related)
266538fd1498Szrj
266638fd1498Szrj /* Used if RTX is a symbol_ref, for machine-specific purposes. */
266738fd1498Szrj #define SYMBOL_REF_FLAG(RTX) \
266838fd1498Szrj (RTL_FLAG_CHECK1 ("SYMBOL_REF_FLAG", (RTX), SYMBOL_REF)->volatil)
266938fd1498Szrj
267038fd1498Szrj /* 1 if RTX is a symbol_ref that has been the library function in
267138fd1498Szrj emit_library_call. */
267238fd1498Szrj #define SYMBOL_REF_USED(RTX) \
267338fd1498Szrj (RTL_FLAG_CHECK1 ("SYMBOL_REF_USED", (RTX), SYMBOL_REF)->used)
267438fd1498Szrj
267538fd1498Szrj /* 1 if RTX is a symbol_ref for a weak symbol. */
267638fd1498Szrj #define SYMBOL_REF_WEAK(RTX) \
267738fd1498Szrj (RTL_FLAG_CHECK1 ("SYMBOL_REF_WEAK", (RTX), SYMBOL_REF)->return_val)
267838fd1498Szrj
267938fd1498Szrj /* A pointer attached to the SYMBOL_REF; either SYMBOL_REF_DECL or
268038fd1498Szrj SYMBOL_REF_CONSTANT. */
268138fd1498Szrj #define SYMBOL_REF_DATA(RTX) X0ANY ((RTX), 1)
268238fd1498Szrj
268338fd1498Szrj /* Set RTX's SYMBOL_REF_DECL to DECL. RTX must not be a constant
268438fd1498Szrj pool symbol. */
268538fd1498Szrj #define SET_SYMBOL_REF_DECL(RTX, DECL) \
268638fd1498Szrj (gcc_assert (!CONSTANT_POOL_ADDRESS_P (RTX)), X0TREE ((RTX), 1) = (DECL))
268738fd1498Szrj
268838fd1498Szrj /* The tree (decl or constant) associated with the symbol, or null. */
268938fd1498Szrj #define SYMBOL_REF_DECL(RTX) \
269038fd1498Szrj (CONSTANT_POOL_ADDRESS_P (RTX) ? NULL : X0TREE ((RTX), 1))
269138fd1498Szrj
269238fd1498Szrj /* Set RTX's SYMBOL_REF_CONSTANT to C. RTX must be a constant pool symbol. */
269338fd1498Szrj #define SET_SYMBOL_REF_CONSTANT(RTX, C) \
269438fd1498Szrj (gcc_assert (CONSTANT_POOL_ADDRESS_P (RTX)), X0CONSTANT ((RTX), 1) = (C))
269538fd1498Szrj
269638fd1498Szrj /* The rtx constant pool entry for a symbol, or null. */
269738fd1498Szrj #define SYMBOL_REF_CONSTANT(RTX) \
269838fd1498Szrj (CONSTANT_POOL_ADDRESS_P (RTX) ? X0CONSTANT ((RTX), 1) : NULL)
269938fd1498Szrj
270038fd1498Szrj /* A set of flags on a symbol_ref that are, in some respects, redundant with
270138fd1498Szrj information derivable from the tree decl associated with this symbol.
270238fd1498Szrj Except that we build a *lot* of SYMBOL_REFs that aren't associated with a
270338fd1498Szrj decl. In some cases this is a bug. But beyond that, it's nice to cache
270438fd1498Szrj this information to avoid recomputing it. Finally, this allows space for
270538fd1498Szrj the target to store more than one bit of information, as with
270638fd1498Szrj SYMBOL_REF_FLAG. */
270738fd1498Szrj #define SYMBOL_REF_FLAGS(RTX) \
270838fd1498Szrj (RTL_FLAG_CHECK1 ("SYMBOL_REF_FLAGS", (RTX), SYMBOL_REF) \
270938fd1498Szrj ->u2.symbol_ref_flags)
271038fd1498Szrj
271138fd1498Szrj /* These flags are common enough to be defined for all targets. They
271238fd1498Szrj are computed by the default version of targetm.encode_section_info. */
271338fd1498Szrj
271438fd1498Szrj /* Set if this symbol is a function. */
271538fd1498Szrj #define SYMBOL_FLAG_FUNCTION (1 << 0)
271638fd1498Szrj #define SYMBOL_REF_FUNCTION_P(RTX) \
271738fd1498Szrj ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_FUNCTION) != 0)
271838fd1498Szrj /* Set if targetm.binds_local_p is true. */
271938fd1498Szrj #define SYMBOL_FLAG_LOCAL (1 << 1)
272038fd1498Szrj #define SYMBOL_REF_LOCAL_P(RTX) \
272138fd1498Szrj ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_LOCAL) != 0)
272238fd1498Szrj /* Set if targetm.in_small_data_p is true. */
272338fd1498Szrj #define SYMBOL_FLAG_SMALL (1 << 2)
272438fd1498Szrj #define SYMBOL_REF_SMALL_P(RTX) \
272538fd1498Szrj ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_SMALL) != 0)
272638fd1498Szrj /* The three-bit field at [5:3] is true for TLS variables; use
272738fd1498Szrj SYMBOL_REF_TLS_MODEL to extract the field as an enum tls_model. */
272838fd1498Szrj #define SYMBOL_FLAG_TLS_SHIFT 3
272938fd1498Szrj #define SYMBOL_REF_TLS_MODEL(RTX) \
273038fd1498Szrj ((enum tls_model) ((SYMBOL_REF_FLAGS (RTX) >> SYMBOL_FLAG_TLS_SHIFT) & 7))
273138fd1498Szrj /* Set if this symbol is not defined in this translation unit. */
273238fd1498Szrj #define SYMBOL_FLAG_EXTERNAL (1 << 6)
273338fd1498Szrj #define SYMBOL_REF_EXTERNAL_P(RTX) \
273438fd1498Szrj ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_EXTERNAL) != 0)
273538fd1498Szrj /* Set if this symbol has a block_symbol structure associated with it. */
273638fd1498Szrj #define SYMBOL_FLAG_HAS_BLOCK_INFO (1 << 7)
273738fd1498Szrj #define SYMBOL_REF_HAS_BLOCK_INFO_P(RTX) \
273838fd1498Szrj ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_HAS_BLOCK_INFO) != 0)
273938fd1498Szrj /* Set if this symbol is a section anchor. SYMBOL_REF_ANCHOR_P implies
274038fd1498Szrj SYMBOL_REF_HAS_BLOCK_INFO_P. */
274138fd1498Szrj #define SYMBOL_FLAG_ANCHOR (1 << 8)
274238fd1498Szrj #define SYMBOL_REF_ANCHOR_P(RTX) \
274338fd1498Szrj ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_ANCHOR) != 0)
274438fd1498Szrj
274538fd1498Szrj /* Subsequent bits are available for the target to use. */
274638fd1498Szrj #define SYMBOL_FLAG_MACH_DEP_SHIFT 9
274738fd1498Szrj #define SYMBOL_FLAG_MACH_DEP (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
274838fd1498Szrj
274938fd1498Szrj /* If SYMBOL_REF_HAS_BLOCK_INFO_P (RTX), this is the object_block
275038fd1498Szrj structure to which the symbol belongs, or NULL if it has not been
275138fd1498Szrj assigned a block. */
275238fd1498Szrj #define SYMBOL_REF_BLOCK(RTX) (BLOCK_SYMBOL_CHECK (RTX)->block)
275338fd1498Szrj
275438fd1498Szrj /* If SYMBOL_REF_HAS_BLOCK_INFO_P (RTX), this is the offset of RTX from
275538fd1498Szrj the first object in SYMBOL_REF_BLOCK (RTX). The value is negative if
275638fd1498Szrj RTX has not yet been assigned to a block, or it has not been given an
275738fd1498Szrj offset within that block. */
275838fd1498Szrj #define SYMBOL_REF_BLOCK_OFFSET(RTX) (BLOCK_SYMBOL_CHECK (RTX)->offset)
275938fd1498Szrj
276038fd1498Szrj /* True if RTX is flagged to be a scheduling barrier. */
276138fd1498Szrj #define PREFETCH_SCHEDULE_BARRIER_P(RTX) \
276238fd1498Szrj (RTL_FLAG_CHECK1 ("PREFETCH_SCHEDULE_BARRIER_P", (RTX), PREFETCH)->volatil)
276338fd1498Szrj
276438fd1498Szrj /* Indicate whether the machine has any sort of auto increment addressing.
276538fd1498Szrj If not, we can avoid checking for REG_INC notes. */
276638fd1498Szrj
276738fd1498Szrj #if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) \
276838fd1498Szrj || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT) \
276938fd1498Szrj || defined (HAVE_PRE_MODIFY_DISP) || defined (HAVE_POST_MODIFY_DISP) \
277038fd1498Szrj || defined (HAVE_PRE_MODIFY_REG) || defined (HAVE_POST_MODIFY_REG))
277138fd1498Szrj #define AUTO_INC_DEC 1
277238fd1498Szrj #else
277338fd1498Szrj #define AUTO_INC_DEC 0
277438fd1498Szrj #endif
277538fd1498Szrj
277638fd1498Szrj /* Define a macro to look for REG_INC notes,
277738fd1498Szrj but save time on machines where they never exist. */
277838fd1498Szrj
277938fd1498Szrj #if AUTO_INC_DEC
278038fd1498Szrj #define FIND_REG_INC_NOTE(INSN, REG) \
278138fd1498Szrj ((REG) != NULL_RTX && REG_P ((REG)) \
278238fd1498Szrj ? find_regno_note ((INSN), REG_INC, REGNO (REG)) \
278338fd1498Szrj : find_reg_note ((INSN), REG_INC, (REG)))
278438fd1498Szrj #else
278538fd1498Szrj #define FIND_REG_INC_NOTE(INSN, REG) 0
278638fd1498Szrj #endif
278738fd1498Szrj
278838fd1498Szrj #ifndef HAVE_PRE_INCREMENT
278938fd1498Szrj #define HAVE_PRE_INCREMENT 0
279038fd1498Szrj #endif
279138fd1498Szrj
279238fd1498Szrj #ifndef HAVE_PRE_DECREMENT
279338fd1498Szrj #define HAVE_PRE_DECREMENT 0
279438fd1498Szrj #endif
279538fd1498Szrj
279638fd1498Szrj #ifndef HAVE_POST_INCREMENT
279738fd1498Szrj #define HAVE_POST_INCREMENT 0
279838fd1498Szrj #endif
279938fd1498Szrj
280038fd1498Szrj #ifndef HAVE_POST_DECREMENT
280138fd1498Szrj #define HAVE_POST_DECREMENT 0
280238fd1498Szrj #endif
280338fd1498Szrj
280438fd1498Szrj #ifndef HAVE_POST_MODIFY_DISP
280538fd1498Szrj #define HAVE_POST_MODIFY_DISP 0
280638fd1498Szrj #endif
280738fd1498Szrj
280838fd1498Szrj #ifndef HAVE_POST_MODIFY_REG
280938fd1498Szrj #define HAVE_POST_MODIFY_REG 0
281038fd1498Szrj #endif
281138fd1498Szrj
281238fd1498Szrj #ifndef HAVE_PRE_MODIFY_DISP
281338fd1498Szrj #define HAVE_PRE_MODIFY_DISP 0
281438fd1498Szrj #endif
281538fd1498Szrj
281638fd1498Szrj #ifndef HAVE_PRE_MODIFY_REG
281738fd1498Szrj #define HAVE_PRE_MODIFY_REG 0
281838fd1498Szrj #endif
281938fd1498Szrj
282038fd1498Szrj
282138fd1498Szrj /* Some architectures do not have complete pre/post increment/decrement
282238fd1498Szrj instruction sets, or only move some modes efficiently. These macros
282338fd1498Szrj allow us to tune autoincrement generation. */
282438fd1498Szrj
282538fd1498Szrj #ifndef USE_LOAD_POST_INCREMENT
282638fd1498Szrj #define USE_LOAD_POST_INCREMENT(MODE) HAVE_POST_INCREMENT
282738fd1498Szrj #endif
282838fd1498Szrj
282938fd1498Szrj #ifndef USE_LOAD_POST_DECREMENT
283038fd1498Szrj #define USE_LOAD_POST_DECREMENT(MODE) HAVE_POST_DECREMENT
283138fd1498Szrj #endif
283238fd1498Szrj
283338fd1498Szrj #ifndef USE_LOAD_PRE_INCREMENT
283438fd1498Szrj #define USE_LOAD_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT
283538fd1498Szrj #endif
283638fd1498Szrj
283738fd1498Szrj #ifndef USE_LOAD_PRE_DECREMENT
283838fd1498Szrj #define USE_LOAD_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT
283938fd1498Szrj #endif
284038fd1498Szrj
284138fd1498Szrj #ifndef USE_STORE_POST_INCREMENT
284238fd1498Szrj #define USE_STORE_POST_INCREMENT(MODE) HAVE_POST_INCREMENT
284338fd1498Szrj #endif
284438fd1498Szrj
284538fd1498Szrj #ifndef USE_STORE_POST_DECREMENT
284638fd1498Szrj #define USE_STORE_POST_DECREMENT(MODE) HAVE_POST_DECREMENT
284738fd1498Szrj #endif
284838fd1498Szrj
284938fd1498Szrj #ifndef USE_STORE_PRE_INCREMENT
285038fd1498Szrj #define USE_STORE_PRE_INCREMENT(MODE) HAVE_PRE_INCREMENT
285138fd1498Szrj #endif
285238fd1498Szrj
285338fd1498Szrj #ifndef USE_STORE_PRE_DECREMENT
285438fd1498Szrj #define USE_STORE_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT
285538fd1498Szrj #endif
285638fd1498Szrj
285738fd1498Szrj /* Nonzero when we are generating CONCATs. */
285838fd1498Szrj extern int generating_concat_p;
285938fd1498Szrj
286038fd1498Szrj /* Nonzero when we are expanding trees to RTL. */
286138fd1498Szrj extern int currently_expanding_to_rtl;
286238fd1498Szrj
286338fd1498Szrj /* Generally useful functions. */
286438fd1498Szrj
286538fd1498Szrj #ifndef GENERATOR_FILE
286638fd1498Szrj /* Return the cost of SET X. SPEED_P is true if optimizing for speed
286738fd1498Szrj rather than size. */
286838fd1498Szrj
286938fd1498Szrj static inline int
287038fd1498Szrj set_rtx_cost (rtx x, bool speed_p)
287138fd1498Szrj {
287238fd1498Szrj return rtx_cost (x, VOIDmode, INSN, 4, speed_p);
287338fd1498Szrj }
287438fd1498Szrj
287538fd1498Szrj /* Like set_rtx_cost, but return both the speed and size costs in C. */
287638fd1498Szrj
287738fd1498Szrj static inline void
287838fd1498Szrj get_full_set_rtx_cost (rtx x, struct full_rtx_costs *c)
287938fd1498Szrj {
288038fd1498Szrj get_full_rtx_cost (x, VOIDmode, INSN, 4, c);
288138fd1498Szrj }
288238fd1498Szrj
288338fd1498Szrj /* Return the cost of moving X into a register, relative to the cost
288438fd1498Szrj of a register move. SPEED_P is true if optimizing for speed rather
288538fd1498Szrj than size. */
288638fd1498Szrj
288738fd1498Szrj static inline int
288838fd1498Szrj set_src_cost (rtx x, machine_mode mode, bool speed_p)
288938fd1498Szrj {
289038fd1498Szrj return rtx_cost (x, mode, SET, 1, speed_p);
289138fd1498Szrj }
289238fd1498Szrj
289338fd1498Szrj /* Like set_src_cost, but return both the speed and size costs in C. */
289438fd1498Szrj
289538fd1498Szrj static inline void
289638fd1498Szrj get_full_set_src_cost (rtx x, machine_mode mode, struct full_rtx_costs *c)
289738fd1498Szrj {
289838fd1498Szrj get_full_rtx_cost (x, mode, SET, 1, c);
289938fd1498Szrj }
290038fd1498Szrj #endif
290138fd1498Szrj
290238fd1498Szrj /* A convenience macro to validate the arguments of a zero_extract
290338fd1498Szrj expression. It determines whether SIZE lies inclusively within
290438fd1498Szrj [1, RANGE], POS lies inclusively within between [0, RANGE - 1]
290538fd1498Szrj and the sum lies inclusively within [1, RANGE]. RANGE must be
290638fd1498Szrj >= 1, but SIZE and POS may be negative. */
290738fd1498Szrj #define EXTRACT_ARGS_IN_RANGE(SIZE, POS, RANGE) \
290838fd1498Szrj (IN_RANGE ((POS), 0, (unsigned HOST_WIDE_INT) (RANGE) - 1) \
290938fd1498Szrj && IN_RANGE ((SIZE), 1, (unsigned HOST_WIDE_INT) (RANGE) \
291038fd1498Szrj - (unsigned HOST_WIDE_INT)(POS)))
291138fd1498Szrj
291238fd1498Szrj /* In explow.c */
291338fd1498Szrj extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, machine_mode);
291438fd1498Szrj extern poly_int64 trunc_int_for_mode (poly_int64, machine_mode);
291538fd1498Szrj extern rtx plus_constant (machine_mode, rtx, poly_int64, bool = false);
291638fd1498Szrj extern HOST_WIDE_INT get_stack_check_protect (void);
291738fd1498Szrj
291838fd1498Szrj /* In rtl.c */
291938fd1498Szrj extern rtx rtx_alloc (RTX_CODE CXX_MEM_STAT_INFO);
292038fd1498Szrj extern rtx rtx_alloc_stat_v (RTX_CODE MEM_STAT_DECL, int);
292138fd1498Szrj #define rtx_alloc_v(c, SZ) rtx_alloc_stat_v (c MEM_STAT_INFO, SZ)
292238fd1498Szrj #define const_wide_int_alloc(NWORDS) \
292338fd1498Szrj rtx_alloc_v (CONST_WIDE_INT, \
292438fd1498Szrj (sizeof (struct hwivec_def) \
292538fd1498Szrj + ((NWORDS)-1) * sizeof (HOST_WIDE_INT))) \
292638fd1498Szrj
292738fd1498Szrj extern rtvec rtvec_alloc (int);
292838fd1498Szrj extern rtvec shallow_copy_rtvec (rtvec);
292938fd1498Szrj extern bool shared_const_p (const_rtx);
293038fd1498Szrj extern rtx copy_rtx (rtx);
293138fd1498Szrj extern enum rtx_code classify_insn (rtx);
293238fd1498Szrj extern void dump_rtx_statistics (void);
293338fd1498Szrj
293438fd1498Szrj /* In emit-rtl.c */
293538fd1498Szrj extern rtx copy_rtx_if_shared (rtx);
293638fd1498Szrj
293738fd1498Szrj /* In rtl.c */
293838fd1498Szrj extern unsigned int rtx_size (const_rtx);
293938fd1498Szrj extern rtx shallow_copy_rtx (const_rtx CXX_MEM_STAT_INFO);
294038fd1498Szrj extern int rtx_equal_p (const_rtx, const_rtx);
294138fd1498Szrj extern bool rtvec_all_equal_p (const_rtvec);
294238fd1498Szrj
294338fd1498Szrj /* Return true if X is a vector constant with a duplicated element value. */
294438fd1498Szrj
294538fd1498Szrj inline bool
294638fd1498Szrj const_vec_duplicate_p (const_rtx x)
294738fd1498Szrj {
294838fd1498Szrj return (GET_CODE (x) == CONST_VECTOR
294938fd1498Szrj && CONST_VECTOR_NPATTERNS (x) == 1
295038fd1498Szrj && CONST_VECTOR_DUPLICATE_P (x));
295138fd1498Szrj }
295238fd1498Szrj
295338fd1498Szrj /* Return true if X is a vector constant with a duplicated element value.
295438fd1498Szrj Store the duplicated element in *ELT if so. */
295538fd1498Szrj
295638fd1498Szrj template <typename T>
295738fd1498Szrj inline bool
295838fd1498Szrj const_vec_duplicate_p (T x, T *elt)
295938fd1498Szrj {
296038fd1498Szrj if (const_vec_duplicate_p (x))
296138fd1498Szrj {
296238fd1498Szrj *elt = CONST_VECTOR_ENCODED_ELT (x, 0);
296338fd1498Szrj return true;
296438fd1498Szrj }
296538fd1498Szrj return false;
296638fd1498Szrj }
296738fd1498Szrj
296838fd1498Szrj /* Return true if X is a vector with a duplicated element value, either
296938fd1498Szrj constant or nonconstant. Store the duplicated element in *ELT if so. */
297038fd1498Szrj
297138fd1498Szrj template <typename T>
297238fd1498Szrj inline bool
297338fd1498Szrj vec_duplicate_p (T x, T *elt)
297438fd1498Szrj {
297538fd1498Szrj if (GET_CODE (x) == VEC_DUPLICATE
297638fd1498Szrj && !VECTOR_MODE_P (GET_MODE (XEXP (x, 0))))
297738fd1498Szrj {
297838fd1498Szrj *elt = XEXP (x, 0);
297938fd1498Szrj return true;
298038fd1498Szrj }
298138fd1498Szrj return const_vec_duplicate_p (x, elt);
298238fd1498Szrj }
298338fd1498Szrj
298438fd1498Szrj /* If X is a vector constant with a duplicated element value, return that
298538fd1498Szrj element value, otherwise return X. */
298638fd1498Szrj
298738fd1498Szrj template <typename T>
298838fd1498Szrj inline T
298938fd1498Szrj unwrap_const_vec_duplicate (T x)
299038fd1498Szrj {
299138fd1498Szrj if (const_vec_duplicate_p (x))
299238fd1498Szrj x = CONST_VECTOR_ELT (x, 0);
299338fd1498Szrj return x;
299438fd1498Szrj }
299538fd1498Szrj
299638fd1498Szrj /* In emit-rtl.c. */
299738fd1498Szrj extern wide_int const_vector_int_elt (const_rtx, unsigned int);
299838fd1498Szrj extern rtx const_vector_elt (const_rtx, unsigned int);
299938fd1498Szrj extern bool const_vec_series_p_1 (const_rtx, rtx *, rtx *);
300038fd1498Szrj
300138fd1498Szrj /* Return true if X is an integer constant vector that contains a linear
300238fd1498Szrj series of the form:
300338fd1498Szrj
300438fd1498Szrj { B, B + S, B + 2 * S, B + 3 * S, ... }
300538fd1498Szrj
300638fd1498Szrj for a nonzero S. Store B and S in *BASE_OUT and *STEP_OUT on sucess. */
300738fd1498Szrj
300838fd1498Szrj inline bool
300938fd1498Szrj const_vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
301038fd1498Szrj {
301138fd1498Szrj if (GET_CODE (x) == CONST_VECTOR
301238fd1498Szrj && CONST_VECTOR_NPATTERNS (x) == 1
301338fd1498Szrj && !CONST_VECTOR_DUPLICATE_P (x))
301438fd1498Szrj return const_vec_series_p_1 (x, base_out, step_out);
301538fd1498Szrj return false;
301638fd1498Szrj }
301738fd1498Szrj
301838fd1498Szrj /* Return true if X is a vector that contains a linear series of the
301938fd1498Szrj form:
302038fd1498Szrj
302138fd1498Szrj { B, B + S, B + 2 * S, B + 3 * S, ... }
302238fd1498Szrj
302338fd1498Szrj where B and S are constant or nonconstant. Store B and S in
302438fd1498Szrj *BASE_OUT and *STEP_OUT on sucess. */
302538fd1498Szrj
302638fd1498Szrj inline bool
302738fd1498Szrj vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
302838fd1498Szrj {
302938fd1498Szrj if (GET_CODE (x) == VEC_SERIES)
303038fd1498Szrj {
303138fd1498Szrj *base_out = XEXP (x, 0);
303238fd1498Szrj *step_out = XEXP (x, 1);
303338fd1498Szrj return true;
303438fd1498Szrj }
303538fd1498Szrj return const_vec_series_p (x, base_out, step_out);
303638fd1498Szrj }
303738fd1498Szrj
303838fd1498Szrj /* Return the unpromoted (outer) mode of SUBREG_PROMOTED_VAR_P subreg X. */
303938fd1498Szrj
304038fd1498Szrj inline scalar_int_mode
304138fd1498Szrj subreg_unpromoted_mode (rtx x)
304238fd1498Szrj {
304338fd1498Szrj gcc_checking_assert (SUBREG_PROMOTED_VAR_P (x));
304438fd1498Szrj return as_a <scalar_int_mode> (GET_MODE (x));
304538fd1498Szrj }
304638fd1498Szrj
304738fd1498Szrj /* Return the promoted (inner) mode of SUBREG_PROMOTED_VAR_P subreg X. */
304838fd1498Szrj
304938fd1498Szrj inline scalar_int_mode
305038fd1498Szrj subreg_promoted_mode (rtx x)
305138fd1498Szrj {
305238fd1498Szrj gcc_checking_assert (SUBREG_PROMOTED_VAR_P (x));
305338fd1498Szrj return as_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)));
305438fd1498Szrj }
305538fd1498Szrj
305638fd1498Szrj /* In emit-rtl.c */
305738fd1498Szrj extern rtvec gen_rtvec_v (int, rtx *);
305838fd1498Szrj extern rtvec gen_rtvec_v (int, rtx_insn **);
305938fd1498Szrj extern rtx gen_reg_rtx (machine_mode);
306038fd1498Szrj extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, poly_int64);
306138fd1498Szrj extern rtx gen_reg_rtx_offset (rtx, machine_mode, int);
306238fd1498Szrj extern rtx gen_reg_rtx_and_attrs (rtx);
306338fd1498Szrj extern rtx_code_label *gen_label_rtx (void);
306438fd1498Szrj extern rtx gen_lowpart_common (machine_mode, rtx);
306538fd1498Szrj
306638fd1498Szrj /* In cse.c */
306738fd1498Szrj extern rtx gen_lowpart_if_possible (machine_mode, rtx);
306838fd1498Szrj
306938fd1498Szrj /* In emit-rtl.c */
307038fd1498Szrj extern rtx gen_highpart (machine_mode, rtx);
307138fd1498Szrj extern rtx gen_highpart_mode (machine_mode, machine_mode, rtx);
307238fd1498Szrj extern rtx operand_subword (rtx, poly_uint64, int, machine_mode);
307338fd1498Szrj
307438fd1498Szrj /* In emit-rtl.c */
307538fd1498Szrj extern rtx operand_subword_force (rtx, poly_uint64, machine_mode);
307638fd1498Szrj extern int subreg_lowpart_p (const_rtx);
307738fd1498Szrj extern poly_uint64 subreg_size_lowpart_offset (poly_uint64, poly_uint64);
307838fd1498Szrj
307938fd1498Szrj /* Return true if a subreg of mode OUTERMODE would only access part of
308038fd1498Szrj an inner register with mode INNERMODE. The other bits of the inner
308138fd1498Szrj register would then be "don't care" on read. The behavior for writes
308238fd1498Szrj depends on REGMODE_NATURAL_SIZE; bits in the same REGMODE_NATURAL_SIZE-d
308338fd1498Szrj chunk would be clobbered but other bits would be preserved. */
308438fd1498Szrj
308538fd1498Szrj inline bool
308638fd1498Szrj partial_subreg_p (machine_mode outermode, machine_mode innermode)
308738fd1498Szrj {
308838fd1498Szrj /* Modes involved in a subreg must be ordered. In particular, we must
308938fd1498Szrj always know at compile time whether the subreg is paradoxical. */
309038fd1498Szrj poly_int64 outer_prec = GET_MODE_PRECISION (outermode);
309138fd1498Szrj poly_int64 inner_prec = GET_MODE_PRECISION (innermode);
309238fd1498Szrj gcc_checking_assert (ordered_p (outer_prec, inner_prec));
309338fd1498Szrj return maybe_lt (outer_prec, inner_prec);
309438fd1498Szrj }
309538fd1498Szrj
309638fd1498Szrj /* Likewise return true if X is a subreg that is smaller than the inner
309738fd1498Szrj register. Use read_modify_subreg_p to test whether writing to such
309838fd1498Szrj a subreg preserves any part of the inner register. */
309938fd1498Szrj
310038fd1498Szrj inline bool
310138fd1498Szrj partial_subreg_p (const_rtx x)
310238fd1498Szrj {
310338fd1498Szrj if (GET_CODE (x) != SUBREG)
310438fd1498Szrj return false;
310538fd1498Szrj return partial_subreg_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
310638fd1498Szrj }
310738fd1498Szrj
310838fd1498Szrj /* Return true if a subreg with the given outer and inner modes is
310938fd1498Szrj paradoxical. */
311038fd1498Szrj
311138fd1498Szrj inline bool
311238fd1498Szrj paradoxical_subreg_p (machine_mode outermode, machine_mode innermode)
311338fd1498Szrj {
311438fd1498Szrj /* Modes involved in a subreg must be ordered. In particular, we must
311538fd1498Szrj always know at compile time whether the subreg is paradoxical. */
311638fd1498Szrj poly_int64 outer_prec = GET_MODE_PRECISION (outermode);
311738fd1498Szrj poly_int64 inner_prec = GET_MODE_PRECISION (innermode);
311838fd1498Szrj gcc_checking_assert (ordered_p (outer_prec, inner_prec));
311938fd1498Szrj return maybe_gt (outer_prec, inner_prec);
312038fd1498Szrj }
312138fd1498Szrj
312238fd1498Szrj /* Return true if X is a paradoxical subreg, false otherwise. */
312338fd1498Szrj
312438fd1498Szrj inline bool
312538fd1498Szrj paradoxical_subreg_p (const_rtx x)
312638fd1498Szrj {
312738fd1498Szrj if (GET_CODE (x) != SUBREG)
312838fd1498Szrj return false;
312938fd1498Szrj return paradoxical_subreg_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
313038fd1498Szrj }
313138fd1498Szrj
313238fd1498Szrj /* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value. */
313338fd1498Szrj
313438fd1498Szrj inline poly_uint64
313538fd1498Szrj subreg_lowpart_offset (machine_mode outermode, machine_mode innermode)
313638fd1498Szrj {
313738fd1498Szrj return subreg_size_lowpart_offset (GET_MODE_SIZE (outermode),
313838fd1498Szrj GET_MODE_SIZE (innermode));
313938fd1498Szrj }
314038fd1498Szrj
314138fd1498Szrj /* Given that a subreg has outer mode OUTERMODE and inner mode INNERMODE,
314238fd1498Szrj return the smaller of the two modes if they are different sizes,
314338fd1498Szrj otherwise return the outer mode. */
314438fd1498Szrj
314538fd1498Szrj inline machine_mode
314638fd1498Szrj narrower_subreg_mode (machine_mode outermode, machine_mode innermode)
314738fd1498Szrj {
314838fd1498Szrj return paradoxical_subreg_p (outermode, innermode) ? innermode : outermode;
314938fd1498Szrj }
315038fd1498Szrj
315138fd1498Szrj /* Given that a subreg has outer mode OUTERMODE and inner mode INNERMODE,
315238fd1498Szrj return the mode that is big enough to hold both the outer and inner
315338fd1498Szrj values. Prefer the outer mode in the event of a tie. */
315438fd1498Szrj
315538fd1498Szrj inline machine_mode
315638fd1498Szrj wider_subreg_mode (machine_mode outermode, machine_mode innermode)
315738fd1498Szrj {
315838fd1498Szrj return partial_subreg_p (outermode, innermode) ? innermode : outermode;
315938fd1498Szrj }
316038fd1498Szrj
316138fd1498Szrj /* Likewise for subreg X. */
316238fd1498Szrj
316338fd1498Szrj inline machine_mode
316438fd1498Szrj wider_subreg_mode (const_rtx x)
316538fd1498Szrj {
316638fd1498Szrj return wider_subreg_mode (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
316738fd1498Szrj }
316838fd1498Szrj
316938fd1498Szrj extern poly_uint64 subreg_size_highpart_offset (poly_uint64, poly_uint64);
317038fd1498Szrj
317138fd1498Szrj /* Return the SUBREG_BYTE for an OUTERMODE highpart of an INNERMODE value. */
317238fd1498Szrj
317338fd1498Szrj inline poly_uint64
317438fd1498Szrj subreg_highpart_offset (machine_mode outermode, machine_mode innermode)
317538fd1498Szrj {
317638fd1498Szrj return subreg_size_highpart_offset (GET_MODE_SIZE (outermode),
317738fd1498Szrj GET_MODE_SIZE (innermode));
317838fd1498Szrj }
317938fd1498Szrj
318038fd1498Szrj extern poly_int64 byte_lowpart_offset (machine_mode, machine_mode);
318138fd1498Szrj extern poly_int64 subreg_memory_offset (machine_mode, machine_mode,
318238fd1498Szrj poly_uint64);
318338fd1498Szrj extern poly_int64 subreg_memory_offset (const_rtx);
318438fd1498Szrj extern rtx make_safe_from (rtx, rtx);
318538fd1498Szrj extern rtx convert_memory_address_addr_space_1 (scalar_int_mode, rtx,
318638fd1498Szrj addr_space_t, bool, bool);
318738fd1498Szrj extern rtx convert_memory_address_addr_space (scalar_int_mode, rtx,
318838fd1498Szrj addr_space_t);
318938fd1498Szrj #define convert_memory_address(to_mode,x) \
319038fd1498Szrj convert_memory_address_addr_space ((to_mode), (x), ADDR_SPACE_GENERIC)
319138fd1498Szrj extern const char *get_insn_name (int);
319238fd1498Szrj extern rtx_insn *get_last_insn_anywhere (void);
319338fd1498Szrj extern rtx_insn *get_first_nonnote_insn (void);
319438fd1498Szrj extern rtx_insn *get_last_nonnote_insn (void);
319538fd1498Szrj extern void start_sequence (void);
319638fd1498Szrj extern void push_to_sequence (rtx_insn *);
319738fd1498Szrj extern void push_to_sequence2 (rtx_insn *, rtx_insn *);
319838fd1498Szrj extern void end_sequence (void);
319938fd1498Szrj #if TARGET_SUPPORTS_WIDE_INT == 0
320038fd1498Szrj extern double_int rtx_to_double_int (const_rtx);
320138fd1498Szrj #endif
320238fd1498Szrj extern void cwi_output_hex (FILE *, const_rtx);
320338fd1498Szrj #if TARGET_SUPPORTS_WIDE_INT == 0
320438fd1498Szrj extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
320538fd1498Szrj machine_mode);
320638fd1498Szrj #endif
320738fd1498Szrj extern rtx immed_wide_int_const (const poly_wide_int_ref &, machine_mode);
320838fd1498Szrj
320938fd1498Szrj /* In varasm.c */
321038fd1498Szrj extern rtx force_const_mem (machine_mode, rtx);
321138fd1498Szrj
321238fd1498Szrj /* In varasm.c */
321338fd1498Szrj
321438fd1498Szrj struct function;
321538fd1498Szrj extern rtx get_pool_constant (const_rtx);
321638fd1498Szrj extern rtx get_pool_constant_mark (rtx, bool *);
321738fd1498Szrj extern fixed_size_mode get_pool_mode (const_rtx);
321838fd1498Szrj extern rtx simplify_subtraction (rtx);
321938fd1498Szrj extern void decide_function_section (tree);
322038fd1498Szrj
322138fd1498Szrj /* In emit-rtl.c */
322238fd1498Szrj extern rtx_insn *emit_insn_before (rtx, rtx);
322338fd1498Szrj extern rtx_insn *emit_insn_before_noloc (rtx, rtx_insn *, basic_block);
322438fd1498Szrj extern rtx_insn *emit_insn_before_setloc (rtx, rtx_insn *, int);
322538fd1498Szrj extern rtx_jump_insn *emit_jump_insn_before (rtx, rtx);
322638fd1498Szrj extern rtx_jump_insn *emit_jump_insn_before_noloc (rtx, rtx_insn *);
322738fd1498Szrj extern rtx_jump_insn *emit_jump_insn_before_setloc (rtx, rtx_insn *, int);
322838fd1498Szrj extern rtx_insn *emit_call_insn_before (rtx, rtx_insn *);
322938fd1498Szrj extern rtx_insn *emit_call_insn_before_noloc (rtx, rtx_insn *);
323038fd1498Szrj extern rtx_insn *emit_call_insn_before_setloc (rtx, rtx_insn *, int);
323138fd1498Szrj extern rtx_insn *emit_debug_insn_before (rtx, rtx_insn *);
323238fd1498Szrj extern rtx_insn *emit_debug_insn_before_noloc (rtx, rtx);
323338fd1498Szrj extern rtx_insn *emit_debug_insn_before_setloc (rtx, rtx, int);
323438fd1498Szrj extern rtx_barrier *emit_barrier_before (rtx);
323538fd1498Szrj extern rtx_code_label *emit_label_before (rtx, rtx_insn *);
323638fd1498Szrj extern rtx_note *emit_note_before (enum insn_note, rtx_insn *);
323738fd1498Szrj extern rtx_insn *emit_insn_after (rtx, rtx);
323838fd1498Szrj extern rtx_insn *emit_insn_after_noloc (rtx, rtx, basic_block);
323938fd1498Szrj extern rtx_insn *emit_insn_after_setloc (rtx, rtx, int);
324038fd1498Szrj extern rtx_jump_insn *emit_jump_insn_after (rtx, rtx);
324138fd1498Szrj extern rtx_jump_insn *emit_jump_insn_after_noloc (rtx, rtx);
324238fd1498Szrj extern rtx_jump_insn *emit_jump_insn_after_setloc (rtx, rtx, int);
324338fd1498Szrj extern rtx_insn *emit_call_insn_after (rtx, rtx);
324438fd1498Szrj extern rtx_insn *emit_call_insn_after_noloc (rtx, rtx);
324538fd1498Szrj extern rtx_insn *emit_call_insn_after_setloc (rtx, rtx, int);
324638fd1498Szrj extern rtx_insn *emit_debug_insn_after (rtx, rtx);
324738fd1498Szrj extern rtx_insn *emit_debug_insn_after_noloc (rtx, rtx);
324838fd1498Szrj extern rtx_insn *emit_debug_insn_after_setloc (rtx, rtx, int);
324938fd1498Szrj extern rtx_barrier *emit_barrier_after (rtx);
325038fd1498Szrj extern rtx_insn *emit_label_after (rtx, rtx_insn *);
325138fd1498Szrj extern rtx_note *emit_note_after (enum insn_note, rtx_insn *);
325238fd1498Szrj extern rtx_insn *emit_insn (rtx);
325338fd1498Szrj extern rtx_insn *emit_debug_insn (rtx);
325438fd1498Szrj extern rtx_insn *emit_jump_insn (rtx);
325538fd1498Szrj extern rtx_insn *emit_call_insn (rtx);
325638fd1498Szrj extern rtx_code_label *emit_label (rtx);
325738fd1498Szrj extern rtx_jump_table_data *emit_jump_table_data (rtx);
325838fd1498Szrj extern rtx_barrier *emit_barrier (void);
325938fd1498Szrj extern rtx_note *emit_note (enum insn_note);
326038fd1498Szrj extern rtx_note *emit_note_copy (rtx_note *);
326138fd1498Szrj extern rtx_insn *gen_clobber (rtx);
326238fd1498Szrj extern rtx_insn *emit_clobber (rtx);
326338fd1498Szrj extern rtx_insn *gen_use (rtx);
326438fd1498Szrj extern rtx_insn *emit_use (rtx);
326538fd1498Szrj extern rtx_insn *make_insn_raw (rtx);
326638fd1498Szrj extern void add_function_usage_to (rtx, rtx);
326738fd1498Szrj extern rtx_call_insn *last_call_insn (void);
326838fd1498Szrj extern rtx_insn *previous_insn (rtx_insn *);
326938fd1498Szrj extern rtx_insn *next_insn (rtx_insn *);
327038fd1498Szrj extern rtx_insn *prev_nonnote_insn (rtx_insn *);
327138fd1498Szrj extern rtx_insn *next_nonnote_insn (rtx_insn *);
327238fd1498Szrj extern rtx_insn *prev_nondebug_insn (rtx_insn *);
327338fd1498Szrj extern rtx_insn *next_nondebug_insn (rtx_insn *);
327438fd1498Szrj extern rtx_insn *prev_nonnote_nondebug_insn (rtx_insn *);
327538fd1498Szrj extern rtx_insn *prev_nonnote_nondebug_insn_bb (rtx_insn *);
327638fd1498Szrj extern rtx_insn *next_nonnote_nondebug_insn (rtx_insn *);
327738fd1498Szrj extern rtx_insn *next_nonnote_nondebug_insn_bb (rtx_insn *);
327838fd1498Szrj extern rtx_insn *prev_real_insn (rtx_insn *);
327938fd1498Szrj extern rtx_insn *next_real_insn (rtx);
328038fd1498Szrj extern rtx_insn *prev_real_nondebug_insn (rtx_insn *);
328138fd1498Szrj extern rtx_insn *next_real_nondebug_insn (rtx);
328238fd1498Szrj extern rtx_insn *prev_active_insn (rtx_insn *);
328338fd1498Szrj extern rtx_insn *next_active_insn (rtx_insn *);
328438fd1498Szrj extern int active_insn_p (const rtx_insn *);
328538fd1498Szrj extern rtx_insn *next_cc0_user (rtx_insn *);
328638fd1498Szrj extern rtx_insn *prev_cc0_setter (rtx_insn *);
328738fd1498Szrj
328838fd1498Szrj /* In emit-rtl.c */
328938fd1498Szrj extern int insn_line (const rtx_insn *);
329038fd1498Szrj extern const char * insn_file (const rtx_insn *);
329138fd1498Szrj extern tree insn_scope (const rtx_insn *);
329238fd1498Szrj extern expanded_location insn_location (const rtx_insn *);
329338fd1498Szrj extern location_t prologue_location, epilogue_location;
329438fd1498Szrj
329538fd1498Szrj /* In jump.c */
329638fd1498Szrj extern enum rtx_code reverse_condition (enum rtx_code);
329738fd1498Szrj extern enum rtx_code reverse_condition_maybe_unordered (enum rtx_code);
329838fd1498Szrj extern enum rtx_code swap_condition (enum rtx_code);
329938fd1498Szrj extern enum rtx_code unsigned_condition (enum rtx_code);
330038fd1498Szrj extern enum rtx_code signed_condition (enum rtx_code);
330138fd1498Szrj extern void mark_jump_label (rtx, rtx_insn *, int);
330238fd1498Szrj
330338fd1498Szrj /* In jump.c */
330438fd1498Szrj extern rtx_insn *delete_related_insns (rtx);
330538fd1498Szrj
330638fd1498Szrj /* In recog.c */
330738fd1498Szrj extern rtx *find_constant_term_loc (rtx *);
330838fd1498Szrj
330938fd1498Szrj /* In emit-rtl.c */
331038fd1498Szrj extern rtx_insn *try_split (rtx, rtx_insn *, int);
331138fd1498Szrj
331238fd1498Szrj /* In insn-recog.c (generated by genrecog). */
331338fd1498Szrj extern rtx_insn *split_insns (rtx, rtx_insn *);
331438fd1498Szrj
331538fd1498Szrj /* In simplify-rtx.c */
331638fd1498Szrj extern rtx simplify_const_unary_operation (enum rtx_code, machine_mode,
331738fd1498Szrj rtx, machine_mode);
331838fd1498Szrj extern rtx simplify_unary_operation (enum rtx_code, machine_mode, rtx,
331938fd1498Szrj machine_mode);
332038fd1498Szrj extern rtx simplify_const_binary_operation (enum rtx_code, machine_mode,
332138fd1498Szrj rtx, rtx);
332238fd1498Szrj extern rtx simplify_binary_operation (enum rtx_code, machine_mode, rtx,
332338fd1498Szrj rtx);
332438fd1498Szrj extern rtx simplify_ternary_operation (enum rtx_code, machine_mode,
332538fd1498Szrj machine_mode, rtx, rtx, rtx);
332638fd1498Szrj extern rtx simplify_const_relational_operation (enum rtx_code,
332738fd1498Szrj machine_mode, rtx, rtx);
332838fd1498Szrj extern rtx simplify_relational_operation (enum rtx_code, machine_mode,
332938fd1498Szrj machine_mode, rtx, rtx);
333038fd1498Szrj extern rtx simplify_gen_binary (enum rtx_code, machine_mode, rtx, rtx);
333138fd1498Szrj extern rtx simplify_gen_unary (enum rtx_code, machine_mode, rtx,
333238fd1498Szrj machine_mode);
333338fd1498Szrj extern rtx simplify_gen_ternary (enum rtx_code, machine_mode,
333438fd1498Szrj machine_mode, rtx, rtx, rtx);
333538fd1498Szrj extern rtx simplify_gen_relational (enum rtx_code, machine_mode,
333638fd1498Szrj machine_mode, rtx, rtx);
333738fd1498Szrj extern rtx simplify_subreg (machine_mode, rtx, machine_mode, poly_uint64);
333838fd1498Szrj extern rtx simplify_gen_subreg (machine_mode, rtx, machine_mode, poly_uint64);
333938fd1498Szrj extern rtx lowpart_subreg (machine_mode, rtx, machine_mode);
334038fd1498Szrj extern rtx simplify_replace_fn_rtx (rtx, const_rtx,
334138fd1498Szrj rtx (*fn) (rtx, const_rtx, void *), void *);
334238fd1498Szrj extern rtx simplify_replace_rtx (rtx, const_rtx, rtx);
334338fd1498Szrj extern rtx simplify_rtx (const_rtx);
334438fd1498Szrj extern rtx avoid_constant_pool_reference (rtx);
334538fd1498Szrj extern rtx delegitimize_mem_from_attrs (rtx);
334638fd1498Szrj extern bool mode_signbit_p (machine_mode, const_rtx);
334738fd1498Szrj extern bool val_signbit_p (machine_mode, unsigned HOST_WIDE_INT);
334838fd1498Szrj extern bool val_signbit_known_set_p (machine_mode,
334938fd1498Szrj unsigned HOST_WIDE_INT);
335038fd1498Szrj extern bool val_signbit_known_clear_p (machine_mode,
335138fd1498Szrj unsigned HOST_WIDE_INT);
335238fd1498Szrj
335338fd1498Szrj /* In reginfo.c */
335438fd1498Szrj extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
335538fd1498Szrj bool);
335638fd1498Szrj extern const HARD_REG_SET &simplifiable_subregs (const subreg_shape &);
335738fd1498Szrj
335838fd1498Szrj /* In emit-rtl.c */
335938fd1498Szrj extern rtx set_for_reg_notes (rtx);
336038fd1498Szrj extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
336138fd1498Szrj extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx);
336238fd1498Szrj extern void set_insn_deleted (rtx);
336338fd1498Szrj
336438fd1498Szrj /* Functions in rtlanal.c */
336538fd1498Szrj
336638fd1498Szrj extern rtx single_set_2 (const rtx_insn *, const_rtx);
336738fd1498Szrj extern bool contains_symbol_ref_p (const_rtx);
336838fd1498Szrj extern bool contains_symbolic_reference_p (const_rtx);
336938fd1498Szrj
337038fd1498Szrj /* Handle the cheap and common cases inline for performance. */
337138fd1498Szrj
337238fd1498Szrj inline rtx single_set (const rtx_insn *insn)
337338fd1498Szrj {
337438fd1498Szrj if (!INSN_P (insn))
337538fd1498Szrj return NULL_RTX;
337638fd1498Szrj
337738fd1498Szrj if (GET_CODE (PATTERN (insn)) == SET)
337838fd1498Szrj return PATTERN (insn);
337938fd1498Szrj
338038fd1498Szrj /* Defer to the more expensive case. */
338138fd1498Szrj return single_set_2 (insn, PATTERN (insn));
338238fd1498Szrj }
338338fd1498Szrj
338438fd1498Szrj extern scalar_int_mode get_address_mode (rtx mem);
338538fd1498Szrj extern int rtx_addr_can_trap_p (const_rtx);
338638fd1498Szrj extern bool nonzero_address_p (const_rtx);
338738fd1498Szrj extern int rtx_unstable_p (const_rtx);
338838fd1498Szrj extern bool rtx_varies_p (const_rtx, bool);
338938fd1498Szrj extern bool rtx_addr_varies_p (const_rtx, bool);
339038fd1498Szrj extern rtx get_call_rtx_from (rtx);
339138fd1498Szrj extern HOST_WIDE_INT get_integer_term (const_rtx);
339238fd1498Szrj extern rtx get_related_value (const_rtx);
339338fd1498Szrj extern bool offset_within_block_p (const_rtx, HOST_WIDE_INT);
339438fd1498Szrj extern void split_const (rtx, rtx *, rtx *);
339538fd1498Szrj extern rtx strip_offset (rtx, poly_int64_pod *);
339638fd1498Szrj extern poly_int64 get_args_size (const_rtx);
339738fd1498Szrj extern bool unsigned_reg_p (rtx);
339838fd1498Szrj extern int reg_mentioned_p (const_rtx, const_rtx);
339938fd1498Szrj extern int count_occurrences (const_rtx, const_rtx, int);
340038fd1498Szrj extern int reg_referenced_p (const_rtx, const_rtx);
340138fd1498Szrj extern int reg_used_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
340238fd1498Szrj extern int reg_set_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
340338fd1498Szrj extern int commutative_operand_precedence (rtx);
340438fd1498Szrj extern bool swap_commutative_operands_p (rtx, rtx);
340538fd1498Szrj extern int modified_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
340638fd1498Szrj extern int no_labels_between_p (const rtx_insn *, const rtx_insn *);
340738fd1498Szrj extern int modified_in_p (const_rtx, const_rtx);
340838fd1498Szrj extern int reg_set_p (const_rtx, const_rtx);
340938fd1498Szrj extern int multiple_sets (const_rtx);
341038fd1498Szrj extern int set_noop_p (const_rtx);
341138fd1498Szrj extern int noop_move_p (const rtx_insn *);
341238fd1498Szrj extern bool refers_to_regno_p (unsigned int, unsigned int, const_rtx, rtx *);
341338fd1498Szrj extern int reg_overlap_mentioned_p (const_rtx, const_rtx);
341438fd1498Szrj extern const_rtx set_of (const_rtx, const_rtx);
341538fd1498Szrj extern void record_hard_reg_sets (rtx, const_rtx, void *);
341638fd1498Szrj extern void record_hard_reg_uses (rtx *, void *);
341738fd1498Szrj extern void find_all_hard_regs (const_rtx, HARD_REG_SET *);
341838fd1498Szrj extern void find_all_hard_reg_sets (const rtx_insn *, HARD_REG_SET *, bool);
341938fd1498Szrj extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *);
342038fd1498Szrj extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
342138fd1498Szrj extern int dead_or_set_p (const rtx_insn *, const_rtx);
342238fd1498Szrj extern int dead_or_set_regno_p (const rtx_insn *, unsigned int);
342338fd1498Szrj extern rtx find_reg_note (const_rtx, enum reg_note, const_rtx);
342438fd1498Szrj extern rtx find_regno_note (const_rtx, enum reg_note, unsigned int);
342538fd1498Szrj extern rtx find_reg_equal_equiv_note (const_rtx);
342638fd1498Szrj extern rtx find_constant_src (const rtx_insn *);
342738fd1498Szrj extern int find_reg_fusage (const_rtx, enum rtx_code, const_rtx);
342838fd1498Szrj extern int find_regno_fusage (const_rtx, enum rtx_code, unsigned int);
342938fd1498Szrj extern rtx alloc_reg_note (enum reg_note, rtx, rtx);
343038fd1498Szrj extern void add_reg_note (rtx, enum reg_note, rtx);
343138fd1498Szrj extern void add_int_reg_note (rtx_insn *, enum reg_note, int);
343238fd1498Szrj extern void add_args_size_note (rtx_insn *, poly_int64);
343338fd1498Szrj extern void add_shallow_copy_of_reg_note (rtx_insn *, rtx);
343438fd1498Szrj extern rtx duplicate_reg_note (rtx);
343538fd1498Szrj extern void remove_note (rtx_insn *, const_rtx);
343638fd1498Szrj extern bool remove_reg_equal_equiv_notes (rtx_insn *);
343738fd1498Szrj extern void remove_reg_equal_equiv_notes_for_regno (unsigned int);
343838fd1498Szrj extern int side_effects_p (const_rtx);
343938fd1498Szrj extern int volatile_refs_p (const_rtx);
344038fd1498Szrj extern int volatile_insn_p (const_rtx);
344138fd1498Szrj extern int may_trap_p_1 (const_rtx, unsigned);
344238fd1498Szrj extern int may_trap_p (const_rtx);
344338fd1498Szrj extern int may_trap_or_fault_p (const_rtx);
344438fd1498Szrj extern bool can_throw_internal (const_rtx);
344538fd1498Szrj extern bool can_throw_external (const_rtx);
344638fd1498Szrj extern bool insn_could_throw_p (const_rtx);
344738fd1498Szrj extern bool insn_nothrow_p (const_rtx);
344838fd1498Szrj extern bool can_nonlocal_goto (const rtx_insn *);
344938fd1498Szrj extern void copy_reg_eh_region_note_forward (rtx, rtx_insn *, rtx);
345038fd1498Szrj extern void copy_reg_eh_region_note_backward (rtx, rtx_insn *, rtx);
345138fd1498Szrj extern int inequality_comparisons_p (const_rtx);
345238fd1498Szrj extern rtx replace_rtx (rtx, rtx, rtx, bool = false);
345338fd1498Szrj extern void replace_label (rtx *, rtx, rtx, bool);
345438fd1498Szrj extern void replace_label_in_insn (rtx_insn *, rtx_insn *, rtx_insn *, bool);
345538fd1498Szrj extern bool rtx_referenced_p (const_rtx, const_rtx);
345638fd1498Szrj extern bool tablejump_p (const rtx_insn *, rtx_insn **, rtx_jump_table_data **);
345738fd1498Szrj extern int computed_jump_p (const rtx_insn *);
345838fd1498Szrj extern bool tls_referenced_p (const_rtx);
345938fd1498Szrj extern bool contains_mem_rtx_p (rtx x);
346038fd1498Szrj
346138fd1498Szrj /* Overload for refers_to_regno_p for checking a single register. */
346238fd1498Szrj inline bool
346338fd1498Szrj refers_to_regno_p (unsigned int regnum, const_rtx x, rtx* loc = NULL)
346438fd1498Szrj {
346538fd1498Szrj return refers_to_regno_p (regnum, regnum + 1, x, loc);
346638fd1498Szrj }
346738fd1498Szrj
346838fd1498Szrj /* Callback for for_each_inc_dec, to process the autoinc operation OP
346938fd1498Szrj within MEM that sets DEST to SRC + SRCOFF, or SRC if SRCOFF is
347038fd1498Szrj NULL. The callback is passed the same opaque ARG passed to
347138fd1498Szrj for_each_inc_dec. Return zero to continue looking for other
347238fd1498Szrj autoinc operations or any other value to interrupt the traversal and
347338fd1498Szrj return that value to the caller of for_each_inc_dec. */
347438fd1498Szrj typedef int (*for_each_inc_dec_fn) (rtx mem, rtx op, rtx dest, rtx src,
347538fd1498Szrj rtx srcoff, void *arg);
347638fd1498Szrj extern int for_each_inc_dec (rtx, for_each_inc_dec_fn, void *arg);
347738fd1498Szrj
347838fd1498Szrj typedef int (*rtx_equal_p_callback_function) (const_rtx *, const_rtx *,
347938fd1498Szrj rtx *, rtx *);
348038fd1498Szrj extern int rtx_equal_p_cb (const_rtx, const_rtx,
348138fd1498Szrj rtx_equal_p_callback_function);
348238fd1498Szrj
348338fd1498Szrj typedef int (*hash_rtx_callback_function) (const_rtx, machine_mode, rtx *,
348438fd1498Szrj machine_mode *);
348538fd1498Szrj extern unsigned hash_rtx_cb (const_rtx, machine_mode, int *, int *,
348638fd1498Szrj bool, hash_rtx_callback_function);
348738fd1498Szrj
348838fd1498Szrj extern rtx regno_use_in (unsigned int, rtx);
348938fd1498Szrj extern int auto_inc_p (const_rtx);
349038fd1498Szrj extern bool in_insn_list_p (const rtx_insn_list *, const rtx_insn *);
349138fd1498Szrj extern void remove_node_from_expr_list (const_rtx, rtx_expr_list **);
349238fd1498Szrj extern void remove_node_from_insn_list (const rtx_insn *, rtx_insn_list **);
349338fd1498Szrj extern int loc_mentioned_in_p (rtx *, const_rtx);
349438fd1498Szrj extern rtx_insn *find_first_parameter_load (rtx_insn *, rtx_insn *);
349538fd1498Szrj extern bool keep_with_call_p (const rtx_insn *);
349638fd1498Szrj extern bool label_is_jump_target_p (const_rtx, const rtx_insn *);
349738fd1498Szrj extern int pattern_cost (rtx, bool);
349838fd1498Szrj extern int insn_cost (rtx_insn *, bool);
349938fd1498Szrj extern unsigned seq_cost (const rtx_insn *, bool);
350038fd1498Szrj
350138fd1498Szrj /* Given an insn and condition, return a canonical description of
350238fd1498Szrj the test being made. */
350338fd1498Szrj extern rtx canonicalize_condition (rtx_insn *, rtx, int, rtx_insn **, rtx,
350438fd1498Szrj int, int);
350538fd1498Szrj
350638fd1498Szrj /* Given a JUMP_INSN, return a canonical description of the test
350738fd1498Szrj being made. */
350838fd1498Szrj extern rtx get_condition (rtx_insn *, rtx_insn **, int, int);
350938fd1498Szrj
351038fd1498Szrj /* Information about a subreg of a hard register. */
351138fd1498Szrj struct subreg_info
351238fd1498Szrj {
351338fd1498Szrj /* Offset of first hard register involved in the subreg. */
351438fd1498Szrj int offset;
351538fd1498Szrj /* Number of hard registers involved in the subreg. In the case of
351638fd1498Szrj a paradoxical subreg, this is the number of registers that would
351738fd1498Szrj be modified by writing to the subreg; some of them may be don't-care
351838fd1498Szrj when reading from the subreg. */
351938fd1498Szrj int nregs;
352038fd1498Szrj /* Whether this subreg can be represented as a hard reg with the new
352138fd1498Szrj mode (by adding OFFSET to the original hard register). */
352238fd1498Szrj bool representable_p;
352338fd1498Szrj };
352438fd1498Szrj
352538fd1498Szrj extern void subreg_get_info (unsigned int, machine_mode,
352638fd1498Szrj poly_uint64, machine_mode,
352738fd1498Szrj struct subreg_info *);
352838fd1498Szrj
352938fd1498Szrj /* lists.c */
353038fd1498Szrj
353138fd1498Szrj extern void free_EXPR_LIST_list (rtx_expr_list **);
353238fd1498Szrj extern void free_INSN_LIST_list (rtx_insn_list **);
353338fd1498Szrj extern void free_EXPR_LIST_node (rtx);
353438fd1498Szrj extern void free_INSN_LIST_node (rtx);
353538fd1498Szrj extern rtx_insn_list *alloc_INSN_LIST (rtx, rtx);
353638fd1498Szrj extern rtx_insn_list *copy_INSN_LIST (rtx_insn_list *);
353738fd1498Szrj extern rtx_insn_list *concat_INSN_LIST (rtx_insn_list *, rtx_insn_list *);
353838fd1498Szrj extern rtx_expr_list *alloc_EXPR_LIST (int, rtx, rtx);
353938fd1498Szrj extern void remove_free_INSN_LIST_elem (rtx_insn *, rtx_insn_list **);
354038fd1498Szrj extern rtx remove_list_elem (rtx, rtx *);
354138fd1498Szrj extern rtx_insn *remove_free_INSN_LIST_node (rtx_insn_list **);
354238fd1498Szrj extern rtx remove_free_EXPR_LIST_node (rtx_expr_list **);
354338fd1498Szrj
354438fd1498Szrj
354538fd1498Szrj /* reginfo.c */
354638fd1498Szrj
354738fd1498Szrj /* Resize reg info. */
354838fd1498Szrj extern bool resize_reg_info (void);
354938fd1498Szrj /* Free up register info memory. */
355038fd1498Szrj extern void free_reg_info (void);
355138fd1498Szrj extern void init_subregs_of_mode (void);
355238fd1498Szrj extern void finish_subregs_of_mode (void);
355338fd1498Szrj
355438fd1498Szrj /* recog.c */
355538fd1498Szrj extern rtx extract_asm_operands (rtx);
355638fd1498Szrj extern int asm_noperands (const_rtx);
355738fd1498Szrj extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
355838fd1498Szrj machine_mode *, location_t *);
355938fd1498Szrj extern void get_referenced_operands (const char *, bool *, unsigned int);
356038fd1498Szrj
356138fd1498Szrj extern enum reg_class reg_preferred_class (int);
356238fd1498Szrj extern enum reg_class reg_alternate_class (int);
356338fd1498Szrj extern enum reg_class reg_allocno_class (int);
356438fd1498Szrj extern void setup_reg_classes (int, enum reg_class, enum reg_class,
356538fd1498Szrj enum reg_class);
356638fd1498Szrj
356738fd1498Szrj extern void split_all_insns (void);
356838fd1498Szrj extern unsigned int split_all_insns_noflow (void);
356938fd1498Szrj
357038fd1498Szrj #define MAX_SAVED_CONST_INT 64
357138fd1498Szrj extern GTY(()) rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
357238fd1498Szrj
357338fd1498Szrj #define const0_rtx (const_int_rtx[MAX_SAVED_CONST_INT])
357438fd1498Szrj #define const1_rtx (const_int_rtx[MAX_SAVED_CONST_INT+1])
357538fd1498Szrj #define const2_rtx (const_int_rtx[MAX_SAVED_CONST_INT+2])
357638fd1498Szrj #define constm1_rtx (const_int_rtx[MAX_SAVED_CONST_INT-1])
357738fd1498Szrj extern GTY(()) rtx const_true_rtx;
357838fd1498Szrj
357938fd1498Szrj extern GTY(()) rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];
358038fd1498Szrj
358138fd1498Szrj /* Returns a constant 0 rtx in mode MODE. Integer modes are treated the
358238fd1498Szrj same as VOIDmode. */
358338fd1498Szrj
358438fd1498Szrj #define CONST0_RTX(MODE) (const_tiny_rtx[0][(int) (MODE)])
358538fd1498Szrj
358638fd1498Szrj /* Likewise, for the constants 1 and 2 and -1. */
358738fd1498Szrj
358838fd1498Szrj #define CONST1_RTX(MODE) (const_tiny_rtx[1][(int) (MODE)])
358938fd1498Szrj #define CONST2_RTX(MODE) (const_tiny_rtx[2][(int) (MODE)])
359038fd1498Szrj #define CONSTM1_RTX(MODE) (const_tiny_rtx[3][(int) (MODE)])
359138fd1498Szrj
359238fd1498Szrj extern GTY(()) rtx pc_rtx;
359338fd1498Szrj extern GTY(()) rtx cc0_rtx;
359438fd1498Szrj extern GTY(()) rtx ret_rtx;
359538fd1498Szrj extern GTY(()) rtx simple_return_rtx;
359638fd1498Szrj extern GTY(()) rtx_insn *invalid_insn_rtx;
359738fd1498Szrj
359838fd1498Szrj /* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg
359938fd1498Szrj is used to represent the frame pointer. This is because the
360038fd1498Szrj hard frame pointer and the automatic variables are separated by an amount
360138fd1498Szrj that cannot be determined until after register allocation. We can assume
360238fd1498Szrj that in this case ELIMINABLE_REGS will be defined, one action of which
360338fd1498Szrj will be to eliminate FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. */
360438fd1498Szrj #ifndef HARD_FRAME_POINTER_REGNUM
360538fd1498Szrj #define HARD_FRAME_POINTER_REGNUM FRAME_POINTER_REGNUM
360638fd1498Szrj #endif
360738fd1498Szrj
360838fd1498Szrj #ifndef HARD_FRAME_POINTER_IS_FRAME_POINTER
360938fd1498Szrj #define HARD_FRAME_POINTER_IS_FRAME_POINTER \
361038fd1498Szrj (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM)
361138fd1498Szrj #endif
361238fd1498Szrj
361338fd1498Szrj #ifndef HARD_FRAME_POINTER_IS_ARG_POINTER
361438fd1498Szrj #define HARD_FRAME_POINTER_IS_ARG_POINTER \
361538fd1498Szrj (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM)
361638fd1498Szrj #endif
361738fd1498Szrj
361838fd1498Szrj /* Index labels for global_rtl. */
361938fd1498Szrj enum global_rtl_index
362038fd1498Szrj {
362138fd1498Szrj GR_STACK_POINTER,
362238fd1498Szrj GR_FRAME_POINTER,
362338fd1498Szrj /* For register elimination to work properly these hard_frame_pointer_rtx,
362438fd1498Szrj frame_pointer_rtx, and arg_pointer_rtx must be the same if they refer to
362538fd1498Szrj the same register. */
362638fd1498Szrj #if FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
362738fd1498Szrj GR_ARG_POINTER = GR_FRAME_POINTER,
362838fd1498Szrj #endif
362938fd1498Szrj #if HARD_FRAME_POINTER_IS_FRAME_POINTER
363038fd1498Szrj GR_HARD_FRAME_POINTER = GR_FRAME_POINTER,
363138fd1498Szrj #else
363238fd1498Szrj GR_HARD_FRAME_POINTER,
363338fd1498Szrj #endif
363438fd1498Szrj #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
363538fd1498Szrj #if HARD_FRAME_POINTER_IS_ARG_POINTER
363638fd1498Szrj GR_ARG_POINTER = GR_HARD_FRAME_POINTER,
363738fd1498Szrj #else
363838fd1498Szrj GR_ARG_POINTER,
363938fd1498Szrj #endif
364038fd1498Szrj #endif
364138fd1498Szrj GR_VIRTUAL_INCOMING_ARGS,
364238fd1498Szrj GR_VIRTUAL_STACK_ARGS,
364338fd1498Szrj GR_VIRTUAL_STACK_DYNAMIC,
364438fd1498Szrj GR_VIRTUAL_OUTGOING_ARGS,
364538fd1498Szrj GR_VIRTUAL_CFA,
364638fd1498Szrj GR_VIRTUAL_PREFERRED_STACK_BOUNDARY,
364738fd1498Szrj
364838fd1498Szrj GR_MAX
364938fd1498Szrj };
365038fd1498Szrj
365138fd1498Szrj /* Target-dependent globals. */
365238fd1498Szrj struct GTY(()) target_rtl {
365338fd1498Szrj /* All references to the hard registers in global_rtl_index go through
365438fd1498Szrj these unique rtl objects. On machines where the frame-pointer and
365538fd1498Szrj arg-pointer are the same register, they use the same unique object.
365638fd1498Szrj
365738fd1498Szrj After register allocation, other rtl objects which used to be pseudo-regs
365838fd1498Szrj may be clobbered to refer to the frame-pointer register.
365938fd1498Szrj But references that were originally to the frame-pointer can be
366038fd1498Szrj distinguished from the others because they contain frame_pointer_rtx.
366138fd1498Szrj
366238fd1498Szrj When to use frame_pointer_rtx and hard_frame_pointer_rtx is a little
366338fd1498Szrj tricky: until register elimination has taken place hard_frame_pointer_rtx
366438fd1498Szrj should be used if it is being set, and frame_pointer_rtx otherwise. After
366538fd1498Szrj register elimination hard_frame_pointer_rtx should always be used.
366638fd1498Szrj On machines where the two registers are same (most) then these are the
366738fd1498Szrj same. */
366838fd1498Szrj rtx x_global_rtl[GR_MAX];
366938fd1498Szrj
367038fd1498Szrj /* A unique representation of (REG:Pmode PIC_OFFSET_TABLE_REGNUM). */
367138fd1498Szrj rtx x_pic_offset_table_rtx;
367238fd1498Szrj
367338fd1498Szrj /* A unique representation of (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM).
367438fd1498Szrj This is used to implement __builtin_return_address for some machines;
367538fd1498Szrj see for instance the MIPS port. */
367638fd1498Szrj rtx x_return_address_pointer_rtx;
367738fd1498Szrj
367838fd1498Szrj /* Commonly used RTL for hard registers. These objects are not
367938fd1498Szrj necessarily unique, so we allocate them separately from global_rtl.
368038fd1498Szrj They are initialized once per compilation unit, then copied into
368138fd1498Szrj regno_reg_rtx at the beginning of each function. */
368238fd1498Szrj rtx x_initial_regno_reg_rtx[FIRST_PSEUDO_REGISTER];
368338fd1498Szrj
368438fd1498Szrj /* A sample (mem:M stack_pointer_rtx) rtx for each mode M. */
368538fd1498Szrj rtx x_top_of_stack[MAX_MACHINE_MODE];
368638fd1498Szrj
368738fd1498Szrj /* Static hunks of RTL used by the aliasing code; these are treated
368838fd1498Szrj as persistent to avoid unnecessary RTL allocations. */
368938fd1498Szrj rtx x_static_reg_base_value[FIRST_PSEUDO_REGISTER];
369038fd1498Szrj
369138fd1498Szrj /* The default memory attributes for each mode. */
369238fd1498Szrj struct mem_attrs *x_mode_mem_attrs[(int) MAX_MACHINE_MODE];
369338fd1498Szrj
369438fd1498Szrj /* Track if RTL has been initialized. */
369538fd1498Szrj bool target_specific_initialized;
369638fd1498Szrj };
369738fd1498Szrj
369838fd1498Szrj extern GTY(()) struct target_rtl default_target_rtl;
369938fd1498Szrj #if SWITCHABLE_TARGET
370038fd1498Szrj extern struct target_rtl *this_target_rtl;
370138fd1498Szrj #else
370238fd1498Szrj #define this_target_rtl (&default_target_rtl)
370338fd1498Szrj #endif
370438fd1498Szrj
370538fd1498Szrj #define global_rtl \
370638fd1498Szrj (this_target_rtl->x_global_rtl)
370738fd1498Szrj #define pic_offset_table_rtx \
370838fd1498Szrj (this_target_rtl->x_pic_offset_table_rtx)
370938fd1498Szrj #define return_address_pointer_rtx \
371038fd1498Szrj (this_target_rtl->x_return_address_pointer_rtx)
371138fd1498Szrj #define top_of_stack \
371238fd1498Szrj (this_target_rtl->x_top_of_stack)
371338fd1498Szrj #define mode_mem_attrs \
371438fd1498Szrj (this_target_rtl->x_mode_mem_attrs)
371538fd1498Szrj
371638fd1498Szrj /* All references to certain hard regs, except those created
371738fd1498Szrj by allocating pseudo regs into them (when that's possible),
371838fd1498Szrj go through these unique rtx objects. */
371938fd1498Szrj #define stack_pointer_rtx (global_rtl[GR_STACK_POINTER])
372038fd1498Szrj #define frame_pointer_rtx (global_rtl[GR_FRAME_POINTER])
372138fd1498Szrj #define hard_frame_pointer_rtx (global_rtl[GR_HARD_FRAME_POINTER])
372238fd1498Szrj #define arg_pointer_rtx (global_rtl[GR_ARG_POINTER])
372338fd1498Szrj
372438fd1498Szrj #ifndef GENERATOR_FILE
372538fd1498Szrj /* Return the attributes of a MEM rtx. */
372638fd1498Szrj static inline const struct mem_attrs *
372738fd1498Szrj get_mem_attrs (const_rtx x)
372838fd1498Szrj {
372938fd1498Szrj struct mem_attrs *attrs;
373038fd1498Szrj
373138fd1498Szrj attrs = MEM_ATTRS (x);
373238fd1498Szrj if (!attrs)
373338fd1498Szrj attrs = mode_mem_attrs[(int) GET_MODE (x)];
373438fd1498Szrj return attrs;
373538fd1498Szrj }
373638fd1498Szrj #endif
373738fd1498Szrj
373838fd1498Szrj /* Include the RTL generation functions. */
373938fd1498Szrj
374038fd1498Szrj #ifndef GENERATOR_FILE
374138fd1498Szrj #include "genrtl.h"
374238fd1498Szrj #undef gen_rtx_ASM_INPUT
374338fd1498Szrj #define gen_rtx_ASM_INPUT(MODE, ARG0) \
374438fd1498Szrj gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), 0)
374538fd1498Szrj #define gen_rtx_ASM_INPUT_loc(MODE, ARG0, LOC) \
374638fd1498Szrj gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), (LOC))
374738fd1498Szrj #endif
374838fd1498Szrj
374938fd1498Szrj /* There are some RTL codes that require special attention; the
375038fd1498Szrj generation functions included above do the raw handling. If you
375138fd1498Szrj add to this list, modify special_rtx in gengenrtl.c as well. */
375238fd1498Szrj
375338fd1498Szrj extern rtx_expr_list *gen_rtx_EXPR_LIST (machine_mode, rtx, rtx);
375438fd1498Szrj extern rtx_insn_list *gen_rtx_INSN_LIST (machine_mode, rtx, rtx);
375538fd1498Szrj extern rtx_insn *
375638fd1498Szrj gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
375738fd1498Szrj basic_block bb, rtx pattern, int location, int code,
375838fd1498Szrj rtx reg_notes);
375938fd1498Szrj extern rtx gen_rtx_CONST_INT (machine_mode, HOST_WIDE_INT);
376038fd1498Szrj extern rtx gen_rtx_CONST_VECTOR (machine_mode, rtvec);
376138fd1498Szrj extern void set_mode_and_regno (rtx, machine_mode, unsigned int);
376238fd1498Szrj extern rtx gen_raw_REG (machine_mode, unsigned int);
376338fd1498Szrj extern rtx gen_rtx_REG (machine_mode, unsigned int);
376438fd1498Szrj extern rtx gen_rtx_SUBREG (machine_mode, rtx, poly_uint64);
376538fd1498Szrj extern rtx gen_rtx_MEM (machine_mode, rtx);
376638fd1498Szrj extern rtx gen_rtx_VAR_LOCATION (machine_mode, tree, rtx,
376738fd1498Szrj enum var_init_status);
376838fd1498Szrj
376938fd1498Szrj #ifdef GENERATOR_FILE
377038fd1498Szrj #define PUT_MODE(RTX, MODE) PUT_MODE_RAW (RTX, MODE)
377138fd1498Szrj #else
377238fd1498Szrj static inline void
377338fd1498Szrj PUT_MODE (rtx x, machine_mode mode)
377438fd1498Szrj {
377538fd1498Szrj if (REG_P (x))
377638fd1498Szrj set_mode_and_regno (x, mode, REGNO (x));
377738fd1498Szrj else
377838fd1498Szrj PUT_MODE_RAW (x, mode);
377938fd1498Szrj }
378038fd1498Szrj #endif
378138fd1498Szrj
378238fd1498Szrj #define GEN_INT(N) gen_rtx_CONST_INT (VOIDmode, (N))
378338fd1498Szrj
378438fd1498Szrj /* Virtual registers are used during RTL generation to refer to locations into
378538fd1498Szrj the stack frame when the actual location isn't known until RTL generation
378638fd1498Szrj is complete. The routine instantiate_virtual_regs replaces these with
378738fd1498Szrj the proper value, which is normally {frame,arg,stack}_pointer_rtx plus
378838fd1498Szrj a constant. */
378938fd1498Szrj
379038fd1498Szrj #define FIRST_VIRTUAL_REGISTER (FIRST_PSEUDO_REGISTER)
379138fd1498Szrj
379238fd1498Szrj /* This points to the first word of the incoming arguments passed on the stack,
379338fd1498Szrj either by the caller or by the callee when pretending it was passed by the
379438fd1498Szrj caller. */
379538fd1498Szrj
379638fd1498Szrj #define virtual_incoming_args_rtx (global_rtl[GR_VIRTUAL_INCOMING_ARGS])
379738fd1498Szrj
379838fd1498Szrj #define VIRTUAL_INCOMING_ARGS_REGNUM (FIRST_VIRTUAL_REGISTER)
379938fd1498Szrj
380038fd1498Szrj /* If FRAME_GROWS_DOWNWARD, this points to immediately above the first
380138fd1498Szrj variable on the stack. Otherwise, it points to the first variable on
380238fd1498Szrj the stack. */
380338fd1498Szrj
380438fd1498Szrj #define virtual_stack_vars_rtx (global_rtl[GR_VIRTUAL_STACK_ARGS])
380538fd1498Szrj
380638fd1498Szrj #define VIRTUAL_STACK_VARS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 1)
380738fd1498Szrj
380838fd1498Szrj /* This points to the location of dynamically-allocated memory on the stack
380938fd1498Szrj immediately after the stack pointer has been adjusted by the amount
381038fd1498Szrj desired. */
381138fd1498Szrj
381238fd1498Szrj #define virtual_stack_dynamic_rtx (global_rtl[GR_VIRTUAL_STACK_DYNAMIC])
381338fd1498Szrj
381438fd1498Szrj #define VIRTUAL_STACK_DYNAMIC_REGNUM ((FIRST_VIRTUAL_REGISTER) + 2)
381538fd1498Szrj
381638fd1498Szrj /* This points to the location in the stack at which outgoing arguments should
381738fd1498Szrj be written when the stack is pre-pushed (arguments pushed using push
381838fd1498Szrj insns always use sp). */
381938fd1498Szrj
382038fd1498Szrj #define virtual_outgoing_args_rtx (global_rtl[GR_VIRTUAL_OUTGOING_ARGS])
382138fd1498Szrj
382238fd1498Szrj #define VIRTUAL_OUTGOING_ARGS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 3)
382338fd1498Szrj
382438fd1498Szrj /* This points to the Canonical Frame Address of the function. This
382538fd1498Szrj should correspond to the CFA produced by INCOMING_FRAME_SP_OFFSET,
382638fd1498Szrj but is calculated relative to the arg pointer for simplicity; the
382738fd1498Szrj frame pointer nor stack pointer are necessarily fixed relative to
382838fd1498Szrj the CFA until after reload. */
382938fd1498Szrj
383038fd1498Szrj #define virtual_cfa_rtx (global_rtl[GR_VIRTUAL_CFA])
383138fd1498Szrj
383238fd1498Szrj #define VIRTUAL_CFA_REGNUM ((FIRST_VIRTUAL_REGISTER) + 4)
383338fd1498Szrj
383438fd1498Szrj #define LAST_VIRTUAL_POINTER_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4)
383538fd1498Szrj
383638fd1498Szrj /* This is replaced by crtl->preferred_stack_boundary / BITS_PER_UNIT
383738fd1498Szrj when finalized. */
383838fd1498Szrj
383938fd1498Szrj #define virtual_preferred_stack_boundary_rtx \
384038fd1498Szrj (global_rtl[GR_VIRTUAL_PREFERRED_STACK_BOUNDARY])
384138fd1498Szrj
384238fd1498Szrj #define VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM \
384338fd1498Szrj ((FIRST_VIRTUAL_REGISTER) + 5)
384438fd1498Szrj
384538fd1498Szrj #define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 5)
384638fd1498Szrj
384738fd1498Szrj /* Nonzero if REGNUM is a pointer into the stack frame. */
384838fd1498Szrj #define REGNO_PTR_FRAME_P(REGNUM) \
384938fd1498Szrj ((REGNUM) == STACK_POINTER_REGNUM \
385038fd1498Szrj || (REGNUM) == FRAME_POINTER_REGNUM \
385138fd1498Szrj || (REGNUM) == HARD_FRAME_POINTER_REGNUM \
385238fd1498Szrj || (REGNUM) == ARG_POINTER_REGNUM \
385338fd1498Szrj || ((REGNUM) >= FIRST_VIRTUAL_REGISTER \
385438fd1498Szrj && (REGNUM) <= LAST_VIRTUAL_POINTER_REGISTER))
385538fd1498Szrj
385638fd1498Szrj /* REGNUM never really appearing in the INSN stream. */
385738fd1498Szrj #define INVALID_REGNUM (~(unsigned int) 0)
385838fd1498Szrj
385938fd1498Szrj /* REGNUM for which no debug information can be generated. */
386038fd1498Szrj #define IGNORED_DWARF_REGNUM (INVALID_REGNUM - 1)
386138fd1498Szrj
386238fd1498Szrj extern rtx output_constant_def (tree, int);
386338fd1498Szrj extern rtx lookup_constant_def (tree);
386438fd1498Szrj
386538fd1498Szrj /* Nonzero after end of reload pass.
386638fd1498Szrj Set to 1 or 0 by reload1.c. */
386738fd1498Szrj
386838fd1498Szrj extern int reload_completed;
386938fd1498Szrj
387038fd1498Szrj /* Nonzero after thread_prologue_and_epilogue_insns has run. */
387138fd1498Szrj extern int epilogue_completed;
387238fd1498Szrj
387338fd1498Szrj /* Set to 1 while reload_as_needed is operating.
387438fd1498Szrj Required by some machines to handle any generated moves differently. */
387538fd1498Szrj
387638fd1498Szrj extern int reload_in_progress;
387738fd1498Szrj
387838fd1498Szrj /* Set to 1 while in lra. */
387938fd1498Szrj extern int lra_in_progress;
388038fd1498Szrj
388138fd1498Szrj /* This macro indicates whether you may create a new
388238fd1498Szrj pseudo-register. */
388338fd1498Szrj
388438fd1498Szrj #define can_create_pseudo_p() (!reload_in_progress && !reload_completed)
388538fd1498Szrj
388638fd1498Szrj #ifdef STACK_REGS
388738fd1498Szrj /* Nonzero after end of regstack pass.
388838fd1498Szrj Set to 1 or 0 by reg-stack.c. */
388938fd1498Szrj extern int regstack_completed;
389038fd1498Szrj #endif
389138fd1498Szrj
389238fd1498Szrj /* If this is nonzero, we do not bother generating VOLATILE
389338fd1498Szrj around volatile memory references, and we are willing to
389438fd1498Szrj output indirect addresses. If cse is to follow, we reject
389538fd1498Szrj indirect addresses so a useful potential cse is generated;
389638fd1498Szrj if it is used only once, instruction combination will produce
389738fd1498Szrj the same indirect address eventually. */
389838fd1498Szrj extern int cse_not_expected;
389938fd1498Szrj
390038fd1498Szrj /* Translates rtx code to tree code, for those codes needed by
390138fd1498Szrj real_arithmetic. The function returns an int because the caller may not
390238fd1498Szrj know what `enum tree_code' means. */
390338fd1498Szrj
390438fd1498Szrj extern int rtx_to_tree_code (enum rtx_code);
390538fd1498Szrj
390638fd1498Szrj /* In cse.c */
390738fd1498Szrj extern int delete_trivially_dead_insns (rtx_insn *, int);
390838fd1498Szrj extern int exp_equiv_p (const_rtx, const_rtx, int, bool);
390938fd1498Szrj extern unsigned hash_rtx (const_rtx x, machine_mode, int *, int *, bool);
391038fd1498Szrj
391138fd1498Szrj /* In dse.c */
391238fd1498Szrj extern bool check_for_inc_dec (rtx_insn *insn);
391338fd1498Szrj
391438fd1498Szrj /* In jump.c */
391538fd1498Szrj extern int comparison_dominates_p (enum rtx_code, enum rtx_code);
391638fd1498Szrj extern bool jump_to_label_p (const rtx_insn *);
391738fd1498Szrj extern int condjump_p (const rtx_insn *);
391838fd1498Szrj extern int any_condjump_p (const rtx_insn *);
391938fd1498Szrj extern int any_uncondjump_p (const rtx_insn *);
392038fd1498Szrj extern rtx pc_set (const rtx_insn *);
392138fd1498Szrj extern rtx condjump_label (const rtx_insn *);
392238fd1498Szrj extern int simplejump_p (const rtx_insn *);
392338fd1498Szrj extern int returnjump_p (const rtx_insn *);
392438fd1498Szrj extern int eh_returnjump_p (rtx_insn *);
392538fd1498Szrj extern int onlyjump_p (const rtx_insn *);
392638fd1498Szrj extern int only_sets_cc0_p (const_rtx);
392738fd1498Szrj extern int sets_cc0_p (const_rtx);
392838fd1498Szrj extern int invert_jump_1 (rtx_jump_insn *, rtx);
392938fd1498Szrj extern int invert_jump (rtx_jump_insn *, rtx, int);
393038fd1498Szrj extern int rtx_renumbered_equal_p (const_rtx, const_rtx);
393138fd1498Szrj extern int true_regnum (const_rtx);
393238fd1498Szrj extern unsigned int reg_or_subregno (const_rtx);
393338fd1498Szrj extern int redirect_jump_1 (rtx_insn *, rtx);
393438fd1498Szrj extern void redirect_jump_2 (rtx_jump_insn *, rtx, rtx, int, int);
393538fd1498Szrj extern int redirect_jump (rtx_jump_insn *, rtx, int);
393638fd1498Szrj extern void rebuild_jump_labels (rtx_insn *);
393738fd1498Szrj extern void rebuild_jump_labels_chain (rtx_insn *);
393838fd1498Szrj extern rtx reversed_comparison (const_rtx, machine_mode);
393938fd1498Szrj extern enum rtx_code reversed_comparison_code (const_rtx, const rtx_insn *);
394038fd1498Szrj extern enum rtx_code reversed_comparison_code_parts (enum rtx_code, const_rtx,
394138fd1498Szrj const_rtx, const rtx_insn *);
394238fd1498Szrj extern void delete_for_peephole (rtx_insn *, rtx_insn *);
394338fd1498Szrj extern int condjump_in_parallel_p (const rtx_insn *);
394438fd1498Szrj
394538fd1498Szrj /* In emit-rtl.c. */
394638fd1498Szrj extern int max_reg_num (void);
394738fd1498Szrj extern int max_label_num (void);
394838fd1498Szrj extern int get_first_label_num (void);
394938fd1498Szrj extern void maybe_set_first_label_num (rtx_code_label *);
395038fd1498Szrj extern void delete_insns_since (rtx_insn *);
395138fd1498Szrj extern void mark_reg_pointer (rtx, int);
395238fd1498Szrj extern void mark_user_reg (rtx);
395338fd1498Szrj extern void reset_used_flags (rtx);
395438fd1498Szrj extern void set_used_flags (rtx);
395538fd1498Szrj extern void reorder_insns (rtx_insn *, rtx_insn *, rtx_insn *);
395638fd1498Szrj extern void reorder_insns_nobb (rtx_insn *, rtx_insn *, rtx_insn *);
395738fd1498Szrj extern int get_max_insn_count (void);
395838fd1498Szrj extern int in_sequence_p (void);
395938fd1498Szrj extern void init_emit (void);
396038fd1498Szrj extern void init_emit_regs (void);
396138fd1498Szrj extern void init_derived_machine_modes (void);
396238fd1498Szrj extern void init_emit_once (void);
396338fd1498Szrj extern void push_topmost_sequence (void);
396438fd1498Szrj extern void pop_topmost_sequence (void);
396538fd1498Szrj extern void set_new_first_and_last_insn (rtx_insn *, rtx_insn *);
396638fd1498Szrj extern unsigned int unshare_all_rtl (void);
396738fd1498Szrj extern void unshare_all_rtl_again (rtx_insn *);
396838fd1498Szrj extern void unshare_all_rtl_in_chain (rtx_insn *);
396938fd1498Szrj extern void verify_rtl_sharing (void);
397038fd1498Szrj extern void add_insn (rtx_insn *);
397138fd1498Szrj extern void add_insn_before (rtx, rtx, basic_block);
397238fd1498Szrj extern void add_insn_after (rtx, rtx, basic_block);
397338fd1498Szrj extern void remove_insn (rtx);
397438fd1498Szrj extern rtx_insn *emit (rtx, bool = true);
397538fd1498Szrj extern void emit_insn_at_entry (rtx);
397638fd1498Szrj extern rtx gen_lowpart_SUBREG (machine_mode, rtx);
397738fd1498Szrj extern rtx gen_const_mem (machine_mode, rtx);
397838fd1498Szrj extern rtx gen_frame_mem (machine_mode, rtx);
397938fd1498Szrj extern rtx gen_tmp_stack_mem (machine_mode, rtx);
398038fd1498Szrj extern bool validate_subreg (machine_mode, machine_mode,
398138fd1498Szrj const_rtx, poly_uint64);
398238fd1498Szrj
398338fd1498Szrj /* In combine.c */
398438fd1498Szrj extern unsigned int extended_count (const_rtx, machine_mode, int);
398538fd1498Szrj extern rtx remove_death (unsigned int, rtx_insn *);
398638fd1498Szrj extern void dump_combine_stats (FILE *);
398738fd1498Szrj extern void dump_combine_total_stats (FILE *);
398838fd1498Szrj extern rtx make_compound_operation (rtx, enum rtx_code);
398938fd1498Szrj
399038fd1498Szrj /* In sched-rgn.c. */
399138fd1498Szrj extern void schedule_insns (void);
399238fd1498Szrj
399338fd1498Szrj /* In sched-ebb.c. */
399438fd1498Szrj extern void schedule_ebbs (void);
399538fd1498Szrj
399638fd1498Szrj /* In sel-sched-dump.c. */
399738fd1498Szrj extern void sel_sched_fix_param (const char *param, const char *val);
399838fd1498Szrj
399938fd1498Szrj /* In print-rtl.c */
400038fd1498Szrj extern const char *print_rtx_head;
400138fd1498Szrj extern void debug (const rtx_def &ref);
400238fd1498Szrj extern void debug (const rtx_def *ptr);
400338fd1498Szrj extern void debug_rtx (const_rtx);
400438fd1498Szrj extern void debug_rtx_list (const rtx_insn *, int);
400538fd1498Szrj extern void debug_rtx_range (const rtx_insn *, const rtx_insn *);
400638fd1498Szrj extern const rtx_insn *debug_rtx_find (const rtx_insn *, int);
400738fd1498Szrj extern void print_mem_expr (FILE *, const_tree);
400838fd1498Szrj extern void print_rtl (FILE *, const_rtx);
400938fd1498Szrj extern void print_simple_rtl (FILE *, const_rtx);
401038fd1498Szrj extern int print_rtl_single (FILE *, const_rtx);
401138fd1498Szrj extern int print_rtl_single_with_indent (FILE *, const_rtx, int);
401238fd1498Szrj extern void print_inline_rtx (FILE *, const_rtx, int);
401338fd1498Szrj
401438fd1498Szrj /* In stmt.c */
401538fd1498Szrj extern void expand_null_return (void);
401638fd1498Szrj extern void expand_naked_return (void);
401738fd1498Szrj extern void emit_jump (rtx);
401838fd1498Szrj
401938fd1498Szrj /* In expr.c */
402038fd1498Szrj extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
402138fd1498Szrj unsigned int, int);
402238fd1498Szrj extern poly_int64 find_args_size_adjust (rtx_insn *);
402338fd1498Szrj extern poly_int64 fixup_args_size_notes (rtx_insn *, rtx_insn *, poly_int64);
402438fd1498Szrj
402538fd1498Szrj /* In expmed.c */
402638fd1498Szrj extern void init_expmed (void);
402738fd1498Szrj extern void expand_inc (rtx, rtx);
402838fd1498Szrj extern void expand_dec (rtx, rtx);
402938fd1498Szrj
403038fd1498Szrj /* In lower-subreg.c */
403138fd1498Szrj extern void init_lower_subreg (void);
403238fd1498Szrj
403338fd1498Szrj /* In gcse.c */
403438fd1498Szrj extern bool can_copy_p (machine_mode);
403538fd1498Szrj extern bool can_assign_to_reg_without_clobbers_p (rtx, machine_mode);
403658e805e6Szrj extern rtx_insn *prepare_copy_insn (rtx, rtx);
403758e805e6Szrj
403858e805e6Szrj /* In cprop.c */
403938fd1498Szrj extern rtx fis_get_condition (rtx_insn *);
404038fd1498Szrj
404138fd1498Szrj /* In ira.c */
404238fd1498Szrj extern HARD_REG_SET eliminable_regset;
404338fd1498Szrj extern void mark_elimination (int, int);
404438fd1498Szrj
404538fd1498Szrj /* In reginfo.c */
404638fd1498Szrj extern int reg_classes_intersect_p (reg_class_t, reg_class_t);
404738fd1498Szrj extern int reg_class_subset_p (reg_class_t, reg_class_t);
404838fd1498Szrj extern void globalize_reg (tree, int);
404938fd1498Szrj extern void init_reg_modes_target (void);
405038fd1498Szrj extern void init_regs (void);
405138fd1498Szrj extern void reinit_regs (void);
405238fd1498Szrj extern void init_fake_stack_mems (void);
405338fd1498Szrj extern void save_register_info (void);
405438fd1498Szrj extern void init_reg_sets (void);
405538fd1498Szrj extern void regclass (rtx, int);
405638fd1498Szrj extern void reg_scan (rtx_insn *, unsigned int);
405738fd1498Szrj extern void fix_register (const char *, int, int);
405838fd1498Szrj extern const HARD_REG_SET *valid_mode_changes_for_regno (unsigned int);
405938fd1498Szrj
406038fd1498Szrj /* In reload1.c */
406138fd1498Szrj extern int function_invariant_p (const_rtx);
406238fd1498Szrj
406338fd1498Szrj /* In calls.c */
406438fd1498Szrj enum libcall_type
406538fd1498Szrj {
406638fd1498Szrj LCT_NORMAL = 0,
406738fd1498Szrj LCT_CONST = 1,
406838fd1498Szrj LCT_PURE = 2,
406938fd1498Szrj LCT_NORETURN = 3,
407038fd1498Szrj LCT_THROW = 4,
407138fd1498Szrj LCT_RETURNS_TWICE = 5
407238fd1498Szrj };
407338fd1498Szrj
407438fd1498Szrj extern rtx emit_library_call_value_1 (int, rtx, rtx, enum libcall_type,
407538fd1498Szrj machine_mode, int, rtx_mode_t *);
407638fd1498Szrj
407738fd1498Szrj /* Output a library call and discard the returned value. FUN is the
407838fd1498Szrj address of the function, as a SYMBOL_REF rtx, and OUTMODE is the mode
407938fd1498Szrj of the (discarded) return value. FN_TYPE is LCT_NORMAL for `normal'
408038fd1498Szrj calls, LCT_CONST for `const' calls, LCT_PURE for `pure' calls, or
408138fd1498Szrj another LCT_ value for other types of library calls.
408238fd1498Szrj
408338fd1498Szrj There are different overloads of this function for different numbers
408438fd1498Szrj of arguments. In each case the argument value is followed by its mode. */
408538fd1498Szrj
408638fd1498Szrj inline void
408738fd1498Szrj emit_library_call (rtx fun, libcall_type fn_type, machine_mode outmode)
408838fd1498Szrj {
408938fd1498Szrj emit_library_call_value_1 (0, fun, NULL_RTX, fn_type, outmode, 0, NULL);
409038fd1498Szrj }
409138fd1498Szrj
409238fd1498Szrj inline void
409338fd1498Szrj emit_library_call (rtx fun, libcall_type fn_type, machine_mode outmode,
409438fd1498Szrj rtx arg1, machine_mode arg1_mode)
409538fd1498Szrj {
409638fd1498Szrj rtx_mode_t args[] = { rtx_mode_t (arg1, arg1_mode) };
409738fd1498Szrj emit_library_call_value_1 (0, fun, NULL_RTX, fn_type, outmode, 1, args);
409838fd1498Szrj }
409938fd1498Szrj
410038fd1498Szrj inline void
410138fd1498Szrj emit_library_call (rtx fun, libcall_type fn_type, machine_mode outmode,
410238fd1498Szrj rtx arg1, machine_mode arg1_mode,
410338fd1498Szrj rtx arg2, machine_mode arg2_mode)
410438fd1498Szrj {
410538fd1498Szrj rtx_mode_t args[] = {
410638fd1498Szrj rtx_mode_t (arg1, arg1_mode),
410738fd1498Szrj rtx_mode_t (arg2, arg2_mode)
410838fd1498Szrj };
410938fd1498Szrj emit_library_call_value_1 (0, fun, NULL_RTX, fn_type, outmode, 2, args);
411038fd1498Szrj }
411138fd1498Szrj
411238fd1498Szrj inline void
411338fd1498Szrj emit_library_call (rtx fun, libcall_type fn_type, machine_mode outmode,
411438fd1498Szrj rtx arg1, machine_mode arg1_mode,
411538fd1498Szrj rtx arg2, machine_mode arg2_mode,
411638fd1498Szrj rtx arg3, machine_mode arg3_mode)
411738fd1498Szrj {
411838fd1498Szrj rtx_mode_t args[] = {
411938fd1498Szrj rtx_mode_t (arg1, arg1_mode),
412038fd1498Szrj rtx_mode_t (arg2, arg2_mode),
412138fd1498Szrj rtx_mode_t (arg3, arg3_mode)
412238fd1498Szrj };
412338fd1498Szrj emit_library_call_value_1 (0, fun, NULL_RTX, fn_type, outmode, 3, args);
412438fd1498Szrj }
412538fd1498Szrj
412638fd1498Szrj inline void
412738fd1498Szrj emit_library_call (rtx fun, libcall_type fn_type, machine_mode outmode,
412838fd1498Szrj rtx arg1, machine_mode arg1_mode,
412938fd1498Szrj rtx arg2, machine_mode arg2_mode,
413038fd1498Szrj rtx arg3, machine_mode arg3_mode,
413138fd1498Szrj rtx arg4, machine_mode arg4_mode)
413238fd1498Szrj {
413338fd1498Szrj rtx_mode_t args[] = {
413438fd1498Szrj rtx_mode_t (arg1, arg1_mode),
413538fd1498Szrj rtx_mode_t (arg2, arg2_mode),
413638fd1498Szrj rtx_mode_t (arg3, arg3_mode),
413738fd1498Szrj rtx_mode_t (arg4, arg4_mode)
413838fd1498Szrj };
413938fd1498Szrj emit_library_call_value_1 (0, fun, NULL_RTX, fn_type, outmode, 4, args);
414038fd1498Szrj }
414138fd1498Szrj
414238fd1498Szrj /* Like emit_library_call, but return the value produced by the call.
414338fd1498Szrj Use VALUE to store the result if it is nonnull, otherwise pick a
414438fd1498Szrj convenient location. */
414538fd1498Szrj
414638fd1498Szrj inline rtx
414738fd1498Szrj emit_library_call_value (rtx fun, rtx value, libcall_type fn_type,
414838fd1498Szrj machine_mode outmode)
414938fd1498Szrj {
415038fd1498Szrj return emit_library_call_value_1 (1, fun, value, fn_type, outmode, 0, NULL);
415138fd1498Szrj }
415238fd1498Szrj
415338fd1498Szrj inline rtx
415438fd1498Szrj emit_library_call_value (rtx fun, rtx value, libcall_type fn_type,
415538fd1498Szrj machine_mode outmode,
415638fd1498Szrj rtx arg1, machine_mode arg1_mode)
415738fd1498Szrj {
415838fd1498Szrj rtx_mode_t args[] = { rtx_mode_t (arg1, arg1_mode) };
415938fd1498Szrj return emit_library_call_value_1 (1, fun, value, fn_type, outmode, 1, args);
416038fd1498Szrj }
416138fd1498Szrj
416238fd1498Szrj inline rtx
416338fd1498Szrj emit_library_call_value (rtx fun, rtx value, libcall_type fn_type,
416438fd1498Szrj machine_mode outmode,
416538fd1498Szrj rtx arg1, machine_mode arg1_mode,
416638fd1498Szrj rtx arg2, machine_mode arg2_mode)
416738fd1498Szrj {
416838fd1498Szrj rtx_mode_t args[] = {
416938fd1498Szrj rtx_mode_t (arg1, arg1_mode),
417038fd1498Szrj rtx_mode_t (arg2, arg2_mode)
417138fd1498Szrj };
417238fd1498Szrj return emit_library_call_value_1 (1, fun, value, fn_type, outmode, 2, args);
417338fd1498Szrj }
417438fd1498Szrj
417538fd1498Szrj inline rtx
417638fd1498Szrj emit_library_call_value (rtx fun, rtx value, libcall_type fn_type,
417738fd1498Szrj machine_mode outmode,
417838fd1498Szrj rtx arg1, machine_mode arg1_mode,
417938fd1498Szrj rtx arg2, machine_mode arg2_mode,
418038fd1498Szrj rtx arg3, machine_mode arg3_mode)
418138fd1498Szrj {
418238fd1498Szrj rtx_mode_t args[] = {
418338fd1498Szrj rtx_mode_t (arg1, arg1_mode),
418438fd1498Szrj rtx_mode_t (arg2, arg2_mode),
418538fd1498Szrj rtx_mode_t (arg3, arg3_mode)
418638fd1498Szrj };
418738fd1498Szrj return emit_library_call_value_1 (1, fun, value, fn_type, outmode, 3, args);
418838fd1498Szrj }
418938fd1498Szrj
419038fd1498Szrj inline rtx
419138fd1498Szrj emit_library_call_value (rtx fun, rtx value, libcall_type fn_type,
419238fd1498Szrj machine_mode outmode,
419338fd1498Szrj rtx arg1, machine_mode arg1_mode,
419438fd1498Szrj rtx arg2, machine_mode arg2_mode,
419538fd1498Szrj rtx arg3, machine_mode arg3_mode,
419638fd1498Szrj rtx arg4, machine_mode arg4_mode)
419738fd1498Szrj {
419838fd1498Szrj rtx_mode_t args[] = {
419938fd1498Szrj rtx_mode_t (arg1, arg1_mode),
420038fd1498Szrj rtx_mode_t (arg2, arg2_mode),
420138fd1498Szrj rtx_mode_t (arg3, arg3_mode),
420238fd1498Szrj rtx_mode_t (arg4, arg4_mode)
420338fd1498Szrj };
420438fd1498Szrj return emit_library_call_value_1 (1, fun, value, fn_type, outmode, 4, args);
420538fd1498Szrj }
420638fd1498Szrj
420738fd1498Szrj /* In varasm.c */
420838fd1498Szrj extern void init_varasm_once (void);
420938fd1498Szrj
421038fd1498Szrj extern rtx make_debug_expr_from_rtl (const_rtx);
421138fd1498Szrj
421238fd1498Szrj /* In read-rtl.c */
421338fd1498Szrj #ifdef GENERATOR_FILE
421438fd1498Szrj extern bool read_rtx (const char *, vec<rtx> *);
421538fd1498Szrj #endif
421638fd1498Szrj
421738fd1498Szrj /* In alias.c */
421838fd1498Szrj extern rtx canon_rtx (rtx);
421938fd1498Szrj extern int true_dependence (const_rtx, machine_mode, const_rtx);
422038fd1498Szrj extern rtx get_addr (rtx);
422138fd1498Szrj extern int canon_true_dependence (const_rtx, machine_mode, rtx,
422238fd1498Szrj const_rtx, rtx);
422338fd1498Szrj extern int read_dependence (const_rtx, const_rtx);
422438fd1498Szrj extern int anti_dependence (const_rtx, const_rtx);
422538fd1498Szrj extern int canon_anti_dependence (const_rtx, bool,
422638fd1498Szrj const_rtx, machine_mode, rtx);
422738fd1498Szrj extern int output_dependence (const_rtx, const_rtx);
422838fd1498Szrj extern int canon_output_dependence (const_rtx, bool,
422938fd1498Szrj const_rtx, machine_mode, rtx);
423038fd1498Szrj extern int may_alias_p (const_rtx, const_rtx);
423138fd1498Szrj extern void init_alias_target (void);
423238fd1498Szrj extern void init_alias_analysis (void);
423338fd1498Szrj extern void end_alias_analysis (void);
423438fd1498Szrj extern void vt_equate_reg_base_value (const_rtx, const_rtx);
423538fd1498Szrj extern bool memory_modified_in_insn_p (const_rtx, const_rtx);
423638fd1498Szrj extern bool may_be_sp_based_p (rtx);
423738fd1498Szrj extern rtx gen_hard_reg_clobber (machine_mode, unsigned int);
423838fd1498Szrj extern rtx get_reg_known_value (unsigned int);
423938fd1498Szrj extern bool get_reg_known_equiv_p (unsigned int);
424038fd1498Szrj extern rtx get_reg_base_value (unsigned int);
424138fd1498Szrj
424238fd1498Szrj #ifdef STACK_REGS
424338fd1498Szrj extern int stack_regs_mentioned (const_rtx insn);
424438fd1498Szrj #endif
424538fd1498Szrj
424638fd1498Szrj /* In toplev.c */
424738fd1498Szrj extern GTY(()) rtx stack_limit_rtx;
424838fd1498Szrj
424938fd1498Szrj /* In var-tracking.c */
425038fd1498Szrj extern unsigned int variable_tracking_main (void);
425138fd1498Szrj extern void delete_vta_debug_insns (bool);
425238fd1498Szrj
425338fd1498Szrj /* In stor-layout.c. */
425438fd1498Szrj extern void get_mode_bounds (scalar_int_mode, int,
425538fd1498Szrj scalar_int_mode, rtx *, rtx *);
425638fd1498Szrj
425738fd1498Szrj /* In loop-iv.c */
425838fd1498Szrj extern rtx canon_condition (rtx);
425938fd1498Szrj extern void simplify_using_condition (rtx, rtx *, bitmap);
426038fd1498Szrj
426138fd1498Szrj /* In final.c */
426238fd1498Szrj extern unsigned int compute_alignments (void);
426338fd1498Szrj extern void update_alignments (vec<rtx> &);
426438fd1498Szrj extern int asm_str_count (const char *templ);
426538fd1498Szrj
426638fd1498Szrj struct rtl_hooks
426738fd1498Szrj {
426838fd1498Szrj rtx (*gen_lowpart) (machine_mode, rtx);
426938fd1498Szrj rtx (*gen_lowpart_no_emit) (machine_mode, rtx);
427038fd1498Szrj rtx (*reg_nonzero_bits) (const_rtx, scalar_int_mode, scalar_int_mode,
427138fd1498Szrj unsigned HOST_WIDE_INT *);
427238fd1498Szrj rtx (*reg_num_sign_bit_copies) (const_rtx, scalar_int_mode, scalar_int_mode,
427338fd1498Szrj unsigned int *);
427438fd1498Szrj bool (*reg_truncated_to_mode) (machine_mode, const_rtx);
427538fd1498Szrj
427638fd1498Szrj /* Whenever you add entries here, make sure you adjust rtlhooks-def.h. */
427738fd1498Szrj };
427838fd1498Szrj
427938fd1498Szrj /* Each pass can provide its own. */
428038fd1498Szrj extern struct rtl_hooks rtl_hooks;
428138fd1498Szrj
428238fd1498Szrj /* ... but then it has to restore these. */
428338fd1498Szrj extern const struct rtl_hooks general_rtl_hooks;
428438fd1498Szrj
428538fd1498Szrj /* Keep this for the nonce. */
428638fd1498Szrj #define gen_lowpart rtl_hooks.gen_lowpart
428738fd1498Szrj
428838fd1498Szrj extern void insn_locations_init (void);
428938fd1498Szrj extern void insn_locations_finalize (void);
429038fd1498Szrj extern void set_curr_insn_location (location_t);
429138fd1498Szrj extern location_t curr_insn_location (void);
429238fd1498Szrj
429338fd1498Szrj /* rtl-error.c */
429438fd1498Szrj extern void _fatal_insn_not_found (const_rtx, const char *, int, const char *)
429538fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
429638fd1498Szrj extern void _fatal_insn (const char *, const_rtx, const char *, int, const char *)
429738fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
429838fd1498Szrj
429938fd1498Szrj #define fatal_insn(msgid, insn) \
430038fd1498Szrj _fatal_insn (msgid, insn, __FILE__, __LINE__, __FUNCTION__)
430138fd1498Szrj #define fatal_insn_not_found(insn) \
430238fd1498Szrj _fatal_insn_not_found (insn, __FILE__, __LINE__, __FUNCTION__)
430338fd1498Szrj
430438fd1498Szrj /* reginfo.c */
430538fd1498Szrj extern tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
430638fd1498Szrj
430738fd1498Szrj /* Information about the function that is propagated by the RTL backend.
430838fd1498Szrj Available only for functions that has been already assembled. */
430938fd1498Szrj
431038fd1498Szrj struct GTY(()) cgraph_rtl_info {
431138fd1498Szrj unsigned int preferred_incoming_stack_boundary;
431238fd1498Szrj
431338fd1498Szrj /* Call unsaved hard registers really used by the corresponding
431438fd1498Szrj function (including ones used by functions called by the
431538fd1498Szrj function). */
431638fd1498Szrj HARD_REG_SET function_used_regs;
431738fd1498Szrj /* Set if function_used_regs is valid. */
431838fd1498Szrj unsigned function_used_regs_valid: 1;
431938fd1498Szrj };
432038fd1498Szrj
432138fd1498Szrj /* If loads from memories of mode MODE always sign or zero extend,
432238fd1498Szrj return SIGN_EXTEND or ZERO_EXTEND as appropriate. Return UNKNOWN
432338fd1498Szrj otherwise. */
432438fd1498Szrj
432538fd1498Szrj inline rtx_code
432638fd1498Szrj load_extend_op (machine_mode mode)
432738fd1498Szrj {
432838fd1498Szrj scalar_int_mode int_mode;
432938fd1498Szrj if (is_a <scalar_int_mode> (mode, &int_mode)
433038fd1498Szrj && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
433138fd1498Szrj return LOAD_EXTEND_OP (int_mode);
433238fd1498Szrj return UNKNOWN;
433338fd1498Szrj }
433438fd1498Szrj
433538fd1498Szrj /* If X is a PLUS of a base and a constant offset, add the constant to *OFFSET
433638fd1498Szrj and return the base. Return X otherwise. */
433738fd1498Szrj
433838fd1498Szrj inline rtx
433938fd1498Szrj strip_offset_and_add (rtx x, poly_int64_pod *offset)
434038fd1498Szrj {
434138fd1498Szrj if (GET_CODE (x) == PLUS)
434238fd1498Szrj {
434338fd1498Szrj poly_int64 suboffset;
434438fd1498Szrj x = strip_offset (x, &suboffset);
434538fd1498Szrj *offset = poly_uint64 (*offset) + suboffset;
434638fd1498Szrj }
434738fd1498Szrj return x;
434838fd1498Szrj }
434938fd1498Szrj
435058e805e6Szrj /* Return true if X is an operation that always operates on the full
435158e805e6Szrj registers for WORD_REGISTER_OPERATIONS architectures. */
435258e805e6Szrj
435358e805e6Szrj inline bool
435458e805e6Szrj word_register_operation_p (const_rtx x)
435558e805e6Szrj {
435658e805e6Szrj switch (GET_CODE (x))
435758e805e6Szrj {
4358*e215fc28Szrj case CONST_INT:
435958e805e6Szrj case ROTATE:
436058e805e6Szrj case ROTATERT:
436158e805e6Szrj case SIGN_EXTRACT:
436258e805e6Szrj case ZERO_EXTRACT:
436358e805e6Szrj return false;
436458e805e6Szrj
436558e805e6Szrj default:
436658e805e6Szrj return true;
436758e805e6Szrj }
436858e805e6Szrj }
436958e805e6Szrj
437038fd1498Szrj /* gtype-desc.c. */
437138fd1498Szrj extern void gt_ggc_mx (rtx &);
437238fd1498Szrj extern void gt_pch_nx (rtx &);
437338fd1498Szrj extern void gt_pch_nx (rtx &, gt_pointer_operator, void *);
437438fd1498Szrj
437538fd1498Szrj #endif /* ! GCC_RTL_H */
4376