T_CODE (pat) == ADDR_VEC)
    return XVEC (pat, 0);
  else
    return XVEC (pat, 1); /* presumably an ADDR_DIFF_VEC */
}

/* Return the mode of the data in the table, which is always a scalar
   integer.  */

inline scalar_int_mode
rtx_jump_table_data::get_data_mode () const
{
  return as_a <scalar_int_mode> (GET_MODE (PATTERN (this)));
}

/* If LABEL is followed by a jump table, return the table, otherwise
   return null.  */

inline rtx_jump_table_data *
jump_table_for_label (const rtx_code_label *label)
{
  return safe_dyn_cast <rtx_jump_table_data *> (NEXT_INSN (label));
}

#define RTX_FRAME_RELATED_P(RTX)					\
  (RTL_FLAG_CHECK6 ("RTX_FRAME_RELATED_P", (RTX), DEBUG_INSN, INSN,	\
		    CALL_INSN, JUMP_INSN, BARRIER, SET)->frame_related)

/* 1 if JUMP RTX is a crossing jump.  */
#define CROSSING_JUMP_P(RTX) \
  (RTL_FLAG_CHECK1 ("CROSSING_JUMP_P", (RTX), JUMP_INSN)->jump)

/* 1 if RTX is a call to a const function.  Built from ECF_CONST and
   TREE_READONLY.  */
#define RTL_CONST_CALL_P(RTX)					\
  (RTL_FLAG_CHECK1 ("RTL_CONST_CALL_P", (RTX), CALL_INSN)->unchanging)

/* 1 if RTX is a call to a pure function.  Built from ECF_PURE and
   DECL_PURE_P.  */
#define RTL_PURE_CALL_P(RTX)					\
  (RTL_FLAG_CHECK1 ("RTL_PURE_CALL_P", (RTX), CALL_INSN)->return_val)

/* 1 if RTX is a call to a const or pure function.  */
#define RTL_CONST_OR_PURE_CALL_P(RTX) \
  (RTL_CONST_CALL_P (RTX) || RTL_PURE_CALL_P (RTX))

/* 1 if RTX is a call to a looping const or pure function.  Built from
   ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P.  */
#define RTL_LOOPING_CONST_OR_PURE_CALL_P(RTX)				\
  (RTL_FLAG_CHECK1 ("CONST_OR_PURE_CALL_P", (RTX), CALL_INSN)->call)

/* 1 if RTX is a call_insn for a sibling call.  */
#define SIBLING_CALL_P(RTX)						\
  (RTL_FLAG_CHECK1 ("SIBLING_CALL_P", (RTX), CALL_INSN)->jump)

/* 1 if RTX is a jump_insn, call_insn, or insn that is an annulling branch.  */
#define INSN_ANNULLED_BRANCH_P(RTX)					\
  (RTL_FLAG_CHECK1 ("INSN_ANNULLED_BRANCH_P", (RTX), JUMP_INSN)->unchanging)

/* 1 if RTX is an insn in a delay slot and is from the target of the branch.
   If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be
   executed if the branch is taken.  For annulled branches with this bit
   clear, the insn should be executed only if the branch is not taken.  */
#define INSN_FROM_TARGET_P(RTX)						\
  (RTL_FLAG_CHECK3 ("INSN_FROM_TARGET_P", (RTX), INSN, JUMP_INSN, \
		    CALL_INSN)->in_struct)

/* In an ADDR_DIFF_VEC, the flags for RTX for use by branch shortening.
   See the comments for ADDR_DIFF_VEC in rtl.def.  */
#define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS (RTX, 4)

/* In a VALUE, the value cselib has assigned to RTX.
   This is a "struct cselib_val", see cselib.h.  */
#define CSELIB_VAL_PTR(RTX) X0CSELIB (RTX, 0)

/* Holds a list of notes on what this insn does to various REGs.
   It is a chain of EXPR_LIST rtx's, where the second operand is the
   chain pointer and the first operand is the REG being described.
   The mode field of the EXPR_LIST contains not a real machine mode
   but a value from enum reg_note.  */
#define REG_NOTES(INSN)	XEXP(INSN, 6)

/* In an ENTRY_VALUE this is the DECL_INCOMING_RTL of the argument in
   question.  */
#define ENTRY_VALUE_EXP(RTX) (RTL_CHECKC1 (RTX, 0, ENTRY_VALUE).rt_rtx)

enum reg_note
{
#define DEF_REG_NOTE(NAME) NAME,
#include "reg-notes.def"
#undef DEF_REG_NOTE
  REG_NOTE_MAX
};

