E is after the ADDR_DIFF_VEC.  */
  unsigned min_after_vec: 1;  /* minimum address target label is
				 after the ADDR_DIFF_VEC.  */
  unsigned max_after_vec: 1;  /* maximum address target label is
				 after the ADDR_DIFF_VEC.  */
  unsigned min_after_base: 1; /* minimum address target label is
				 after BASE.  */
  unsigned max_after_base: 1; /* maximum address target label is
				 after BASE.  */
  /* Set by the actual branch shortening process - ONLY WHEN OPTIMIZING - : */
  unsigned offset_unsigned: 1; /* offsets have to be treated as unsigned.  */
  unsigned : 2;
  unsigned scale : 8;
};

/* Structure used to describe the attributes of a MEM.  These are hashed
   so MEMs that the same attributes share a data structure.  This means
   they cannot be modified in place.  */
class GTY(()) mem_attrs
{
public:
  mem_attrs ();

  /* The expression that the MEM accesses, or null if not known.
     This expression might be larger than the memory reference itself.
     (In other words, the MEM might access only part of the object.)  */
  tree expr;

  /* The offset of the memory reference from the start of EXPR.
     Only valid if OFFSET_KNOWN_P.  */
  poly_int64 offset;

  /* The size of the memory reference in bytes.  Only valid if
     SIZE_KNOWN_P.  */
  poly_int64 size;

  /* The alias set of the memory reference.  */
  alias_set_type alias;

  /* The alignment of the reference in bits.  Always a multiple of
     BITS_PER_UNIT.  Note that EXPR may have a stricter alignment
     than the memory reference itself.  */
  unsigned int align;

  /* The address space that the memory reference uses.  */
  unsigned char addrspace;

  /* True if OFFSET is known.  */
  bool offset_known_p;

  /* True if SIZE is known.  */
  bool size_known_p;
};

/* Structure used to describe the attributes of a REG in similar way as
   mem_attrs does for MEM above.  Note that the OFFSET field is calculated
   in the same way as for mem_attrs, rather than in the same way as a
   SUBREG_BYTE.  For example, if a big-endian target stores a byte
   object in the low part of a 4-byte register, the OFFSET field
   will be -3 rather than 0.  */

class GTY((for_user)) reg_attrs {
public:
  tree decl;			/* decl corresponding to REG.  */
  poly_int64 offset;		/* Offset from start of DECL.  */
};

/* Common union for an element of an rtx.  */

union rtunion
{
  int rt_int;
  unsigned int rt_uint;
  poly_uint16_pod rt_subreg;
  const char *rt_str;
  rtx rt_rtx;
  rtvec rt_rtvec;
  machine_mode rt_type;
  addr_diff_vec_flags rt_addr_diff_vec_flags;
  struct cselib_val *rt_cselib;
  tree rt_tree;
  basic_block rt_bb;
  mem_attrs *rt_mem;
  class constant_descriptor_rtx *rt_constant;
  struct dw_cfi_node *rt_cfi;
};

/* Describes the properties of a REG.  */
struct GTY(()) reg_info {
  /* The value of REGNO.  */
  unsigned int regno;

  /* The value of REG_NREGS.  */
  unsigned int nregs : 8;
  unsigned int unused : 24;

  /* The value of REG_ATTRS.  */
  reg_attrs *attrs;
};

/* This structure remembers the position of a SYMBOL_REF within an
   object_block structure.  A SYMBOL_REF only provides this information
   if SYMBOL_REF_HAS_BLOCK_INFO_P is true.  */
struct GTY(()) block_symbol {
  /* The usual SYMBOL_REF fields.  */
  rtunion GTY ((skip)) fld[2];

  /* The block that contains this object.  */
  struct object_block *block;

  /* The offset of this object from the start of its block.  It is negative
     if the symbol has not yet been assigned an offset.  */
  HOST_WIDE_INT offset;
};

/* Describes a group of objects that are to be placed together in such
   a way that their relative positions are known.  */
struct GTY((for_user)) object_block {
  /* The section in which these objects should be placed.  */
  section *sect;

  /* The alignment of the first object, measured in bits.  */
  unsigned int alignment;

  /* The total size of the objects, measured in bytes.  */
  HOST_WIDE_INT size;

  /* The SYMBOL_REFs for each object.  The vector is sorted in
     order of increasing offset and the following conditions will
     hold for each element X:

	 SYMBOL_REF_HAS_BLOCK_INFO_P (X)
	 !SYMBOL_REF_ANCHOR_P (X)
	 SYMBOL_REF_BLOCK (X) == [address of this structure]
	 SYMBOL_REF_BLOCK_OFFSET (X) >= 0.  */
  vec<rtx, va_gc> *objects;

  /* All the anchor SYMBOL_REFs used to address these objects, sorted
     in order of increasing offset, and then increasing TLS model.
     The following conditions will hold for each element X in this vector:

	 SYMBOL_REF_HAS_BLOCK_INFO_P (X)
	 SYMBOL_REF_ANCHOR_P (X)
	 SYMBOL_REF_BLOCK (X) == [address of this structure]
	 SYMBOL_REF_BLOCK_OFFSET (X) >= 0.  */
  vec<rtx, va_gc> *anchors;
};

struct GTY((variable_size)) hwivec_def {
  HOST_WIDE_INT elem[1];
};

/* Number of elements of the HWIVEC if RTX is a CONST_WIDE_INT.  */
#define CWI_GET_NUM_ELEM(RTX)					\
  ((int)RTL_FLAG_CHECK1("CWI_GET_NUM_ELEM", (RTX), CONST_WIDE_INT)->u2.num_elem)
#define CWI_PUT_NUM_ELEM(RTX, NUM)					\
  (RTL_FLAG_CHECK1("CWI_PUT_NUM_ELEM", (RTX), CONST_WIDE_INT)->u2.num_elem = (NUM))

struct GTY((variable_size)) const_poly_int_def {
  trailing_wide_ints<NUM_POLY_INT_COEFFS> coeffs;
};

/* RTL expression ("rtx").  */

