190075Sobrien/* RTL utility routines.
2117395Skan   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
3169689Skan   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2118334Speter
22169689Skan/* This file is compiled twice: once for the generator programs
23169689Skan   once for the compiler.  */
24169689Skan#ifdef GENERATOR_FILE
25169689Skan#include "bconfig.h"
26169689Skan#else
2718334Speter#include "config.h"
28169689Skan#endif
29169689Skan
3050397Sobrien#include "system.h"
31132718Skan#include "coretypes.h"
32132718Skan#include "tm.h"
3318334Speter#include "rtl.h"
3418334Speter#include "real.h"
3590075Sobrien#include "ggc.h"
36169689Skan#ifdef GENERATOR_FILE
37169689Skan# include "errors.h"
38169689Skan#else
39169689Skan# include "toplev.h"
40169689Skan#endif
4118334Speter
4290075Sobrien
4318334Speter/* Indexed by rtx code, gives number of operands for an rtx with that code.
4490075Sobrien   Does NOT include rtx header data (code and links).  */
4518334Speter
4690075Sobrien#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   sizeof FORMAT - 1 ,
4718334Speter
4890075Sobrienconst unsigned char rtx_length[NUM_RTX_CODE] = {
4990075Sobrien#include "rtl.def"
5090075Sobrien};
5190075Sobrien
5290075Sobrien#undef DEF_RTL_EXPR
5390075Sobrien
5418334Speter/* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
5518334Speter
5618334Speter#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
5718334Speter
5890075Sobrienconst char * const rtx_name[NUM_RTX_CODE] = {
5918334Speter#include "rtl.def"		/* rtl expressions are documented here */
6018334Speter};
6118334Speter
6218334Speter#undef DEF_RTL_EXPR
6318334Speter
6418334Speter/* Indexed by rtx code, gives a sequence of operand-types for
6518334Speter   rtx's of that code.  The sequence is a C string in which
6618334Speter   each character describes one operand.  */
6718334Speter
6890075Sobrienconst char * const rtx_format[NUM_RTX_CODE] = {
6918334Speter  /* "*" undefined.
7018334Speter         can cause a warning message
7118334Speter     "0" field is unused (or used in a phase-dependent manner)
7218334Speter         prints nothing
7318334Speter     "i" an integer
7418334Speter         prints the integer
7518334Speter     "n" like "i", but prints entries from `note_insn_name'
7618334Speter     "w" an integer of width HOST_BITS_PER_WIDE_INT
7718334Speter         prints the integer
7818334Speter     "s" a pointer to a string
7918334Speter         prints the string
8018334Speter     "S" like "s", but optional:
8118334Speter	 the containing rtx may end before this operand
8290075Sobrien     "T" like "s", but treated specially by the RTL reader;
8390075Sobrien         only found in machine description patterns.
8418334Speter     "e" a pointer to an rtl expression
8518334Speter         prints the expression
8618334Speter     "E" a pointer to a vector that points to a number of rtl expressions
8718334Speter         prints a list of the rtl expressions
8818334Speter     "V" like "E", but optional:
8918334Speter	 the containing rtx may end before this operand
9018334Speter     "u" a pointer to another insn
9150397Sobrien         prints the uid of the insn.
9250397Sobrien     "b" is a pointer to a bitmap header.
93117395Skan     "B" is a basic block pointer.
9490075Sobrien     "t" is a tree pointer.  */
9518334Speter
9618334Speter#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
9718334Speter#include "rtl.def"		/* rtl expressions are defined here */
9818334Speter#undef DEF_RTL_EXPR
9918334Speter};
10018334Speter
10118334Speter/* Indexed by rtx code, gives a character representing the "class" of
10218334Speter   that rtx code.  See rtl.def for documentation on the defined classes.  */
10318334Speter
104169689Skanconst enum rtx_class rtx_class[NUM_RTX_CODE] = {
10590075Sobrien#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   CLASS,
10618334Speter#include "rtl.def"		/* rtl expressions are defined here */
10718334Speter#undef DEF_RTL_EXPR
10818334Speter};
10918334Speter
110132718Skan/* Indexed by rtx code, gives the size of the rtx in bytes.  */
111132718Skan
112169689Skanconst unsigned char rtx_code_size[NUM_RTX_CODE] = {
113132718Skan#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)				\
114132718Skan  ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE			\
115132718Skan   ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT)	\
116132718Skan   : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
117132718Skan
118132718Skan#include "rtl.def"
119132718Skan#undef DEF_RTL_EXPR
120132718Skan};
121132718Skan
122169689Skan/* Make sure all NOTE_INSN_* values are negative.  */
123169689Skanextern char NOTE_INSN_MAX_isnt_negative_adjust_NOTE_INSN_BIAS
124169689Skan[NOTE_INSN_MAX < 0 ? 1 : -1];
125169689Skan
12618334Speter/* Names for kinds of NOTEs and REG_NOTEs.  */
12718334Speter
12890075Sobrienconst char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
12990075Sobrien{
130169689Skan  "",
131169689Skan#define DEF_INSN_NOTE(NAME) #NAME,
132169689Skan#include "insn-notes.def"
133169689Skan#undef DEF_INSN_NOTE
13490075Sobrien};
13518334Speter
136169689Skanconst char * const reg_note_name[REG_NOTE_MAX] =
13790075Sobrien{
138169689Skan#define DEF_REG_NOTE(NAME) #NAME,
139169689Skan#include "reg-notes.def"
140169689Skan#undef DEF_REG_NOTE
14190075Sobrien};
14218334Speter
143132718Skan#ifdef GATHER_STATISTICS
144132718Skanstatic int rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
145132718Skanstatic int rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
146132718Skanstatic int rtvec_alloc_counts;
147132718Skanstatic int rtvec_alloc_sizes;
148132718Skan#endif
149132718Skan
15050397Sobrien
15118334Speter/* Allocate an rtx vector of N elements.
15218334Speter   Store the length, and initialize all elements to zero.  */
15318334Speter
15418334Speterrtvec
155132718Skanrtvec_alloc (int n)
15618334Speter{
15718334Speter  rtvec rt;
15818334Speter
15990075Sobrien  rt = ggc_alloc_rtvec (n);
160169689Skan  /* Clear out the vector.  */
16190075Sobrien  memset (&rt->elem[0], 0, n * sizeof (rtx));
16218334Speter
16350397Sobrien  PUT_NUM_ELEM (rt, n);
164132718Skan
165132718Skan#ifdef GATHER_STATISTICS
166132718Skan  rtvec_alloc_counts++;
167132718Skan  rtvec_alloc_sizes += n * sizeof (rtx);
168132718Skan#endif
169132718Skan
17018334Speter  return rt;
17118334Speter}
17218334Speter
173169689Skan/* Return the number of bytes occupied by rtx value X.  */
174169689Skan
175169689Skanunsigned int
176169689Skanrtx_size (rtx x)
177169689Skan{
178169689Skan  if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x))
179169689Skan    return RTX_HDR_SIZE + sizeof (struct block_symbol);
180169689Skan  return RTX_CODE_SIZE (GET_CODE (x));
181169689Skan}
182169689Skan
18318334Speter/* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
18418334Speter   all the rest is initialized to zero.  */
18518334Speter
18618334Speterrtx
187169689Skanrtx_alloc_stat (RTX_CODE code MEM_STAT_DECL)
18818334Speter{
18918334Speter  rtx rt;
19018334Speter
191169689Skan  rt = (rtx) ggc_alloc_zone_pass_stat (RTX_CODE_SIZE (code), &rtl_zone);
19218334Speter
19390075Sobrien  /* We want to clear everything up to the FLD array.  Normally, this
19490075Sobrien     is one int, but we don't want to assume that and it isn't very
19590075Sobrien     portable anyway; this is.  */
19618334Speter
197132718Skan  memset (rt, 0, RTX_HDR_SIZE);
19818334Speter  PUT_CODE (rt, code);
199132718Skan
200132718Skan#ifdef GATHER_STATISTICS
201132718Skan  rtx_alloc_counts[code]++;
202169689Skan  rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
203132718Skan#endif
204132718Skan
20518334Speter  return rt;
20618334Speter}
20718334Speter
20818334Speter
20918334Speter/* Create a new copy of an rtx.
21018334Speter   Recursively copies the operands of the rtx,
21118334Speter   except for those few rtx codes that are sharable.  */
21218334Speter
21318334Speterrtx
214132718Skancopy_rtx (rtx orig)
21518334Speter{
21690075Sobrien  rtx copy;
21790075Sobrien  int i, j;
21890075Sobrien  RTX_CODE code;
21990075Sobrien  const char *format_ptr;
22018334Speter
22118334Speter  code = GET_CODE (orig);
22218334Speter
22318334Speter  switch (code)
22418334Speter    {
22518334Speter    case REG:
22618334Speter    case CONST_INT:
22718334Speter    case CONST_DOUBLE:
22896263Sobrien    case CONST_VECTOR:
22918334Speter    case SYMBOL_REF:
23018334Speter    case CODE_LABEL:
23118334Speter    case PC:
23218334Speter    case CC0:
23318334Speter    case SCRATCH:
23450397Sobrien      /* SCRATCH must be shared because they represent distinct values.  */
23518334Speter      return orig;
236169689Skan    case CLOBBER:
237169689Skan      if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
238169689Skan	return orig;
239169689Skan      break;
24018334Speter
24118334Speter    case CONST:
24218334Speter      /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
24318334Speter	 a LABEL_REF, it isn't sharable.  */
24418334Speter      if (GET_CODE (XEXP (orig, 0)) == PLUS
24518334Speter	  && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
24618334Speter	  && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
24718334Speter	return orig;
24818334Speter      break;
24918334Speter
25018334Speter      /* A MEM with a constant address is not sharable.  The problem is that
25118334Speter	 the constant address may need to be reloaded.  If the mem is shared,
25218334Speter	 then reloading one copy of this mem will cause all copies to appear
25318334Speter	 to have been reloaded.  */
25450397Sobrien
25550397Sobrien    default:
25650397Sobrien      break;
25718334Speter    }
25818334Speter
259169689Skan  /* Copy the various flags, fields, and other information.  We assume
260169689Skan     that all fields need copying, and then clear the fields that should
26152284Sobrien     not be copied.  That is the sensible default behavior, and forces
26252284Sobrien     us to explicitly document why we are *not* copying a flag.  */
263169689Skan  copy = shallow_copy_rtx (orig);
26452284Sobrien
26552284Sobrien  /* We do not copy the USED flag, which is used as a mark bit during
26652284Sobrien     walks over the RTL.  */
267117395Skan  RTX_FLAG (copy, used) = 0;
26852284Sobrien
26990075Sobrien  /* We do not copy FRAME_RELATED for INSNs.  */
270169689Skan  if (INSN_P (orig))
271117395Skan    RTX_FLAG (copy, frame_related) = 0;
272117395Skan  RTX_FLAG (copy, jump) = RTX_FLAG (orig, jump);
273117395Skan  RTX_FLAG (copy, call) = RTX_FLAG (orig, call);
27490075Sobrien
27518334Speter  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
27618334Speter
27718334Speter  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
278169689Skan    switch (*format_ptr++)
279169689Skan      {
280169689Skan      case 'e':
281169689Skan	if (XEXP (orig, i) != NULL)
282169689Skan	  XEXP (copy, i) = copy_rtx (XEXP (orig, i));
283169689Skan	break;
28418334Speter
285169689Skan      case 'E':
286169689Skan      case 'V':
287169689Skan	if (XVEC (orig, i) != NULL)
288169689Skan	  {
289169689Skan	    XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
290169689Skan	    for (j = 0; j < XVECLEN (copy, i); j++)
291169689Skan	      XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
292169689Skan	  }
293169689Skan	break;
29418334Speter
295169689Skan      case 't':
296169689Skan      case 'w':
297169689Skan      case 'i':
298169689Skan      case 's':
299169689Skan      case 'S':
300169689Skan      case 'T':
301169689Skan      case 'u':
302169689Skan      case 'B':
303169689Skan      case '0':
304169689Skan	/* These are left unchanged.  */
305169689Skan	break;
30618334Speter
307169689Skan      default:
308169689Skan	gcc_unreachable ();
309169689Skan      }
31018334Speter  return copy;
31118334Speter}
31218334Speter
31352284Sobrien/* Create a new copy of an rtx.  Only copy just one level.  */
31490075Sobrien
31552284Sobrienrtx
316169689Skanshallow_copy_rtx_stat (rtx orig MEM_STAT_DECL)
31752284Sobrien{
318169689Skan  unsigned int size;
319132718Skan  rtx copy;
32052284Sobrien
321169689Skan  size = rtx_size (orig);
322169689Skan  copy = (rtx) ggc_alloc_zone_pass_stat (size, &rtl_zone);
323169689Skan  memcpy (copy, orig, size);
32452284Sobrien  return copy;
32552284Sobrien}
32690075Sobrien
32790075Sobrien/* Nonzero when we are generating CONCATs.  */
32890075Sobrienint generating_concat_p;
329169689Skan
330169689Skan/* Nonzero when we are expanding trees to RTL.  */
331169689Skanint currently_expanding_to_rtl;
332169689Skan
33390075Sobrien
33490075Sobrien/* Return 1 if X and Y are identical-looking rtx's.
33590075Sobrien   This is the Lisp function EQUAL for rtx arguments.  */
33618334Speter
33718334Speterint
338132718Skanrtx_equal_p (rtx x, rtx y)
33918334Speter{
34090075Sobrien  int i;
34190075Sobrien  int j;
34290075Sobrien  enum rtx_code code;
34390075Sobrien  const char *fmt;
34418334Speter
34590075Sobrien  if (x == y)
34690075Sobrien    return 1;
34790075Sobrien  if (x == 0 || y == 0)
34890075Sobrien    return 0;
34918334Speter
35090075Sobrien  code = GET_CODE (x);
35190075Sobrien  /* Rtx's of different codes cannot be equal.  */
35290075Sobrien  if (code != GET_CODE (y))
35390075Sobrien    return 0;
35418334Speter
35590075Sobrien  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
35690075Sobrien     (REG:SI x) and (REG:HI x) are NOT equivalent.  */
35718334Speter
35890075Sobrien  if (GET_MODE (x) != GET_MODE (y))
35990075Sobrien    return 0;
36018334Speter
36190075Sobrien  /* Some RTL can be compared nonrecursively.  */
36290075Sobrien  switch (code)
36350397Sobrien    {
36490075Sobrien    case REG:
365169689Skan      return (REGNO (x) == REGNO (y));
36650397Sobrien
36790075Sobrien    case LABEL_REF:
36890075Sobrien      return XEXP (x, 0) == XEXP (y, 0);
36950397Sobrien
37090075Sobrien    case SYMBOL_REF:
37190075Sobrien      return XSTR (x, 0) == XSTR (y, 0);
37218334Speter
37390075Sobrien    case SCRATCH:
37490075Sobrien    case CONST_DOUBLE:
37590075Sobrien    case CONST_INT:
37690075Sobrien      return 0;
37718334Speter
37890075Sobrien    default:
37990075Sobrien      break;
38090075Sobrien    }
38118334Speter
38290075Sobrien  /* Compare the elements.  If any pair of corresponding elements
383132718Skan     fail to match, return 0 for the whole thing.  */
38418334Speter
38590075Sobrien  fmt = GET_RTX_FORMAT (code);
38690075Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
38718334Speter    {
38890075Sobrien      switch (fmt[i])
38918334Speter	{
39090075Sobrien	case 'w':
39190075Sobrien	  if (XWINT (x, i) != XWINT (y, i))
39290075Sobrien	    return 0;
39318334Speter	  break;
39418334Speter
39590075Sobrien	case 'n':
39690075Sobrien	case 'i':
39790075Sobrien	  if (XINT (x, i) != XINT (y, i))
39890075Sobrien	    return 0;
39990075Sobrien	  break;
40018334Speter
40190075Sobrien	case 'V':
40290075Sobrien	case 'E':
40390075Sobrien	  /* Two vectors must have the same length.  */
40490075Sobrien	  if (XVECLEN (x, i) != XVECLEN (y, i))
40590075Sobrien	    return 0;
40618334Speter
40790075Sobrien	  /* And the corresponding elements must match.  */
40890075Sobrien	  for (j = 0; j < XVECLEN (x, i); j++)
40990075Sobrien	    if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
41090075Sobrien	      return 0;
41118334Speter	  break;
41218334Speter
41390075Sobrien	case 'e':
41490075Sobrien	  if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
41590075Sobrien	    return 0;
41690075Sobrien	  break;
41718334Speter
41890075Sobrien	case 'S':
41990075Sobrien	case 's':
42090075Sobrien	  if ((XSTR (x, i) || XSTR (y, i))
42190075Sobrien	      && (! XSTR (x, i) || ! XSTR (y, i)
42290075Sobrien		  || strcmp (XSTR (x, i), XSTR (y, i))))
42390075Sobrien	    return 0;
42490075Sobrien	  break;
42518334Speter
42690075Sobrien	case 'u':
42790075Sobrien	  /* These are just backpointers, so they don't matter.  */
42890075Sobrien	  break;
42918334Speter
43090075Sobrien	case '0':
43190075Sobrien	case 't':
43290075Sobrien	  break;
43318334Speter
43490075Sobrien	  /* It is believed that rtx's at this level will never
43590075Sobrien	     contain anything but integers and other rtx's,
43690075Sobrien	     except for within LABEL_REFs and SYMBOL_REFs.  */
43790075Sobrien	default:
438169689Skan	  gcc_unreachable ();
43918334Speter	}
44090075Sobrien    }
44190075Sobrien  return 1;
44218334Speter}
443132718Skan
444169689Skanvoid
445169689Skandump_rtx_statistics (void)
446132718Skan{
447132718Skan#ifdef GATHER_STATISTICS
448132718Skan  int i;
449132718Skan  int total_counts = 0;
450132718Skan  int total_sizes = 0;
451132718Skan  fprintf (stderr, "\nRTX Kind               Count      Bytes\n");
452132718Skan  fprintf (stderr, "---------------------------------------\n");
453132718Skan  for (i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
454132718Skan    if (rtx_alloc_counts[i])
455132718Skan      {
456132718Skan        fprintf (stderr, "%-20s %7d %10d\n", GET_RTX_NAME (i),
457132718Skan                 rtx_alloc_counts[i], rtx_alloc_sizes[i]);
458132718Skan        total_counts += rtx_alloc_counts[i];
459132718Skan        total_sizes += rtx_alloc_sizes[i];
460132718Skan      }
461132718Skan  if (rtvec_alloc_counts)
462132718Skan    {
463132718Skan      fprintf (stderr, "%-20s %7d %10d\n", "rtvec",
464132718Skan               rtvec_alloc_counts, rtvec_alloc_sizes);
465132718Skan      total_counts += rtvec_alloc_counts;
466132718Skan      total_sizes += rtvec_alloc_sizes;
467132718Skan    }
468132718Skan  fprintf (stderr, "---------------------------------------\n");
469132718Skan  fprintf (stderr, "%-20s %7d %10d\n",
470132718Skan           "Total", total_counts, total_sizes);
471132718Skan  fprintf (stderr, "---------------------------------------\n");
472132718Skan#endif
473132718Skan}
47418334Speter
47590075Sobrien#if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
47690075Sobrienvoid
477132718Skanrtl_check_failed_bounds (rtx r, int n, const char *file, int line,
478132718Skan			 const char *func)
47990075Sobrien{
48090075Sobrien  internal_error
481169689Skan    ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
48290075Sobrien     n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
48390075Sobrien     func, trim_filename (file), line);
48490075Sobrien}
48518334Speter
48618334Spetervoid
487132718Skanrtl_check_failed_type1 (rtx r, int n, int c1, const char *file, int line,
488132718Skan			const char *func)
48918334Speter{
49090075Sobrien  internal_error
49190075Sobrien    ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
49290075Sobrien     n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
49390075Sobrien     func, trim_filename (file), line);
49490075Sobrien}
49518334Speter
49690075Sobrienvoid
497132718Skanrtl_check_failed_type2 (rtx r, int n, int c1, int c2, const char *file,
498132718Skan			int line, const char *func)
49990075Sobrien{
50090075Sobrien  internal_error
50190075Sobrien    ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
50290075Sobrien     n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
50390075Sobrien     func, trim_filename (file), line);
50490075Sobrien}
50518334Speter
50690075Sobrienvoid
507132718Skanrtl_check_failed_code1 (rtx r, enum rtx_code code, const char *file,
508132718Skan			int line, const char *func)
50990075Sobrien{
510169689Skan  internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
51190075Sobrien		  GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
51290075Sobrien		  trim_filename (file), line);
51390075Sobrien}
51418334Speter
51590075Sobrienvoid
516132718Skanrtl_check_failed_code2 (rtx r, enum rtx_code code1, enum rtx_code code2,
517132718Skan			const char *file, int line, const char *func)
51890075Sobrien{
51990075Sobrien  internal_error
520169689Skan    ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
52190075Sobrien     GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
52290075Sobrien     func, trim_filename (file), line);
52390075Sobrien}
52418334Speter
525169689Skanvoid
526169689Skanrtl_check_failed_code_mode (rtx r, enum rtx_code code, enum machine_mode mode,
527169689Skan			    bool not_mode, const char *file, int line,
528169689Skan			    const char *func)
529169689Skan{
530169689Skan  internal_error ((not_mode
531169689Skan		   ? ("RTL check: expected code '%s' and not mode '%s', "
532169689Skan		      "have code '%s' and mode '%s' in %s, at %s:%d")
533169689Skan		   : ("RTL check: expected code '%s' and mode '%s', "
534169689Skan		      "have code '%s' and mode '%s' in %s, at %s:%d")),
535169689Skan		  GET_RTX_NAME (code), GET_MODE_NAME (mode),
536169689Skan		  GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
537169689Skan		  func, trim_filename (file), line);
538169689Skan}
539169689Skan
540169689Skan/* Report that line LINE of FILE tried to access the block symbol fields
541169689Skan   of a non-block symbol.  FUNC is the function that contains the line.  */
542169689Skan
543169689Skanvoid
544169689Skanrtl_check_failed_block_symbol (const char *file, int line, const char *func)
545169689Skan{
546169689Skan  internal_error
547169689Skan    ("RTL check: attempt to treat non-block symbol as a block symbol "
548169689Skan     "in %s, at %s:%d", func, trim_filename (file), line);
549169689Skan}
550169689Skan
55190075Sobrien/* XXX Maybe print the vector?  */
55290075Sobrienvoid
553132718Skanrtvec_check_failed_bounds (rtvec r, int n, const char *file, int line,
554132718Skan			   const char *func)
55590075Sobrien{
55690075Sobrien  internal_error
55790075Sobrien    ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
55890075Sobrien     n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line);
55918334Speter}
56090075Sobrien#endif /* ENABLE_RTL_CHECKING */
561117395Skan
562117395Skan#if defined ENABLE_RTL_FLAG_CHECKING
563117395Skanvoid
564132718Skanrtl_check_failed_flag (const char *name, rtx r, const char *file,
565132718Skan		       int line, const char *func)
566117395Skan{
567117395Skan  internal_error
568169689Skan    ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
569117395Skan     name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
570117395Skan}
571117395Skan#endif /* ENABLE_RTL_FLAG_CHECKING */
572