/* Define macros to extract and insert the reg-note kind in an EXPR_LIST.  */
#define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
#define PUT_REG_NOTE_KIND(LINK, KIND) \
  PUT_MODE_RAW (LINK, (machine_mode) (KIND))

/* Names for REG_NOTE's in EXPR_LIST insn's.  */

extern const char * const reg_note_name[];
#define GET_REG_NOTE_NAME(MODE) (reg_note_name[(int) (MODE)])

/* This field is only present on CALL_INSNs.  It holds a chain of EXPR_LIST of
   USE, CLOBBER and SET expressions.
     USE expressions list the registers filled with arguments that
   are passed to the function.
     CLOBBER expressions document the registers explicitly clobbered
   by this CALL_INSN.
     SET expressions say that the return value of the call (the SET_DEST)
   is equivalent to a value available before the call (the SET_SRC).
   This kind of SET is used when the return value is predictable in
   advance.  It is purely an optimisation hint; unlike USEs and CLOBBERs,
   it does not affect register liveness.

     Pseudo registers cannot be mentioned in this list.  */
#define CALL_INSN_FUNCTION_USAGE(INSN)	XEXP(INSN, 7)

/* The label-number of a code-label.  The assembler label
   is made from `L' and the label-number printed in decimal.
   Label numbers are unique in a compilation.  */
#define CODE_LABEL_NUMBER(INSN)	XINT (INSN, 5)

/* In a NOTE that is a line number, this is a string for the file name that the
   line is in.  We use the same field to record block numbers temporarily in
   NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes.  (We avoid lots of casts
   between ints and pointers if we use a different macro for the block number.)
   */

/* Opaque data.  */
#define NOTE_DATA(INSN)	        RTL_CHECKC1 (INSN, 3, NOTE)
#define NOTE_DELETED_LABEL_NAME(INSN) XCSTR (INSN, 3, NOTE)
#define SET_INSN_DELETED(INSN) set_insn_deleted (INSN);
#define NOTE_BLOCK(INSN)	XCTREE (INSN, 3, NOTE)
#define NOTE_EH_HANDLER(INSN)	XCINT (INSN, 3, NOTE)
#define NOTE_BASIC_BLOCK(INSN)	XCBBDEF (INSN, 3, NOTE)
#define NOTE_VAR_LOCATION(INSN)	XCEXP (INSN, 3, NOTE)
#define NOTE_MARKER_LOCATION(INSN) XCUINT (INSN, 3, NOTE)
#define NOTE_CFI(INSN)		XCCFI (INSN, 3, NOTE)
#define NOTE_LABEL_NUMBER(INSN)	XCINT (INSN, 3, NOTE)

/* In a NOTE that is a line number, this is the line number.
   Other kinds of NOTEs are identified by negative numbers here.  */
#define NOTE_KIND(INSN) XCINT (INSN, 4, NOTE)

/* Nonzero if INSN is a note marking the beginning of a basic block.  */
#define NOTE_INSN_BASIC_BLOCK_P(INSN) \
  (NOTE_P (INSN) && NOTE_KIND (INSN) == NOTE_INSN_BASIC_BLOCK)

/* Nonzero if INSN is a debug nonbind marker note,
   for which NOTE_MARKER_LOCATION can be used.  */
#define NOTE_MARKER_P(INSN)				\
  (NOTE_P (INSN) &&					\
   (NOTE_KIND (INSN) == NOTE_INSN_BEGIN_STMT		\
    || NOTE_KIND (INSN) == NOTE_INSN_INLINE_ENTRY))

/* Variable declaration and the location of a variable.  */
#define PAT_VAR_LOCATION_DECL(PAT) (XCTREE ((PAT), 0, VAR_LOCATION))
#define PAT_VAR_LOCATION_LOC(PAT) (XCEXP ((PAT), 1, VAR_LOCATION))

/* Initialization status of the variable in the location.  Status
   can be unknown, uninitialized or initialized.  See enumeration
   type below.  */
#define PAT_VAR_LOCATION_STATUS(PAT) \
  (RTL_FLAG_CHECK1 ("PAT_VAR_LOCATION_STATUS", PAT, VAR_LOCATION) \
   ->u2.var_location_status)

/* Accessors for a NOTE_INSN_VAR_LOCATION.  */
#define NOTE_VAR_LOCATION_DECL(NOTE) \
  PAT_VAR_LOCATION_DECL (NOTE_VAR_LOCATION (NOTE))
#define NOTE_VAR_LOCATION_LOC(NOTE) \
  PAT_VAR_LOCATION_LOC (NOTE_VAR_LOCATION (NOTE))
