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