/* The GTY "desc" and "tag" options below are a kludge: we need a desc
   field for gengtype to recognize that inheritance is occurring,
   so that all subclasses are redirected to the traversal hook for the
   base class.
   However, all of the fields are in the base class, and special-casing
   is at work.  Hence we use desc and tag of 0, generating a switch
   statement of the form:
     switch (0)
       {
       case 0: // all the work happens here
      }
   in order to work with the existing special-casing in gengtype.  */

struct GTY((desc("0"), tag("0"),
	    chain_next ("RTX_NEXT (&%h)"),
	    chain_prev ("RTX_PREV (&%h)"))) rtx_def {
  /* The kind of expression this is.  */
  ENUM_BITFIELD(rtx_code) code: 16;

  /* The kind of value the expression has.  */
  ENUM_BITFIELD(machine_mode) mode : 8;

  /* 1 in a MEM if we should keep the alias set for this mem unchanged
     when we access a component.
     1 in a JUMP_INSN if it is a crossing jump.
     1 in a CALL_INSN if it is a sibling call.
     1 in a SET that is for a return.
     In a CODE_LABEL, part of the two-bit alternate entry field.
     1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.cc.
     1 in a VALUE is SP_BASED_VALUE_P in cselib.cc.
     1 in a SUBREG generated by LRA for reload insns.
     1 in a REG if this is a static chain register.
     Dumped as "/j" in RTL dumps.  */
  unsigned int jump : 1;
  /* In a CODE_LABEL, part of the two-bit alternate entry field.
     1 in a MEM if it cannot trap.
     1 in a CALL_INSN logically equivalent to
       ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P.
     1 in a VALUE is SP_DERIVED_VALUE_P in cselib.cc.
     Dumped as "/c" in RTL dumps.  */
  unsigned int call : 1;
  /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
     1 in a SUBREG used for SUBREG_PROMOTED_UNSIGNED_P.
     1 in a SYMBOL_REF if it addresses something in the per-function
     constants pool.
     1 in a CALL_INSN logically equivalent to ECF_CONST and TREE_READONLY.
     1 in a NOTE, or EXPR_LIST for a const call.
     1 in a JUMP_INSN of an annulling branch.
     1 in a CONCAT is VAL_EXPR_IS_CLOBBERED in var-tracking.cc.
     1 in a preserved VALUE is PRESERVED_VALUE_P in cselib.cc.
     1 in a clobber temporarily created for LRA.
     Dumped as "/u" in RTL dumps.  */
  unsigned int unchanging : 1;
  /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile.
     1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE
     if it has been deleted.
     1 in a REG expression if corresponds to a variable declared by the user,
     0 for an internally generated temporary.
     1 in a SUBREG used for SUBREG_PROMOTED_UNSIGNED_P.
     1 in a LABEL_REF, REG_LABEL_TARGET or REG_LABEL_OPERAND note for a
     non-local label.
     In a SYMBOL_REF, this flag is used for machine-specific purposes.
     In a PREFETCH, this flag indicates that it should be considered a
     scheduling barrier.
     1 in a CONCAT is VAL_NEEDS_RESOLUTION in var-tracking.cc.
     Dumped as "/v" in RTL dumps.  */
  unsigned int volatil : 1;
  /* 1 in a REG if the register is used only in exit code a loop.
     1 in a SUBREG expression if was generated from a variable with a
     promoted mode.
     1 in a CODE_LABEL if the label is used for nonlocal gotos
     and must not be deleted even if its count is zero.
     1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled
     together with the preceding insn.  Valid only within sched.
     1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and
     from the target of a branch.  Valid from reorg until end of compilation;
     cleared before used.

     The name of the field is historical.  It used to be used in MEMs
     to record whether the MEM accessed part of a structure.
     Dumped as "/s" in RTL dumps.  */
  unsigned int in_struct : 1;
  /* At the end of RTL generation, 1 if this rtx is used.  This is used for
     copying shared structure.  See `unshare_all_rtl'.
     In a REG, this is not needed for that purpose, and used instead
     in `leaf_renumber_regs_insn'.
     1 in a SYMBOL_REF, means that emit_library_call
     has used it as the function.
     1 in a CONCAT is VAL_HOLDS_TRACK_EXPR in var-tracking.cc.
     1 in a VALUE or DEBUG_EXPR is VALUE_RECURSED_INTO in var-tracking.cc.  */
  unsigned int used : 1;
  /* 1 in an INSN or a SET if this rtx is related to the call frame,
     either changing how we compute the frame address or saving and
     restoring registers in the prologue and epilogue.
     1 in a REG or MEM if it is a pointer.
     1 in a SYMBOL_REF if it addresses something in the per-function
     constant string pool.
     1 in a VALUE is VALUE_CHANGED in var-tracking.cc.
     Dumped as "/f" in RTL dumps.  */
  unsigned frame_related : 1;
  /* 1 in a REG or PARALLEL that is the current function's return value.
     1 in a SYMBOL_REF for a weak symbol.
     1 in a CALL_INSN logically equivalent to ECF_PURE and DECL_PURE_P.
     1 in a CONCAT is VAL_EXPR_HAS_REVERSE in var-tracking.cc.
     1 in a VALUE or DEBUG_EXPR is NO_LOC_P in var-tracking.cc.
     Dumped as "/i" in RTL dumps.  */
  unsigned return_val : 1;

  union {
    /* The final union field is aligned to 64 bits on LP64 hosts,
       giving a 32-bit gap after the fields above.  We optimize the
       layout for that case and use the gap for extra code-specific
       information.  */

    /* The ORIGINAL_REGNO of a REG.  */
    unsigned int original_regno;

    /* The INSN_UID of an RTX_INSN-class code.  */
    int insn_uid;

    /* The SYMBOL_REF_FLAGS of a SYMBOL_REF.  */
    unsigned int symbol_ref_flags;

    /* The PAT_VAR_LOCATION_STATUS of a VAR_LOCATION.  */
    enum var_init_status var_location_status;

    /* In a CONST_WIDE_INT (aka hwivec_def), this is the number of
       HOST_WIDE_INTs in the hwivec_def.  */
    unsigned int num_elem;

    /* Information about a CONST_VECTOR.  */
    struct
    {
      /* The value of CONST_VECTOR_NPATTERNS.  */
      unsigned int npatterns : 16;

      /* The value of CONST_VECTOR_NELTS_PER_PATTERN.  */
      unsigned int nelts_per_pattern : 8;

      /* For future expansion.  */
      unsigned int unused : 8;
    } const_vector;
  } GTY ((skip)) u2;

  /* The first element of the operands of this rtx.
     The number of operands and their types are controlled
     by the `code' field, according to rtl.def.  */
  union u {
    rtunion fld[1];
    HOST_WIDE_INT hwint[1];
    struct reg_info reg;
    struct block_symbol block_sym;
    struct real_value rv;
    struct fixed_value fv;
    struct hwivec_def hwiv;
    struct const_poly_int_def cpi;
  } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u;
};

