|
|
1.1 root 1: /* Emit RTL for the GNU C-Compiler expander.
2: Copyright (C) 1987, 1988, 1992 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: /* Middle-to-low level generation of rtx code and insns.
22:
23: This file contains the functions `gen_rtx', `gen_reg_rtx'
24: and `gen_label_rtx' that are the usual ways of creating rtl
25: expressions for most purposes.
26:
27: It also has the functions for creating insns and linking
28: them in the doubly-linked chain.
29:
30: The patterns of the insns are created by machine-dependent
31: routines in insn-emit.c, which is generated automatically from
32: the machine description. These routines use `gen_rtx' to make
33: the individual rtx's of the pattern; what is machine dependent
34: is the kind of rtx's they make and what arguments they use. */
35:
36: #include "config.h"
37: #include <stdio.h>
38: #include "gvarargs.h"
39: #include "rtl.h"
40: #include "flags.h"
41: #include "function.h"
42: #include "expr.h"
43: #include "regs.h"
44: #include "insn-config.h"
45: #include "real.h"
46:
47: /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
48: After rtl generation, it is 1 plus the largest register number used. */
49:
50: int reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
51:
52: /* This is *not* reset after each function. It gives each CODE_LABEL
53: in the entire compilation a unique label number. */
54:
55: static int label_num = 1;
56:
57: /* Lowest label number in current function. */
58:
59: static int first_label_num;
60:
61: /* Highest label number in current function.
62: Zero means use the value of label_num instead.
63: This is nonzero only when belatedly compiling an inline function. */
64:
65: static int last_label_num;
66:
67: /* Value label_num had when set_new_first_and_last_label_number was called.
68: If label_num has not changed since then, last_label_num is valid. */
69:
70: static int base_label_num;
71:
72: /* Nonzero means do not generate NOTEs for source line numbers. */
73:
74: static int no_line_numbers;
75:
76: /* Commonly used rtx's, so that we only need space for one copy.
77: These are initialized once for the entire compilation.
78: All of these except perhaps the floating-point CONST_DOUBLEs
79: are unique; no other rtx-object will be equal to any of these. */
80:
81: rtx pc_rtx; /* (PC) */
82: rtx cc0_rtx; /* (CC0) */
83: rtx cc1_rtx; /* (CC1) (not actually used nowadays) */
84: rtx const0_rtx; /* (CONST_INT 0) */
85: rtx const1_rtx; /* (CONST_INT 1) */
86: rtx const2_rtx; /* (CONST_INT 2) */
87: rtx constm1_rtx; /* (CONST_INT -1) */
88: rtx const_true_rtx; /* (CONST_INT STORE_FLAG_VALUE) */
89:
90: /* We record floating-point CONST_DOUBLEs in each floating-point mode for
91: the values of 0, 1, and 2. For the integer entries and VOIDmode, we
92: record a copy of const[012]_rtx. */
93:
94: rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
95:
96: REAL_VALUE_TYPE dconst0;
97: REAL_VALUE_TYPE dconst1;
98: REAL_VALUE_TYPE dconst2;
99: REAL_VALUE_TYPE dconstm1;
100:
101: /* All references to the following fixed hard registers go through
102: these unique rtl objects. On machines where the frame-pointer and
103: arg-pointer are the same register, they use the same unique object.
104:
105: After register allocation, other rtl objects which used to be pseudo-regs
106: may be clobbered to refer to the frame-pointer register.
107: But references that were originally to the frame-pointer can be
108: distinguished from the others because they contain frame_pointer_rtx.
109:
110: In an inline procedure, the stack and frame pointer rtxs may not be
111: used for anything else. */
112: rtx stack_pointer_rtx; /* (REG:Pmode STACK_POINTER_REGNUM) */
113: rtx frame_pointer_rtx; /* (REG:Pmode FRAME_POINTER_REGNUM) */
114: rtx arg_pointer_rtx; /* (REG:Pmode ARG_POINTER_REGNUM) */
115: rtx struct_value_rtx; /* (REG:Pmode STRUCT_VALUE_REGNUM) */
116: rtx struct_value_incoming_rtx; /* (REG:Pmode STRUCT_VALUE_INCOMING_REGNUM) */
117: rtx static_chain_rtx; /* (REG:Pmode STATIC_CHAIN_REGNUM) */
118: rtx static_chain_incoming_rtx; /* (REG:Pmode STATIC_CHAIN_INCOMING_REGNUM) */
119: rtx pic_offset_table_rtx; /* (REG:Pmode PIC_OFFSET_TABLE_REGNUM) */
120:
121: rtx virtual_incoming_args_rtx; /* (REG:Pmode VIRTUAL_INCOMING_ARGS_REGNUM) */
122: rtx virtual_stack_vars_rtx; /* (REG:Pmode VIRTUAL_STACK_VARS_REGNUM) */
123: rtx virtual_stack_dynamic_rtx; /* (REG:Pmode VIRTUAL_STACK_DYNAMIC_REGNUM) */
124: rtx virtual_outgoing_args_rtx; /* (REG:Pmode VIRTUAL_OUTGOING_ARGS_REGNUM) */
125:
126: /* We make one copy of (const_int C) where C is in
127: [- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT]
128: to save space during the compilation and simplify comparisons of
129: integers. */
130:
131: #define MAX_SAVED_CONST_INT 64
132:
133: static rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
134:
135: /* The ends of the doubly-linked chain of rtl for the current function.
136: Both are reset to null at the start of rtl generation for the function.
137:
138: start_sequence saves both of these on `sequence_stack' and then
139: starts a new, nested sequence of insns. */
140:
141: static rtx first_insn = NULL;
142: static rtx last_insn = NULL;
143:
144: /* INSN_UID for next insn emitted.
145: Reset to 1 for each function compiled. */
146:
147: static int cur_insn_uid = 1;
148:
149: /* Line number and source file of the last line-number NOTE emitted.
150: This is used to avoid generating duplicates. */
151:
152: static int last_linenum = 0;
153: static char *last_filename = 0;
154:
155: /* A vector indexed by pseudo reg number. The allocated length
156: of this vector is regno_pointer_flag_length. Since this
157: vector is needed during the expansion phase when the total
158: number of registers in the function is not yet known,
159: it is copied and made bigger when necessary. */
160:
161: char *regno_pointer_flag;
162: int regno_pointer_flag_length;
163:
164: /* Indexed by pseudo register number, gives the rtx for that pseudo.
165: Allocated in parallel with regno_pointer_flag. */
166:
167: rtx *regno_reg_rtx;
168:
169: /* Stack of pending (incomplete) sequences saved by `start_sequence'.
170: Each element describes one pending sequence.
171: The main insn-chain is saved in the last element of the chain,
172: unless the chain is empty. */
173:
174: struct sequence_stack *sequence_stack;
175:
176: /* start_sequence and gen_sequence can make a lot of rtx expressions which are
177: shortly thrown away. We use two mechanisms to prevent this waste:
178:
179: First, we keep a list of the expressions used to represent the sequence
180: stack in sequence_element_free_list.
181:
182: Second, for sizes up to 5 elements, we keep a SEQUENCE and its associated
183: rtvec for use by gen_sequence. One entry for each size is sufficient
184: because most cases are calls to gen_sequence followed by immediately
185: emitting the SEQUENCE. Reuse is safe since emitting a sequence is
186: destructive on the insn in it anyway and hence can't be redone.
187:
188: We do not bother to save this cached data over nested function calls.
189: Instead, we just reinitialize them. */
190:
191: #define SEQUENCE_RESULT_SIZE 5
192:
193: static struct sequence_stack *sequence_element_free_list;
194: static rtx sequence_result[SEQUENCE_RESULT_SIZE];
195:
196: extern int rtx_equal_function_value_matters;
197:
198: /* Filename and line number of last line-number note,
199: whether we actually emitted it or not. */
200: extern char *emit_filename;
201: extern int emit_lineno;
202:
203: rtx change_address ();
204: void init_emit ();
205:
206: /* rtx gen_rtx (code, mode, [element1, ..., elementn])
207: **
208: ** This routine generates an RTX of the size specified by
209: ** <code>, which is an RTX code. The RTX structure is initialized
210: ** from the arguments <element1> through <elementn>, which are
211: ** interpreted according to the specific RTX type's format. The
212: ** special machine mode associated with the rtx (if any) is specified
213: ** in <mode>.
214: **
215: ** gen_rtx() can be invoked in a way which resembles the lisp-like
216: ** rtx it will generate. For example, the following rtx structure:
217: **
218: ** (plus:QI (mem:QI (reg:SI 1))
219: ** (mem:QI (plusw:SI (reg:SI 2) (reg:SI 3))))
220: **
221: ** ...would be generated by the following C code:
222: **
223: ** gen_rtx (PLUS, QImode,
224: ** gen_rtx (MEM, QImode,
225: ** gen_rtx (REG, SImode, 1)),
226: ** gen_rtx (MEM, QImode,
227: ** gen_rtx (PLUS, SImode,
228: ** gen_rtx (REG, SImode, 2),
229: ** gen_rtx (REG, SImode, 3)))),
230: */
231:
232: /*VARARGS2*/
233: rtx
234: gen_rtx (va_alist)
235: va_dcl
236: {
237: va_list p;
238: enum rtx_code code;
239: enum machine_mode mode;
240: register int i; /* Array indices... */
241: register char *fmt; /* Current rtx's format... */
242: register rtx rt_val; /* RTX to return to caller... */
243:
244: va_start (p);
245: code = va_arg (p, enum rtx_code);
246: mode = va_arg (p, enum machine_mode);
247:
248: if (code == CONST_INT)
249: {
250: int arg = va_arg (p, int);
251:
252: if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
253: return const_int_rtx[arg + MAX_SAVED_CONST_INT];
254:
255: if (const_true_rtx && arg == STORE_FLAG_VALUE)
256: return const_true_rtx;
257:
258: rt_val = rtx_alloc (code);
259: INTVAL (rt_val) = arg;
260: }
261: else if (code == REG)
262: {
263: int regno = va_arg (p, int);
264:
265: /* In case the MD file explicitly references the frame pointer, have
266: all such references point to the same frame pointer. This is used
267: during frame pointer elimination to distinguish the explicit
1.1.1.2 root 268: references to these registers from pseudos that happened to be
1.1 root 269: assigned to them.
270:
271: If we have eliminated the frame pointer or arg pointer, we will
272: be using it as a normal register, for example as a spill register.
273: In such cases, we might be accessing it in a mode that is not
274: Pmode and therefore cannot use the pre-allocated rtx. */
275:
276: if (frame_pointer_rtx && regno == FRAME_POINTER_REGNUM && mode == Pmode)
277: return frame_pointer_rtx;
278: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
279: if (arg_pointer_rtx && regno == ARG_POINTER_REGNUM && mode == Pmode)
280: return arg_pointer_rtx;
281: #endif
282: if (stack_pointer_rtx && regno == STACK_POINTER_REGNUM && mode == Pmode)
283: return stack_pointer_rtx;
284: else
285: {
286: rt_val = rtx_alloc (code);
287: rt_val->mode = mode;
288: REGNO (rt_val) = regno;
289: return rt_val;
290: }
291: }
292: else
293: {
294: rt_val = rtx_alloc (code); /* Allocate the storage space. */
295: rt_val->mode = mode; /* Store the machine mode... */
296:
297: fmt = GET_RTX_FORMAT (code); /* Find the right format... */
298: for (i = 0; i < GET_RTX_LENGTH (code); i++)
299: {
300: switch (*fmt++)
301: {
302: case '0': /* Unused field. */
303: break;
304:
305: case 'i': /* An integer? */
306: XINT (rt_val, i) = va_arg (p, int);
307: break;
308:
309: case 's': /* A string? */
310: XSTR (rt_val, i) = va_arg (p, char *);
311: break;
312:
313: case 'e': /* An expression? */
314: case 'u': /* An insn? Same except when printing. */
315: XEXP (rt_val, i) = va_arg (p, rtx);
316: break;
317:
318: case 'E': /* An RTX vector? */
319: XVEC (rt_val, i) = va_arg (p, rtvec);
320: break;
321:
322: default:
323: abort();
324: }
325: }
326: }
327: va_end (p);
328: return rt_val; /* Return the new RTX... */
329: }
330:
331: /* gen_rtvec (n, [rt1, ..., rtn])
332: **
333: ** This routine creates an rtvec and stores within it the
334: ** pointers to rtx's which are its arguments.
335: */
336:
337: /*VARARGS1*/
338: rtvec
339: gen_rtvec (va_alist)
340: va_dcl
341: {
342: int n, i;
343: va_list p;
344: rtx *vector;
345:
346: va_start (p);
347: n = va_arg (p, int);
348:
349: if (n == 0)
350: return NULL_RTVEC; /* Don't allocate an empty rtvec... */
351:
352: vector = (rtx *) alloca (n * sizeof (rtx));
353: for (i = 0; i < n; i++)
354: vector[i] = va_arg (p, rtx);
355: va_end (p);
356:
357: return gen_rtvec_v (n, vector);
358: }
359:
360: rtvec
361: gen_rtvec_v (n, argp)
362: int n;
363: rtx *argp;
364: {
365: register int i;
366: register rtvec rt_val;
367:
368: if (n == 0)
369: return NULL_RTVEC; /* Don't allocate an empty rtvec... */
370:
371: rt_val = rtvec_alloc (n); /* Allocate an rtvec... */
372:
373: for (i = 0; i < n; i++)
374: rt_val->elem[i].rtx = *argp++;
375:
376: return rt_val;
377: }
378:
379: /* Generate a REG rtx for a new pseudo register of mode MODE.
380: This pseudo is assigned the next sequential register number. */
381:
382: rtx
383: gen_reg_rtx (mode)
384: enum machine_mode mode;
385: {
386: register rtx val;
387:
388: /* Don't let anything called by or after reload create new registers
389: (actually, registers can't be created after flow, but this is a good
390: approximation). */
391:
392: if (reload_in_progress || reload_completed)
393: abort ();
394:
395: /* Make sure regno_pointer_flag and regno_reg_rtx are large
396: enough to have an element for this pseudo reg number. */
397:
398: if (reg_rtx_no == regno_pointer_flag_length)
399: {
400: rtx *new1;
401: char *new =
402: (char *) oballoc (regno_pointer_flag_length * 2);
403: bzero (new, regno_pointer_flag_length * 2);
404: bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
405: regno_pointer_flag = new;
406:
407: new1 = (rtx *) oballoc (regno_pointer_flag_length * 2 * sizeof (rtx));
408: bzero (new1, regno_pointer_flag_length * 2 * sizeof (rtx));
409: bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx));
410: regno_reg_rtx = new1;
411:
412: regno_pointer_flag_length *= 2;
413: }
414:
415: val = gen_rtx (REG, mode, reg_rtx_no);
416: regno_reg_rtx[reg_rtx_no++] = val;
417: return val;
418: }
419:
420: /* Identify REG as a probable pointer register. */
421:
422: void
423: mark_reg_pointer (reg)
424: rtx reg;
425: {
426: REGNO_POINTER_FLAG (REGNO (reg)) = 1;
427: }
428:
429: /* Return 1 plus largest pseudo reg number used in the current function. */
430:
431: int
432: max_reg_num ()
433: {
434: return reg_rtx_no;
435: }
436:
437: /* Return 1 + the largest label number used so far in the current function. */
438:
439: int
440: max_label_num ()
441: {
442: if (last_label_num && label_num == base_label_num)
443: return last_label_num;
444: return label_num;
445: }
446:
447: /* Return first label number used in this function (if any were used). */
448:
449: int
450: get_first_label_num ()
451: {
452: return first_label_num;
453: }
454:
455: /* Return a value representing some low-order bits of X, where the number
456: of low-order bits is given by MODE. Note that no conversion is done
457: between floating-point and fixed-point values, rather, the bit
458: representation is returned.
459:
460: This function handles the cases in common between gen_lowpart, below,
461: and two variants in cse.c and combine.c. These are the cases that can
462: be safely handled at all points in the compilation.
463:
464: If this is not a case we can handle, return 0. */
465:
466: rtx
467: gen_lowpart_common (mode, x)
468: enum machine_mode mode;
469: register rtx x;
470: {
471: int word = 0;
472:
473: if (GET_MODE (x) == mode)
474: return x;
475:
476: /* MODE must occupy no more words than the mode of X. */
477: if (GET_MODE (x) != VOIDmode
478: && ((GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD
479: > ((GET_MODE_SIZE (GET_MODE (x)) + (UNITS_PER_WORD - 1))
480: / UNITS_PER_WORD)))
481: return 0;
482:
483: if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
484: word = ((GET_MODE_SIZE (GET_MODE (x))
485: - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
486: / UNITS_PER_WORD);
487:
488: if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
489: && GET_MODE_CLASS (mode) == MODE_INT)
490: {
491: /* If we are getting the low-order part of something that has been
492: sign- or zero-extended, we can either just use the object being
493: extended or make a narrower extension. If we want an even smaller
494: piece than the size of the object being extended, call ourselves
495: recursively.
496:
497: This case is used mostly by combine and cse. */
498:
499: if (GET_MODE (XEXP (x, 0)) == mode)
500: return XEXP (x, 0);
501: else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (XEXP (x, 0))))
502: return gen_lowpart_common (mode, XEXP (x, 0));
503: else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
504: return gen_rtx (GET_CODE (x), mode, XEXP (x, 0));
505: }
506: else if (GET_CODE (x) == SUBREG
507: && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
508: || GET_MODE_SIZE (mode) == GET_MODE_UNIT_SIZE (GET_MODE (x))))
509: return (GET_MODE (SUBREG_REG (x)) == mode && SUBREG_WORD (x) == 0
510: ? SUBREG_REG (x)
511: : gen_rtx (SUBREG, mode, SUBREG_REG (x), SUBREG_WORD (x)));
512: else if (GET_CODE (x) == REG)
513: {
514: /* If the register is not valid for MODE, return 0. If we don't
515: do this, there is no way to fix up the resulting REG later. */
516: if (REGNO (x) < FIRST_PSEUDO_REGISTER
517: && ! HARD_REGNO_MODE_OK (REGNO (x) + word, mode))
518: return 0;
519: else if (REGNO (x) < FIRST_PSEUDO_REGISTER
520: /* integrate.c can't handle parts of a return value register. */
521: && (! REG_FUNCTION_VALUE_P (x)
522: || ! rtx_equal_function_value_matters))
523: return gen_rtx (REG, mode, REGNO (x) + word);
524: else
525: return gen_rtx (SUBREG, mode, x, word);
526: }
527:
528: /* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits
529: from the low-order part of the constant. */
530: else if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE (x) == VOIDmode
531: && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
1.1.1.3 ! root 532: {
! 533: /* If MODE is twice the host word size, X is already the desired
! 534: representation. Otherwise, if MODE is wider than a word, we can't
! 535: do this. If MODE is exactly a word, return just one CONST_INT.
! 536: If MODE is smaller than a word, clear the bits that don't belong
! 537: in our mode, unless they and our sign bit are all one. So we get
! 538: either a reasonable negative value or a reasonable unsigned value
! 539: for this mode. */
! 540:
! 541: if (GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_INT)
! 542: return x;
! 543: else if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_INT)
! 544: return 0;
! 545: else if (GET_MODE_BITSIZE (mode) == HOST_BITS_PER_INT)
! 546: return (GET_CODE (x) == CONST_INT ? x
! 547: : gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (x)));
! 548: else
! 549: {
! 550: /* MODE must be narrower than HOST_BITS_PER_INT. */
! 551: int width = GET_MODE_BITSIZE (mode);
! 552: int val = (GET_CODE (x) == CONST_INT ? INTVAL (x)
! 553: : CONST_DOUBLE_LOW (x));
! 554:
! 555: if (((val & ((-1) << (width - 1))) != ((-1) << (width - 1))))
! 556: val &= (1 << width) - 1;
! 557:
! 558: return (GET_CODE (x) == CONST_INT && INTVAL (x) == val ? x
! 559: : gen_rtx (CONST_INT, VOIDmode, val));
! 560: }
! 561: }
! 562:
! 563: /* If X is an integral constant but we want it in floating-point, it
! 564: must be the case that we have a union of an integer and a floating-point
! 565: value. If the machine-parameters allow it, simulate that union here
! 566: and return the result. The two-word and single-word cases are
! 567: different. */
! 568:
! 569: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
! 570: && HOST_BITS_PER_INT == BITS_PER_WORD)
! 571: || flag_pretend_float)
! 572: && GET_MODE_CLASS (mode) == MODE_FLOAT
! 573: && GET_MODE_SIZE (mode) == UNITS_PER_WORD
! 574: && GET_CODE (x) == CONST_INT
! 575: && sizeof (float) * HOST_BITS_PER_CHAR == HOST_BITS_PER_INT)
! 576: {
! 577: union {int i; float d; } u;
! 578:
! 579: u.i = INTVAL (x);
! 580: return immed_real_const_1 (u.d, mode);
! 581: }
! 582:
! 583: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
! 584: && HOST_BITS_PER_INT == BITS_PER_WORD)
! 585: || flag_pretend_float)
! 586: && GET_MODE_CLASS (mode) == MODE_FLOAT
! 587: && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
! 588: && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
! 589: && GET_MODE (x) == VOIDmode
! 590: && sizeof (double) * HOST_BITS_PER_CHAR == 2 * HOST_BITS_PER_INT)
! 591: {
! 592: union {int i[2]; double d; } u;
! 593: int low, high;
! 594:
! 595: if (GET_CODE (x) == CONST_INT)
! 596: low = INTVAL (x), high = low >> (HOST_BITS_PER_INT -1);
! 597: else
! 598: low = CONST_DOUBLE_LOW (x), high = CONST_DOUBLE_HIGH (x);
! 599:
! 600: #ifdef HOST_WORDS_BIG_ENDIAN
! 601: u.i[0] = high, u.i[1] = low;
! 602: #else
! 603: u.i[0] = low, u.i[1] = high;
! 604: #endif
! 605:
! 606: return immed_real_const_1 (u.d, mode);
! 607: }
! 608:
! 609: /* Similarly, if this is converting a floating-point value into a
! 610: single-word integer. Only do this is the host and target parameters are
! 611: compatible. */
! 612:
! 613: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
! 614: && HOST_BITS_PER_INT == BITS_PER_WORD)
! 615: || flag_pretend_float)
! 616: && GET_MODE_CLASS (mode) == MODE_INT
! 617: && GET_CODE (x) == CONST_DOUBLE
! 618: && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 619: && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
! 620: return operand_subword (x, 0, 0, GET_MODE (x));
! 621:
! 622: /* Similarly, if this is converting a floating-point value into a
! 623: two-word integer, we can do this one word at a time and make an
! 624: integer. Only do this is the host and target parameters are
! 625: compatible. */
! 626:
! 627: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
! 628: && HOST_BITS_PER_INT == BITS_PER_WORD)
! 629: || flag_pretend_float)
! 630: && GET_MODE_CLASS (mode) == MODE_INT
! 631: && GET_CODE (x) == CONST_DOUBLE
! 632: && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 633: && GET_MODE_BITSIZE (mode) == 2 * BITS_PER_WORD)
! 634: {
! 635: rtx lowpart = operand_subword (x, WORDS_BIG_ENDIAN, 0, GET_MODE (x));
! 636: rtx highpart = operand_subword (x, ! WORDS_BIG_ENDIAN, 0, GET_MODE (x));
! 637:
! 638: if (lowpart && GET_CODE (lowpart) == CONST_INT
! 639: && highpart && GET_CODE (highpart) == CONST_INT)
! 640: return immed_double_const (INTVAL (lowpart), INTVAL (highpart), mode);
! 641: }
1.1 root 642:
643: /* Otherwise, we can't do this. */
644: return 0;
645: }
646:
647: /* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value,
648: return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
649: least-significant part of X.
650: MODE specifies how big a part of X to return;
651: it usually should not be larger than a word.
652: If X is a MEM whose address is a QUEUED, the value may be so also. */
653:
654: rtx
655: gen_lowpart (mode, x)
656: enum machine_mode mode;
657: register rtx x;
658: {
659: rtx result = gen_lowpart_common (mode, x);
660:
661: if (result)
662: return result;
663: else if (GET_CODE (x) == MEM)
664: {
665: /* The only additional case we can do is MEM. */
666: register int offset = 0;
667: if (WORDS_BIG_ENDIAN)
668: offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
669: - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
670:
671: if (BYTES_BIG_ENDIAN)
672: /* Adjust the address so that the address-after-the-data
673: is unchanged. */
674: offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
675: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
676:
677: return change_address (x, mode, plus_constant (XEXP (x, 0), offset));
678: }
679: else
680: abort ();
681: }
682:
683: /* Return 1 iff X, assumed to be a SUBREG,
684: refers to the least significant part of its containing reg.
685: If X is not a SUBREG, always return 1 (it is its own low part!). */
686:
687: int
688: subreg_lowpart_p (x)
689: rtx x;
690: {
691: if (GET_CODE (x) != SUBREG)
692: return 1;
693:
694: if (WORDS_BIG_ENDIAN
695: && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) > UNITS_PER_WORD)
696: return (SUBREG_WORD (x)
697: == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
698: - MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD))
699: / UNITS_PER_WORD));
700:
701: return SUBREG_WORD (x) == 0;
702: }
703:
704: /* Return subword I of operand OP.
705: The word number, I, is interpreted as the word number starting at the
706: low-order address. Word 0 is the low-order word if not WORDS_BIG_ENDIAN,
707: otherwise it is the high-order word.
708:
709: If we cannot extract the required word, we return zero. Otherwise, an
710: rtx corresponding to the requested word will be returned.
711:
712: VALIDATE_ADDRESS is nonzero if the address should be validated. Before
713: reload has completed, a valid address will always be returned. After
714: reload, if a valid address cannot be returned, we return zero.
715:
716: If VALIDATE_ADDRESS is zero, we simply form the required address; validating
717: it is the responsibility of the caller.
718:
719: MODE is the mode of OP in case it is a CONST_INT. */
720:
721: rtx
722: operand_subword (op, i, validate_address, mode)
723: rtx op;
724: int i;
725: int validate_address;
726: enum machine_mode mode;
727: {
728: int val;
729: int size_ratio = HOST_BITS_PER_INT / BITS_PER_WORD;
730:
731: if (mode == VOIDmode)
732: mode = GET_MODE (op);
733:
734: if (mode == VOIDmode)
735: abort ();
736:
737: /* If OP is narrower than a word or if we want a word outside OP, fail. */
738: if (mode != BLKmode
739: && (GET_MODE_SIZE (mode) < UNITS_PER_WORD
740: || (i + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode)))
741: return 0;
742:
743: /* If OP is already an integer word, return it. */
744: if (GET_MODE_CLASS (mode) == MODE_INT
745: && GET_MODE_SIZE (mode) == UNITS_PER_WORD)
746: return op;
747:
748: /* If OP is a REG or SUBREG, we can handle it very simply. */
749: if (GET_CODE (op) == REG)
750: {
751: /* If the register is not valid for MODE, return 0. If we don't
752: do this, there is no way to fix up the resulting REG later. */
753: if (REGNO (op) < FIRST_PSEUDO_REGISTER
754: && ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode))
755: return 0;
756: else if (REGNO (op) >= FIRST_PSEUDO_REGISTER
757: || (REG_FUNCTION_VALUE_P (op)
758: && rtx_equal_function_value_matters))
759: return gen_rtx (SUBREG, word_mode, op, i);
760: else
761: return gen_rtx (REG, word_mode, REGNO (op) + i);
762: }
763: else if (GET_CODE (op) == SUBREG)
764: return gen_rtx (SUBREG, word_mode, SUBREG_REG (op), i + SUBREG_WORD (op));
765:
766: /* Form a new MEM at the requested address. */
767: if (GET_CODE (op) == MEM)
768: {
769: rtx addr = plus_constant (XEXP (op, 0), i * UNITS_PER_WORD);
770: rtx new;
771:
772: if (validate_address)
773: {
774: if (reload_completed)
775: {
776: if (! strict_memory_address_p (word_mode, addr))
777: return 0;
778: }
779: else
780: addr = memory_address (word_mode, addr);
781: }
782:
783: new = gen_rtx (MEM, word_mode, addr);
784:
785: MEM_VOLATILE_P (new) = MEM_VOLATILE_P (op);
786: MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (op);
787: RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
788:
789: return new;
790: }
791:
792: /* The only remaining cases are when OP is a constant. If the host and
793: target floating formats are the same, handling two-word floating
794: constants are easy. */
795: if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
796: && HOST_BITS_PER_INT == BITS_PER_WORD)
797: || flag_pretend_float)
798: && GET_MODE_CLASS (mode) == MODE_FLOAT
799: && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
800: && GET_CODE (op) == CONST_DOUBLE)
801: return gen_rtx (CONST_INT, VOIDmode,
1.1.1.3 ! root 802: i ^ (WORDS_BIG_ENDIAN !=
! 803: /* The constant is stored in the host's word-ordering,
! 804: but we want to access it in the target's word-ordering. */
! 805: #ifdef HOST_WORDS_BIG_ENDIAN
! 806: 1
! 807: #else
! 808: 0
! 809: #endif
! 810: ) ? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op));
1.1 root 811:
812: /* Single word float is a little harder, since single- and double-word
813: values often do not have the same high-order bits. We have already
814: verified that we want the only defined word of the single-word value. */
815: if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
816: && HOST_BITS_PER_INT == BITS_PER_WORD)
817: || flag_pretend_float)
818: && GET_MODE_CLASS (mode) == MODE_FLOAT
819: && GET_MODE_SIZE (mode) == UNITS_PER_WORD
820: && GET_CODE (op) == CONST_DOUBLE)
821: {
822: double d;
823: union {float f; int i; } u;
824:
825: REAL_VALUE_FROM_CONST_DOUBLE (d, op);
826:
827: u.f = d;
828: return gen_rtx (CONST_INT, VOIDmode, u.i);
829: }
830:
831: /* The only remaining cases that we can handle are integers.
832: Convert to proper endianness now since these cases need it.
833: At this point, i == 0 means the low-order word.
834:
835: Note that it must be that BITS_PER_WORD <= HOST_BITS_PER_INT.
836: This is because if it were greater, it could only have been two
837: times greater since we do not support making wider constants. In
838: that case, it MODE would have already been the proper size and
839: it would have been handled above. This means we do not have to
840: worry about the case where we would be returning a CONST_DOUBLE. */
841:
842: if (GET_MODE_CLASS (mode) != MODE_INT
843: || (GET_CODE (op) != CONST_INT && GET_CODE (op) != CONST_DOUBLE))
844: return 0;
845:
846: if (WORDS_BIG_ENDIAN)
847: i = GET_MODE_SIZE (mode) / UNITS_PER_WORD - 1 - i;
848:
849: /* Find out which word on the host machine this value is in and get
850: it from the constant. */
851: val = (i / size_ratio == 0
852: ? (GET_CODE (op) == CONST_INT ? INTVAL (op) : CONST_DOUBLE_LOW (op))
853: : (GET_CODE (op) == CONST_INT
854: ? (INTVAL (op) < 0 ? ~0 : 0) : CONST_DOUBLE_HIGH (op)));
855:
856: /* If BITS_PER_WORD is smaller than an int, get the appropriate bits. */
857: if (BITS_PER_WORD < HOST_BITS_PER_INT)
858: val = ((val >> ((i % size_ratio) * BITS_PER_WORD))
859: & ((1 << (BITS_PER_WORD % HOST_BITS_PER_INT)) - 1));
860:
861: return gen_rtx (CONST_INT, VOIDmode, val);
862: }
863:
864: /* Similar to `operand_subword', but never return 0. If we can't extract
865: the required subword, put OP into a register and try again. If that fails,
866: abort. We always validate the address in this case. It is not valid
867: to call this function after reload; it is mostly meant for RTL
868: generation.
869:
870: MODE is the mode of OP, in case it is CONST_INT. */
871:
872: rtx
873: operand_subword_force (op, i, mode)
874: rtx op;
875: int i;
876: enum machine_mode mode;
877: {
878: rtx result = operand_subword (op, i, 1, mode);
879:
880: if (result)
881: return result;
882:
883: if (mode != BLKmode && mode != VOIDmode)
884: op = force_reg (mode, op);
885:
886: result = operand_subword (op, i, 1, mode);
887: if (result == 0)
888: abort ();
889:
890: return result;
891: }
892:
893: /* Given a compare instruction, swap the operands.
894: A test instruction is changed into a compare of 0 against the operand. */
895:
896: void
897: reverse_comparison (insn)
898: rtx insn;
899: {
900: rtx body = PATTERN (insn);
901: rtx comp;
902:
903: if (GET_CODE (body) == SET)
904: comp = SET_SRC (body);
905: else
906: comp = SET_SRC (XVECEXP (body, 0, 0));
907:
908: if (GET_CODE (comp) == COMPARE)
909: {
910: rtx op0 = XEXP (comp, 0);
911: rtx op1 = XEXP (comp, 1);
912: XEXP (comp, 0) = op1;
913: XEXP (comp, 1) = op0;
914: }
915: else
916: {
917: rtx new = gen_rtx (COMPARE, VOIDmode,
918: CONST0_RTX (GET_MODE (comp)), comp);
919: if (GET_CODE (body) == SET)
920: SET_SRC (body) = new;
921: else
922: SET_SRC (XVECEXP (body, 0, 0)) = new;
923: }
924: }
925:
926: /* Return a memory reference like MEMREF, but with its mode changed
927: to MODE and its address changed to ADDR.
928: (VOIDmode means don't change the mode.
929: NULL for ADDR means don't change the address.) */
930:
931: rtx
932: change_address (memref, mode, addr)
933: rtx memref;
934: enum machine_mode mode;
935: rtx addr;
936: {
937: rtx new;
938:
939: if (GET_CODE (memref) != MEM)
940: abort ();
941: if (mode == VOIDmode)
942: mode = GET_MODE (memref);
943: if (addr == 0)
944: addr = XEXP (memref, 0);
945:
946: /* If reload is in progress or has completed, ADDR must be valid.
947: Otherwise, we can call memory_address to make it valid. */
948: if (reload_completed || reload_in_progress)
949: {
950: if (! memory_address_p (mode, addr))
951: abort ();
952: }
953: else
954: addr = memory_address (mode, addr);
955:
956: new = gen_rtx (MEM, mode, addr);
957: MEM_VOLATILE_P (new) = MEM_VOLATILE_P (memref);
958: RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (memref);
959: MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (memref);
960: return new;
961: }
962:
963: /* Return a newly created CODE_LABEL rtx with a unique label number. */
964:
965: rtx
966: gen_label_rtx ()
967: {
968: register rtx label = gen_rtx (CODE_LABEL, VOIDmode, 0, 0, 0, label_num++, 0);
969: LABEL_NUSES (label) = 0;
970: return label;
971: }
972:
973: /* For procedure integration. */
974:
975: /* Return a newly created INLINE_HEADER rtx. Should allocate this
976: from a permanent obstack when the opportunity arises. */
977:
978: rtx
979: gen_inline_header_rtx (first_insn, first_parm_insn, first_labelno,
980: last_labelno, max_parm_regnum, max_regnum, args_size,
981: pops_args, stack_slots, function_flags,
982: outgoing_args_size, original_arg_vector,
983: original_decl_initial)
984: rtx first_insn, first_parm_insn;
985: int first_labelno, last_labelno, max_parm_regnum, max_regnum, args_size;
986: int pops_args;
987: rtx stack_slots;
988: int function_flags;
989: int outgoing_args_size;
990: rtvec original_arg_vector;
991: rtx original_decl_initial;
992: {
993: rtx header = gen_rtx (INLINE_HEADER, VOIDmode,
994: cur_insn_uid++, NULL,
995: first_insn, first_parm_insn,
996: first_labelno, last_labelno,
997: max_parm_regnum, max_regnum, args_size, pops_args,
998: stack_slots, function_flags, outgoing_args_size,
999: original_arg_vector, original_decl_initial);
1000: return header;
1001: }
1002:
1003: /* Install new pointers to the first and last insns in the chain.
1004: Used for an inline-procedure after copying the insn chain. */
1005:
1006: void
1007: set_new_first_and_last_insn (first, last)
1008: rtx first, last;
1009: {
1010: first_insn = first;
1011: last_insn = last;
1012: }
1013:
1014: /* Set the range of label numbers found in the current function.
1015: This is used when belatedly compiling an inline function. */
1016:
1017: void
1018: set_new_first_and_last_label_num (first, last)
1019: int first, last;
1020: {
1021: base_label_num = label_num;
1022: first_label_num = first;
1023: last_label_num = last;
1024: }
1025:
1026: /* Save all variables describing the current status into the structure *P.
1027: This is used before starting a nested function. */
1028:
1029: void
1030: save_emit_status (p)
1031: struct function *p;
1032: {
1033: p->reg_rtx_no = reg_rtx_no;
1034: p->first_label_num = first_label_num;
1035: p->first_insn = first_insn;
1036: p->last_insn = last_insn;
1037: p->sequence_stack = sequence_stack;
1038: p->cur_insn_uid = cur_insn_uid;
1039: p->last_linenum = last_linenum;
1040: p->last_filename = last_filename;
1041: p->regno_pointer_flag = regno_pointer_flag;
1042: p->regno_pointer_flag_length = regno_pointer_flag_length;
1043: p->regno_reg_rtx = regno_reg_rtx;
1044: }
1045:
1046: /* Restore all variables describing the current status from the structure *P.
1047: This is used after a nested function. */
1048:
1049: void
1050: restore_emit_status (p)
1051: struct function *p;
1052: {
1053: int i;
1054:
1055: reg_rtx_no = p->reg_rtx_no;
1056: first_label_num = p->first_label_num;
1057: first_insn = p->first_insn;
1058: last_insn = p->last_insn;
1059: sequence_stack = p->sequence_stack;
1060: cur_insn_uid = p->cur_insn_uid;
1061: last_linenum = p->last_linenum;
1062: last_filename = p->last_filename;
1063: regno_pointer_flag = p->regno_pointer_flag;
1064: regno_pointer_flag_length = p->regno_pointer_flag_length;
1065: regno_reg_rtx = p->regno_reg_rtx;
1066:
1067: /* Clear our cache of rtx expressions for start_sequence and gen_sequence. */
1068: sequence_element_free_list = 0;
1069: for (i = 0; i < SEQUENCE_RESULT_SIZE; i++)
1070: sequence_result[i] = 0;
1071: }
1072:
1073: /* Go through all the RTL insn bodies and copy any invalid shared structure.
1074: It does not work to do this twice, because the mark bits set here
1075: are not cleared afterwards. */
1076:
1077: void
1078: unshare_all_rtl (insn)
1079: register rtx insn;
1080: {
1081: for (; insn; insn = NEXT_INSN (insn))
1082: if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
1083: || GET_CODE (insn) == CALL_INSN)
1084: {
1085: PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
1086: REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
1087: LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
1088: }
1089:
1090: /* Make sure the addresses of stack slots found outside the insn chain
1091: (such as, in DECL_RTL of a variable) are not shared
1092: with the insn chain.
1093:
1094: This special care is necessary when the stack slot MEM does not
1095: actually appear in the insn chain. If it does appear, its address
1096: is unshared from all else at that point. */
1097:
1098: copy_rtx_if_shared (stack_slot_list);
1099: }
1100:
1101: /* Mark ORIG as in use, and return a copy of it if it was already in use.
1102: Recursively does the same for subexpressions. */
1103:
1104: rtx
1105: copy_rtx_if_shared (orig)
1106: rtx orig;
1107: {
1108: register rtx x = orig;
1109: register int i;
1110: register enum rtx_code code;
1111: register char *format_ptr;
1112: int copied = 0;
1113:
1114: if (x == 0)
1115: return 0;
1116:
1117: code = GET_CODE (x);
1118:
1119: /* These types may be freely shared. */
1120:
1121: switch (code)
1122: {
1123: case REG:
1124: case QUEUED:
1125: case CONST_INT:
1126: case CONST_DOUBLE:
1127: case SYMBOL_REF:
1128: case CODE_LABEL:
1129: case PC:
1130: case CC0:
1131: case SCRATCH:
1132: /* SCRATCH must be shared because they represent distinct values. */
1133: return x;
1134:
1135: case INSN:
1136: case JUMP_INSN:
1137: case CALL_INSN:
1138: case NOTE:
1139: case LABEL_REF:
1140: case BARRIER:
1141: /* The chain of insns is not being copied. */
1142: return x;
1143:
1144: case MEM:
1145: /* A MEM is allowed to be shared if its address is constant
1146: or is a constant plus one of the special registers. */
1147: if (CONSTANT_ADDRESS_P (XEXP (x, 0))
1148: || XEXP (x, 0) == virtual_stack_vars_rtx
1149: || XEXP (x, 0) == virtual_incoming_args_rtx)
1150: return x;
1151:
1152: if (GET_CODE (XEXP (x, 0)) == PLUS
1153: && (XEXP (XEXP (x, 0), 0) == virtual_stack_vars_rtx
1154: || XEXP (XEXP (x, 0), 0) == virtual_incoming_args_rtx)
1155: && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
1156: {
1157: /* This MEM can appear in more than one place,
1158: but its address better not be shared with anything else. */
1159: if (! x->used)
1160: XEXP (x, 0) = copy_rtx_if_shared (XEXP (x, 0));
1161: x->used = 1;
1162: return x;
1163: }
1164: }
1165:
1166: /* This rtx may not be shared. If it has already been seen,
1167: replace it with a copy of itself. */
1168:
1169: if (x->used)
1170: {
1171: register rtx copy;
1172:
1173: copy = rtx_alloc (code);
1174: bcopy (x, copy, (sizeof (*copy) - sizeof (copy->fld)
1175: + sizeof (copy->fld[0]) * GET_RTX_LENGTH (code)));
1176: x = copy;
1177: copied = 1;
1178: }
1179: x->used = 1;
1180:
1181: /* Now scan the subexpressions recursively.
1182: We can store any replaced subexpressions directly into X
1183: since we know X is not shared! Any vectors in X
1184: must be copied if X was copied. */
1185:
1186: format_ptr = GET_RTX_FORMAT (code);
1187:
1188: for (i = 0; i < GET_RTX_LENGTH (code); i++)
1189: {
1190: switch (*format_ptr++)
1191: {
1192: case 'e':
1193: XEXP (x, i) = copy_rtx_if_shared (XEXP (x, i));
1194: break;
1195:
1196: case 'E':
1197: if (XVEC (x, i) != NULL)
1198: {
1199: register int j;
1200:
1201: if (copied)
1202: XVEC (x, i) = gen_rtvec_v (XVECLEN (x, i), &XVECEXP (x, i, 0));
1203: for (j = 0; j < XVECLEN (x, i); j++)
1204: XVECEXP (x, i, j)
1205: = copy_rtx_if_shared (XVECEXP (x, i, j));
1206: }
1207: break;
1208: }
1209: }
1210: return x;
1211: }
1212:
1213: /* Clear all the USED bits in X to allow copy_rtx_if_shared to be used
1214: to look for shared sub-parts. */
1215:
1216: void
1217: reset_used_flags (x)
1218: rtx x;
1219: {
1220: register int i, j;
1221: register enum rtx_code code;
1222: register char *format_ptr;
1223: int copied = 0;
1224:
1225: if (x == 0)
1226: return;
1227:
1228: code = GET_CODE (x);
1229:
1230: /* These types may be freely shared so we needn't do any reseting
1231: for them. */
1232:
1233: switch (code)
1234: {
1235: case REG:
1236: case QUEUED:
1237: case CONST_INT:
1238: case CONST_DOUBLE:
1239: case SYMBOL_REF:
1240: case CODE_LABEL:
1241: case PC:
1242: case CC0:
1243: return;
1244:
1245: case INSN:
1246: case JUMP_INSN:
1247: case CALL_INSN:
1248: case NOTE:
1249: case LABEL_REF:
1250: case BARRIER:
1251: /* The chain of insns is not being copied. */
1252: return;
1253: }
1254:
1255: x->used = 0;
1256:
1257: format_ptr = GET_RTX_FORMAT (code);
1258: for (i = 0; i < GET_RTX_LENGTH (code); i++)
1259: {
1260: switch (*format_ptr++)
1261: {
1262: case 'e':
1263: reset_used_flags (XEXP (x, i));
1264: break;
1265:
1266: case 'E':
1267: for (j = 0; j < XVECLEN (x, i); j++)
1268: reset_used_flags (XVECEXP (x, i, j));
1269: break;
1270: }
1271: }
1272: }
1273:
1274: /* Copy X if necessary so that it won't be altered by changes in OTHER.
1275: Return X or the rtx for the pseudo reg the value of X was copied into.
1276: OTHER must be valid as a SET_DEST. */
1277:
1278: rtx
1279: make_safe_from (x, other)
1280: rtx x, other;
1281: {
1282: while (1)
1283: switch (GET_CODE (other))
1284: {
1285: case SUBREG:
1286: other = SUBREG_REG (other);
1287: break;
1288: case STRICT_LOW_PART:
1289: case SIGN_EXTEND:
1290: case ZERO_EXTEND:
1291: other = XEXP (other, 0);
1292: break;
1293: default:
1294: goto done;
1295: }
1296: done:
1297: if ((GET_CODE (other) == MEM
1298: && ! CONSTANT_P (x)
1299: && GET_CODE (x) != REG
1300: && GET_CODE (x) != SUBREG)
1301: || (GET_CODE (other) == REG
1302: && (REGNO (other) < FIRST_PSEUDO_REGISTER
1303: || reg_mentioned_p (other, x))))
1304: {
1305: rtx temp = gen_reg_rtx (GET_MODE (x));
1306: emit_move_insn (temp, x);
1307: return temp;
1308: }
1309: return x;
1310: }
1311:
1312: /* Emission of insns (adding them to the doubly-linked list). */
1313:
1314: /* Return the first insn of the current sequence or current function. */
1315:
1316: rtx
1317: get_insns ()
1318: {
1319: return first_insn;
1320: }
1321:
1322: /* Return the last insn emitted in current sequence or current function. */
1323:
1324: rtx
1325: get_last_insn ()
1326: {
1327: return last_insn;
1328: }
1329:
1330: /* Specify a new insn as the last in the chain. */
1331:
1332: void
1333: set_last_insn (insn)
1334: rtx insn;
1335: {
1336: if (NEXT_INSN (insn) != 0)
1337: abort ();
1338: last_insn = insn;
1339: }
1340:
1341: /* Return the last insn emitted, even if it is in a sequence now pushed. */
1342:
1343: rtx
1344: get_last_insn_anywhere ()
1345: {
1346: struct sequence_stack *stack;
1347: if (last_insn)
1348: return last_insn;
1349: for (stack = sequence_stack; stack; stack = stack->next)
1350: if (stack->last != 0)
1351: return stack->last;
1352: return 0;
1353: }
1354:
1355: /* Return a number larger than any instruction's uid in this function. */
1356:
1357: int
1358: get_max_uid ()
1359: {
1360: return cur_insn_uid;
1361: }
1362:
1363: /* Return the next insn. If it is a SEQUENCE, return the first insn
1364: of the sequence. */
1365:
1366: rtx
1367: next_insn (insn)
1368: rtx insn;
1369: {
1370: if (insn)
1371: {
1372: insn = NEXT_INSN (insn);
1373: if (insn && GET_CODE (insn) == INSN
1374: && GET_CODE (PATTERN (insn)) == SEQUENCE)
1375: insn = XVECEXP (PATTERN (insn), 0, 0);
1376: }
1377:
1378: return insn;
1379: }
1380:
1381: /* Return the previous insn. If it is a SEQUENCE, return the last insn
1382: of the sequence. */
1383:
1384: rtx
1385: previous_insn (insn)
1386: rtx insn;
1387: {
1388: if (insn)
1389: {
1390: insn = PREV_INSN (insn);
1391: if (insn && GET_CODE (insn) == INSN
1392: && GET_CODE (PATTERN (insn)) == SEQUENCE)
1393: insn = XVECEXP (PATTERN (insn), 0, XVECLEN (PATTERN (insn), 0) - 1);
1394: }
1395:
1396: return insn;
1397: }
1398:
1399: /* Return the next insn after INSN that is not a NOTE. This routine does not
1400: look inside SEQUENCEs. */
1401:
1402: rtx
1403: next_nonnote_insn (insn)
1404: rtx insn;
1405: {
1406: while (insn)
1407: {
1408: insn = NEXT_INSN (insn);
1409: if (insn == 0 || GET_CODE (insn) != NOTE)
1410: break;
1411: }
1412:
1413: return insn;
1414: }
1415:
1416: /* Return the previous insn before INSN that is not a NOTE. This routine does
1417: not look inside SEQUENCEs. */
1418:
1419: rtx
1420: prev_nonnote_insn (insn)
1421: rtx insn;
1422: {
1423: while (insn)
1424: {
1425: insn = PREV_INSN (insn);
1426: if (insn == 0 || GET_CODE (insn) != NOTE)
1427: break;
1428: }
1429:
1430: return insn;
1431: }
1432:
1433: /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
1434: or 0, if there is none. This routine does not look inside
1435: SEQUENCEs. */
1436:
1437: rtx
1438: next_real_insn (insn)
1439: rtx insn;
1440: {
1441: while (insn)
1442: {
1443: insn = NEXT_INSN (insn);
1444: if (insn == 0 || GET_CODE (insn) == INSN
1445: || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
1446: break;
1447: }
1448:
1449: return insn;
1450: }
1451:
1452: /* Return the last INSN, CALL_INSN or JUMP_INSN before INSN;
1453: or 0, if there is none. This routine does not look inside
1454: SEQUENCEs. */
1455:
1456: rtx
1457: prev_real_insn (insn)
1458: rtx insn;
1459: {
1460: while (insn)
1461: {
1462: insn = PREV_INSN (insn);
1463: if (insn == 0 || GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
1464: || GET_CODE (insn) == JUMP_INSN)
1465: break;
1466: }
1467:
1468: return insn;
1469: }
1470:
1471: /* Find the next insn after INSN that really does something. This routine
1472: does not look inside SEQUENCEs. Until reload has completed, this is the
1473: same as next_real_insn. */
1474:
1475: rtx
1476: next_active_insn (insn)
1477: rtx insn;
1478: {
1479: while (insn)
1480: {
1481: insn = NEXT_INSN (insn);
1482: if (insn == 0
1483: || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN
1484: || (GET_CODE (insn) == INSN
1485: && (! reload_completed
1486: || (GET_CODE (PATTERN (insn)) != USE
1487: && GET_CODE (PATTERN (insn)) != CLOBBER))))
1488: break;
1489: }
1490:
1491: return insn;
1492: }
1493:
1494: /* Find the last insn before INSN that really does something. This routine
1495: does not look inside SEQUENCEs. Until reload has completed, this is the
1496: same as prev_real_insn. */
1497:
1498: rtx
1499: prev_active_insn (insn)
1500: rtx insn;
1501: {
1502: while (insn)
1503: {
1504: insn = PREV_INSN (insn);
1505: if (insn == 0
1506: || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN
1507: || (GET_CODE (insn) == INSN
1508: && (! reload_completed
1509: || (GET_CODE (PATTERN (insn)) != USE
1510: && GET_CODE (PATTERN (insn)) != CLOBBER))))
1511: break;
1512: }
1513:
1514: return insn;
1515: }
1516:
1517: /* Return the next CODE_LABEL after the insn INSN, or 0 if there is none. */
1518:
1519: rtx
1520: next_label (insn)
1521: rtx insn;
1522: {
1523: while (insn)
1524: {
1525: insn = NEXT_INSN (insn);
1526: if (insn == 0 || GET_CODE (insn) == CODE_LABEL)
1527: break;
1528: }
1529:
1530: return insn;
1531: }
1532:
1533: /* Return the last CODE_LABEL before the insn INSN, or 0 if there is none. */
1534:
1535: rtx
1536: prev_label (insn)
1537: rtx insn;
1538: {
1539: while (insn)
1540: {
1541: insn = PREV_INSN (insn);
1542: if (insn == 0 || GET_CODE (insn) == CODE_LABEL)
1543: break;
1544: }
1545:
1546: return insn;
1547: }
1548:
1549: #ifdef HAVE_cc0
1.1.1.3 ! root 1550: /* INSN uses CC0 and is being moved into a delay slot. Set up REG_CC_SETTER
! 1551: and REG_CC_USER notes so we can find it. */
! 1552:
! 1553: void
! 1554: link_cc0_insns (insn)
! 1555: rtx insn;
! 1556: {
! 1557: rtx user = next_nonnote_insn (insn);
! 1558:
! 1559: if (GET_CODE (user) == INSN && GET_CODE (PATTERN (user)) == SEQUENCE)
! 1560: user = XVECEXP (PATTERN (user), 0, 0);
! 1561:
! 1562: REG_NOTES (user) = gen_rtx (INSN_LIST, REG_CC_SETTER, insn,
! 1563: REG_NOTES (user));
! 1564: REG_NOTES (insn) = gen_rtx (INSN_LIST, REG_CC_USER, user, REG_NOTES (insn));
! 1565: }
! 1566:
1.1 root 1567: /* Return the next insn that uses CC0 after INSN, which is assumed to
1568: set it. This is the inverse of prev_cc0_setter (i.e., prev_cc0_setter
1569: applied to the result of this function should yield INSN).
1570:
1571: Normally, this is simply the next insn. However, if a REG_CC_USER note
1572: is present, it contains the insn that uses CC0.
1573:
1574: Return 0 if we can't find the insn. */
1575:
1576: rtx
1577: next_cc0_user (insn)
1578: rtx insn;
1579: {
1580: rtx note = find_reg_note (insn, REG_CC_USER, 0);
1581:
1582: if (note)
1583: return XEXP (note, 0);
1584:
1585: insn = next_nonnote_insn (insn);
1586: if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
1587: insn = XVECEXP (PATTERN (insn), 0, 0);
1588:
1589: if (insn && GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1590: && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
1591: return insn;
1592:
1593: return 0;
1594: }
1595:
1596: /* Find the insn that set CC0 for INSN. Unless INSN has a REG_CC_SETTER
1597: note, it is the previous insn. */
1598:
1599: rtx
1600: prev_cc0_setter (insn)
1601: rtx insn;
1602: {
1603: rtx note = find_reg_note (insn, REG_CC_SETTER, 0);
1604: rtx link;
1605:
1606: if (note)
1607: return XEXP (note, 0);
1608:
1609: insn = prev_nonnote_insn (insn);
1610: if (! sets_cc0_p (PATTERN (insn)))
1611: abort ();
1612:
1613: return insn;
1614: }
1615: #endif
1616:
1617: /* Try splitting insns that can be split for better scheduling.
1618: PAT is the pattern which might split.
1619: TRIAL is the insn providing PAT.
1620: BACKWARDS is non-zero if we are scanning insns from last to first.
1621:
1622: If this routine succeeds in splitting, it returns the first or last
1623: replacement insn depending on the value of BACKWARDS. Otherwise, it
1624: returns TRIAL. If the insn to be returned can be split, it will be. */
1625:
1626: rtx
1627: try_split (pat, trial, backwards)
1628: rtx pat, trial;
1629: int backwards;
1630: {
1631: rtx before = PREV_INSN (trial);
1632: rtx after = NEXT_INSN (trial);
1633: rtx seq = split_insns (pat, trial);
1634: int has_barrier = 0;
1635: rtx tem;
1636:
1637: /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER.
1638: We may need to handle this specially. */
1639: if (after && GET_CODE (after) == BARRIER)
1640: {
1641: has_barrier = 1;
1642: after = NEXT_INSN (after);
1643: }
1644:
1645: if (seq)
1646: {
1647: /* SEQ can either be a SEQUENCE or the pattern of a single insn.
1648: The latter case will normally arise only when being done so that
1649: it, in turn, will be split (SFmode on the 29k is an example). */
1650: if (GET_CODE (seq) == SEQUENCE)
1651: {
1652: /* If we are splitting a JUMP_INSN, look for the JUMP_INSN in
1653: SEQ and copy our JUMP_LABEL to it. If JUMP_LABEL is non-zero,
1654: increment the usage count so we don't delete the label. */
1655: int i;
1656:
1657: if (GET_CODE (trial) == JUMP_INSN)
1658: for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
1659: if (GET_CODE (XVECEXP (seq, 0, i)) == JUMP_INSN)
1660: {
1661: JUMP_LABEL (XVECEXP (seq, 0, i)) = JUMP_LABEL (trial);
1662:
1663: if (JUMP_LABEL (trial))
1664: LABEL_NUSES (JUMP_LABEL (trial))++;
1665: }
1666:
1667: tem = emit_insn_after (seq, before);
1668:
1669: delete_insn (trial);
1670: if (has_barrier)
1671: emit_barrier_after (tem);
1672: }
1673: /* Avoid infinite loop if the result matches the original pattern. */
1674: else if (rtx_equal_p (seq, pat))
1675: return trial;
1676: else
1677: {
1678: PATTERN (trial) = seq;
1679: INSN_CODE (trial) = -1;
1680: }
1681:
1682: /* Set TEM to the insn we should return. */
1683: tem = backwards ? prev_active_insn (after) : next_active_insn (before);
1684: return try_split (PATTERN (tem), tem, backwards);
1685: }
1686:
1687: return trial;
1688: }
1689:
1690: /* Make and return an INSN rtx, initializing all its slots.
1691: Store PATTERN in the pattern slots.
1692: PAT_FORMALS is an idea that never really went anywhere. */
1693:
1694: rtx
1695: make_insn_raw (pattern, pat_formals)
1696: rtx pattern;
1697: rtvec pat_formals;
1698: {
1699: register rtx insn;
1700:
1701: insn = rtx_alloc(INSN);
1702: INSN_UID(insn) = cur_insn_uid++;
1703:
1704: PATTERN (insn) = pattern;
1705: INSN_CODE (insn) = -1;
1706: LOG_LINKS(insn) = NULL;
1707: REG_NOTES(insn) = NULL;
1708:
1709: return insn;
1710: }
1711:
1712: /* Like `make_insn' but make a JUMP_INSN instead of an insn. */
1713:
1714: static rtx
1715: make_jump_insn_raw (pattern, pat_formals)
1716: rtx pattern;
1717: rtvec pat_formals;
1718: {
1719: register rtx insn;
1720:
1721: insn = rtx_alloc(JUMP_INSN);
1722: INSN_UID(insn) = cur_insn_uid++;
1723:
1724: PATTERN (insn) = pattern;
1725: INSN_CODE (insn) = -1;
1726: LOG_LINKS(insn) = NULL;
1727: REG_NOTES(insn) = NULL;
1728: JUMP_LABEL(insn) = NULL;
1729:
1730: return insn;
1731: }
1732:
1733: /* Add INSN to the end of the doubly-linked list.
1734: INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE. */
1735:
1736: void
1737: add_insn (insn)
1738: register rtx insn;
1739: {
1740: PREV_INSN (insn) = last_insn;
1741: NEXT_INSN (insn) = 0;
1742:
1743: if (NULL != last_insn)
1744: NEXT_INSN (last_insn) = insn;
1745:
1746: if (NULL == first_insn)
1747: first_insn = insn;
1748:
1749: last_insn = insn;
1750: }
1751:
1752: /* Add INSN into the doubly-linked list after insn AFTER. This should be the
1753: only function called to insert an insn once delay slots have been filled
1754: since only it knows how to update a SEQUENCE. */
1755:
1756: void
1757: add_insn_after (insn, after)
1758: rtx insn, after;
1759: {
1760: rtx next = NEXT_INSN (after);
1761:
1762: NEXT_INSN (insn) = next;
1763: PREV_INSN (insn) = after;
1764:
1765: if (next)
1766: {
1767: PREV_INSN (next) = insn;
1768: if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE)
1769: PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;
1770: }
1771: else if (last_insn == after)
1772: last_insn = insn;
1773: else
1774: {
1775: struct sequence_stack *stack = sequence_stack;
1776: /* Scan all pending sequences too. */
1777: for (; stack; stack = stack->next)
1778: if (after == stack->last)
1779: stack->last = insn;
1780: }
1781:
1782: NEXT_INSN (after) = insn;
1783: if (GET_CODE (after) == INSN && GET_CODE (PATTERN (after)) == SEQUENCE)
1784: {
1785: rtx sequence = PATTERN (after);
1786: NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
1787: }
1788: }
1789:
1790: /* Delete all insns made since FROM.
1791: FROM becomes the new last instruction. */
1792:
1793: void
1794: delete_insns_since (from)
1795: rtx from;
1796: {
1797: if (from == 0)
1798: first_insn = 0;
1799: else
1800: NEXT_INSN (from) = 0;
1801: last_insn = from;
1802: }
1803:
1804: /* Move a consecutive bunch of insns to a different place in the chain.
1805: The insns to be moved are those between FROM and TO.
1806: They are moved to a new position after the insn AFTER.
1807: AFTER must not be FROM or TO or any insn in between.
1808:
1809: This function does not know about SEQUENCEs and hence should not be
1810: called after delay-slot filling has been done. */
1811:
1812: void
1813: reorder_insns (from, to, after)
1814: rtx from, to, after;
1815: {
1816: /* Splice this bunch out of where it is now. */
1817: if (PREV_INSN (from))
1818: NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);
1819: if (NEXT_INSN (to))
1820: PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);
1821: if (last_insn == to)
1822: last_insn = PREV_INSN (from);
1823: if (first_insn == from)
1824: first_insn = NEXT_INSN (to);
1825:
1826: /* Make the new neighbors point to it and it to them. */
1827: if (NEXT_INSN (after))
1828: PREV_INSN (NEXT_INSN (after)) = to;
1829:
1830: NEXT_INSN (to) = NEXT_INSN (after);
1831: PREV_INSN (from) = after;
1832: NEXT_INSN (after) = from;
1833: if (after == last_insn)
1834: last_insn = to;
1835: }
1836:
1837: /* Return the line note insn preceding INSN. */
1838:
1839: static rtx
1840: find_line_note (insn)
1841: rtx insn;
1842: {
1843: if (no_line_numbers)
1844: return 0;
1845:
1846: for (; insn; insn = PREV_INSN (insn))
1847: if (GET_CODE (insn) == NOTE
1848: && NOTE_LINE_NUMBER (insn) >= 0)
1849: break;
1850:
1851: return insn;
1852: }
1853:
1854: /* Like reorder_insns, but inserts line notes to preserve the line numbers
1855: of the moved insns when debugging. This may insert a note between AFTER
1856: and FROM, and another one after TO. */
1857:
1858: void
1859: reorder_insns_with_line_notes (from, to, after)
1860: rtx from, to, after;
1861: {
1862: rtx from_line = find_line_note (from);
1863: rtx after_line = find_line_note (after);
1864:
1865: reorder_insns (from, to, after);
1866:
1867: if (from_line == after_line)
1868: return;
1869:
1870: if (from_line)
1871: emit_line_note_after (NOTE_SOURCE_FILE (from_line),
1872: NOTE_LINE_NUMBER (from_line),
1873: after);
1874: if (after_line)
1875: emit_line_note_after (NOTE_SOURCE_FILE (after_line),
1876: NOTE_LINE_NUMBER (after_line),
1877: to);
1878: }
1879:
1880: /* Emit an insn of given code and pattern
1881: at a specified place within the doubly-linked list. */
1882:
1883: /* Make an instruction with body PATTERN
1884: and output it before the instruction BEFORE. */
1885:
1886: rtx
1887: emit_insn_before (pattern, before)
1888: register rtx pattern, before;
1889: {
1890: register rtx insn = before;
1891:
1892: if (GET_CODE (pattern) == SEQUENCE)
1893: {
1894: register int i;
1895:
1896: for (i = 0; i < XVECLEN (pattern, 0); i++)
1897: {
1898: insn = XVECEXP (pattern, 0, i);
1899: add_insn_after (insn, PREV_INSN (before));
1900: }
1901: if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE)
1902: sequence_result[XVECLEN (pattern, 0)] = pattern;
1903: }
1904: else
1905: {
1906: insn = make_insn_raw (pattern, 0);
1907: add_insn_after (insn, PREV_INSN (before));
1908: }
1909:
1910: return insn;
1911: }
1912:
1913: /* Make an instruction with body PATTERN and code JUMP_INSN
1914: and output it before the instruction BEFORE. */
1915:
1916: rtx
1917: emit_jump_insn_before (pattern, before)
1918: register rtx pattern, before;
1919: {
1920: register rtx insn;
1921:
1922: if (GET_CODE (pattern) == SEQUENCE)
1923: insn = emit_insn_before (pattern, before);
1924: else
1925: {
1926: insn = make_jump_insn_raw (pattern, 0);
1927: add_insn_after (insn, PREV_INSN (before));
1928: }
1929:
1930: return insn;
1931: }
1932:
1933: /* Make an instruction with body PATTERN and code CALL_INSN
1934: and output it before the instruction BEFORE. */
1935:
1936: rtx
1937: emit_call_insn_before (pattern, before)
1938: register rtx pattern, before;
1939: {
1940: rtx insn = emit_insn_before (pattern, before);
1941: PUT_CODE (insn, CALL_INSN);
1942: return insn;
1943: }
1944:
1945: /* Make an insn of code BARRIER
1946: and output it before the insn AFTER. */
1947:
1948: rtx
1949: emit_barrier_before (before)
1950: register rtx before;
1951: {
1952: register rtx insn = rtx_alloc (BARRIER);
1953:
1954: INSN_UID (insn) = cur_insn_uid++;
1955:
1956: add_insn_after (insn, PREV_INSN (before));
1957: return insn;
1958: }
1959:
1960: /* Emit a note of subtype SUBTYPE before the insn BEFORE. */
1961:
1962: rtx
1963: emit_note_before (subtype, before)
1964: int subtype;
1965: rtx before;
1966: {
1967: register rtx note = rtx_alloc (NOTE);
1968: INSN_UID (note) = cur_insn_uid++;
1969: NOTE_SOURCE_FILE (note) = 0;
1970: NOTE_LINE_NUMBER (note) = subtype;
1971:
1972: add_insn_after (note, PREV_INSN (before));
1973: return note;
1974: }
1975:
1976: /* Make an insn of code INSN with body PATTERN
1977: and output it after the insn AFTER. */
1978:
1979: rtx
1980: emit_insn_after (pattern, after)
1981: register rtx pattern, after;
1982: {
1983: register rtx insn = after;
1984:
1985: if (GET_CODE (pattern) == SEQUENCE)
1986: {
1987: register int i;
1988:
1989: for (i = 0; i < XVECLEN (pattern, 0); i++)
1990: {
1991: insn = XVECEXP (pattern, 0, i);
1992: add_insn_after (insn, after);
1993: after = insn;
1994: }
1995: if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE)
1996: sequence_result[XVECLEN (pattern, 0)] = pattern;
1997: }
1998: else
1999: {
2000: insn = make_insn_raw (pattern, 0);
2001: add_insn_after (insn, after);
2002: }
2003:
2004: return insn;
2005: }
2006:
2007: /* Make an insn of code JUMP_INSN with body PATTERN
2008: and output it after the insn AFTER. */
2009:
2010: rtx
2011: emit_jump_insn_after (pattern, after)
2012: register rtx pattern, after;
2013: {
2014: register rtx insn;
2015:
2016: if (GET_CODE (pattern) == SEQUENCE)
2017: insn = emit_insn_after (pattern, after);
2018: else
2019: {
2020: insn = make_jump_insn_raw (pattern, 0);
2021: add_insn_after (insn, after);
2022: }
2023:
2024: return insn;
2025: }
2026:
2027: /* Make an insn of code BARRIER
2028: and output it after the insn AFTER. */
2029:
2030: rtx
2031: emit_barrier_after (after)
2032: register rtx after;
2033: {
2034: register rtx insn = rtx_alloc (BARRIER);
2035:
2036: INSN_UID (insn) = cur_insn_uid++;
2037:
2038: add_insn_after (insn, after);
2039: return insn;
2040: }
2041:
2042: /* Emit the label LABEL after the insn AFTER. */
2043:
2044: rtx
2045: emit_label_after (label, after)
2046: rtx label, after;
2047: {
2048: /* This can be called twice for the same label
2049: as a result of the confusion that follows a syntax error!
2050: So make it harmless. */
2051: if (INSN_UID (label) == 0)
2052: {
2053: INSN_UID (label) = cur_insn_uid++;
2054: add_insn_after (label, after);
2055: }
2056:
2057: return label;
2058: }
2059:
2060: /* Emit a note of subtype SUBTYPE after the insn AFTER. */
2061:
2062: rtx
2063: emit_note_after (subtype, after)
2064: int subtype;
2065: rtx after;
2066: {
2067: register rtx note = rtx_alloc (NOTE);
2068: INSN_UID (note) = cur_insn_uid++;
2069: NOTE_SOURCE_FILE (note) = 0;
2070: NOTE_LINE_NUMBER (note) = subtype;
2071: add_insn_after (note, after);
2072: return note;
2073: }
2074:
2075: /* Emit a line note for FILE and LINE after the insn AFTER. */
2076:
2077: rtx
2078: emit_line_note_after (file, line, after)
2079: char *file;
2080: int line;
2081: rtx after;
2082: {
2083: register rtx note;
2084:
2085: if (no_line_numbers && line > 0)
2086: {
2087: cur_insn_uid++;
2088: return 0;
2089: }
2090:
2091: note = rtx_alloc (NOTE);
2092: INSN_UID (note) = cur_insn_uid++;
2093: NOTE_SOURCE_FILE (note) = file;
2094: NOTE_LINE_NUMBER (note) = line;
2095: add_insn_after (note, after);
2096: return note;
2097: }
2098:
2099: /* Make an insn of code INSN with pattern PATTERN
2100: and add it to the end of the doubly-linked list.
2101: If PATTERN is a SEQUENCE, take the elements of it
2102: and emit an insn for each element.
2103:
2104: Returns the last insn emitted. */
2105:
2106: rtx
2107: emit_insn (pattern)
2108: rtx pattern;
2109: {
2110: rtx insn = last_insn;
2111:
2112: if (GET_CODE (pattern) == SEQUENCE)
2113: {
2114: register int i;
2115:
2116: for (i = 0; i < XVECLEN (pattern, 0); i++)
2117: {
2118: insn = XVECEXP (pattern, 0, i);
2119: add_insn (insn);
2120: }
2121: if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE)
2122: sequence_result[XVECLEN (pattern, 0)] = pattern;
2123: }
2124: else
2125: {
2126: insn = make_insn_raw (pattern, NULL);
2127: add_insn (insn);
2128: }
2129:
2130: return insn;
2131: }
2132:
2133: /* Emit the insns in a chain starting with INSN.
2134: Return the last insn emitted. */
2135:
2136: rtx
2137: emit_insns (insn)
2138: rtx insn;
2139: {
2140: rtx last = 0;
2141:
2142: while (insn)
2143: {
2144: rtx next = NEXT_INSN (insn);
2145: add_insn (insn);
2146: last = insn;
2147: insn = next;
2148: }
2149:
2150: return last;
2151: }
2152:
2153: /* Emit the insns in a chain starting with INSN and place them in front of
2154: the insn BEFORE. Return the last insn emitted. */
2155:
2156: rtx
2157: emit_insns_before (insn, before)
2158: rtx insn;
2159: rtx before;
2160: {
2161: rtx last = 0;
2162:
2163: while (insn)
2164: {
2165: rtx next = NEXT_INSN (insn);
2166: add_insn_after (insn, PREV_INSN (before));
2167: last = insn;
2168: insn = next;
2169: }
2170:
2171: return last;
2172: }
2173:
2174: /* Make an insn of code JUMP_INSN with pattern PATTERN
2175: and add it to the end of the doubly-linked list. */
2176:
2177: rtx
2178: emit_jump_insn (pattern)
2179: rtx pattern;
2180: {
2181: if (GET_CODE (pattern) == SEQUENCE)
2182: return emit_insn (pattern);
2183: else
2184: {
2185: register rtx insn = make_jump_insn_raw (pattern, NULL);
2186: add_insn (insn);
2187: return insn;
2188: }
2189: }
2190:
2191: /* Make an insn of code CALL_INSN with pattern PATTERN
2192: and add it to the end of the doubly-linked list. */
2193:
2194: rtx
2195: emit_call_insn (pattern)
2196: rtx pattern;
2197: {
2198: if (GET_CODE (pattern) == SEQUENCE)
2199: return emit_insn (pattern);
2200: else
2201: {
2202: register rtx insn = make_insn_raw (pattern, NULL);
2203: add_insn (insn);
2204: PUT_CODE (insn, CALL_INSN);
2205: return insn;
2206: }
2207: }
2208:
2209: /* Add the label LABEL to the end of the doubly-linked list. */
2210:
2211: rtx
2212: emit_label (label)
2213: rtx label;
2214: {
2215: /* This can be called twice for the same label
2216: as a result of the confusion that follows a syntax error!
2217: So make it harmless. */
2218: if (INSN_UID (label) == 0)
2219: {
2220: INSN_UID (label) = cur_insn_uid++;
2221: add_insn (label);
2222: }
2223: return label;
2224: }
2225:
2226: /* Make an insn of code BARRIER
2227: and add it to the end of the doubly-linked list. */
2228:
2229: rtx
2230: emit_barrier ()
2231: {
2232: register rtx barrier = rtx_alloc (BARRIER);
2233: INSN_UID (barrier) = cur_insn_uid++;
2234: add_insn (barrier);
2235: return barrier;
2236: }
2237:
2238: /* Make an insn of code NOTE
2239: with data-fields specified by FILE and LINE
2240: and add it to the end of the doubly-linked list,
2241: but only if line-numbers are desired for debugging info. */
2242:
2243: rtx
2244: emit_line_note (file, line)
2245: char *file;
2246: int line;
2247: {
2248: emit_filename = file;
2249: emit_lineno = line;
2250:
2251: #if 0
2252: if (no_line_numbers)
2253: return 0;
2254: #endif
2255:
2256: return emit_note (file, line);
2257: }
2258:
2259: /* Make an insn of code NOTE
2260: with data-fields specified by FILE and LINE
2261: and add it to the end of the doubly-linked list.
2262: If it is a line-number NOTE, omit it if it matches the previous one. */
2263:
2264: rtx
2265: emit_note (file, line)
2266: char *file;
2267: int line;
2268: {
2269: register rtx note;
2270:
2271: if (line > 0)
2272: {
2273: if (file && last_filename && !strcmp (file, last_filename)
2274: && line == last_linenum)
2275: return 0;
2276: last_filename = file;
2277: last_linenum = line;
2278: }
2279:
2280: if (no_line_numbers && line > 0)
2281: {
2282: cur_insn_uid++;
2283: return 0;
2284: }
2285:
2286: note = rtx_alloc (NOTE);
2287: INSN_UID (note) = cur_insn_uid++;
2288: NOTE_SOURCE_FILE (note) = file;
2289: NOTE_LINE_NUMBER (note) = line;
2290: add_insn (note);
2291: return note;
2292: }
2293:
2294: /* Emit a NOTE, and don't omit it even if LINE it the previous note. */
2295:
2296: rtx
2297: emit_line_note_force (file, line)
2298: char *file;
2299: int line;
2300: {
2301: last_linenum = -1;
2302: return emit_line_note (file, line);
2303: }
2304:
2305: /* Cause next statement to emit a line note even if the line number
2306: has not changed. This is used at the beginning of a function. */
2307:
2308: void
2309: force_next_line_note ()
2310: {
2311: last_linenum = -1;
2312: }
2313:
2314: /* Return an indication of which type of insn should have X as a body.
2315: The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN. */
2316:
2317: enum rtx_code
2318: classify_insn (x)
2319: rtx x;
2320: {
2321: if (GET_CODE (x) == CODE_LABEL)
2322: return CODE_LABEL;
2323: if (GET_CODE (x) == CALL)
2324: return CALL_INSN;
2325: if (GET_CODE (x) == RETURN)
2326: return JUMP_INSN;
2327: if (GET_CODE (x) == SET)
2328: {
2329: if (SET_DEST (x) == pc_rtx)
2330: return JUMP_INSN;
2331: else if (GET_CODE (SET_SRC (x)) == CALL)
2332: return CALL_INSN;
2333: else
2334: return INSN;
2335: }
2336: if (GET_CODE (x) == PARALLEL)
2337: {
2338: register int j;
2339: for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
2340: if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
2341: return CALL_INSN;
2342: else if (GET_CODE (XVECEXP (x, 0, j)) == SET
2343: && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx)
2344: return JUMP_INSN;
2345: else if (GET_CODE (XVECEXP (x, 0, j)) == SET
2346: && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
2347: return CALL_INSN;
2348: }
2349: return INSN;
2350: }
2351:
2352: /* Emit the rtl pattern X as an appropriate kind of insn.
2353: If X is a label, it is simply added into the insn chain. */
2354:
2355: rtx
2356: emit (x)
2357: rtx x;
2358: {
2359: enum rtx_code code = classify_insn (x);
2360:
2361: if (code == CODE_LABEL)
2362: return emit_label (x);
2363: else if (code == INSN)
2364: return emit_insn (x);
2365: else if (code == JUMP_INSN)
2366: {
2367: register rtx insn = emit_jump_insn (x);
2368: if (simplejump_p (insn) || GET_CODE (x) == RETURN)
2369: return emit_barrier ();
2370: return insn;
2371: }
2372: else if (code == CALL_INSN)
2373: return emit_call_insn (x);
2374: else
2375: abort ();
2376: }
2377:
2378: /* Begin emitting insns to a sequence which can be packaged in an RTL_EXPR. */
2379:
2380: void
2381: start_sequence ()
2382: {
2383: struct sequence_stack *tem;
2384:
2385: if (sequence_element_free_list)
2386: {
2387: /* Reuse a previously-saved struct sequence_stack. */
2388: tem = sequence_element_free_list;
2389: sequence_element_free_list = tem->next;
2390: }
2391: else
2392: tem = (struct sequence_stack *) permalloc (sizeof (struct sequence_stack));
2393:
2394: tem->next = sequence_stack;
2395: tem->first = first_insn;
2396: tem->last = last_insn;
2397:
2398: sequence_stack = tem;
2399:
2400: first_insn = 0;
2401: last_insn = 0;
2402: }
2403:
2404: /* Set up the insn chain starting with FIRST
2405: as the current sequence, saving the previously current one. */
2406:
2407: void
2408: push_to_sequence (first)
2409: rtx first;
2410: {
2411: rtx last;
2412:
2413: start_sequence ();
2414:
2415: for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last));
2416:
2417: first_insn = first;
2418: last_insn = last;
2419: }
2420:
2421: /* After emitting to a sequence, restore previous saved state.
2422:
2423: To get the contents of the sequence just made,
2424: you must call `gen_sequence' *before* calling here. */
2425:
2426: void
2427: end_sequence ()
2428: {
2429: struct sequence_stack *tem = sequence_stack;
2430:
2431: first_insn = tem->first;
2432: last_insn = tem->last;
2433: sequence_stack = tem->next;
2434:
2435: tem->next = sequence_element_free_list;
2436: sequence_element_free_list = tem;
2437: }
2438:
2439: /* Return 1 if currently emitting into a sequence. */
2440:
2441: int
2442: in_sequence_p ()
2443: {
2444: return sequence_stack != 0;
2445: }
2446:
2447: /* Generate a SEQUENCE rtx containing the insns already emitted
2448: to the current sequence.
2449:
2450: This is how the gen_... function from a DEFINE_EXPAND
2451: constructs the SEQUENCE that it returns. */
2452:
2453: rtx
2454: gen_sequence ()
2455: {
2456: rtx result;
2457: rtx tem;
2458: rtvec newvec;
2459: int i;
2460: int len;
2461:
2462: /* Count the insns in the chain. */
2463: len = 0;
2464: for (tem = first_insn; tem; tem = NEXT_INSN (tem))
2465: len++;
2466:
2467: /* If only one insn, return its pattern rather than a SEQUENCE.
2468: (Now that we cache SEQUENCE expressions, it isn't worth special-casing
2469: the case of an empty list.) */
2470: if (len == 1
2471: && (GET_CODE (first_insn) == INSN
2472: || GET_CODE (first_insn) == JUMP_INSN
2473: || GET_CODE (first_insn) == CALL_INSN))
2474: return PATTERN (first_insn);
2475:
2476: /* Put them in a vector. See if we already have a SEQUENCE of the
2477: appropriate length around. */
2478: if (len < SEQUENCE_RESULT_SIZE && (result = sequence_result[len]) != 0)
2479: sequence_result[len] = 0;
2480: else
2481: {
2482: /* Ensure that this rtl goes in saveable_obstack, since we may be
2483: caching it. */
2484: int in_current_obstack = rtl_in_saveable_obstack ();
2485: result = gen_rtx (SEQUENCE, VOIDmode, rtvec_alloc (len));
2486: if (in_current_obstack)
2487: rtl_in_current_obstack ();
2488: }
2489:
2490: for (i = 0, tem = first_insn; tem; tem = NEXT_INSN (tem), i++)
2491: XVECEXP (result, 0, i) = tem;
2492:
2493: return result;
2494: }
2495:
2496: /* Set up regno_reg_rtx, reg_rtx_no and regno_pointer_flag
2497: according to the chain of insns starting with FIRST.
2498:
2499: Also set cur_insn_uid to exceed the largest uid in that chain.
2500:
2501: This is used when an inline function's rtl is saved
2502: and passed to rest_of_compilation later. */
2503:
2504: static void restore_reg_data_1 ();
2505:
2506: void
2507: restore_reg_data (first)
2508: rtx first;
2509: {
2510: register rtx insn;
2511: int i;
2512: register int max_uid = 0;
2513:
2514: for (insn = first; insn; insn = NEXT_INSN (insn))
2515: {
2516: if (INSN_UID (insn) >= max_uid)
2517: max_uid = INSN_UID (insn);
2518:
2519: switch (GET_CODE (insn))
2520: {
2521: case NOTE:
2522: case CODE_LABEL:
2523: case BARRIER:
2524: break;
2525:
2526: case JUMP_INSN:
2527: case CALL_INSN:
2528: case INSN:
2529: restore_reg_data_1 (PATTERN (insn));
2530: break;
2531: }
2532: }
2533:
2534: /* Don't duplicate the uids already in use. */
2535: cur_insn_uid = max_uid + 1;
2536:
2537: /* If any regs are missing, make them up.
2538:
2539: ??? word_mode is not necessarily the right mode. Most likely these REGs
2540: are never used. At some point this should be checked. */
2541:
2542: for (i = FIRST_PSEUDO_REGISTER; i < reg_rtx_no; i++)
2543: if (regno_reg_rtx[i] == 0)
2544: regno_reg_rtx[i] = gen_rtx (REG, word_mode, i);
2545: }
2546:
2547: static void
2548: restore_reg_data_1 (orig)
2549: rtx orig;
2550: {
2551: register rtx x = orig;
2552: register int i;
2553: register enum rtx_code code;
2554: register char *format_ptr;
2555:
2556: code = GET_CODE (x);
2557:
2558: switch (code)
2559: {
2560: case QUEUED:
2561: case CONST_INT:
2562: case CONST_DOUBLE:
2563: case SYMBOL_REF:
2564: case CODE_LABEL:
2565: case PC:
2566: case CC0:
2567: case LABEL_REF:
2568: return;
2569:
2570: case REG:
2571: if (REGNO (x) >= FIRST_PSEUDO_REGISTER)
2572: {
2573: /* Make sure regno_pointer_flag and regno_reg_rtx are large
2574: enough to have an element for this pseudo reg number. */
2575: if (REGNO (x) >= reg_rtx_no)
2576: {
2577: reg_rtx_no = REGNO (x);
2578:
2579: if (reg_rtx_no >= regno_pointer_flag_length)
2580: {
2581: int newlen = MAX (regno_pointer_flag_length * 2,
2582: reg_rtx_no + 30);
2583: rtx *new1;
2584: char *new = (char *) oballoc (newlen);
2585: bzero (new, newlen);
2586: bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
2587:
2588: new1 = (rtx *) oballoc (newlen * sizeof (rtx));
2589: bzero (new1, newlen * sizeof (rtx));
2590: bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx));
2591:
2592: regno_pointer_flag = new;
2593: regno_reg_rtx = new1;
2594: regno_pointer_flag_length = newlen;
2595: }
2596: reg_rtx_no ++;
2597: }
2598: regno_reg_rtx[REGNO (x)] = x;
2599: }
2600: return;
2601:
2602: case MEM:
2603: if (GET_CODE (XEXP (x, 0)) == REG)
2604: mark_reg_pointer (XEXP (x, 0));
2605: restore_reg_data_1 (XEXP (x, 0));
2606: return;
2607: }
2608:
2609: /* Now scan the subexpressions recursively. */
2610:
2611: format_ptr = GET_RTX_FORMAT (code);
2612:
2613: for (i = 0; i < GET_RTX_LENGTH (code); i++)
2614: {
2615: switch (*format_ptr++)
2616: {
2617: case 'e':
2618: restore_reg_data_1 (XEXP (x, i));
2619: break;
2620:
2621: case 'E':
2622: if (XVEC (x, i) != NULL)
2623: {
2624: register int j;
2625:
2626: for (j = 0; j < XVECLEN (x, i); j++)
2627: restore_reg_data_1 (XVECEXP (x, i, j));
2628: }
2629: break;
2630: }
2631: }
2632: }
2633:
2634: /* Initialize data structures and variables in this file
2635: before generating rtl for each function. */
2636:
2637: void
2638: init_emit ()
2639: {
2640: int i;
2641:
2642: first_insn = NULL;
2643: last_insn = NULL;
2644: cur_insn_uid = 1;
2645: reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
2646: last_linenum = 0;
2647: last_filename = 0;
2648: first_label_num = label_num;
2649: last_label_num = 0;
2650:
2651: /* Clear the start_sequence/gen_sequence cache. */
2652: sequence_element_free_list = 0;
2653: for (i = 0; i < SEQUENCE_RESULT_SIZE; i++)
2654: sequence_result[i] = 0;
2655:
2656: /* Init the tables that describe all the pseudo regs. */
2657:
2658: regno_pointer_flag_length = LAST_VIRTUAL_REGISTER + 101;
2659:
2660: regno_pointer_flag
2661: = (char *) oballoc (regno_pointer_flag_length);
2662: bzero (regno_pointer_flag, regno_pointer_flag_length);
2663:
2664: regno_reg_rtx
2665: = (rtx *) oballoc (regno_pointer_flag_length * sizeof (rtx));
2666: bzero (regno_reg_rtx, regno_pointer_flag_length * sizeof (rtx));
2667:
2668: /* Put copies of all the virtual register rtx into regno_reg_rtx. */
2669: regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
2670: regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
2671: regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
2672: regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
2673: }
2674:
2675: /* Create some permanent unique rtl objects shared between all functions.
2676: LINE_NUMBERS is nonzero if line numbers are to be generated. */
2677:
2678: void
2679: init_emit_once (line_numbers)
2680: int line_numbers;
2681: {
2682: int i;
2683: enum machine_mode mode;
2684:
2685: no_line_numbers = ! line_numbers;
2686:
2687: sequence_stack = NULL;
2688:
2689: /* Create the unique rtx's for certain rtx codes and operand values. */
2690:
2691: pc_rtx = gen_rtx (PC, VOIDmode);
2692: cc0_rtx = gen_rtx (CC0, VOIDmode);
2693:
2694: /* Don't use gen_rtx here since gen_rtx in this case
2695: tries to use these variables. */
2696: for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
2697: {
2698: const_int_rtx[i + MAX_SAVED_CONST_INT] = rtx_alloc (CONST_INT);
2699: PUT_MODE (const_int_rtx[i + MAX_SAVED_CONST_INT], VOIDmode);
2700: INTVAL (const_int_rtx[i + MAX_SAVED_CONST_INT]) = i;
2701: }
2702:
2703: /* These four calls obtain some of the rtx expressions made above. */
2704: const0_rtx = gen_rtx (CONST_INT, VOIDmode, 0);
2705: const1_rtx = gen_rtx (CONST_INT, VOIDmode, 1);
2706: const2_rtx = gen_rtx (CONST_INT, VOIDmode, 2);
2707: constm1_rtx = gen_rtx (CONST_INT, VOIDmode, -1);
2708:
2709: /* This will usually be one of the above constants, but may be a new rtx. */
2710: const_true_rtx = gen_rtx (CONST_INT, VOIDmode, STORE_FLAG_VALUE);
2711:
2712: dconst0 = REAL_VALUE_ATOF ("0");
2713: dconst1 = REAL_VALUE_ATOF ("1");
2714: dconst2 = REAL_VALUE_ATOF ("2");
2715: dconstm1 = REAL_VALUE_ATOF ("-1");
2716:
2717: for (i = 0; i <= 2; i++)
2718: {
2719: for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
2720: mode = GET_MODE_WIDER_MODE (mode))
2721: {
2722: rtx tem = rtx_alloc (CONST_DOUBLE);
2723: union real_extract u;
2724:
2725: bzero (&u, sizeof u); /* Zero any holes in a structure. */
2726: u.d = i == 0 ? dconst0 : i == 1 ? dconst1 : dconst2;
2727:
2728: bcopy (&u, &CONST_DOUBLE_LOW (tem), sizeof u);
2729: CONST_DOUBLE_MEM (tem) = cc0_rtx;
2730: PUT_MODE (tem, mode);
2731:
2732: const_tiny_rtx[i][(int) mode] = tem;
2733: }
2734:
1.1.1.2 root 2735: const_tiny_rtx[i][(int) VOIDmode] = gen_rtx (CONST_INT, VOIDmode, i);
1.1 root 2736:
2737: for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
2738: mode = GET_MODE_WIDER_MODE (mode))
2739: const_tiny_rtx[i][(int) mode] = gen_rtx (CONST_INT, VOIDmode, i);
2740: }
2741:
2742: stack_pointer_rtx = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);
2743: frame_pointer_rtx = gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM);
2744:
2745: if (FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM)
2746: arg_pointer_rtx = frame_pointer_rtx;
2747: else if (STACK_POINTER_REGNUM == ARG_POINTER_REGNUM)
2748: arg_pointer_rtx = stack_pointer_rtx;
2749: else
2750: arg_pointer_rtx = gen_rtx (REG, Pmode, ARG_POINTER_REGNUM);
2751:
2752: /* Create the virtual registers. Do so here since the following objects
2753: might reference them. */
2754:
2755: virtual_incoming_args_rtx = gen_rtx (REG, Pmode,
2756: VIRTUAL_INCOMING_ARGS_REGNUM);
2757: virtual_stack_vars_rtx = gen_rtx (REG, Pmode,
2758: VIRTUAL_STACK_VARS_REGNUM);
2759: virtual_stack_dynamic_rtx = gen_rtx (REG, Pmode,
2760: VIRTUAL_STACK_DYNAMIC_REGNUM);
2761: virtual_outgoing_args_rtx = gen_rtx (REG, Pmode,
2762: VIRTUAL_OUTGOING_ARGS_REGNUM);
2763:
2764: #ifdef STRUCT_VALUE
2765: struct_value_rtx = STRUCT_VALUE;
2766: #else
2767: struct_value_rtx = gen_rtx (REG, Pmode, STRUCT_VALUE_REGNUM);
2768: #endif
2769:
2770: #ifdef STRUCT_VALUE_INCOMING
2771: struct_value_incoming_rtx = STRUCT_VALUE_INCOMING;
2772: #else
2773: #ifdef STRUCT_VALUE_INCOMING_REGNUM
2774: struct_value_incoming_rtx
2775: = gen_rtx (REG, Pmode, STRUCT_VALUE_INCOMING_REGNUM);
2776: #else
2777: struct_value_incoming_rtx = struct_value_rtx;
2778: #endif
2779: #endif
2780:
2781: #ifdef STATIC_CHAIN_REGNUM
2782: static_chain_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
2783:
2784: #ifdef STATIC_CHAIN_INCOMING_REGNUM
2785: if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)
2786: static_chain_incoming_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_INCOMING_REGNUM);
2787: else
2788: #endif
2789: static_chain_incoming_rtx = static_chain_rtx;
2790: #endif
2791:
2792: #ifdef STATIC_CHAIN
2793: static_chain_rtx = STATIC_CHAIN;
2794:
2795: #ifdef STATIC_CHAIN_INCOMING
2796: static_chain_incoming_rtx = STATIC_CHAIN_INCOMING;
2797: #else
2798: static_chain_incoming_rtx = static_chain_rtx;
2799: #endif
2800: #endif
2801:
2802: #ifdef PIC_OFFSET_TABLE_REGNUM
2803: pic_offset_table_rtx = gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM);
2804: #endif
2805: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.