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