/* A node for constructing singly-linked lists of rtx.  */

struct GTY(()) rtx_expr_list : public rtx_def
{
private:
  /* No extra fields, but adds invariant: (GET_CODE (X) == EXPR_LIST).  */

public:
  /* Get next in list.  */
  rtx_expr_list *next () const;

  /* Get at the underlying rtx.  */
  rtx element () const;
};

template <>
template <>
inline bool
is_a_helper <rtx_expr_list *>::test (rtx rt)
{
  return rt->code == EXPR_LIST;
}

struct GTY(()) rtx_insn_list : public rtx_def
{
private:
  /* No extra fields, but adds invariant: (GET_CODE (X) == INSN_LIST).

     This is an instance of:

       DEF_RTL_EXPR(INSN_LIST, "insn_list", "ue", RTX_EXTRA)

     i.e. a node for constructing singly-linked lists of rtx_insn *, where
     the list is "external" to the insn (as opposed to the doubly-linked
     list embedded within rtx_insn itself).  */

public:
  /* Get next in list.  */
  rtx_insn_list *next () const;

  /* Get at the underlying instruction.  */
  rtx_insn *insn () const;

};

template <>
template <>
inline bool
is_a_helper <rtx_insn_list *>::test (rtx rt)
{
  return rt->code == INSN_LIST;
}

/* A node with invariant GET_CODE (X) == SEQUENCE i.e. a vector of rtx,
   typically (but not always) of rtx_insn *, used in the late passes.  */

struct GTY(()) rtx_sequence : public rtx_def
{
private:
  /* No extra fields, but adds invariant: (GET_CODE (X) == SEQUENCE).  */

public:
  /* Get number of elements in sequence.  */
  int len () const;

  /* Get i-th element of the sequence.  */
  rtx element (int index) const;

  /* Get i-th element of the sequence, with a checked cast to
     rtx_insn *.  */
  rtx_insn *insn (int index) const;
};

template <>
template <>
inline bool
is_a_helper <rtx_sequence *>::test (rtx rt)
{
  return rt->code == SEQUENCE;
}

template <>
template <>
inline bool
is_a_helper <const rtx_sequence *>::test (const_rtx rt)
{
  return rt->code == SEQUENCE;
}

struct GTY(()) rtx_insn : public rtx_def
{
public:
  /* No extra fields, but adds the invariant:

     (INSN_P (X)
      || NOTE_P (X)
      || JUMP_TABLE_DATA_P (X)
      || BARRIER_P (X)
      || LABEL_P (X))

     i.e. that we must be able to use the following:
      INSN_UID ()
      NEXT_INSN ()
      PREV_INSN ()
    i.e. we have an rtx that has an INSN_UID field and can be part of
    a linked list of insns.
  */

  /* Returns true if this insn has been deleted.  */

  bool deleted () const { return volatil; }

  /* Mark this insn as deleted.  */

  void set_deleted () { volatil = true; }

  /* Mark this insn as not deleted.  */

  void set_undeleted () { volatil = false; }
};

/* Subclasses of rtx_insn.  */

struct GTY(()) rtx_debug_insn : public rtx_insn
{
  /* No extra fields, but adds the invariant:
       DEBUG_INSN_P (X) aka (GET_CODE (X) == DEBUG_INSN)
     i.e. an annotation for tracking variable assignments.

     This is an instance of:
       DEF_RTL_EXPR(DEBUG_INSN, "debug_insn", "uuBeiie", RTX_INSN)
     from rtl.def.  */
};

struct GTY(()) rtx_nonjump_insn : public rtx_insn
{
  /* No extra fields, but adds the invariant:
       NONJUMP_INSN_P (X) aka (GET_CODE (X) == INSN)
     i.e an instruction that cannot jump.

     This is an instance of:
       DEF_RTL_EXPR(INSN, "insn", "uuBeiie", RTX_INSN)
     from rtl.def.  */
};

struct GTY(()) rtx_jump_insn : public rtx_insn
{
public:
  /* No extra fields, but adds the invariant:
       JUMP_P (X) aka (GET_CODE (X) == JUMP_INSN)
     i.e. an instruction that can possibly jump.

     This is an instance of:
       DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeiie0", RTX_INSN)
     from rtl.def.  */

  /* Returns jump target of this instruction.  The returned value is not
     necessarily a code label: it may also be a RETURN or SIMPLE_RETURN
     expression.  Also, when the code label is marked "deleted", it is
     replaced by a NOTE.  In some cases the value is NULL_RTX.  */

  inline rtx jump_label () const;

  /* Returns jump target cast to rtx_code_label *.  */

  inline rtx_code_label *jump_target () const;

  /* Set jump target.  */

  inline void set_jump_target (rtx_code_label *);
};

struct GTY(()) rtx_call_insn : public rtx_insn
{
  /* No extra fields, but adds the invariant:
       CALL_P (X) aka (GET_CODE (X) == CALL_INSN)
     i.e. an instruction that can possibly call a subroutine
     but which will not change which instruction comes next
     in the current function.

     This is an instance of:
       DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeiiee", RTX_INSN)
     from rtl.def.  */
};

