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