]>
Commit | Line | Data |
---|---|---|
875d8740 | 1 | /* RTL utility routines. |
33181afc | 2 | Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002 |
7014838c | 3 | Free Software Foundation, Inc. |
759bebca | 4 | |
f12b58b3 | 5 | This file is part of GCC. |
759bebca | 6 | |
f12b58b3 | 7 | GCC is free software; you can redistribute it and/or modify it under |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 2, or (at your option) any later | |
10 | version. | |
759bebca | 11 | |
f12b58b3 | 12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
759bebca | 16 | |
17 | You should have received a copy of the GNU General Public License | |
f12b58b3 | 18 | along with GCC; see the file COPYING. If not, write to the Free |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
759bebca | 21 | |
759bebca | 22 | #include "config.h" |
405711de | 23 | #include "system.h" |
759bebca | 24 | #include "rtl.h" |
750323c1 | 25 | #include "real.h" |
1bfd55c5 | 26 | #include "ggc.h" |
aa4c562d | 27 | #include "errors.h" |
759bebca | 28 | |
759bebca | 29 | \f |
30 | /* Indexed by rtx code, gives number of operands for an rtx with that code. | |
0e3985ee | 31 | Does NOT include rtx header data (code and links). */ |
759bebca | 32 | |
0e3985ee | 33 | #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) sizeof FORMAT - 1 , |
34 | ||
1af5f160 | 35 | const unsigned char rtx_length[NUM_RTX_CODE] = { |
0e3985ee | 36 | #include "rtl.def" |
37 | }; | |
38 | ||
39 | #undef DEF_RTL_EXPR | |
759bebca | 40 | |
41 | /* Indexed by rtx code, gives the name of that kind of rtx, as a C string. */ | |
42 | ||
43 | #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME , | |
44 | ||
1af5f160 | 45 | const char * const rtx_name[NUM_RTX_CODE] = { |
759bebca | 46 | #include "rtl.def" /* rtl expressions are documented here */ |
47 | }; | |
48 | ||
49 | #undef DEF_RTL_EXPR | |
50 | ||
51 | /* Indexed by machine mode, gives the name of that machine mode. | |
52 | This name does not include the letters "mode". */ | |
53 | ||
886cfd4f | 54 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) NAME, |
759bebca | 55 | |
1af5f160 | 56 | const char * const mode_name[NUM_MACHINE_MODES] = { |
759bebca | 57 | #include "machmode.def" |
759bebca | 58 | }; |
59 | ||
60 | #undef DEF_MACHMODE | |
61 | ||
3573fd04 | 62 | /* Indexed by machine mode, gives the class mode for GET_MODE_CLASS. */ |
759bebca | 63 | |
886cfd4f | 64 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) CLASS, |
759bebca | 65 | |
1af5f160 | 66 | const enum mode_class mode_class[NUM_MACHINE_MODES] = { |
759bebca | 67 | #include "machmode.def" |
68 | }; | |
69 | ||
70 | #undef DEF_MACHMODE | |
71 | ||
3573fd04 | 72 | /* Indexed by machine mode, gives the length of the mode, in bits. |
73 | GET_MODE_BITSIZE uses this. */ | |
74 | ||
886cfd4f | 75 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) BITSIZE, |
3573fd04 | 76 | |
1af5f160 | 77 | const unsigned short mode_bitsize[NUM_MACHINE_MODES] = { |
3573fd04 | 78 | #include "machmode.def" |
79 | }; | |
80 | ||
81 | #undef DEF_MACHMODE | |
82 | ||
759bebca | 83 | /* Indexed by machine mode, gives the length of the mode, in bytes. |
84 | GET_MODE_SIZE uses this. */ | |
85 | ||
886cfd4f | 86 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) SIZE, |
759bebca | 87 | |
1af5f160 | 88 | const unsigned char mode_size[NUM_MACHINE_MODES] = { |
759bebca | 89 | #include "machmode.def" |
90 | }; | |
91 | ||
92 | #undef DEF_MACHMODE | |
93 | ||
94 | /* Indexed by machine mode, gives the length of the mode's subunit. | |
95 | GET_MODE_UNIT_SIZE uses this. */ | |
96 | ||
886cfd4f | 97 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) UNIT, |
759bebca | 98 | |
1af5f160 | 99 | const unsigned char mode_unit_size[NUM_MACHINE_MODES] = { |
759bebca | 100 | #include "machmode.def" /* machine modes are documented here */ |
101 | }; | |
102 | ||
103 | #undef DEF_MACHMODE | |
104 | ||
105 | /* Indexed by machine mode, gives next wider natural mode | |
106 | (QI -> HI -> SI -> DI, etc.) Widening multiply instructions | |
107 | use this. */ | |
108 | ||
886cfd4f | 109 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \ |
33685f56 | 110 | (unsigned char) WIDER, |
759bebca | 111 | |
1af5f160 | 112 | const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = { |
759bebca | 113 | #include "machmode.def" /* machine modes are documented here */ |
114 | }; | |
115 | ||
116 | #undef DEF_MACHMODE | |
117 | ||
886cfd4f | 118 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \ |
33181afc | 119 | ((BITSIZE) >= HOST_BITS_PER_WIDE_INT) ? ~(unsigned HOST_WIDE_INT) 0 : ((unsigned HOST_WIDE_INT) 1 << (BITSIZE)) - 1, |
33685f56 | 120 | |
121 | /* Indexed by machine mode, gives mask of significant bits in mode. */ | |
122 | ||
1af5f160 | 123 | const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES] = { |
33685f56 | 124 | #include "machmode.def" |
125 | }; | |
126 | ||
886cfd4f | 127 | #undef DEF_MACHMODE |
128 | ||
129 | #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) INNER, | |
130 | ||
131 | /* Indexed by machine mode, gives the mode of the inner elements in a | |
132 | vector type. */ | |
133 | ||
134 | const enum machine_mode inner_mode_array[NUM_MACHINE_MODES] = { | |
135 | #include "machmode.def" | |
136 | }; | |
137 | ||
0e3985ee | 138 | /* Indexed by mode class, gives the narrowest mode for each class. |
139 | The Q modes are always of width 1 (2 for complex) - it is impossible | |
3573fd04 | 140 | for any mode to be narrower. |
141 | ||
142 | Note that we use QImode instead of BImode for MODE_INT, since | |
143 | otherwise the middle end will try to use it for bitfields in | |
144 | structures and the like, which we do not want. Only the target | |
145 | md file should generate BImode widgets. */ | |
0e3985ee | 146 | |
147 | const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS] = { | |
148 | /* MODE_RANDOM */ VOIDmode, | |
149 | /* MODE_INT */ QImode, | |
150 | /* MODE_FLOAT */ QFmode, | |
151 | /* MODE_PARTIAL_INT */ PQImode, | |
152 | /* MODE_CC */ CCmode, | |
153 | /* MODE_COMPLEX_INT */ CQImode, | |
54f4746e | 154 | /* MODE_COMPLEX_FLOAT */ QCmode, |
d33e2bd3 | 155 | /* MODE_VECTOR_INT */ V1DImode, |
54f4746e | 156 | /* MODE_VECTOR_FLOAT */ V2SFmode |
0e3985ee | 157 | }; |
f220c8f0 | 158 | |
2d066017 | 159 | |
759bebca | 160 | /* Indexed by rtx code, gives a sequence of operand-types for |
161 | rtx's of that code. The sequence is a C string in which | |
4bbea254 | 162 | each character describes one operand. */ |
759bebca | 163 | |
1af5f160 | 164 | const char * const rtx_format[NUM_RTX_CODE] = { |
759bebca | 165 | /* "*" undefined. |
166 | can cause a warning message | |
167 | "0" field is unused (or used in a phase-dependent manner) | |
168 | prints nothing | |
169 | "i" an integer | |
170 | prints the integer | |
171 | "n" like "i", but prints entries from `note_insn_name' | |
d3115c90 | 172 | "w" an integer of width HOST_BITS_PER_WIDE_INT |
173 | prints the integer | |
759bebca | 174 | "s" a pointer to a string |
175 | prints the string | |
176 | "S" like "s", but optional: | |
177 | the containing rtx may end before this operand | |
aa4c562d | 178 | "T" like "s", but treated specially by the RTL reader; |
179 | only found in machine description patterns. | |
759bebca | 180 | "e" a pointer to an rtl expression |
181 | prints the expression | |
182 | "E" a pointer to a vector that points to a number of rtl expressions | |
183 | prints a list of the rtl expressions | |
184 | "V" like "E", but optional: | |
185 | the containing rtx may end before this operand | |
186 | "u" a pointer to another insn | |
a3426c4c | 187 | prints the uid of the insn. |
188 | "b" is a pointer to a bitmap header. | |
c849df63 | 189 | "B" is a basic block pointer. |
aa40f561 | 190 | "t" is a tree pointer. */ |
759bebca | 191 | |
192 | #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , | |
193 | #include "rtl.def" /* rtl expressions are defined here */ | |
194 | #undef DEF_RTL_EXPR | |
195 | }; | |
196 | ||
197 | /* Indexed by rtx code, gives a character representing the "class" of | |
198 | that rtx code. See rtl.def for documentation on the defined classes. */ | |
199 | ||
1af5f160 | 200 | const char rtx_class[NUM_RTX_CODE] = { |
f220c8f0 | 201 | #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS, |
759bebca | 202 | #include "rtl.def" /* rtl expressions are defined here */ |
203 | #undef DEF_RTL_EXPR | |
204 | }; | |
205 | ||
206 | /* Names for kinds of NOTEs and REG_NOTEs. */ | |
207 | ||
0c981e42 | 208 | const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] = |
f220c8f0 | 209 | { |
0c981e42 | 210 | "", "NOTE_INSN_DELETED", |
f220c8f0 | 211 | "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END", |
212 | "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END", | |
f220c8f0 | 213 | "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP", |
cab14df7 | 214 | "NOTE_INSN_LOOP_END_TOP_COND", "NOTE_INSN_FUNCTION_END", |
f220c8f0 | 215 | "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG", |
216 | "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG", | |
217 | "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END", | |
f16b6102 | 218 | "NOTE_INSN_REPEATED_LINE_NUMBER", |
cd0fe062 | 219 | "NOTE_INSN_BASIC_BLOCK", "NOTE_INSN_EXPECTED_VALUE", |
220 | "NOTE_INSN_PREDICTION" | |
f220c8f0 | 221 | }; |
222 | ||
223 | const char * const reg_note_name[] = | |
224 | { | |
225 | "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_EQUAL", | |
226 | "REG_WAS_0", "REG_RETVAL", "REG_LIBCALL", "REG_NONNEG", | |
227 | "REG_NO_CONFLICT", "REG_UNUSED", "REG_CC_SETTER", "REG_CC_USER", | |
228 | "REG_LABEL", "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB", | |
229 | "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED", | |
230 | "REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION", | |
b1b11f7c | 231 | "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN", |
cef0c6a0 | 232 | "REG_NON_LOCAL_GOTO", "REG_SETJMP", "REG_ALWAYS_RETURN", |
233 | "REG_VTABLE_REF" | |
f220c8f0 | 234 | }; |
759bebca | 235 | |
ad87de1e | 236 | \f |
759bebca | 237 | /* Allocate an rtx vector of N elements. |
238 | Store the length, and initialize all elements to zero. */ | |
239 | ||
240 | rtvec | |
241 | rtvec_alloc (n) | |
242 | int n; | |
243 | { | |
244 | rtvec rt; | |
f220c8f0 | 245 | |
d7c47c0e | 246 | rt = ggc_alloc_rtvec (n); |
791ceafe | 247 | /* clear out the vector */ |
248 | memset (&rt->elem[0], 0, n * sizeof (rtx)); | |
759bebca | 249 | |
53d3f913 | 250 | PUT_NUM_ELEM (rt, n); |
759bebca | 251 | return rt; |
252 | } | |
253 | ||
254 | /* Allocate an rtx of code CODE. The CODE is stored in the rtx; | |
255 | all the rest is initialized to zero. */ | |
256 | ||
257 | rtx | |
258 | rtx_alloc (code) | |
259 | RTX_CODE code; | |
260 | { | |
261 | rtx rt; | |
791ceafe | 262 | int n = GET_RTX_LENGTH (code); |
759bebca | 263 | |
d7c47c0e | 264 | rt = ggc_alloc_rtx (n); |
1bfd55c5 | 265 | |
791ceafe | 266 | /* We want to clear everything up to the FLD array. Normally, this |
267 | is one int, but we don't want to assume that and it isn't very | |
268 | portable anyway; this is. */ | |
b56b76ec | 269 | |
791ceafe | 270 | memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion)); |
759bebca | 271 | PUT_CODE (rt, code); |
759bebca | 272 | return rt; |
273 | } | |
c49a29c7 | 274 | |
759bebca | 275 | \f |
276 | /* Create a new copy of an rtx. | |
277 | Recursively copies the operands of the rtx, | |
278 | except for those few rtx codes that are sharable. */ | |
279 | ||
280 | rtx | |
281 | copy_rtx (orig) | |
19cb6b50 | 282 | rtx orig; |
759bebca | 283 | { |
19cb6b50 | 284 | rtx copy; |
285 | int i, j; | |
286 | RTX_CODE code; | |
287 | const char *format_ptr; | |
759bebca | 288 | |
289 | code = GET_CODE (orig); | |
290 | ||
291 | switch (code) | |
292 | { | |
293 | case REG: | |
294 | case QUEUED: | |
295 | case CONST_INT: | |
296 | case CONST_DOUBLE: | |
886cfd4f | 297 | case CONST_VECTOR: |
759bebca | 298 | case SYMBOL_REF: |
299 | case CODE_LABEL: | |
300 | case PC: | |
301 | case CC0: | |
42e57659 | 302 | case SCRATCH: |
a92771b8 | 303 | /* SCRATCH must be shared because they represent distinct values. */ |
0dbd1c74 | 304 | case ADDRESSOF: |
759bebca | 305 | return orig; |
42e57659 | 306 | |
307 | case CONST: | |
308 | /* CONST can be shared if it contains a SYMBOL_REF. If it contains | |
309 | a LABEL_REF, it isn't sharable. */ | |
310 | if (GET_CODE (XEXP (orig, 0)) == PLUS | |
311 | && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF | |
312 | && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT) | |
313 | return orig; | |
314 | break; | |
315 | ||
b4495254 | 316 | /* A MEM with a constant address is not sharable. The problem is that |
317 | the constant address may need to be reloaded. If the mem is shared, | |
318 | then reloading one copy of this mem will cause all copies to appear | |
319 | to have been reloaded. */ | |
0dbd1c74 | 320 | |
321 | default: | |
322 | break; | |
759bebca | 323 | } |
324 | ||
325 | copy = rtx_alloc (code); | |
59241190 | 326 | |
327 | /* Copy the various flags, and other information. We assume that | |
328 | all fields need copying, and then clear the fields that should | |
329 | not be copied. That is the sensible default behavior, and forces | |
330 | us to explicitly document why we are *not* copying a flag. */ | |
ca7f6516 | 331 | memcpy (copy, orig, sizeof (struct rtx_def) - sizeof (rtunion)); |
59241190 | 332 | |
333 | /* We do not copy the USED flag, which is used as a mark bit during | |
334 | walks over the RTL. */ | |
e7f75e15 | 335 | RTX_FLAG (copy, used) = 0; |
59241190 | 336 | |
60ecc450 | 337 | /* We do not copy FRAME_RELATED for INSNs. */ |
59241190 | 338 | if (GET_RTX_CLASS (code) == 'i') |
e7f75e15 | 339 | RTX_FLAG (copy, frame_related) = 0; |
340 | RTX_FLAG (copy, jump) = RTX_FLAG (orig, jump); | |
341 | RTX_FLAG (copy, call) = RTX_FLAG (orig, call); | |
60ecc450 | 342 | |
759bebca | 343 | format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); |
344 | ||
345 | for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) | |
346 | { | |
d925550d | 347 | copy->fld[i] = orig->fld[i]; |
759bebca | 348 | switch (*format_ptr++) |
349 | { | |
350 | case 'e': | |
759bebca | 351 | if (XEXP (orig, i) != NULL) |
352 | XEXP (copy, i) = copy_rtx (XEXP (orig, i)); | |
353 | break; | |
354 | ||
355 | case 'E': | |
356 | case 'V': | |
759bebca | 357 | if (XVEC (orig, i) != NULL) |
358 | { | |
359 | XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); | |
360 | for (j = 0; j < XVECLEN (copy, i); j++) | |
361 | XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j)); | |
362 | } | |
363 | break; | |
364 | ||
a3426c4c | 365 | case 't': |
d3115c90 | 366 | case 'w': |
d3115c90 | 367 | case 'i': |
d3115c90 | 368 | case 's': |
369 | case 'S': | |
9abd2cd7 | 370 | case 'T': |
d925550d | 371 | case 'u': |
ab87d1bc | 372 | case 'B': |
25999090 | 373 | case '0': |
d925550d | 374 | /* These are left unchanged. */ |
25999090 | 375 | break; |
f220c8f0 | 376 | |
d3115c90 | 377 | default: |
378 | abort (); | |
759bebca | 379 | } |
380 | } | |
381 | return copy; | |
759bebca | 382 | } |
57ff0c05 | 383 | |
384 | /* Create a new copy of an rtx. Only copy just one level. */ | |
2a631e19 | 385 | |
57ff0c05 | 386 | rtx |
387 | shallow_copy_rtx (orig) | |
388 | rtx orig; | |
389 | { | |
19cb6b50 | 390 | RTX_CODE code = GET_CODE (orig); |
35aae09b | 391 | size_t n = GET_RTX_LENGTH (code); |
392 | rtx copy = ggc_alloc_rtx (n); | |
57ff0c05 | 393 | |
35aae09b | 394 | memcpy (copy, orig, |
395 | sizeof (struct rtx_def) + sizeof (rtunion) * (n - 1)); | |
57ff0c05 | 396 | |
397 | return copy; | |
398 | } | |
2a631e19 | 399 | |
400 | /* Return the alignment of MODE. This will be bounded by 1 and | |
401 | BIGGEST_ALIGNMENT. */ | |
402 | ||
403 | unsigned int | |
404 | get_mode_alignment (mode) | |
405 | enum machine_mode mode; | |
406 | { | |
886cfd4f | 407 | unsigned int alignment; |
408 | ||
409 | if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT | |
410 | || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) | |
411 | alignment = GET_MODE_UNIT_SIZE (mode); | |
412 | else | |
413 | alignment = GET_MODE_SIZE (mode); | |
2617fe26 | 414 | |
2a631e19 | 415 | /* Extract the LSB of the size. */ |
416 | alignment = alignment & -alignment; | |
417 | alignment *= BITS_PER_UNIT; | |
418 | ||
419 | alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); | |
420 | return alignment; | |
421 | } | |
759bebca | 422 | \f |
140cb7e4 | 423 | /* This is 1 until after the rtl generation pass. */ |
424 | int rtx_equal_function_value_matters; | |
316bc009 | 425 | |
426 | /* Nonzero when we are generating CONCATs. */ | |
427 | int generating_concat_p; | |
140cb7e4 | 428 | \f |
429 | /* Return 1 if X and Y are identical-looking rtx's. | |
430 | This is the Lisp function EQUAL for rtx arguments. */ | |
431 | ||
432 | int | |
433 | rtx_equal_p (x, y) | |
434 | rtx x, y; | |
435 | { | |
19cb6b50 | 436 | int i; |
437 | int j; | |
438 | enum rtx_code code; | |
439 | const char *fmt; | |
140cb7e4 | 440 | |
441 | if (x == y) | |
442 | return 1; | |
443 | if (x == 0 || y == 0) | |
444 | return 0; | |
445 | ||
446 | code = GET_CODE (x); | |
447 | /* Rtx's of different codes cannot be equal. */ | |
448 | if (code != GET_CODE (y)) | |
449 | return 0; | |
450 | ||
451 | /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. | |
452 | (REG:SI x) and (REG:HI x) are NOT equivalent. */ | |
453 | ||
454 | if (GET_MODE (x) != GET_MODE (y)) | |
455 | return 0; | |
456 | ||
73f5c1e3 | 457 | /* Some RTL can be compared nonrecursively. */ |
458 | switch (code) | |
459 | { | |
460 | case REG: | |
19cb6b50 | 461 | /* Until rtl generation is complete, don't consider a reference |
462 | to the return register of the current function the same as | |
463 | the return from a called function. This eases the job of | |
464 | function integration. Once the distinction is no longer | |
465 | needed, they can be considered equivalent. */ | |
73f5c1e3 | 466 | return (REGNO (x) == REGNO (y) |
467 | && (! rtx_equal_function_value_matters | |
468 | || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y))); | |
469 | ||
470 | case LABEL_REF: | |
471 | return XEXP (x, 0) == XEXP (y, 0); | |
472 | ||
473 | case SYMBOL_REF: | |
474 | return XSTR (x, 0) == XSTR (y, 0); | |
475 | ||
476 | case SCRATCH: | |
477 | case CONST_DOUBLE: | |
478 | case CONST_INT: | |
886cfd4f | 479 | case CONST_VECTOR: |
73f5c1e3 | 480 | return 0; |
481 | ||
482 | default: | |
483 | break; | |
484 | } | |
140cb7e4 | 485 | |
486 | /* Compare the elements. If any pair of corresponding elements | |
487 | fail to match, return 0 for the whole things. */ | |
488 | ||
489 | fmt = GET_RTX_FORMAT (code); | |
490 | for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
491 | { | |
492 | switch (fmt[i]) | |
493 | { | |
494 | case 'w': | |
495 | if (XWINT (x, i) != XWINT (y, i)) | |
496 | return 0; | |
497 | break; | |
498 | ||
499 | case 'n': | |
500 | case 'i': | |
501 | if (XINT (x, i) != XINT (y, i)) | |
502 | return 0; | |
503 | break; | |
504 | ||
505 | case 'V': | |
506 | case 'E': | |
507 | /* Two vectors must have the same length. */ | |
508 | if (XVECLEN (x, i) != XVECLEN (y, i)) | |
509 | return 0; | |
510 | ||
511 | /* And the corresponding elements must match. */ | |
512 | for (j = 0; j < XVECLEN (x, i); j++) | |
513 | if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) | |
514 | return 0; | |
515 | break; | |
516 | ||
517 | case 'e': | |
518 | if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0) | |
519 | return 0; | |
520 | break; | |
521 | ||
522 | case 'S': | |
523 | case 's': | |
100e94da | 524 | if ((XSTR (x, i) || XSTR (y, i)) |
525 | && (! XSTR (x, i) || ! XSTR (y, i) | |
526 | || strcmp (XSTR (x, i), XSTR (y, i)))) | |
140cb7e4 | 527 | return 0; |
528 | break; | |
529 | ||
530 | case 'u': | |
531 | /* These are just backpointers, so they don't matter. */ | |
532 | break; | |
533 | ||
534 | case '0': | |
535 | case 't': | |
536 | break; | |
537 | ||
538 | /* It is believed that rtx's at this level will never | |
539 | contain anything but integers and other rtx's, | |
540 | except for within LABEL_REFs and SYMBOL_REFs. */ | |
541 | default: | |
542 | abort (); | |
543 | } | |
544 | } | |
545 | return 1; | |
546 | } | |
547 | \f | |
0c4e40c5 | 548 | #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) |
25999090 | 549 | void |
550 | rtl_check_failed_bounds (r, n, file, line, func) | |
551 | rtx r; | |
552 | int n; | |
553 | const char *file; | |
554 | int line; | |
555 | const char *func; | |
556 | { | |
0fc48b82 | 557 | internal_error |
558 | ("RTL check: access of elt %d of `%s' with last elt %d in %s, at %s:%d", | |
559 | n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1, | |
560 | func, trim_filename (file), line); | |
25999090 | 561 | } |
562 | ||
563 | void | |
564 | rtl_check_failed_type1 (r, n, c1, file, line, func) | |
565 | rtx r; | |
566 | int n; | |
567 | int c1; | |
568 | const char *file; | |
569 | int line; | |
570 | const char *func; | |
571 | { | |
0fc48b82 | 572 | internal_error |
573 | ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d", | |
574 | n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)), | |
575 | func, trim_filename (file), line); | |
25999090 | 576 | } |
577 | ||
578 | void | |
579 | rtl_check_failed_type2 (r, n, c1, c2, file, line, func) | |
580 | rtx r; | |
581 | int n; | |
582 | int c1; | |
583 | int c2; | |
584 | const char *file; | |
585 | int line; | |
586 | const char *func; | |
587 | { | |
0fc48b82 | 588 | internal_error |
589 | ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d", | |
590 | n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)), | |
591 | func, trim_filename (file), line); | |
25999090 | 592 | } |
593 | ||
005d995b | 594 | void |
595 | rtl_check_failed_code1 (r, code, file, line, func) | |
596 | rtx r; | |
597 | enum rtx_code code; | |
598 | const char *file; | |
599 | int line; | |
600 | const char *func; | |
601 | { | |
0fc48b82 | 602 | internal_error ("RTL check: expected code `%s', have `%s' in %s, at %s:%d", |
603 | GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func, | |
604 | trim_filename (file), line); | |
005d995b | 605 | } |
606 | ||
607 | void | |
608 | rtl_check_failed_code2 (r, code1, code2, file, line, func) | |
609 | rtx r; | |
610 | enum rtx_code code1, code2; | |
611 | const char *file; | |
612 | int line; | |
613 | const char *func; | |
614 | { | |
0fc48b82 | 615 | internal_error |
616 | ("RTL check: expected code `%s' or `%s', have `%s' in %s, at %s:%d", | |
617 | GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)), | |
a194077b | 618 | func, trim_filename (file), line); |
005d995b | 619 | } |
620 | ||
25999090 | 621 | /* XXX Maybe print the vector? */ |
622 | void | |
623 | rtvec_check_failed_bounds (r, n, file, line, func) | |
624 | rtvec r; | |
625 | int n; | |
626 | const char *file; | |
627 | int line; | |
628 | const char *func; | |
629 | { | |
0fc48b82 | 630 | internal_error |
631 | ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d", | |
632 | n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line); | |
25999090 | 633 | } |
0c4e40c5 | 634 | #endif /* ENABLE_RTL_CHECKING */ |
e7f75e15 | 635 | |
636 | #if defined ENABLE_RTL_FLAG_CHECKING | |
637 | void | |
3c6858c6 | 638 | rtl_check_failed_flag (name, r, file, line, func) |
639 | const char *name; | |
e7f75e15 | 640 | rtx r; |
641 | const char *file; | |
642 | int line; | |
643 | const char *func; | |
644 | { | |
645 | internal_error | |
3c6858c6 | 646 | ("RTL flag check: %s used with unexpected rtx code `%s' in %s, at %s:%d", |
647 | name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line); | |
e7f75e15 | 648 | } |
649 | #endif /* ENABLE_RTL_FLAG_CHECKING */ |