struct GTY(()) rtx_jump_table_data : public rtx_insn
{
  /* No extra fields, but adds the invariant:
       JUMP_TABLE_DATA_P (X) aka (GET_CODE (INSN) == JUMP_TABLE_DATA)
     i.e. a data for a jump table, considered an instruction for
     historical reasons.

     This is an instance of:
       DEF_RTL_EXPR(JUMP_TABLE_DATA, "jump_table_data", "uuBe0000", RTX_INSN)
     from rtl.def.  */

  /* This can be either:

       (a) a table of absolute jumps, in which case PATTERN (this) is an
           ADDR_VEC with arg 0 a vector of labels, or

       (b) a table of relative jumps (e.g. for -fPIC), in which case
           PATTERN (this) is an ADDR_DIFF_VEC, with arg 0 a LABEL_REF and
	   arg 1 the vector of labels.

     This method gets the underlying vec.  */

  inline rtvec get_labels () const;
  inline scalar_int_mode get_data_mode () const;
};

struct GTY(()) rtx_barrier : public rtx_insn
{
  /* No extra fields, but adds the invariant:
       BARRIER_P (X) aka (GET_CODE (X) == BARRIER)
     i.e. a marker that indicates that control will not flow through.

     This is an instance of:
       DEF_RTL_EXPR(BARRIER, "barrier", "uu00000", RTX_EXTRA)
     from rtl.def.  */
};

struct GTY(()) rtx_code_label : public rtx_insn
{
  /* No extra fields, but adds the invariant:
       LABEL_P (X) aka (GET_CODE (X) == CODE_LABEL)
     i.e. a label in the assembler.

     This is an instance of:
       DEF_RTL_EXPR(CODE_LABEL, "code_label", "uuB00is", RTX_EXTRA)
     from rtl.def.  */
};

struct GTY(()) rtx_note : public rtx_insn
{
  /* No extra fields, but adds the invariant:
       NOTE_P(X) aka (GET_CODE (X) == NOTE)
     i.e. a note about the corresponding source code.

     This is an instance of:
       DEF_RTL_EXPR(NOTE, "note", "uuB0ni", RTX_EXTRA)
     from rtl.def.  */
};

/* The size in bytes of an rtx header (code, mode and flags).  */
#define RTX_HDR_SIZE offsetof (struct rtx_def, u)

/* The size in bytes of an rtx with code CODE.  */
#define RTX_CODE_SIZE(CODE) rtx_code_size[CODE]

#define NULL_RTX (rtx) 0

/* The "next" and "previous" RTX, relative to this one.  */

#define RTX_NEXT(X) (rtx_next[GET_CODE (X)] == 0 ? NULL			\
		     : *(rtx *)(((char *)X) + rtx_next[GET_CODE (X)]))

/* FIXME: the "NEXT_INSN (PREV_INSN (X)) == X" condition shouldn't be needed.
 */
#define RTX_PREV(X) ((INSN_P (X)       			\
                      || NOTE_P (X)       		\
                      || JUMP_TABLE_DATA_P (X)		\
                      || BARRIER_P (X)        		\
                      || LABEL_P (X))    		\
		     && PREV_INSN (as_a <rtx_insn *> (X)) != NULL	\
                     && NEXT_INSN (PREV_INSN (as_a <rtx_insn *> (X))) == X \
                     ? PREV_INSN (as_a <rtx_insn *> (X)) : NULL)

/* Define macros to access the `code' field of the rtx.  */

#define GET_CODE(RTX)	    ((enum rtx_code) (RTX)->code)
#define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE))

#define GET_MODE(RTX)		((machine_mode) (RTX)->mode)
#define PUT_MODE_RAW(RTX, MODE)	((RTX)->mode = (MODE))

/* RTL vector.  These appear inside RTX's when there is a need
   for a variable number of things.  The principle use is inside
   PARALLEL expressions.  */

struct GTY(()) rtvec_def {
  int num_elem;		/* number of elements */
  rtx GTY ((length ("%h.num_elem"))) elem[1];
};

#define NULL_RTVEC (rtvec) 0

#define GET_NUM_ELEM(RTVEC)		((RTVEC)->num_elem)
#define PUT_NUM_ELEM(RTVEC, NUM)	((RTVEC)->num_elem = (NUM))

/* Predicate yielding nonzero iff X is an rtx for a register.  */
#define REG_P(X) (GET_CODE (X) == REG)

/* Predicate yielding nonzero iff X is an rtx for a memory location.  */
#define MEM_P(X) (GET_CODE (X) == MEM)

#if TARGET_SUPPORTS_WIDE_INT

/* Match CONST_*s that can represent compile-time constant integers.  */
#define CASE_CONST_SCALAR_INT \
   case CONST_INT: \
   case CONST_WIDE_INT

/* Match CONST_*s for which pointer equality corresponds to value
   equality.  */
#define CASE_CONST_UNIQUE \
   case CONST_INT: \
   case CONST_WIDE_INT: \
   case CONST_POLY_INT: \
   case CONST_DOUBLE: \
   case CONST_FIXED

/* Match all CONST_* rtxes.  */
#define CASE_CONST_ANY \
   case CONST_INT: \
   case CONST_WIDE_INT: \
   case CONST_POLY_INT: \
   case CONST_DOUBLE: \
   case CONST_FIXED: \
   case CONST_VECTOR

#else

/* Match CONST_*s that can represent compile-time constant integers.  */
#define CASE_CONST_SCALAR_INT \
   case CONST_INT: \
   case CONST_DOUBLE

/* Match CONST_*s for which pointer equality corresponds to value
   equality.  */
#define CASE_CONST_UNIQUE \
   case CONST_INT: \
   case CONST_DOUBLE: \
   case CONST_FIXED

/* Match all CONST_* rtxes.  */
#define CASE_CONST_ANY \
   case CONST_INT: \
   case CONST_DOUBLE: \
   case CONST_FIXED: \
   case CONST_VECTOR
#endif

/* Predicate yielding nonzero iff X is an rtx for a constant integer.  */
#define CONST_INT_P(X) (GET_CODE (X) == CONST_INT)