#define NOTE_VAR_LOCATION_STATUS(NOTE) \
  PAT_VAR_LOCATION_STATUS (NOTE_VAR_LOCATION (NOTE))

/* Evaluate to TRUE if INSN is a debug insn that denotes a variable
   location/value tracking annotation.  */
#define DEBUG_BIND_INSN_P(INSN)			\
  (DEBUG_INSN_P (INSN)				\
   && (GET_CODE (PATTERN (INSN))		\
       == VAR_LOCATION))
/* Evaluate to TRUE if INSN is a debug insn that denotes a program
   source location marker.  */
#define DEBUG_MARKER_INSN_P(INSN)		\
  (DEBUG_INSN_P (INSN)				\
   && (GET_CODE (PATTERN (INSN))		\
       != VAR_LOCATION))
/* Evaluate to the marker kind.  */
#define INSN_DEBUG_MARKER_KIND(INSN)		  \
  (GET_CODE (PATTERN (INSN)) == DEBUG_MARKER	  \
   ? (GET_MODE (PATTERN (INSN)) == VOIDmode	  \
      ? NOTE_INSN_BEGIN_STMT			  \
      : GET_MODE (PATTERN (INSN)) == BLKmode	  \
      ? NOTE_INSN_INLINE_ENTRY			  \
      : (enum insn_note)-1) 			  \
   : (enum insn_note)-1)
/* Create patterns for debug markers.  These and the above abstract
   the representation, so that it's easier to get rid of the abuse of
   the mode to hold the marker kind.  Other marker types are
   envisioned, so a single bit flag won't do; maybe separate RTL codes
   wouldn't be a problem.  */
#define GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT() \
  gen_rtx_DEBUG_MARKER (VOIDmode)
#define GEN_RTX_DEBUG_MARKER_INLINE_ENTRY_PAT() \
  gen_rtx_DEBUG_MARKER (BLKmode)

/* The VAR_LOCATION rtx in a DEBUG_INSN.  */
#define INSN_VAR_LOCATION(INSN) \
  (RTL_FLAG_CHECK1 ("INSN_VAR_LOCATION", PATTERN (INSN), VAR_LOCATION))
/* A pointer to the VAR_LOCATION rtx in a DEBUG_INSN.  */
#define INSN_VAR_LOCATION_PTR(INSN) \
  (&PATTERN (INSN))

/* Accessors for a tree-expanded var location debug insn.  */
#define INSN_VAR_LOCATION_DECL(INSN) \
  PAT_VAR_LOCATION_DECL (INSN_VAR_LOCATION (INSN))
#define INSN_VAR_LOCATION_LOC(INSN) \
  PAT_VAR_LOCATION_LOC (INSN_VAR_LOCATION (INSN))
#define INSN_VAR_LOCATION_STATUS(INSN) \
  PAT_VAR_LOCATION_STATUS (INSN_VAR_LOCATION (INSN))

/* Expand to the RTL that denotes an unknown variable location in a
   DEBUG_INSN.  */
#define gen_rtx_UNKNOWN_VAR_LOC() (gen_rtx_CLOBBER (VOIDmode, const0_rtx))

/* Determine whether X is such an unknown location.  */
#define VAR_LOC_UNKNOWN_P(X) \
  (GET_CODE (X) == CLOBBER && XEXP ((X), 0) == const0_rtx)

/* 1 if RTX is emitted after a call, but it should take effect before
   the call returns.  */
#define NOTE_DURING_CALL_P(RTX)				\
  (RTL_FLAG_CHECK1 ("NOTE_VAR_LOCATION_DURING_CALL_P", (RTX), NOTE)->call)

/* DEBUG_EXPR_DECL corresponding to a DEBUG_EXPR RTX.  */
#define DEBUG_EXPR_TREE_DECL(RTX) XCTREE (RTX, 0, DEBUG_EXPR)

/* VAR_DECL/PARM_DECL DEBUG_IMPLICIT_PTR takes address of.  */
#define DEBUG_IMPLICIT_PTR_DECL(RTX) XCTREE (RTX, 0, DEBUG_IMPLICIT_PTR)

/* PARM_DECL DEBUG_PARAMETER_REF references.  */
#define DEBUG_PARAMETER_REF_DECL(RTX) XCTREE (RTX, 0, DEBUG_PARAMETER_REF)

/* Codes that appear in the NOTE_KIND field for kinds of notes
   that are not line numbers.  These codes are all negative.

   Notice that we do not try to use zero here for any of
   the special note codes because sometimes the source line
   actually can be zero!  This happens (for example) when we
   are generating code for the per-translation-unit constructor
   and destructor routines for some C++ translation unit.  */

