]> gcc.gnu.org Git - gcc.git/blame - gcc/rtlanal.c
*** empty log message ***
[gcc.git] / gcc / rtlanal.c
CommitLineData
2c88418c 1/* Analyze RTL for C-Compiler
84607dc1 2 Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
2c88418c
RS
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include "rtl.h"
23
24void note_stores ();
25int reg_set_p ();
26
27/* Bit flags that specify the machine subtype we are compiling for.
28 Bits are tested using macros TARGET_... defined in the tm.h file
29 and set by `-m...' switches. Must be defined in rtlanal.c. */
30
31int target_flags;
32\f
33/* Return 1 if the value of X is unstable
34 (would be different at a different point in the program).
35 The frame pointer, arg pointer, etc. are considered stable
36 (within one function) and so is anything marked `unchanging'. */
37
38int
39rtx_unstable_p (x)
40 rtx x;
41{
42 register RTX_CODE code = GET_CODE (x);
43 register int i;
44 register char *fmt;
45
46 if (code == MEM)
47 return ! RTX_UNCHANGING_P (x);
48
49 if (code == QUEUED)
50 return 1;
51
52 if (code == CONST || code == CONST_INT)
53 return 0;
54
55 if (code == REG)
56 return ! (REGNO (x) == FRAME_POINTER_REGNUM
57 || REGNO (x) == ARG_POINTER_REGNUM
58 || RTX_UNCHANGING_P (x));
59
60 fmt = GET_RTX_FORMAT (code);
61 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
62 if (fmt[i] == 'e')
63 if (rtx_unstable_p (XEXP (x, i)))
64 return 1;
65 return 0;
66}
67
68/* Return 1 if X has a value that can vary even between two
69 executions of the program. 0 means X can be compared reliably
70 against certain constants or near-constants.
71 The frame pointer and the arg pointer are considered constant. */
72
73int
74rtx_varies_p (x)
75 rtx x;
76{
77 register RTX_CODE code = GET_CODE (x);
78 register int i;
79 register char *fmt;
80
81 switch (code)
82 {
83 case MEM:
84 case QUEUED:
85 return 1;
86
87 case CONST:
88 case CONST_INT:
89 case CONST_DOUBLE:
90 case SYMBOL_REF:
91 case LABEL_REF:
92 return 0;
93
94 case REG:
95 /* Note that we have to test for the actual rtx used for the frame
96 and arg pointers and not just the register number in case we have
97 eliminated the frame and/or arg pointer and are using it
98 for pseudos. */
99 return ! (x == frame_pointer_rtx || x == arg_pointer_rtx);
100
101 case LO_SUM:
102 /* The operand 0 of a LO_SUM is considered constant
103 (in fact is it related specifically to operand 1). */
104 return rtx_varies_p (XEXP (x, 1));
105 }
106
107 fmt = GET_RTX_FORMAT (code);
108 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
109 if (fmt[i] == 'e')
110 if (rtx_varies_p (XEXP (x, i)))
111 return 1;
112 return 0;
113}
114
115/* Return 0 if the use of X as an address in a MEM can cause a trap. */
116
117int
118rtx_addr_can_trap_p (x)
119 register rtx x;
120{
121 register enum rtx_code code = GET_CODE (x);
122
123 switch (code)
124 {
125 case SYMBOL_REF:
126 case LABEL_REF:
127 /* SYMBOL_REF is problematic due to the possible presence of
128 a #pragma weak, but to say that loads from symbols can trap is
129 *very* costly. It's not at all clear what's best here. For
130 now, we ignore the impact of #pragma weak. */
131 return 0;
132
133 case REG:
134 /* As in rtx_varies_p, we have to use the actual rtx, not reg number. */
135 return ! (x == frame_pointer_rtx || x == stack_pointer_rtx
136 || x == arg_pointer_rtx);
137
138 case CONST:
139 return rtx_addr_can_trap_p (XEXP (x, 0));
140
141 case PLUS:
142 /* An address is assumed not to trap if it is an address that can't
143 trap plus a constant integer. */
144 return (rtx_addr_can_trap_p (XEXP (x, 0))
145 || GET_CODE (XEXP (x, 1)) != CONST_INT);
146
147 case LO_SUM:
148 return rtx_addr_can_trap_p (XEXP (x, 1));
149 }
150
151 /* If it isn't one of the case above, it can cause a trap. */
152 return 1;
153}
154
155/* Return 1 if X refers to a memory location whose address
156 cannot be compared reliably with constant addresses,
157 or if X refers to a BLKmode memory object. */
158
159int
160rtx_addr_varies_p (x)
161 rtx x;
162{
163 register enum rtx_code code;
164 register int i;
165 register char *fmt;
166
167 if (x == 0)
168 return 0;
169
170 code = GET_CODE (x);
171 if (code == MEM)
172 return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
173
174 fmt = GET_RTX_FORMAT (code);
175 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
176 if (fmt[i] == 'e')
177 if (rtx_addr_varies_p (XEXP (x, i)))
178 return 1;
179 return 0;
180}
181\f
182/* Return the value of the integer term in X, if one is apparent;
183 otherwise return 0.
184 Only obvious integer terms are detected.
185 This is used in cse.c with the `related_value' field.*/
186
187int
188get_integer_term (x)
189 rtx x;
190{
191 if (GET_CODE (x) == CONST)
192 x = XEXP (x, 0);
193
194 if (GET_CODE (x) == MINUS
195 && GET_CODE (XEXP (x, 1)) == CONST_INT)
196 return - INTVAL (XEXP (x, 1));
197 if (GET_CODE (x) == PLUS
198 && GET_CODE (XEXP (x, 1)) == CONST_INT)
199 return INTVAL (XEXP (x, 1));
200 return 0;
201}
202
203/* If X is a constant, return the value sans apparent integer term;
204 otherwise return 0.
205 Only obvious integer terms are detected. */
206
207rtx
208get_related_value (x)
209 rtx x;
210{
211 if (GET_CODE (x) != CONST)
212 return 0;
213 x = XEXP (x, 0);
214 if (GET_CODE (x) == PLUS
215 && GET_CODE (XEXP (x, 1)) == CONST_INT)
216 return XEXP (x, 0);
217 else if (GET_CODE (x) == MINUS
218 && GET_CODE (XEXP (x, 1)) == CONST_INT)
219 return XEXP (x, 0);
220 return 0;
221}
222\f
223/* Nonzero if register REG appears somewhere within IN.
224 Also works if REG is not a register; in this case it checks
225 for a subexpression of IN that is Lisp "equal" to REG. */
226
227int
228reg_mentioned_p (reg, in)
229 register rtx reg, in;
230{
231 register char *fmt;
232 register int i;
233 register enum rtx_code code;
234
235 if (in == 0)
236 return 0;
237
238 if (reg == in)
239 return 1;
240
241 if (GET_CODE (in) == LABEL_REF)
242 return reg == XEXP (in, 0);
243
244 code = GET_CODE (in);
245
246 switch (code)
247 {
248 /* Compare registers by number. */
249 case REG:
250 return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
251
252 /* These codes have no constituent expressions
253 and are unique. */
254 case SCRATCH:
255 case CC0:
256 case PC:
257 return 0;
258
259 case CONST_INT:
260 return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
261
262 case CONST_DOUBLE:
263 /* These are kept unique for a given value. */
264 return 0;
265 }
266
267 if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
268 return 1;
269
270 fmt = GET_RTX_FORMAT (code);
271
272 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
273 {
274 if (fmt[i] == 'E')
275 {
276 register int j;
277 for (j = XVECLEN (in, i) - 1; j >= 0; j--)
278 if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
279 return 1;
280 }
281 else if (fmt[i] == 'e'
282 && reg_mentioned_p (reg, XEXP (in, i)))
283 return 1;
284 }
285 return 0;
286}
287\f
288/* Return 1 if in between BEG and END, exclusive of BEG and END, there is
289 no CODE_LABEL insn. */
290
291int
292no_labels_between_p (beg, end)
293 rtx beg, end;
294{
295 register rtx p;
296 for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
297 if (GET_CODE (p) == CODE_LABEL)
298 return 0;
299 return 1;
300}
301
302/* Nonzero if register REG is used in an insn between
303 FROM_INSN and TO_INSN (exclusive of those two). */
304
305int
306reg_used_between_p (reg, from_insn, to_insn)
307 rtx reg, from_insn, to_insn;
308{
309 register rtx insn;
310
311 if (from_insn == to_insn)
312 return 0;
313
314 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
315 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
316 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
317 return 1;
318 return 0;
319}
320\f
321/* Nonzero if the old value of X, a register, is referenced in BODY. If X
322 is entirely replaced by a new value and the only use is as a SET_DEST,
323 we do not consider it a reference. */
324
325int
326reg_referenced_p (x, body)
327 rtx x;
328 rtx body;
329{
330 int i;
331
332 switch (GET_CODE (body))
333 {
334 case SET:
335 if (reg_overlap_mentioned_p (x, SET_SRC (body)))
336 return 1;
337
338 /* If the destination is anything other than CC0, PC, a REG or a SUBREG
339 of a REG that occupies all of the REG, the insn references X if
340 it is mentioned in the destination. */
341 if (GET_CODE (SET_DEST (body)) != CC0
342 && GET_CODE (SET_DEST (body)) != PC
343 && GET_CODE (SET_DEST (body)) != REG
344 && ! (GET_CODE (SET_DEST (body)) == SUBREG
345 && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG
346 && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
347 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
348 == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
349 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
350 && reg_overlap_mentioned_p (x, SET_DEST (body)))
351 return 1;
352 break;
353
354 case ASM_OPERANDS:
355 for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
356 if (reg_overlap_mentioned_p (x, ASM_OPERANDS_INPUT (body, i)))
357 return 1;
358 break;
359
360 case CALL:
361 case USE:
362 return reg_overlap_mentioned_p (x, body);
363
364 case TRAP_IF:
365 return reg_overlap_mentioned_p (x, TRAP_CONDITION (body));
366
367 case PARALLEL:
368 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
369 if (reg_referenced_p (x, XVECEXP (body, 0, i)))
370 return 1;
371 break;
372 }
373
374 return 0;
375}
376
377/* Nonzero if register REG is referenced in an insn between
378 FROM_INSN and TO_INSN (exclusive of those two). Sets of REG do
379 not count. */
380
381int
382reg_referenced_between_p (reg, from_insn, to_insn)
383 rtx reg, from_insn, to_insn;
384{
385 register rtx insn;
386
387 if (from_insn == to_insn)
388 return 0;
389
390 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
391 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
392 && reg_referenced_p (reg, PATTERN (insn)))
393 return 1;
394 return 0;
395}
396\f
397/* Nonzero if register REG is set or clobbered in an insn between
398 FROM_INSN and TO_INSN (exclusive of those two). */
399
400int
401reg_set_between_p (reg, from_insn, to_insn)
402 rtx reg, from_insn, to_insn;
403{
404 register rtx insn;
405
406 if (from_insn == to_insn)
407 return 0;
408
409 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
410 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
84607dc1 411 && reg_set_p (reg, insn))
2c88418c
RS
412 return 1;
413 return 0;
414}
415
416/* Internals of reg_set_between_p. */
417
418static rtx reg_set_reg;
419static int reg_set_flag;
420
421void
422reg_set_p_1 (x)
423 rtx x;
424{
425 /* We don't want to return 1 if X is a MEM that contains a register
426 within REG_SET_REG. */
427
428 if ((GET_CODE (x) != MEM)
429 && reg_overlap_mentioned_p (reg_set_reg, x))
430 reg_set_flag = 1;
431}
432
433int
434reg_set_p (reg, insn)
435 rtx reg, insn;
436{
437 rtx body = insn;
438
439 /* We can be passed an insn or part of one. If we are passed an insn,
440 check if a side-effect of the insn clobbers REG. */
441 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
442 {
443 if (FIND_REG_INC_NOTE (insn, reg)
444 || (GET_CODE (insn) == CALL_INSN
445 /* We'd like to test call_used_regs here, but rtlanal.c can't
446 reference that variable due to its use in genattrtab. So
447 we'll just be more conservative. */
448 && ((GET_CODE (reg) == REG
449 && REGNO (reg) < FIRST_PSEUDO_REGISTER)
450 || GET_CODE (reg) == MEM)))
451 return 1;
452
453 body = PATTERN (insn);
454 }
455
456 reg_set_reg = reg;
457 reg_set_flag = 0;
458 note_stores (body, reg_set_p_1);
459 return reg_set_flag;
460}
461
462/* Similar to reg_set_between_p, but check all registers in X. Return 0
463 only if none of them are modified between START and END. Return 1 if
464 X contains a MEM; this routine does not perform any memory aliasing. */
465
466int
467modified_between_p (x, start, end)
468 rtx x;
469 rtx start, end;
470{
471 enum rtx_code code = GET_CODE (x);
472 char *fmt;
473 int i;
474
475 switch (code)
476 {
477 case CONST_INT:
478 case CONST_DOUBLE:
479 case CONST:
480 case SYMBOL_REF:
481 case LABEL_REF:
482 return 0;
483
484 case PC:
485 case CC0:
486 return 1;
487
488 case MEM:
489 /* If the memory is not constant, assume it is modified. If it is
490 constant, we still have to check the address. */
491 if (! RTX_UNCHANGING_P (x))
492 return 1;
493 break;
494
495 case REG:
496 return reg_set_between_p (x, start, end);
497 }
498
499 fmt = GET_RTX_FORMAT (code);
500 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
501 if (fmt[i] == 'e'
502 && modified_between_p (XEXP (x, i), start, end))
503 return 1;
504
505 return 0;
506}
507\f
508/* Given an INSN, return a SET expression if this insn has only a single SET.
509 It may also have CLOBBERs, USEs, or SET whose output
510 will not be used, which we ignore. */
511
512rtx
513single_set (insn)
514 rtx insn;
515{
516 rtx set;
517 int i;
518
519 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
520 return 0;
521
522 if (GET_CODE (PATTERN (insn)) == SET)
523 return PATTERN (insn);
524
525 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
526 {
527 for (i = 0, set = 0; i < XVECLEN (PATTERN (insn), 0); i++)
528 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
529 && ! (find_reg_note (insn, REG_UNUSED,
530 SET_DEST (XVECEXP (PATTERN (insn), 0, i)))
531 || side_effects_p (XVECEXP (PATTERN (insn), 0, i))))
532 {
533 if (set)
534 return 0;
535 else
536 set = XVECEXP (PATTERN (insn), 0, i);
537 }
538 return set;
539 }
540
541 return 0;
542}
543\f
544/* Return the last thing that X was assigned from before *PINSN. Verify that
545 the object is not modified up to VALID_TO. If it was, if we hit
546 a partial assignment to X, or hit a CODE_LABEL first, return X. If we
547 found an assignment, update *PINSN to point to it. */
548
549rtx
550find_last_value (x, pinsn, valid_to)
551 rtx x;
552 rtx *pinsn;
553 rtx valid_to;
554{
555 rtx p;
556
557 for (p = PREV_INSN (*pinsn); p && GET_CODE (p) != CODE_LABEL;
558 p = PREV_INSN (p))
559 if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
560 {
561 rtx set = single_set (p);
562 rtx note = find_reg_note (p, REG_EQUAL, 0);
563
564 if (set && rtx_equal_p (x, SET_DEST (set)))
565 {
566 rtx src = SET_SRC (set);
567
568 if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
569 src = XEXP (note, 0);
570
571 if (! modified_between_p (src, PREV_INSN (p), valid_to)
572 /* Reject hard registers because we don't usually want
573 to use them; we'd rather use a pseudo. */
574 && ! (GET_CODE (src) == REG
575 && REGNO (src) < FIRST_PSEUDO_REGISTER))
576 {
577 *pinsn = p;
578 return src;
579 }
580 }
581
582 /* If set in non-simple way, we don't have a value. */
583 if (reg_set_p (x, p))
584 break;
585 }
586
587 return x;
588}
589\f
590/* Return nonzero if register in range [REGNO, ENDREGNO)
591 appears either explicitly or implicitly in X
592 other than being stored into.
593
594 References contained within the substructure at LOC do not count.
595 LOC may be zero, meaning don't ignore anything. */
596
597int
598refers_to_regno_p (regno, endregno, x, loc)
599 int regno, endregno;
600 rtx x;
601 rtx *loc;
602{
603 register int i;
604 register RTX_CODE code;
605 register char *fmt;
606
607 repeat:
608 /* The contents of a REG_NONNEG note is always zero, so we must come here
609 upon repeat in case the last REG_NOTE is a REG_NONNEG note. */
610 if (x == 0)
611 return 0;
612
613 code = GET_CODE (x);
614
615 switch (code)
616 {
617 case REG:
618 i = REGNO (x);
619 return (endregno > i
620 && regno < i + (i < FIRST_PSEUDO_REGISTER
621 ? HARD_REGNO_NREGS (i, GET_MODE (x))
622 : 1));
623
624 case SUBREG:
625 /* If this is a SUBREG of a hard reg, we can see exactly which
626 registers are being modified. Otherwise, handle normally. */
627 if (GET_CODE (SUBREG_REG (x)) == REG
628 && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
629 {
630 int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
631 int inner_endregno
632 = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
633 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
634
635 return endregno > inner_regno && regno < inner_endregno;
636 }
637 break;
638
639 case CLOBBER:
640 case SET:
641 if (&SET_DEST (x) != loc
642 /* Note setting a SUBREG counts as referring to the REG it is in for
643 a pseudo but not for hard registers since we can
644 treat each word individually. */
645 && ((GET_CODE (SET_DEST (x)) == SUBREG
646 && loc != &SUBREG_REG (SET_DEST (x))
647 && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
648 && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
649 && refers_to_regno_p (regno, endregno,
650 SUBREG_REG (SET_DEST (x)), loc))
651 || (GET_CODE (SET_DEST (x)) != REG
652 && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))))
653 return 1;
654
655 if (code == CLOBBER || loc == &SET_SRC (x))
656 return 0;
657 x = SET_SRC (x);
658 goto repeat;
659 }
660
661 /* X does not match, so try its subexpressions. */
662
663 fmt = GET_RTX_FORMAT (code);
664 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
665 {
666 if (fmt[i] == 'e' && loc != &XEXP (x, i))
667 {
668 if (i == 0)
669 {
670 x = XEXP (x, 0);
671 goto repeat;
672 }
673 else
674 if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
675 return 1;
676 }
677 else if (fmt[i] == 'E')
678 {
679 register int j;
680 for (j = XVECLEN (x, i) - 1; j >=0; j--)
681 if (loc != &XVECEXP (x, i, j)
682 && refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
683 return 1;
684 }
685 }
686 return 0;
687}
688
689/* Nonzero if modifying X will affect IN. If X is a register or a SUBREG,
690 we check if any register number in X conflicts with the relevant register
691 numbers. If X is a constant, return 0. If X is a MEM, return 1 iff IN
692 contains a MEM (we don't bother checking for memory addresses that can't
693 conflict because we expect this to be a rare case. */
694
695int
696reg_overlap_mentioned_p (x, in)
697 rtx x, in;
698{
699 int regno, endregno;
700
701 if (GET_CODE (x) == SUBREG)
702 {
703 regno = REGNO (SUBREG_REG (x));
704 if (regno < FIRST_PSEUDO_REGISTER)
705 regno += SUBREG_WORD (x);
706 }
707 else if (GET_CODE (x) == REG)
708 regno = REGNO (x);
709 else if (CONSTANT_P (x))
710 return 0;
711 else if (GET_CODE (x) == MEM)
712 {
713 char *fmt;
714 int i;
715
716 if (GET_CODE (in) == MEM)
717 return 1;
718
719 fmt = GET_RTX_FORMAT (GET_CODE (in));
720
721 for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
722 if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
723 return 1;
724
725 return 0;
726 }
727 else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
728 || GET_CODE (x) == CC0)
729 return reg_mentioned_p (x, in);
730 else
731 abort ();
732
733 endregno = regno + (regno < FIRST_PSEUDO_REGISTER
734 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
735
736 return refers_to_regno_p (regno, endregno, in, 0);
737}
738\f
739/* Used for communications between the next few functions. */
740
741static int reg_set_last_unknown;
742static rtx reg_set_last_value;
743static int reg_set_last_first_regno, reg_set_last_last_regno;
744
745/* Called via note_stores from reg_set_last. */
746
747static void
748reg_set_last_1 (x, pat)
749 rtx x;
750 rtx pat;
751{
752 int first, last;
753
754 /* If X is not a register, or is not one in the range we care
755 about, ignore. */
756 if (GET_CODE (x) != REG)
757 return;
758
759 first = REGNO (x);
760 last = first + (first < FIRST_PSEUDO_REGISTER
761 ? HARD_REGNO_NREGS (first, GET_MODE (x)) : 1);
762
763 if (first >= reg_set_last_last_regno
764 || last <= reg_set_last_first_regno)
765 return;
766
767 /* If this is a CLOBBER or is some complex LHS, or doesn't modify
768 exactly the registers we care about, show we don't know the value. */
769 if (GET_CODE (pat) == CLOBBER || SET_DEST (pat) != x
770 || first != reg_set_last_first_regno
771 || last != reg_set_last_last_regno)
772 reg_set_last_unknown = 1;
773 else
774 reg_set_last_value = SET_SRC (pat);
775}
776
777/* Return the last value to which REG was set prior to INSN. If we can't
778 find it easily, return 0.
779
780 We only return a REG or constant because it is too hard to check if a
781 MEM remains unchanged. */
782
783rtx
784reg_set_last (x, insn)
785 rtx x;
786 rtx insn;
787{
788 rtx orig_insn = insn;
789
790 reg_set_last_first_regno = REGNO (x);
791
792 reg_set_last_last_regno
793 = reg_set_last_first_regno
794 + (reg_set_last_first_regno < FIRST_PSEUDO_REGISTER
795 ? HARD_REGNO_NREGS (reg_set_last_first_regno, GET_MODE (x)) : 1);
796
797 reg_set_last_unknown = 0;
798 reg_set_last_value = 0;
799
800 /* Scan backwards until reg_set_last_1 changed one of the above flags.
801 Stop when we reach a label or X is a hard reg and we reach a
802 CALL_INSN (if reg_set_last_last_regno is a hard reg).
803
804 If we find a set of X, ensure that its SET_SRC remains unchanged. */
805
806 for (;
807 insn && GET_CODE (insn) != CODE_LABEL
808 && ! (GET_CODE (insn) == CALL_INSN
809 && reg_set_last_last_regno <= FIRST_PSEUDO_REGISTER);
810 insn = PREV_INSN (insn))
811 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
812 {
813 note_stores (PATTERN (insn), reg_set_last_1);
814 if (reg_set_last_unknown)
815 return 0;
816 else if (reg_set_last_value)
817 {
818 if (CONSTANT_P (reg_set_last_value)
819 || (GET_CODE (reg_set_last_value) == REG
820 && ! reg_set_between_p (reg_set_last_value,
821 NEXT_INSN (insn), orig_insn)))
822 return reg_set_last_value;
823 else
824 return 0;
825 }
826 }
827
828 return 0;
829}
830\f
831/* This is 1 until after reload pass. */
832int rtx_equal_function_value_matters;
833
834/* Return 1 if X and Y are identical-looking rtx's.
835 This is the Lisp function EQUAL for rtx arguments. */
836
837int
838rtx_equal_p (x, y)
839 rtx x, y;
840{
841 register int i;
842 register int j;
843 register enum rtx_code code;
844 register char *fmt;
845
846 if (x == y)
847 return 1;
848 if (x == 0 || y == 0)
849 return 0;
850
851 code = GET_CODE (x);
852 /* Rtx's of different codes cannot be equal. */
853 if (code != GET_CODE (y))
854 return 0;
855
856 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
857 (REG:SI x) and (REG:HI x) are NOT equivalent. */
858
859 if (GET_MODE (x) != GET_MODE (y))
860 return 0;
861
862 /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */
863
864 if (code == REG)
865 /* Until rtl generation is complete, don't consider a reference to the
866 return register of the current function the same as the return from a
867 called function. This eases the job of function integration. Once the
868 distinction is no longer needed, they can be considered equivalent. */
869 return (REGNO (x) == REGNO (y)
870 && (! rtx_equal_function_value_matters
871 || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
872 else if (code == LABEL_REF)
873 return XEXP (x, 0) == XEXP (y, 0);
874 else if (code == SYMBOL_REF)
875 return XSTR (x, 0) == XSTR (y, 0);
876 else if (code == SCRATCH || code == CONST_DOUBLE)
877 return 0;
878
879 /* Compare the elements. If any pair of corresponding elements
880 fail to match, return 0 for the whole things. */
881
882 fmt = GET_RTX_FORMAT (code);
883 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
884 {
885 switch (fmt[i])
886 {
887 case 'n':
888 case 'i':
889 if (XINT (x, i) != XINT (y, i))
890 return 0;
891 break;
892
893 case 'V':
894 case 'E':
895 /* Two vectors must have the same length. */
896 if (XVECLEN (x, i) != XVECLEN (y, i))
897 return 0;
898
899 /* And the corresponding elements must match. */
900 for (j = 0; j < XVECLEN (x, i); j++)
901 if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
902 return 0;
903 break;
904
905 case 'e':
906 if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
907 return 0;
908 break;
909
910 case 'S':
911 case 's':
912 if (strcmp (XSTR (x, i), XSTR (y, i)))
913 return 0;
914 break;
915
916 case 'u':
917 /* These are just backpointers, so they don't matter. */
918 break;
919
920 case '0':
921 break;
922
923 /* It is believed that rtx's at this level will never
924 contain anything but integers and other rtx's,
925 except for within LABEL_REFs and SYMBOL_REFs. */
926 default:
927 abort ();
928 }
929 }
930 return 1;
931}
932\f
933/* Call FUN on each register or MEM that is stored into or clobbered by X.
934 (X would be the pattern of an insn).
935 FUN receives two arguments:
936 the REG, MEM, CC0 or PC being stored in or clobbered,
937 the SET or CLOBBER rtx that does the store.
938
939 If the item being stored in or clobbered is a SUBREG of a hard register,
940 the SUBREG will be passed. */
941
942void
943note_stores (x, fun)
944 register rtx x;
945 void (*fun) ();
946{
947 if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
948 {
949 register rtx dest = SET_DEST (x);
950 while ((GET_CODE (dest) == SUBREG
951 && (GET_CODE (SUBREG_REG (dest)) != REG
952 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
953 || GET_CODE (dest) == ZERO_EXTRACT
954 || GET_CODE (dest) == SIGN_EXTRACT
955 || GET_CODE (dest) == STRICT_LOW_PART)
956 dest = XEXP (dest, 0);
957 (*fun) (dest, x);
958 }
959 else if (GET_CODE (x) == PARALLEL)
960 {
961 register int i;
962 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
963 {
964 register rtx y = XVECEXP (x, 0, i);
965 if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
966 {
967 register rtx dest = SET_DEST (y);
968 while ((GET_CODE (dest) == SUBREG
969 && (GET_CODE (SUBREG_REG (dest)) != REG
970 || (REGNO (SUBREG_REG (dest))
971 >= FIRST_PSEUDO_REGISTER)))
972 || GET_CODE (dest) == ZERO_EXTRACT
973 || GET_CODE (dest) == SIGN_EXTRACT
974 || GET_CODE (dest) == STRICT_LOW_PART)
975 dest = XEXP (dest, 0);
976 (*fun) (dest, y);
977 }
978 }
979 }
980}
981\f
982/* Return nonzero if X's old contents don't survive after INSN.
983 This will be true if X is (cc0) or if X is a register and
984 X dies in INSN or because INSN entirely sets X.
985
986 "Entirely set" means set directly and not through a SUBREG,
987 ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
988 Likewise, REG_INC does not count.
989
990 REG may be a hard or pseudo reg. Renumbering is not taken into account,
991 but for this use that makes no difference, since regs don't overlap
992 during their lifetimes. Therefore, this function may be used
993 at any time after deaths have been computed (in flow.c).
994
995 If REG is a hard reg that occupies multiple machine registers, this
996 function will only return 1 if each of those registers will be replaced
997 by INSN. */
998
999int
1000dead_or_set_p (insn, x)
1001 rtx insn;
1002 rtx x;
1003{
1004 register int regno, last_regno;
1005 register int i;
1006
1007 /* Can't use cc0_rtx below since this file is used by genattrtab.c. */
1008 if (GET_CODE (x) == CC0)
1009 return 1;
1010
1011 if (GET_CODE (x) != REG)
1012 abort ();
1013
1014 regno = REGNO (x);
1015 last_regno = (regno >= FIRST_PSEUDO_REGISTER ? regno
1016 : regno + HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1);
1017
1018 for (i = regno; i <= last_regno; i++)
1019 if (! dead_or_set_regno_p (insn, i))
1020 return 0;
1021
1022 return 1;
1023}
1024
1025/* Utility function for dead_or_set_p to check an individual register. Also
1026 called from flow.c. */
1027
1028int
1029dead_or_set_regno_p (insn, test_regno)
1030 rtx insn;
1031 int test_regno;
1032{
1033 int regno, endregno;
1034 rtx link;
1035
1036 /* See if there is a death note for something that includes TEST_REGNO. */
1037 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1038 {
1039 if (REG_NOTE_KIND (link) != REG_DEAD || GET_CODE (XEXP (link, 0)) != REG)
1040 continue;
1041
1042 regno = REGNO (XEXP (link, 0));
1043 endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1044 : regno + HARD_REGNO_NREGS (regno,
1045 GET_MODE (XEXP (link, 0))));
1046
1047 if (test_regno >= regno && test_regno < endregno)
1048 return 1;
1049 }
1050
1051 if (GET_CODE (PATTERN (insn)) == SET)
1052 {
1053 rtx dest = SET_DEST (PATTERN (insn));
1054
1055 /* A value is totally replaced if it is the destination or the
1056 destination is a SUBREG of REGNO that does not change the number of
1057 words in it. */
1058 if (GET_CODE (dest) == SUBREG
1059 && (((GET_MODE_SIZE (GET_MODE (dest))
1060 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1061 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1062 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
1063 dest = SUBREG_REG (dest);
1064
1065 if (GET_CODE (dest) != REG)
1066 return 0;
1067
1068 regno = REGNO (dest);
1069 endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1070 : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
1071
1072 return (test_regno >= regno && test_regno < endregno);
1073 }
1074 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1075 {
1076 register int i;
1077
1078 for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
1079 {
1080 rtx body = XVECEXP (PATTERN (insn), 0, i);
1081
1082 if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
1083 {
1084 rtx dest = SET_DEST (body);
1085
1086 if (GET_CODE (dest) == SUBREG
1087 && (((GET_MODE_SIZE (GET_MODE (dest))
1088 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1089 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1090 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
1091 dest = SUBREG_REG (dest);
1092
1093 if (GET_CODE (dest) != REG)
1094 continue;
1095
1096 regno = REGNO (dest);
1097 endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1098 : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
1099
1100 if (test_regno >= regno && test_regno < endregno)
1101 return 1;
1102 }
1103 }
1104 }
1105
1106 return 0;
1107}
1108
1109/* Return the reg-note of kind KIND in insn INSN, if there is one.
1110 If DATUM is nonzero, look for one whose datum is DATUM. */
1111
1112rtx
1113find_reg_note (insn, kind, datum)
1114 rtx insn;
1115 enum reg_note kind;
1116 rtx datum;
1117{
1118 register rtx link;
1119
1120 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1121 if (REG_NOTE_KIND (link) == kind
1122 && (datum == 0 || datum == XEXP (link, 0)))
1123 return link;
1124 return 0;
1125}
1126
1127/* Return the reg-note of kind KIND in insn INSN which applies to register
1128 number REGNO, if any. Return 0 if there is no such reg-note. */
1129
1130rtx
1131find_regno_note (insn, kind, regno)
1132 rtx insn;
1133 enum reg_note kind;
1134 int regno;
1135{
1136 register rtx link;
1137
1138 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1139 if (REG_NOTE_KIND (link) == kind
1140 /* Verify that it is a register, so that scratch and MEM won't cause a
1141 problem here. */
1142 && GET_CODE (XEXP (link, 0)) == REG
1143 && REGNO (XEXP (link, 0)) == regno)
1144 return link;
1145 return 0;
1146}
1147\f
1148/* Remove register note NOTE from the REG_NOTES of INSN. */
1149
1150void
1151remove_note (insn, note)
1152 register rtx note;
1153 register rtx insn;
1154{
1155 register rtx link;
1156
1157 if (REG_NOTES (insn) == note)
1158 {
1159 REG_NOTES (insn) = XEXP (note, 1);
1160 return;
1161 }
1162
1163 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1164 if (XEXP (link, 1) == note)
1165 {
1166 XEXP (link, 1) = XEXP (note, 1);
1167 return;
1168 }
1169
1170 abort ();
1171}
1172\f
1173/* Nonzero if X contains any volatile memory references
1174 or volatile ASM_OPERANDS expressions. */
1175
1176int
1177volatile_refs_p (x)
1178 rtx x;
1179{
1180 register RTX_CODE code;
1181
1182 code = GET_CODE (x);
1183 switch (code)
1184 {
1185 case LABEL_REF:
1186 case SYMBOL_REF:
1187 case CONST_INT:
1188 case CONST:
1189 case CONST_DOUBLE:
1190 case CC0:
1191 case PC:
1192 case REG:
1193 case SCRATCH:
1194 case CLOBBER:
1195 case ASM_INPUT:
1196 case ADDR_VEC:
1197 case ADDR_DIFF_VEC:
1198 return 0;
1199
1200 case CALL:
1201 /* case TRAP_IF: This isn't clear yet. */
1202 return 1;
1203
1204 case MEM:
1205 case ASM_OPERANDS:
1206 if (MEM_VOLATILE_P (x))
1207 return 1;
1208 }
1209
1210 /* Recursively scan the operands of this expression. */
1211
1212 {
1213 register char *fmt = GET_RTX_FORMAT (code);
1214 register int i;
1215
1216 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1217 {
1218 if (fmt[i] == 'e')
1219 {
1220 if (volatile_refs_p (XEXP (x, i)))
1221 return 1;
1222 }
1223 if (fmt[i] == 'E')
1224 {
1225 register int j;
1226 for (j = 0; j < XVECLEN (x, i); j++)
1227 if (volatile_refs_p (XVECEXP (x, i, j)))
1228 return 1;
1229 }
1230 }
1231 }
1232 return 0;
1233}
1234
1235/* Similar to above, except that it also rejects register pre- and post-
1236 incrementing. */
1237
1238int
1239side_effects_p (x)
1240 rtx x;
1241{
1242 register RTX_CODE code;
1243
1244 code = GET_CODE (x);
1245 switch (code)
1246 {
1247 case LABEL_REF:
1248 case SYMBOL_REF:
1249 case CONST_INT:
1250 case CONST:
1251 case CONST_DOUBLE:
1252 case CC0:
1253 case PC:
1254 case REG:
1255 case SCRATCH:
1256 case ASM_INPUT:
1257 case ADDR_VEC:
1258 case ADDR_DIFF_VEC:
1259 return 0;
1260
1261 case CLOBBER:
1262 /* Reject CLOBBER with a non-VOID mode. These are made by combine.c
1263 when some combination can't be done. If we see one, don't think
1264 that we can simplify the expression. */
1265 return (GET_MODE (x) != VOIDmode);
1266
1267 case PRE_INC:
1268 case PRE_DEC:
1269 case POST_INC:
1270 case POST_DEC:
1271 case CALL:
1272 /* case TRAP_IF: This isn't clear yet. */
1273 return 1;
1274
1275 case MEM:
1276 case ASM_OPERANDS:
1277 if (MEM_VOLATILE_P (x))
1278 return 1;
1279 }
1280
1281 /* Recursively scan the operands of this expression. */
1282
1283 {
1284 register char *fmt = GET_RTX_FORMAT (code);
1285 register int i;
1286
1287 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1288 {
1289 if (fmt[i] == 'e')
1290 {
1291 if (side_effects_p (XEXP (x, i)))
1292 return 1;
1293 }
1294 if (fmt[i] == 'E')
1295 {
1296 register int j;
1297 for (j = 0; j < XVECLEN (x, i); j++)
1298 if (side_effects_p (XVECEXP (x, i, j)))
1299 return 1;
1300 }
1301 }
1302 }
1303 return 0;
1304}
1305\f
1306/* Return nonzero if evaluating rtx X might cause a trap. */
1307
1308int
1309may_trap_p (x)
1310 rtx x;
1311{
1312 int i;
1313 enum rtx_code code;
1314 char *fmt;
1315
1316 if (x == 0)
1317 return 0;
1318 code = GET_CODE (x);
1319 switch (code)
1320 {
1321 /* Handle these cases quickly. */
1322 case CONST_INT:
1323 case CONST_DOUBLE:
1324 case SYMBOL_REF:
1325 case LABEL_REF:
1326 case CONST:
1327 case PC:
1328 case CC0:
1329 case REG:
1330 case SCRATCH:
1331 return 0;
1332
1333 /* Conditional trap can trap! */
1334 case TRAP_IF:
1335 return 1;
1336
1337 /* Memory ref can trap unless it's a static var or a stack slot. */
1338 case MEM:
1339 return rtx_addr_can_trap_p (XEXP (x, 0));
1340
1341 /* Division by a non-constant might trap. */
1342 case DIV:
1343 case MOD:
1344 case UDIV:
1345 case UMOD:
1346 if (! CONSTANT_P (XEXP (x, 1)))
1347 return 1;
1348 /* This was const0_rtx, but by not using that,
1349 we can link this file into other programs. */
1350 if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
1351 return 1;
1352 default:
1353 /* Any floating arithmetic may trap. */
1354 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
1355 return 1;
1356 }
1357
1358 fmt = GET_RTX_FORMAT (code);
1359 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1360 {
1361 if (fmt[i] == 'e')
1362 {
1363 if (may_trap_p (XEXP (x, i)))
1364 return 1;
1365 }
1366 else if (fmt[i] == 'E')
1367 {
1368 register int j;
1369 for (j = 0; j < XVECLEN (x, i); j++)
1370 if (may_trap_p (XVECEXP (x, i, j)))
1371 return 1;
1372 }
1373 }
1374 return 0;
1375}
1376\f
1377/* Return nonzero if X contains a comparison that is not either EQ or NE,
1378 i.e., an inequality. */
1379
1380int
1381inequality_comparisons_p (x)
1382 rtx x;
1383{
1384 register char *fmt;
1385 register int len, i;
1386 register enum rtx_code code = GET_CODE (x);
1387
1388 switch (code)
1389 {
1390 case REG:
1391 case SCRATCH:
1392 case PC:
1393 case CC0:
1394 case CONST_INT:
1395 case CONST_DOUBLE:
1396 case CONST:
1397 case LABEL_REF:
1398 case SYMBOL_REF:
1399 return 0;
1400
1401 case LT:
1402 case LTU:
1403 case GT:
1404 case GTU:
1405 case LE:
1406 case LEU:
1407 case GE:
1408 case GEU:
1409 return 1;
1410 }
1411
1412 len = GET_RTX_LENGTH (code);
1413 fmt = GET_RTX_FORMAT (code);
1414
1415 for (i = 0; i < len; i++)
1416 {
1417 if (fmt[i] == 'e')
1418 {
1419 if (inequality_comparisons_p (XEXP (x, i)))
1420 return 1;
1421 }
1422 else if (fmt[i] == 'E')
1423 {
1424 register int j;
1425 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1426 if (inequality_comparisons_p (XVECEXP (x, i, j)))
1427 return 1;
1428 }
1429 }
1430
1431 return 0;
1432}
1433\f
1434/* Replace any occurrence of FROM in X with TO.
1435
1436 Note that copying is not done so X must not be shared unless all copies
1437 are to be modified. */
1438
1439rtx
1440replace_rtx (x, from, to)
1441 rtx x, from, to;
1442{
1443 register int i, j;
1444 register char *fmt;
1445
1446 if (x == from)
1447 return to;
1448
1449 /* Allow this function to make replacements in EXPR_LISTs. */
1450 if (x == 0)
1451 return 0;
1452
1453 fmt = GET_RTX_FORMAT (GET_CODE (x));
1454 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
1455 {
1456 if (fmt[i] == 'e')
1457 XEXP (x, i) = replace_rtx (XEXP (x, i), from, to);
1458 else if (fmt[i] == 'E')
1459 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1460 XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to);
1461 }
1462
1463 return x;
1464}
1465\f
1466/* Throughout the rtx X, replace many registers according to REG_MAP.
1467 Return the replacement for X (which may be X with altered contents).
1468 REG_MAP[R] is the replacement for register R, or 0 for don't replace.
1469 NREGS is the length of REG_MAP; regs >= NREGS are not mapped.
1470
1471 We only support REG_MAP entries of REG or SUBREG. Also, hard registers
1472 should not be mapped to pseudos or vice versa since validate_change
1473 is not called.
1474
1475 If REPLACE_DEST is 1, replacements are also done in destinations;
1476 otherwise, only sources are replaced. */
1477
1478rtx
1479replace_regs (x, reg_map, nregs, replace_dest)
1480 rtx x;
1481 rtx *reg_map;
1482 int nregs;
1483 int replace_dest;
1484{
1485 register enum rtx_code code;
1486 register int i;
1487 register char *fmt;
1488
1489 if (x == 0)
1490 return x;
1491
1492 code = GET_CODE (x);
1493 switch (code)
1494 {
1495 case SCRATCH:
1496 case PC:
1497 case CC0:
1498 case CONST_INT:
1499 case CONST_DOUBLE:
1500 case CONST:
1501 case SYMBOL_REF:
1502 case LABEL_REF:
1503 return x;
1504
1505 case REG:
1506 /* Verify that the register has an entry before trying to access it. */
1507 if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0)
1508 return reg_map[REGNO (x)];
1509 return x;
1510
1511 case SUBREG:
1512 /* Prevent making nested SUBREGs. */
1513 if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs
1514 && reg_map[REGNO (SUBREG_REG (x))] != 0
1515 && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
1516 {
1517 rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
1518 rtx map_inner = SUBREG_REG (map_val);
1519
1520 if (GET_MODE (x) == GET_MODE (map_inner))
1521 return map_inner;
1522 else
1523 {
1524 /* We cannot call gen_rtx here since we may be linked with
1525 genattrtab.c. */
1526 /* Let's try clobbering the incoming SUBREG and see
1527 if this is really safe. */
1528 SUBREG_REG (x) = map_inner;
1529 SUBREG_WORD (x) += SUBREG_WORD (map_val);
1530 return x;
1531#if 0
1532 rtx new = rtx_alloc (SUBREG);
1533 PUT_MODE (new, GET_MODE (x));
1534 SUBREG_REG (new) = map_inner;
1535 SUBREG_WORD (new) = SUBREG_WORD (x) + SUBREG_WORD (map_val);
1536#endif
1537 }
1538 }
1539 break;
1540
1541 case SET:
1542 if (replace_dest)
1543 SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0);
1544
1545 else if (GET_CODE (SET_DEST (x)) == MEM
1546 || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
1547 /* Even if we are not to replace destinations, replace register if it
1548 is CONTAINED in destination (destination is memory or
1549 STRICT_LOW_PART). */
1550 XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0),
1551 reg_map, nregs, 0);
1552 else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
1553 /* Similarly, for ZERO_EXTRACT we replace all operands. */
1554 break;
1555
1556 SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0);
1557 return x;
1558 }
1559
1560 fmt = GET_RTX_FORMAT (code);
1561 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1562 {
1563 if (fmt[i] == 'e')
1564 XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest);
1565 if (fmt[i] == 'E')
1566 {
1567 register int j;
1568 for (j = 0; j < XVECLEN (x, i); j++)
1569 XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map,
1570 nregs, replace_dest);
1571 }
1572 }
1573 return x;
1574}
This page took 0.174168 seconds and 5 git commands to generate.