/* Predicate yielding nonzero iff X is an rtx for a constant integer.  */
#define CONST_WIDE_INT_P(X) (GET_CODE (X) == CONST_WIDE_INT)

/* Predicate yielding nonzero iff X is an rtx for a polynomial constant
   integer.  */
#define CONST_POLY_INT_P(X) \
  (NUM_POLY_INT_COEFFS > 1 && GET_CODE (X) == CONST_POLY_INT)

/* Predicate yielding nonzero iff X is an rtx for a constant fixed-point.  */
#define CONST_FIXED_P(X) (GET_CODE (X) == CONST_FIXED)

/* Predicate yielding true iff X is an rtx for a double-int
   or floating point constant.  */
#define CONST_DOUBLE_P(X) (GET_CODE (X) == CONST_DOUBLE)

/* Predicate yielding true iff X is an rtx for a double-int.  */
#define CONST_DOUBLE_AS_INT_P(X) \
  (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == VOIDmode)

/* Predicate yielding true iff X is an rtx for a integer const.  */
#if TARGET_SUPPORTS_WIDE_INT
#define CONST_SCALAR_INT_P(X) \
  (CONST_INT_P (X) || CONST_WIDE_INT_P (X))
#else
#define CONST_SCALAR_INT_P(X) \
  (CONST_INT_P (X) || CONST_DOUBLE_AS_INT_P (X))
#endif

/* Predicate yielding true iff X is an rtx for a double-int.  */
#define CONST_DOUBLE_AS_FLOAT_P(X) \
  (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode)

/* Predicate yielding nonzero iff X is an rtx for a constant vector.  */
#define CONST_VECTOR_P(X) (GET_CODE (X) == CONST_VECTOR)

/* Predicate yielding nonzero iff X is a label insn.  */
#define LABEL_P(X) (GET_CODE (X) == CODE_LABEL)

/* Predicate yielding nonzero iff X is a jump insn.  */
#define JUMP_P(X) (GET_CODE (X) == JUMP_INSN)

/* Predicate yielding nonzero iff X is a call insn.  */
#define CALL_P(X) (GET_CODE (X) == CALL_INSN)

/* 1 if RTX is a call_insn for a fake call.
   CALL_INSN use "used" flag to indicate it's a fake call.  */
#define FAKE_CALL_P(RTX)                                        \
  (RTL_FLAG_CHECK1 ("FAKE_CALL_P", (RTX), CALL_INSN)->used)

/* Predicate yielding nonzero iff X is an insn that cannot jump.  */
#define NONJUMP_INSN_P(X) (GET_CODE (X) == INSN)

/* Predicate yielding nonzero iff X is a debug note/insn.  */
#define DEBUG_INSN_P(X) (GET_CODE (X) == DEBUG_INSN)

/* Predicate yielding nonzero iff X is an insn that is not a debug insn.  */
#define NONDEBUG_INSN_P(X) (NONJUMP_INSN_P (X) || JUMP_P (X) || CALL_P (X))

/* Nonzero if DEBUG_MARKER_INSN_P may possibly hold.  */
#define MAY_HAVE_DEBUG_MARKER_INSNS debug_nonbind_markers_p
/* Nonzero if DEBUG_BIND_INSN_P may possibly hold.  */
#define MAY_HAVE_DEBUG_BIND_INSNS flag_var_tracking_assignments
/* Nonzero if DEBUG_INSN_P may possibly hold.  */
#define MAY_HAVE_DEBUG_INSNS					\
  (MAY_HAVE_DEBUG_MARKER_INSNS || MAY_HAVE_DEBUG_BIND_INSNS)

/* Predicate yielding nonzero iff X is a real insn.  */
#define INSN_P(X) (NONDEBUG_INSN_P (X) || DEBUG_INSN_P (X))

/* Predicate yielding nonzero iff X is a note insn.  */
#define NOTE_P(X) (GET_CODE (X) == NOTE)

/* Predicate yielding nonzero iff X is a barrier insn.  */
#define BARRIER_P(X) (GET_CODE (X) == BARRIER)

/* Predicate yielding nonzero iff X is a data for a jump table.  */
#define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA)

/* Predicate yielding nonzero iff RTX is a subreg.  */
#define SUBREG_P(RTX) (GET_CODE (RTX) == SUBREG)

/* Predicate yielding true iff RTX is a symbol ref.  */
#define SYMBOL_REF_P(RTX) (GET_CODE (RTX) == SYMBOL_REF)

template <>
template <>
inline bool
is_a_helper <rtx_insn *>::test (rtx rt)
{
  return (INSN_P (rt)
	  || NOTE_P (rt)
	  || JUMP_TABLE_DATA_P (rt)
	  || BARRIER_P (rt)
	  || LABEL_P (rt));
}

template <>
template <>
inline bool
is_a_helper <const rtx_insn *>::test (const_rtx rt)
{
  return (INSN_P (rt)
	  || NOTE_P (rt)
	  || JUMP_TABLE_DATA_P (rt)
	  || BARRIER_P (rt)
	  || LABEL_P (rt));
}