enum insn_note
{
#define DEF_INSN_NOTE(NAME) NAME,
#include "insn-notes.def"
#undef DEF_INSN_NOTE

  NOTE_INSN_MAX
};

/* Names for NOTE insn's other than line numbers.  */

extern const char * const note_insn_name[NOTE_INSN_MAX];
#define GET_NOTE_INSN_NAME(NOTE_CODE) \
  (note_insn_name[(NOTE_CODE)])

/* The name of a label, in case it corresponds to an explicit label
   in the input source code.  */
#define LABEL_NAME(RTX) XCSTR (RTX, 6, CODE_LABEL)

/* In jump.cc, each label contains a count of the number
   of LABEL_REFs that point at it, so unused labels can be deleted.  */
#define LABEL_NUSES(RTX) XCINT (RTX, 4, CODE_LABEL)

/* Labels carry a two-bit field composed of the ->jump and ->call
   bits.  This field indicates whether the label is an alternate
   entry point, and if so, what kind.  */
enum label_kind
{
  LABEL_NORMAL = 0,	/* ordinary label */
  LABEL_STATIC_ENTRY,	/* alternate entry point, not exported */
  LABEL_GLOBAL_ENTRY,	/* alternate entry point, exported */
  LABEL_WEAK_ENTRY	/* alternate entry point, exported as weak symbol */
};

#if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION > 2007)

/* Retrieve the kind of LABEL.  */
#define LABEL_KIND(LABEL) __extension__					\
({ __typeof (LABEL) const _label = (LABEL);				\
   if (! LABEL_P (_label))						\
     rtl_check_failed_flag ("LABEL_KIND", _label, __FILE__, __LINE__,	\
			    __FUNCTION__);				\
   (enum label_kind) ((_label->jump << 1) | _label->call); })

/* Set the kind of LABEL.  */
#define SET_LABEL_KIND(LABEL, KIND) do {				\
   __typeof (LABEL) const _label = (LABEL);				\
   const unsigned int _kind = (KIND);					\
   if (! LABEL_P (_label))						\
     rtl_check_failed_flag ("SET_LABEL_KIND", _label, __FILE__, __LINE__, \
			    __FUNCTION__);				\
   _label->jump = ((_kind >> 1) & 1);					\
   _label->call = (_kind & 1);						\
} while (0)

#else

/* Retrieve the kind of LABEL.  */
#define LABEL_KIND(LABEL) \
   ((enum label_kind) (((LABEL)->jump << 1) | (LABEL)->call))

/* Set the kind of LABEL.  */
#define SET_LABEL_KIND(LABEL, KIND) do {				\
   rtx const _label = (LABEL);						\
   const unsigned int _kind = (KIND);					\
   _label->jump = ((_kind >> 1) & 1);					\
   _label->call = (_kind & 1);						\
} while (0)

#endif /* rtl flag checking */

#define LABEL_ALT_ENTRY_P(LABEL) (LABEL_KIND (LABEL) != LABEL_NORMAL)

/* In jump.cc, each JUMP_INSN can point to a label that it can jump to,
   so that if the JUMP_INSN is deleted, the label's LABEL_NUSES can
   be decremented and possibly the label can be deleted.  */
#define JUMP_LABEL(INSN)   XCEXP (INSN, 7, JUMP_INSN)

inline rtx_insn *JUMP_LABEL_AS_INSN (const rtx_insn *insn)
{
  return safe_as_a <rtx_insn *> (JUMP_LABEL (insn));
}

/* Methods of rtx_jump_insn.  */

inline rtx rtx_jump_insn::jump_label () const
{
  return JUMP_LABEL (this);
}

inline rtx_code_label *rtx_jump_insn::jump_target () const
{
  return safe_as_a <rtx_code_label *> (JUMP_LABEL (this));
}

inline void rtx_jump_insn::set_jump_target (rtx_code_label *target)
{
  JUMP_LABEL (this) = target;
}

/* Once basic blocks are found, each CODE_LABEL starts a chain that
   goes through all the LABEL_REFs that jump to that label.  The chain
   eventually winds up at the CODE_LABEL: it is circular.  */
#define LABEL_REFS(LABEL) XCEXP (LABEL, 3, CODE_LABEL)

/* Get the label that a LABEL_REF references.  */
inline rtx_insn *
label_ref_label (const_rtx ref)
{
  return as_a<rtx_insn *> (XCEXP (ref, 0, LABEL_REF));
}

/* Set the label that LABEL_REF ref refers to.  */

inline void
set_label_ref_label (rtx ref, rtx_insn *label)
{
  XCEXP (ref, 0, LABEL_REF) = label;
}
