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