template <>
template <>
inline bool
is_a_helper <rtx_debug_insn *>::test (rtx rt)
{
  return DEBUG_INSN_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_nonjump_insn *>::test (rtx rt)
{
  return NONJUMP_INSN_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_jump_insn *>::test (rtx rt)
{
  return JUMP_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_jump_insn *>::test (rtx_insn *insn)
{
  return JUMP_P (insn);
}

template <>
template <>
inline bool
is_a_helper <rtx_call_insn *>::test (rtx rt)
{
  return CALL_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_call_insn *>::test (rtx_insn *insn)
{
  return CALL_P (insn);
}

template <>
template <>
inline bool
is_a_helper <rtx_jump_table_data *>::test (rtx rt)
{
  return JUMP_TABLE_DATA_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_jump_table_data *>::test (rtx_insn *insn)
{
  return JUMP_TABLE_DATA_P (insn);
}

template <>
template <>
inline bool
is_a_helper <rtx_barrier *>::test (rtx rt)
{
  return BARRIER_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_code_label *>::test (rtx rt)
{
  return LABEL_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_code_label *>::test (rtx_insn *insn)
{
  return LABEL_P (insn);
}

template <>
template <>
inline bool
is_a_helper <rtx_note *>::test (rtx rt)
{
  return NOTE_P (rt);
}

template <>
template <>
inline bool
is_a_helper <rtx_note *>::test (rtx_insn *insn)
{
  return NOTE_P (insn);
}

/* Predicate yielding nonzero iff X is a return or simple_return.  */
#define ANY_RETURN_P(X) \
  (GET_CODE (X) == RETURN || GET_CODE (X) == SIMPLE_RETURN)

/* 1 if X is a unary operator.  */

#define UNARY_P(X)   \
  (GET_RTX_CLASS (GET_CODE (X)) == RTX_UNARY)

/* 1 if X is a binary operator.  */

#define BINARY_P(X)   \
  ((GET_RTX_CLASS (GET_CODE (X)) & RTX_BINARY_MASK) == RTX_BINARY_RESULT)

/* 1 if X is an arithmetic operator.  */

#define ARITHMETIC_P(X)   \
  ((GET_RTX_CLASS (GET_CODE (X)) & RTX_ARITHMETIC_MASK)			\
    == RTX_ARITHMETIC_RESULT)

/* 1 if X is an arithmetic operator.  */

#define COMMUTATIVE_ARITH_P(X)   \
  (GET_RTX_CLASS (GET_CODE (X)) == RTX_COMM_ARITH)

/* 1 if X is a commutative arithmetic operator or a comparison operator.
   These two are sometimes selected together because it is possible to
   swap the two operands.  */

#define SWAPPABLE_OPERANDS_P(X)   \
  ((1 << GET_RTX_CLASS (GET_CODE (X)))					\
    & ((1 << RTX_COMM_ARITH) | (1 << RTX_COMM_COMPARE)			\
       | (1 << RTX_COMPARE)))

/* 1 if X is a non-commutative operator.  */

#define NON_COMMUTATIVE_P(X)   \
  ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMMUTATIVE_MASK)		\
    == RTX_NON_COMMUTATIVE_RESULT)

/* 1 if X is a commutative operator on integers.  */

#define COMMUTATIVE_P(X)   \
  ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMMUTATIVE_MASK)		\
    == RTX_COMMUTATIVE_RESULT)

/* 1 if X is a relational operator.  */

#define COMPARISON_P(X)   \
  ((GET_RTX_CLASS (GET_CODE (X)) & RTX_COMPARE_MASK) == RTX_COMPARE_RESULT)

/* 1 if X is a constant value that is an integer.  */

#define CONSTANT_P(X)   \
  (GET_RTX_CLASS (GET_CODE (X)) == RTX_CONST_OBJ)

/* 1 if X is a LABEL_REF.  */
#define LABEL_REF_P(X)  \
  (GET_CODE (X) == LABEL_REF)

/* 1 if X can be used to represent an object.  */
#define OBJECT_P(X)							\
  ((GET_RTX_CLASS (GET_CODE (X)) & RTX_OBJ_MASK) == RTX_OBJ_RESULT)

/* General accessor macros for accessing the fields of an rtx.  */

#if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
/* The bit with a star outside the statement expr and an & inside is
   so that N can be evaluated only once.  */
#define RTL_CHECK1(RTX, N, C1) __extension__				\
(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);		\
     const enum rtx_code _code = GET_CODE (_rtx);			\
     if (_n < 0 || _n >= GET_RTX_LENGTH (_code))			\
       rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__,		\
				__FUNCTION__);				\
     if (GET_RTX_FORMAT (_code)[_n] != C1)				\
       rtl_check_failed_type1 (_rtx, _n, C1, __FILE__, __LINE__,	\
			       __FUNCTION__);				\
     &_rtx->u.fld[_n]; }))

#define RTL_CHECK2(RTX, N, C1, C2) __extension__			\
(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);		\
     const enum rtx_code _code = GET_CODE (_rtx);			\
     if (_n < 0 || _n >= GET_RTX_LENGTH (_code))			\
       rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__,		\
				__FUNCTION__);				\
     if (GET_RTX_FORMAT (_code)[_n] != C1				\
	 && GET_RTX_FORMAT (_code)[_n] != C2)				\
       rtl_check_failed_type2 (_rtx, _n, C1, C2, __FILE__, __LINE__,	\
			       __FUNCTION__);				\
     &_rtx->u.fld[_n]; }))

#define RTL_CHECKC1(RTX, N, C) __extension__				\
(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);		\
     if (GET_CODE (_rtx) != (C))					\
       rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__,		\
			       __FUNCTION__);				\
     &_rtx->u.fld[_n]; }))

#define RTL_CHECKC2(RTX, N, C1, C2) __extension__			\
(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);		\
     const enum rtx_code _code = GET_CODE (_rtx);			\
     if (_code != (C1) && _code != (C2))				\
       rtl_check_failed_code2 (_rtx, (C1), (C2), __FILE__, __LINE__,	\
			       __FUNCTION__); \
     &_rtx->u.fld[_n]; }))

#define RTL_CHECKC3(RTX, N, C1, C2, C3) __extension__			\
(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);		\
     const enum rtx_code _code = GET_CODE (_rtx);			\
     if (_code != (C1) && _code != (C2) && _code != (C3))		\
       rtl_check_failed_code3 (_rtx, (C1), (C2), (C3), __FILE__,	\
			       __LINE__, __FUNCTION__);			\
     &_rtx->u.fld[_n]; }))

#define RTVEC_ELT(RTVEC, I) __extension__				\
(*({ __typeof (RTVEC) const _rtvec = (RTVEC); const int _i = (I);	\
     if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec))				\
       rtvec_check_failed_bounds (_rtvec, _i, __FILE__, __LINE__,	\
				  __FUNCTION__);			\
     &_rtvec->elem[_i]; }))

#define XWINT(RTX, N) __extension__					\
(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);		\
     const enum rtx_code _code = GET_CODE (_rtx);			\
     if (_n < 0 || _n >= GET_RTX_LENGTH (_code))			\
       rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__,		\
				__FUNCTION__);				\
     if (GET_RTX_FORMAT (_code)[_n] != 'w')				\
       rtl_check_failed_type1 (_rtx, _n, 'w', __FILE__, __LINE__,	\
			       __FUNCTION__);				\
     &_rtx->u.hwint[_n]; }))

#define CWI_ELT(RTX, I) __extension__					\
(*({ __typeof (RTX) const _cwi = (RTX);					\
     int _max = CWI_GET_NUM_ELEM (_cwi);				\
     const int _i = (I);						\
     if (_i < 0 || _i >= _max)						\
       cwi_check_failed_bounds (_cwi, _i, __FILE__, __LINE__,		\
				__FUNCTION__);				\
     &_cwi->u.hwiv.elem[_i]; }))

#define XCWINT(RTX, N, C) __extension__					\
(*({ __typeof (RTX) const _rtx = (RTX);					\
     if (GET_CODE (_rtx) != (C))					\
       rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__,		\
			       __FUNCTION__);				\
     &_rtx->u.hwint[N]; }))

#define XCMWINT(RTX, N, C, M) __extension__				\
(*({ __typeof (RTX) const _rtx = (RTX);					\
     if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) != (M))		\
       rtl_check_failed_code_mode (_rtx, (C), (M), false, __FILE__,	\
				   __LINE__, __FUNCTION__);		\
     &_rtx->u.hwint[N]; }))

#define XCNMPRV(RTX, C, M) __extension__				\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) == (M))		\
     rtl_check_failed_code_mode (_rtx, (C), (M), true, __FILE__,	\
				 __LINE__, __FUNCTION__);		\
   &_rtx->u.rv; })

#define XCNMPFV(RTX, C, M) __extension__				\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) == (M))		\
     rtl_check_failed_code_mode (_rtx, (C), (M), true, __FILE__,	\
				 __LINE__, __FUNCTION__);		\
   &_rtx->u.fv; })

#define REG_CHECK(RTX) __extension__					\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != REG)						\
     rtl_check_failed_code1 (_rtx, REG,  __FILE__, __LINE__,		\
			     __FUNCTION__);				\
   &_rtx->u.reg; })

#define BLOCK_SYMBOL_CHECK(RTX) __extension__				\
({ __typeof (RTX) const _symbol = (RTX);				\
   const unsigned int flags = SYMBOL_REF_FLAGS (_symbol);		\
   if ((flags & SYMBOL_FLAG_HAS_BLOCK_INFO) == 0)			\
     rtl_check_failed_block_symbol (__FILE__, __LINE__,			\
				    __FUNCTION__);			\
   &_symbol->u.block_sym; })

#define HWIVEC_CHECK(RTX,C) __extension__				\
({ __typeof (RTX) const _symbol = (RTX);				\
   RTL_CHECKC1 (_symbol, 0, C);						\
   &_symbol->u.hwiv; })

extern void rtl_check_failed_bounds (const_rtx, int, const char *, int,
				     const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtl_check_failed_type1 (const_rtx, int, int, const char *, int,
				    const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtl_check_failed_type2 (const_rtx, int, int, int, const char *,
				    int, const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtl_check_failed_code1 (const_rtx, enum rtx_code, const char *,
				    int, const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtl_check_failed_code2 (const_rtx, enum rtx_code, enum rtx_code,
				    const char *, int, const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtl_check_failed_code3 (const_rtx, enum rtx_code, enum rtx_code,
				    enum rtx_code, const char *, int,
				    const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, machine_mode,
					bool, const char *, int, const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtl_check_failed_block_symbol (const char *, int, const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void cwi_check_failed_bounds (const_rtx, int, const char *, int,
				     const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int,
				       const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;

#else   /* not ENABLE_RTL_CHECKING */

#define RTL_CHECK1(RTX, N, C1)      ((RTX)->u.fld[N])
#define RTL_CHECK2(RTX, N, C1, C2)  ((RTX)->u.fld[N])
#define RTL_CHECKC1(RTX, N, C)	    ((RTX)->u.fld[N])
#define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->u.fld[N])
#define RTL_CHECKC3(RTX, N, C1, C2, C3) ((RTX)->u.fld[N])
#define RTVEC_ELT(RTVEC, I)	    ((RTVEC)->elem[I])
#define XWINT(RTX, N)		    ((RTX)->u.hwint[N])
#define CWI_ELT(RTX, I)		    ((RTX)->u.hwiv.elem[I])
#define XCWINT(RTX, N, C)	    ((RTX)->u.hwint[N])
#define XCMWINT(RTX, N, C, M)	    ((RTX)->u.hwint[N])
#define XCNMWINT(RTX, N, C, M)	    ((RTX)->u.hwint[N])
#define XCNMPRV(RTX, C, M)	    (&(RTX)->u.rv)
#define XCNMPFV(RTX, C, M)	    (&(RTX)->u.fv)
#define REG_CHECK(RTX)		    (&(RTX)->u.reg)
#define BLOCK_SYMBOL_CHECK(RTX)	    (&(RTX)->u.block_sym)
#define HWIVEC_CHECK(RTX,C)	    (&(RTX)->u.hwiv)

#endif

/* General accessor macros for accessing the flags of an rtx.  */

/* Access an individual rtx flag, with no checking of any kind.  */
#define RTX_FLAG(RTX, FLAG)	((RTX)->FLAG)

#if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION >= 2007)
#define RTL_FLAG_CHECK1(NAME, RTX, C1) __extension__			\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != C1)						\
     rtl_check_failed_flag  (NAME, _rtx, __FILE__, __LINE__,		\
			     __FUNCTION__);				\
   _rtx; })

#define RTL_FLAG_CHECK2(NAME, RTX, C1, C2) __extension__		\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != C1 && GET_CODE(_rtx) != C2)			\
     rtl_check_failed_flag  (NAME,_rtx, __FILE__, __LINE__,		\
			      __FUNCTION__);				\
   _rtx; })

#define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3) __extension__		\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != C1 && GET_CODE(_rtx) != C2			\
       && GET_CODE (_rtx) != C3)					\
     rtl_check_failed_flag  (NAME, _rtx, __FILE__, __LINE__,		\
			     __FUNCTION__);				\
   _rtx; })

#define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4) __extension__	\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != C1 && GET_CODE(_rtx) != C2			\
       && GET_CODE (_rtx) != C3 && GET_CODE(_rtx) != C4)		\
     rtl_check_failed_flag  (NAME, _rtx, __FILE__, __LINE__,		\
			      __FUNCTION__);				\
   _rtx; })

#define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) __extension__	\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != C1 && GET_CODE (_rtx) != C2			\
       && GET_CODE (_rtx) != C3 && GET_CODE (_rtx) != C4		\
       && GET_CODE (_rtx) != C5)					\
     rtl_check_failed_flag  (NAME, _rtx, __FILE__, __LINE__,		\
			     __FUNCTION__);				\
   _rtx; })

#define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6)		\
  __extension__								\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != C1 && GET_CODE (_rtx) != C2			\
       && GET_CODE (_rtx) != C3 && GET_CODE (_rtx) != C4		\
       && GET_CODE (_rtx) != C5 && GET_CODE (_rtx) != C6)		\
     rtl_check_failed_flag  (NAME,_rtx, __FILE__, __LINE__,		\
			     __FUNCTION__);				\
   _rtx; })

#define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7)		\
  __extension__								\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (GET_CODE (_rtx) != C1 && GET_CODE (_rtx) != C2			\
       && GET_CODE (_rtx) != C3 && GET_CODE (_rtx) != C4		\
       && GET_CODE (_rtx) != C5 && GET_CODE (_rtx) != C6		\
       && GET_CODE (_rtx) != C7)					\
     rtl_check_failed_flag  (NAME, _rtx, __FILE__, __LINE__,		\
			     __FUNCTION__);				\
   _rtx; })

#define RTL_INSN_CHAIN_FLAG_CHECK(NAME, RTX) 				\
  __extension__								\
({ __typeof (RTX) const _rtx = (RTX);					\
   if (!INSN_CHAIN_CODE_P (GET_CODE (_rtx)))				\
     rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__,		\
			    __FUNCTION__);				\
   _rtx; })

extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
				   int, const char *)
    ATTRIBUTE_NORETURN ATTRIBUTE_COLD
    ;

#else	/* not ENABLE_RTL_FLAG_CHECKING */

#define RTL_FLAG_CHECK1(NAME, RTX, C1)					(RTX)
#define RTL_FLAG_CHECK2(NAME, RTX, C1, C2)				(RTX)
#define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3)				(RTX)
#define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4)			(RTX)
#define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5)			(RTX)
#define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6)		(RTX)
#define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7)		(RTX)
#define RTL_INSN_CHAIN_FLAG_CHECK(NAME, RTX) 				(RTX)
#endif

#define XINT(RTX, N)	(RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
#define XUINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
#define XSTR(RTX, N)	(RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
#define XEXP(RTX, N)	(RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
#define XVEC(RTX, N)	(RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
#define XMODE(RTX, N)	(RTL_CHECK1 (RTX, N, 'M').rt_type)
#define XTREE(RTX, N)   (RTL_CHECK1 (RTX, N, 't').rt_tree)
#define XBBDEF(RTX, N)	(RTL_CHECK1 (RTX, N, 'B').rt_bb)
#define XTMPL(RTX, N)	(RTL_CHECK1 (RTX, N, 'T').rt_str)
#define XCFI(RTX, N)	(RTL_CHECK1 (RTX, N, 'C').rt_cfi)

#define XVECEXP(RTX, N, M)	RTVEC_ELT (XVEC (RTX, N), M)
#define XVECLEN(RTX, N)		GET_NUM_ELEM (XVEC (RTX, N))

/* These are like XINT, etc. except that they expect a '0' field instead
   of the normal type code.  */

#define X0INT(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_int)
#define X0UINT(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_uint)
#define X0STR(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_str)
#define X0EXP(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_rtx)
#define X0VEC(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_rtvec)
#define X0MODE(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_type)
#define X0TREE(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_tree)
#define X0BBDEF(RTX, N)	   (RTL_CHECK1 (RTX, N, '0').rt_bb)
#define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags)
#define X0CSELIB(RTX, N)   (RTL_CHECK1 (RTX, N, '0').rt_cselib)
#define X0MEMATTR(RTX, N)  (RTL_CHECKC1 (RTX, N, MEM).rt_mem)
#define X0CONSTANT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_constant)

/* Access a '0' field with any type.  */
#define X0ANY(RTX, N)	   RTL_CHECK1 (RTX, N, '0')

#define XCINT(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_int)
#define XCUINT(RTX, N, C)     (RTL_CHECKC1 (RTX, N, C).rt_uint)
#define XCSUBREG(RTX, N, C)   (RTL_CHECKC1 (RTX, N, C).rt_subreg)
#define XCSTR(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_str)
#define XCEXP(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_rtx)
#define XCVEC(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_rtvec)
#define XCMODE(RTX, N, C)     (RTL_CHECKC1 (RTX, N, C).rt_type)
#define XCTREE(RTX, N, C)     (RTL_CHECKC1 (RTX, N, C).rt_tree)
#define XCBBDEF(RTX, N, C)    (RTL_CHECKC1 (RTX, N, C).rt_bb)
#define XCCFI(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_cfi)
#define XCCSELIB(RTX, N, C)   (RTL_CHECKC1 (RTX, N, C).rt_cselib)

#define XCVECEXP(RTX, N, M, C)	RTVEC_ELT (XCVEC (RTX, N, C), M)
#define XCVECLEN(RTX, N, C)	GET_NUM_ELEM (XCVEC (RTX, N, C))

#define XC2EXP(RTX, N, C1, C2)      (RTL_CHECKC2 (RTX, N, C1, C2).rt_rtx)
#define XC3EXP(RTX, N, C1, C2, C3)  (RTL_CHECKC3 (RTX, N, C1, C2, C3).rt_rtx)
