xref: /dragonfly/contrib/gcc-4.7/gcc/emit-rtl.c (revision 5ce9237c)
1e4b17023SJohn Marino /* Emit RTL for the GCC expander.
2e4b17023SJohn Marino    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3e4b17023SJohn Marino    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4e4b17023SJohn Marino    2010, 2011
5e4b17023SJohn Marino    Free Software Foundation, Inc.
6e4b17023SJohn Marino 
7e4b17023SJohn Marino This file is part of GCC.
8e4b17023SJohn Marino 
9e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
10e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
11e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
12e4b17023SJohn Marino version.
13e4b17023SJohn Marino 
14e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
16e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17e4b17023SJohn Marino for more details.
18e4b17023SJohn Marino 
19e4b17023SJohn Marino You should have received a copy of the GNU General Public License
20e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
21e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
22e4b17023SJohn Marino 
23e4b17023SJohn Marino 
24e4b17023SJohn Marino /* Middle-to-low level generation of rtx code and insns.
25e4b17023SJohn Marino 
26e4b17023SJohn Marino    This file contains support functions for creating rtl expressions
27e4b17023SJohn Marino    and manipulating them in the doubly-linked chain of insns.
28e4b17023SJohn Marino 
29e4b17023SJohn Marino    The patterns of the insns are created by machine-dependent
30e4b17023SJohn Marino    routines in insn-emit.c, which is generated automatically from
31e4b17023SJohn Marino    the machine description.  These routines make the individual rtx's
32e4b17023SJohn Marino    of the pattern with `gen_rtx_fmt_ee' and others in genrtl.[ch],
33e4b17023SJohn Marino    which are automatically generated from rtl.def; what is machine
34e4b17023SJohn Marino    dependent is the kind of rtx's they make and what arguments they
35e4b17023SJohn Marino    use.  */
36e4b17023SJohn Marino 
37e4b17023SJohn Marino #include "config.h"
38e4b17023SJohn Marino #include "system.h"
39e4b17023SJohn Marino #include "coretypes.h"
40e4b17023SJohn Marino #include "tm.h"
41e4b17023SJohn Marino #include "diagnostic-core.h"
42e4b17023SJohn Marino #include "rtl.h"
43e4b17023SJohn Marino #include "tree.h"
44e4b17023SJohn Marino #include "tm_p.h"
45e4b17023SJohn Marino #include "flags.h"
46e4b17023SJohn Marino #include "function.h"
47e4b17023SJohn Marino #include "expr.h"
48e4b17023SJohn Marino #include "regs.h"
49e4b17023SJohn Marino #include "hard-reg-set.h"
50e4b17023SJohn Marino #include "hashtab.h"
51e4b17023SJohn Marino #include "insn-config.h"
52e4b17023SJohn Marino #include "recog.h"
53e4b17023SJohn Marino #include "bitmap.h"
54e4b17023SJohn Marino #include "basic-block.h"
55e4b17023SJohn Marino #include "ggc.h"
56e4b17023SJohn Marino #include "debug.h"
57e4b17023SJohn Marino #include "langhooks.h"
58e4b17023SJohn Marino #include "tree-pass.h"
59e4b17023SJohn Marino #include "df.h"
60e4b17023SJohn Marino #include "params.h"
61e4b17023SJohn Marino #include "target.h"
62e4b17023SJohn Marino #include "tree-flow.h"
63e4b17023SJohn Marino 
64e4b17023SJohn Marino struct target_rtl default_target_rtl;
65e4b17023SJohn Marino #if SWITCHABLE_TARGET
66e4b17023SJohn Marino struct target_rtl *this_target_rtl = &default_target_rtl;
67e4b17023SJohn Marino #endif
68e4b17023SJohn Marino 
69e4b17023SJohn Marino #define initial_regno_reg_rtx (this_target_rtl->x_initial_regno_reg_rtx)
70e4b17023SJohn Marino 
71e4b17023SJohn Marino /* Commonly used modes.  */
72e4b17023SJohn Marino 
73e4b17023SJohn Marino enum machine_mode byte_mode;	/* Mode whose width is BITS_PER_UNIT.  */
74e4b17023SJohn Marino enum machine_mode word_mode;	/* Mode whose width is BITS_PER_WORD.  */
75e4b17023SJohn Marino enum machine_mode double_mode;	/* Mode whose width is DOUBLE_TYPE_SIZE.  */
76e4b17023SJohn Marino enum machine_mode ptr_mode;	/* Mode whose width is POINTER_SIZE.  */
77e4b17023SJohn Marino 
78e4b17023SJohn Marino /* Datastructures maintained for currently processed function in RTL form.  */
79e4b17023SJohn Marino 
80e4b17023SJohn Marino struct rtl_data x_rtl;
81e4b17023SJohn Marino 
82e4b17023SJohn Marino /* Indexed by pseudo register number, gives the rtx for that pseudo.
83e4b17023SJohn Marino    Allocated in parallel with regno_pointer_align.
84e4b17023SJohn Marino    FIXME: We could put it into emit_status struct, but gengtype is not able to deal
85e4b17023SJohn Marino    with length attribute nested in top level structures.  */
86e4b17023SJohn Marino 
87e4b17023SJohn Marino rtx * regno_reg_rtx;
88e4b17023SJohn Marino 
89e4b17023SJohn Marino /* This is *not* reset after each function.  It gives each CODE_LABEL
90e4b17023SJohn Marino    in the entire compilation a unique label number.  */
91e4b17023SJohn Marino 
92e4b17023SJohn Marino static GTY(()) int label_num = 1;
93e4b17023SJohn Marino 
94e4b17023SJohn Marino /* We record floating-point CONST_DOUBLEs in each floating-point mode for
95e4b17023SJohn Marino    the values of 0, 1, and 2.  For the integer entries and VOIDmode, we
96e4b17023SJohn Marino    record a copy of const[012]_rtx and constm1_rtx.  CONSTM1_RTX
97e4b17023SJohn Marino    is set only for MODE_INT and MODE_VECTOR_INT modes.  */
98e4b17023SJohn Marino 
99e4b17023SJohn Marino rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];
100e4b17023SJohn Marino 
101e4b17023SJohn Marino rtx const_true_rtx;
102e4b17023SJohn Marino 
103e4b17023SJohn Marino REAL_VALUE_TYPE dconst0;
104e4b17023SJohn Marino REAL_VALUE_TYPE dconst1;
105e4b17023SJohn Marino REAL_VALUE_TYPE dconst2;
106e4b17023SJohn Marino REAL_VALUE_TYPE dconstm1;
107e4b17023SJohn Marino REAL_VALUE_TYPE dconsthalf;
108e4b17023SJohn Marino 
109e4b17023SJohn Marino /* Record fixed-point constant 0 and 1.  */
110e4b17023SJohn Marino FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
111e4b17023SJohn Marino FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
112e4b17023SJohn Marino 
113e4b17023SJohn Marino /* We make one copy of (const_int C) where C is in
114e4b17023SJohn Marino    [- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT]
115e4b17023SJohn Marino    to save space during the compilation and simplify comparisons of
116e4b17023SJohn Marino    integers.  */
117e4b17023SJohn Marino 
118e4b17023SJohn Marino rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
119e4b17023SJohn Marino 
120e4b17023SJohn Marino /* A hash table storing CONST_INTs whose absolute value is greater
121e4b17023SJohn Marino    than MAX_SAVED_CONST_INT.  */
122e4b17023SJohn Marino 
123e4b17023SJohn Marino static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
124e4b17023SJohn Marino      htab_t const_int_htab;
125e4b17023SJohn Marino 
126e4b17023SJohn Marino /* A hash table storing memory attribute structures.  */
127e4b17023SJohn Marino static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
128e4b17023SJohn Marino      htab_t mem_attrs_htab;
129e4b17023SJohn Marino 
130e4b17023SJohn Marino /* A hash table storing register attribute structures.  */
131e4b17023SJohn Marino static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs)))
132e4b17023SJohn Marino      htab_t reg_attrs_htab;
133e4b17023SJohn Marino 
134e4b17023SJohn Marino /* A hash table storing all CONST_DOUBLEs.  */
135e4b17023SJohn Marino static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
136e4b17023SJohn Marino      htab_t const_double_htab;
137e4b17023SJohn Marino 
138e4b17023SJohn Marino /* A hash table storing all CONST_FIXEDs.  */
139e4b17023SJohn Marino static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
140e4b17023SJohn Marino      htab_t const_fixed_htab;
141e4b17023SJohn Marino 
142e4b17023SJohn Marino #define cur_insn_uid (crtl->emit.x_cur_insn_uid)
143e4b17023SJohn Marino #define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid)
144e4b17023SJohn Marino #define last_location (crtl->emit.x_last_location)
145e4b17023SJohn Marino #define first_label_num (crtl->emit.x_first_label_num)
146e4b17023SJohn Marino 
147e4b17023SJohn Marino static rtx make_call_insn_raw (rtx);
148e4b17023SJohn Marino static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
149e4b17023SJohn Marino static void set_used_decls (tree);
150e4b17023SJohn Marino static void mark_label_nuses (rtx);
151e4b17023SJohn Marino static hashval_t const_int_htab_hash (const void *);
152e4b17023SJohn Marino static int const_int_htab_eq (const void *, const void *);
153e4b17023SJohn Marino static hashval_t const_double_htab_hash (const void *);
154e4b17023SJohn Marino static int const_double_htab_eq (const void *, const void *);
155e4b17023SJohn Marino static rtx lookup_const_double (rtx);
156e4b17023SJohn Marino static hashval_t const_fixed_htab_hash (const void *);
157e4b17023SJohn Marino static int const_fixed_htab_eq (const void *, const void *);
158e4b17023SJohn Marino static rtx lookup_const_fixed (rtx);
159e4b17023SJohn Marino static hashval_t mem_attrs_htab_hash (const void *);
160e4b17023SJohn Marino static int mem_attrs_htab_eq (const void *, const void *);
161e4b17023SJohn Marino static hashval_t reg_attrs_htab_hash (const void *);
162e4b17023SJohn Marino static int reg_attrs_htab_eq (const void *, const void *);
163e4b17023SJohn Marino static reg_attrs *get_reg_attrs (tree, int);
164e4b17023SJohn Marino static rtx gen_const_vector (enum machine_mode, int);
165e4b17023SJohn Marino static void copy_rtx_if_shared_1 (rtx *orig);
166e4b17023SJohn Marino 
167e4b17023SJohn Marino /* Probability of the conditional branch currently proceeded by try_split.
168e4b17023SJohn Marino    Set to -1 otherwise.  */
169e4b17023SJohn Marino int split_branch_probability = -1;
170e4b17023SJohn Marino 
171e4b17023SJohn Marino /* Returns a hash code for X (which is a really a CONST_INT).  */
172e4b17023SJohn Marino 
173e4b17023SJohn Marino static hashval_t
const_int_htab_hash(const void * x)174e4b17023SJohn Marino const_int_htab_hash (const void *x)
175e4b17023SJohn Marino {
176e4b17023SJohn Marino   return (hashval_t) INTVAL ((const_rtx) x);
177e4b17023SJohn Marino }
178e4b17023SJohn Marino 
179e4b17023SJohn Marino /* Returns nonzero if the value represented by X (which is really a
180e4b17023SJohn Marino    CONST_INT) is the same as that given by Y (which is really a
181e4b17023SJohn Marino    HOST_WIDE_INT *).  */
182e4b17023SJohn Marino 
183e4b17023SJohn Marino static int
const_int_htab_eq(const void * x,const void * y)184e4b17023SJohn Marino const_int_htab_eq (const void *x, const void *y)
185e4b17023SJohn Marino {
186e4b17023SJohn Marino   return (INTVAL ((const_rtx) x) == *((const HOST_WIDE_INT *) y));
187e4b17023SJohn Marino }
188e4b17023SJohn Marino 
189e4b17023SJohn Marino /* Returns a hash code for X (which is really a CONST_DOUBLE).  */
190e4b17023SJohn Marino static hashval_t
const_double_htab_hash(const void * x)191e4b17023SJohn Marino const_double_htab_hash (const void *x)
192e4b17023SJohn Marino {
193e4b17023SJohn Marino   const_rtx const value = (const_rtx) x;
194e4b17023SJohn Marino   hashval_t h;
195e4b17023SJohn Marino 
196e4b17023SJohn Marino   if (GET_MODE (value) == VOIDmode)
197e4b17023SJohn Marino     h = CONST_DOUBLE_LOW (value) ^ CONST_DOUBLE_HIGH (value);
198e4b17023SJohn Marino   else
199e4b17023SJohn Marino     {
200e4b17023SJohn Marino       h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
201e4b17023SJohn Marino       /* MODE is used in the comparison, so it should be in the hash.  */
202e4b17023SJohn Marino       h ^= GET_MODE (value);
203e4b17023SJohn Marino     }
204e4b17023SJohn Marino   return h;
205e4b17023SJohn Marino }
206e4b17023SJohn Marino 
207e4b17023SJohn Marino /* Returns nonzero if the value represented by X (really a ...)
208e4b17023SJohn Marino    is the same as that represented by Y (really a ...) */
209e4b17023SJohn Marino static int
const_double_htab_eq(const void * x,const void * y)210e4b17023SJohn Marino const_double_htab_eq (const void *x, const void *y)
211e4b17023SJohn Marino {
212e4b17023SJohn Marino   const_rtx const a = (const_rtx)x, b = (const_rtx)y;
213e4b17023SJohn Marino 
214e4b17023SJohn Marino   if (GET_MODE (a) != GET_MODE (b))
215e4b17023SJohn Marino     return 0;
216e4b17023SJohn Marino   if (GET_MODE (a) == VOIDmode)
217e4b17023SJohn Marino     return (CONST_DOUBLE_LOW (a) == CONST_DOUBLE_LOW (b)
218e4b17023SJohn Marino 	    && CONST_DOUBLE_HIGH (a) == CONST_DOUBLE_HIGH (b));
219e4b17023SJohn Marino   else
220e4b17023SJohn Marino     return real_identical (CONST_DOUBLE_REAL_VALUE (a),
221e4b17023SJohn Marino 			   CONST_DOUBLE_REAL_VALUE (b));
222e4b17023SJohn Marino }
223e4b17023SJohn Marino 
224e4b17023SJohn Marino /* Returns a hash code for X (which is really a CONST_FIXED).  */
225e4b17023SJohn Marino 
226e4b17023SJohn Marino static hashval_t
const_fixed_htab_hash(const void * x)227e4b17023SJohn Marino const_fixed_htab_hash (const void *x)
228e4b17023SJohn Marino {
229e4b17023SJohn Marino   const_rtx const value = (const_rtx) x;
230e4b17023SJohn Marino   hashval_t h;
231e4b17023SJohn Marino 
232e4b17023SJohn Marino   h = fixed_hash (CONST_FIXED_VALUE (value));
233e4b17023SJohn Marino   /* MODE is used in the comparison, so it should be in the hash.  */
234e4b17023SJohn Marino   h ^= GET_MODE (value);
235e4b17023SJohn Marino   return h;
236e4b17023SJohn Marino }
237e4b17023SJohn Marino 
238e4b17023SJohn Marino /* Returns nonzero if the value represented by X (really a ...)
239e4b17023SJohn Marino    is the same as that represented by Y (really a ...).  */
240e4b17023SJohn Marino 
241e4b17023SJohn Marino static int
const_fixed_htab_eq(const void * x,const void * y)242e4b17023SJohn Marino const_fixed_htab_eq (const void *x, const void *y)
243e4b17023SJohn Marino {
244e4b17023SJohn Marino   const_rtx const a = (const_rtx) x, b = (const_rtx) y;
245e4b17023SJohn Marino 
246e4b17023SJohn Marino   if (GET_MODE (a) != GET_MODE (b))
247e4b17023SJohn Marino     return 0;
248e4b17023SJohn Marino   return fixed_identical (CONST_FIXED_VALUE (a), CONST_FIXED_VALUE (b));
249e4b17023SJohn Marino }
250e4b17023SJohn Marino 
251e4b17023SJohn Marino /* Returns a hash code for X (which is a really a mem_attrs *).  */
252e4b17023SJohn Marino 
253e4b17023SJohn Marino static hashval_t
mem_attrs_htab_hash(const void * x)254e4b17023SJohn Marino mem_attrs_htab_hash (const void *x)
255e4b17023SJohn Marino {
256e4b17023SJohn Marino   const mem_attrs *const p = (const mem_attrs *) x;
257e4b17023SJohn Marino 
258e4b17023SJohn Marino   return (p->alias ^ (p->align * 1000)
259e4b17023SJohn Marino 	  ^ (p->addrspace * 4000)
260e4b17023SJohn Marino 	  ^ ((p->offset_known_p ? p->offset : 0) * 50000)
261e4b17023SJohn Marino 	  ^ ((p->size_known_p ? p->size : 0) * 2500000)
262e4b17023SJohn Marino 	  ^ (size_t) iterative_hash_expr (p->expr, 0));
263e4b17023SJohn Marino }
264e4b17023SJohn Marino 
265e4b17023SJohn Marino /* Return true if the given memory attributes are equal.  */
266e4b17023SJohn Marino 
267e4b17023SJohn Marino static bool
mem_attrs_eq_p(const struct mem_attrs * p,const struct mem_attrs * q)268e4b17023SJohn Marino mem_attrs_eq_p (const struct mem_attrs *p, const struct mem_attrs *q)
269e4b17023SJohn Marino {
270e4b17023SJohn Marino   return (p->alias == q->alias
271e4b17023SJohn Marino 	  && p->offset_known_p == q->offset_known_p
272e4b17023SJohn Marino 	  && (!p->offset_known_p || p->offset == q->offset)
273e4b17023SJohn Marino 	  && p->size_known_p == q->size_known_p
274e4b17023SJohn Marino 	  && (!p->size_known_p || p->size == q->size)
275e4b17023SJohn Marino 	  && p->align == q->align
276e4b17023SJohn Marino 	  && p->addrspace == q->addrspace
277e4b17023SJohn Marino 	  && (p->expr == q->expr
278e4b17023SJohn Marino 	      || (p->expr != NULL_TREE && q->expr != NULL_TREE
279e4b17023SJohn Marino 		  && operand_equal_p (p->expr, q->expr, 0))));
280e4b17023SJohn Marino }
281e4b17023SJohn Marino 
282e4b17023SJohn Marino /* Returns nonzero if the value represented by X (which is really a
283e4b17023SJohn Marino    mem_attrs *) is the same as that given by Y (which is also really a
284e4b17023SJohn Marino    mem_attrs *).  */
285e4b17023SJohn Marino 
286e4b17023SJohn Marino static int
mem_attrs_htab_eq(const void * x,const void * y)287e4b17023SJohn Marino mem_attrs_htab_eq (const void *x, const void *y)
288e4b17023SJohn Marino {
289e4b17023SJohn Marino   return mem_attrs_eq_p ((const mem_attrs *) x, (const mem_attrs *) y);
290e4b17023SJohn Marino }
291e4b17023SJohn Marino 
292e4b17023SJohn Marino /* Set MEM's memory attributes so that they are the same as ATTRS.  */
293e4b17023SJohn Marino 
294e4b17023SJohn Marino static void
set_mem_attrs(rtx mem,mem_attrs * attrs)295e4b17023SJohn Marino set_mem_attrs (rtx mem, mem_attrs *attrs)
296e4b17023SJohn Marino {
297e4b17023SJohn Marino   void **slot;
298e4b17023SJohn Marino 
299e4b17023SJohn Marino   /* If everything is the default, we can just clear the attributes.  */
300e4b17023SJohn Marino   if (mem_attrs_eq_p (attrs, mode_mem_attrs[(int) GET_MODE (mem)]))
301e4b17023SJohn Marino     {
302e4b17023SJohn Marino       MEM_ATTRS (mem) = 0;
303e4b17023SJohn Marino       return;
304e4b17023SJohn Marino     }
305e4b17023SJohn Marino 
306e4b17023SJohn Marino   slot = htab_find_slot (mem_attrs_htab, attrs, INSERT);
307e4b17023SJohn Marino   if (*slot == 0)
308e4b17023SJohn Marino     {
309e4b17023SJohn Marino       *slot = ggc_alloc_mem_attrs ();
310e4b17023SJohn Marino       memcpy (*slot, attrs, sizeof (mem_attrs));
311e4b17023SJohn Marino     }
312e4b17023SJohn Marino 
313e4b17023SJohn Marino   MEM_ATTRS (mem) = (mem_attrs *) *slot;
314e4b17023SJohn Marino }
315e4b17023SJohn Marino 
316e4b17023SJohn Marino /* Returns a hash code for X (which is a really a reg_attrs *).  */
317e4b17023SJohn Marino 
318e4b17023SJohn Marino static hashval_t
reg_attrs_htab_hash(const void * x)319e4b17023SJohn Marino reg_attrs_htab_hash (const void *x)
320e4b17023SJohn Marino {
321e4b17023SJohn Marino   const reg_attrs *const p = (const reg_attrs *) x;
322e4b17023SJohn Marino 
323e4b17023SJohn Marino   return ((p->offset * 1000) ^ (intptr_t) p->decl);
324e4b17023SJohn Marino }
325e4b17023SJohn Marino 
326e4b17023SJohn Marino /* Returns nonzero if the value represented by X (which is really a
327e4b17023SJohn Marino    reg_attrs *) is the same as that given by Y (which is also really a
328e4b17023SJohn Marino    reg_attrs *).  */
329e4b17023SJohn Marino 
330e4b17023SJohn Marino static int
reg_attrs_htab_eq(const void * x,const void * y)331e4b17023SJohn Marino reg_attrs_htab_eq (const void *x, const void *y)
332e4b17023SJohn Marino {
333e4b17023SJohn Marino   const reg_attrs *const p = (const reg_attrs *) x;
334e4b17023SJohn Marino   const reg_attrs *const q = (const reg_attrs *) y;
335e4b17023SJohn Marino 
336e4b17023SJohn Marino   return (p->decl == q->decl && p->offset == q->offset);
337e4b17023SJohn Marino }
338e4b17023SJohn Marino /* Allocate a new reg_attrs structure and insert it into the hash table if
339e4b17023SJohn Marino    one identical to it is not already in the table.  We are doing this for
340e4b17023SJohn Marino    MEM of mode MODE.  */
341e4b17023SJohn Marino 
342e4b17023SJohn Marino static reg_attrs *
get_reg_attrs(tree decl,int offset)343e4b17023SJohn Marino get_reg_attrs (tree decl, int offset)
344e4b17023SJohn Marino {
345e4b17023SJohn Marino   reg_attrs attrs;
346e4b17023SJohn Marino   void **slot;
347e4b17023SJohn Marino 
348e4b17023SJohn Marino   /* If everything is the default, we can just return zero.  */
349e4b17023SJohn Marino   if (decl == 0 && offset == 0)
350e4b17023SJohn Marino     return 0;
351e4b17023SJohn Marino 
352e4b17023SJohn Marino   attrs.decl = decl;
353e4b17023SJohn Marino   attrs.offset = offset;
354e4b17023SJohn Marino 
355e4b17023SJohn Marino   slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
356e4b17023SJohn Marino   if (*slot == 0)
357e4b17023SJohn Marino     {
358e4b17023SJohn Marino       *slot = ggc_alloc_reg_attrs ();
359e4b17023SJohn Marino       memcpy (*slot, &attrs, sizeof (reg_attrs));
360e4b17023SJohn Marino     }
361e4b17023SJohn Marino 
362e4b17023SJohn Marino   return (reg_attrs *) *slot;
363e4b17023SJohn Marino }
364e4b17023SJohn Marino 
365e4b17023SJohn Marino 
366e4b17023SJohn Marino #if !HAVE_blockage
367e4b17023SJohn Marino /* Generate an empty ASM_INPUT, which is used to block attempts to schedule
368e4b17023SJohn Marino    across this insn. */
369e4b17023SJohn Marino 
370e4b17023SJohn Marino rtx
gen_blockage(void)371e4b17023SJohn Marino gen_blockage (void)
372e4b17023SJohn Marino {
373e4b17023SJohn Marino   rtx x = gen_rtx_ASM_INPUT (VOIDmode, "");
374e4b17023SJohn Marino   MEM_VOLATILE_P (x) = true;
375e4b17023SJohn Marino   return x;
376e4b17023SJohn Marino }
377e4b17023SJohn Marino #endif
378e4b17023SJohn Marino 
379e4b17023SJohn Marino 
380e4b17023SJohn Marino /* Generate a new REG rtx.  Make sure ORIGINAL_REGNO is set properly, and
381e4b17023SJohn Marino    don't attempt to share with the various global pieces of rtl (such as
382e4b17023SJohn Marino    frame_pointer_rtx).  */
383e4b17023SJohn Marino 
384e4b17023SJohn Marino rtx
gen_raw_REG(enum machine_mode mode,int regno)385e4b17023SJohn Marino gen_raw_REG (enum machine_mode mode, int regno)
386e4b17023SJohn Marino {
387e4b17023SJohn Marino   rtx x = gen_rtx_raw_REG (mode, regno);
388e4b17023SJohn Marino   ORIGINAL_REGNO (x) = regno;
389e4b17023SJohn Marino   return x;
390e4b17023SJohn Marino }
391e4b17023SJohn Marino 
392e4b17023SJohn Marino /* There are some RTL codes that require special attention; the generation
393e4b17023SJohn Marino    functions do the raw handling.  If you add to this list, modify
394e4b17023SJohn Marino    special_rtx in gengenrtl.c as well.  */
395e4b17023SJohn Marino 
396e4b17023SJohn Marino rtx
gen_rtx_CONST_INT(enum machine_mode mode ATTRIBUTE_UNUSED,HOST_WIDE_INT arg)397e4b17023SJohn Marino gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
398e4b17023SJohn Marino {
399e4b17023SJohn Marino   void **slot;
400e4b17023SJohn Marino 
401e4b17023SJohn Marino   if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
402e4b17023SJohn Marino     return const_int_rtx[arg + MAX_SAVED_CONST_INT];
403e4b17023SJohn Marino 
404e4b17023SJohn Marino #if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1
405e4b17023SJohn Marino   if (const_true_rtx && arg == STORE_FLAG_VALUE)
406e4b17023SJohn Marino     return const_true_rtx;
407e4b17023SJohn Marino #endif
408e4b17023SJohn Marino 
409e4b17023SJohn Marino   /* Look up the CONST_INT in the hash table.  */
410e4b17023SJohn Marino   slot = htab_find_slot_with_hash (const_int_htab, &arg,
411e4b17023SJohn Marino 				   (hashval_t) arg, INSERT);
412e4b17023SJohn Marino   if (*slot == 0)
413e4b17023SJohn Marino     *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);
414e4b17023SJohn Marino 
415e4b17023SJohn Marino   return (rtx) *slot;
416e4b17023SJohn Marino }
417e4b17023SJohn Marino 
418e4b17023SJohn Marino rtx
gen_int_mode(HOST_WIDE_INT c,enum machine_mode mode)419e4b17023SJohn Marino gen_int_mode (HOST_WIDE_INT c, enum machine_mode mode)
420e4b17023SJohn Marino {
421e4b17023SJohn Marino   return GEN_INT (trunc_int_for_mode (c, mode));
422e4b17023SJohn Marino }
423e4b17023SJohn Marino 
424e4b17023SJohn Marino /* CONST_DOUBLEs might be created from pairs of integers, or from
425e4b17023SJohn Marino    REAL_VALUE_TYPEs.  Also, their length is known only at run time,
426e4b17023SJohn Marino    so we cannot use gen_rtx_raw_CONST_DOUBLE.  */
427e4b17023SJohn Marino 
428e4b17023SJohn Marino /* Determine whether REAL, a CONST_DOUBLE, already exists in the
429e4b17023SJohn Marino    hash table.  If so, return its counterpart; otherwise add it
430e4b17023SJohn Marino    to the hash table and return it.  */
431e4b17023SJohn Marino static rtx
lookup_const_double(rtx real)432e4b17023SJohn Marino lookup_const_double (rtx real)
433e4b17023SJohn Marino {
434e4b17023SJohn Marino   void **slot = htab_find_slot (const_double_htab, real, INSERT);
435e4b17023SJohn Marino   if (*slot == 0)
436e4b17023SJohn Marino     *slot = real;
437e4b17023SJohn Marino 
438e4b17023SJohn Marino   return (rtx) *slot;
439e4b17023SJohn Marino }
440e4b17023SJohn Marino 
441e4b17023SJohn Marino /* Return a CONST_DOUBLE rtx for a floating-point value specified by
442e4b17023SJohn Marino    VALUE in mode MODE.  */
443e4b17023SJohn Marino rtx
const_double_from_real_value(REAL_VALUE_TYPE value,enum machine_mode mode)444e4b17023SJohn Marino const_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode)
445e4b17023SJohn Marino {
446e4b17023SJohn Marino   rtx real = rtx_alloc (CONST_DOUBLE);
447e4b17023SJohn Marino   PUT_MODE (real, mode);
448e4b17023SJohn Marino 
449e4b17023SJohn Marino   real->u.rv = value;
450e4b17023SJohn Marino 
451e4b17023SJohn Marino   return lookup_const_double (real);
452e4b17023SJohn Marino }
453e4b17023SJohn Marino 
454e4b17023SJohn Marino /* Determine whether FIXED, a CONST_FIXED, already exists in the
455e4b17023SJohn Marino    hash table.  If so, return its counterpart; otherwise add it
456e4b17023SJohn Marino    to the hash table and return it.  */
457e4b17023SJohn Marino 
458e4b17023SJohn Marino static rtx
lookup_const_fixed(rtx fixed)459e4b17023SJohn Marino lookup_const_fixed (rtx fixed)
460e4b17023SJohn Marino {
461e4b17023SJohn Marino   void **slot = htab_find_slot (const_fixed_htab, fixed, INSERT);
462e4b17023SJohn Marino   if (*slot == 0)
463e4b17023SJohn Marino     *slot = fixed;
464e4b17023SJohn Marino 
465e4b17023SJohn Marino   return (rtx) *slot;
466e4b17023SJohn Marino }
467e4b17023SJohn Marino 
468e4b17023SJohn Marino /* Return a CONST_FIXED rtx for a fixed-point value specified by
469e4b17023SJohn Marino    VALUE in mode MODE.  */
470e4b17023SJohn Marino 
471e4b17023SJohn Marino rtx
const_fixed_from_fixed_value(FIXED_VALUE_TYPE value,enum machine_mode mode)472e4b17023SJohn Marino const_fixed_from_fixed_value (FIXED_VALUE_TYPE value, enum machine_mode mode)
473e4b17023SJohn Marino {
474e4b17023SJohn Marino   rtx fixed = rtx_alloc (CONST_FIXED);
475e4b17023SJohn Marino   PUT_MODE (fixed, mode);
476e4b17023SJohn Marino 
477e4b17023SJohn Marino   fixed->u.fv = value;
478e4b17023SJohn Marino 
479e4b17023SJohn Marino   return lookup_const_fixed (fixed);
480e4b17023SJohn Marino }
481e4b17023SJohn Marino 
482e4b17023SJohn Marino /* Constructs double_int from rtx CST.  */
483e4b17023SJohn Marino 
484e4b17023SJohn Marino double_int
rtx_to_double_int(const_rtx cst)485e4b17023SJohn Marino rtx_to_double_int (const_rtx cst)
486e4b17023SJohn Marino {
487e4b17023SJohn Marino   double_int r;
488e4b17023SJohn Marino 
489e4b17023SJohn Marino   if (CONST_INT_P (cst))
490e4b17023SJohn Marino       r = shwi_to_double_int (INTVAL (cst));
491e4b17023SJohn Marino   else if (CONST_DOUBLE_P (cst) && GET_MODE (cst) == VOIDmode)
492e4b17023SJohn Marino     {
493e4b17023SJohn Marino       r.low = CONST_DOUBLE_LOW (cst);
494e4b17023SJohn Marino       r.high = CONST_DOUBLE_HIGH (cst);
495e4b17023SJohn Marino     }
496e4b17023SJohn Marino   else
497e4b17023SJohn Marino     gcc_unreachable ();
498e4b17023SJohn Marino 
499e4b17023SJohn Marino   return r;
500e4b17023SJohn Marino }
501e4b17023SJohn Marino 
502e4b17023SJohn Marino 
503e4b17023SJohn Marino /* Return a CONST_DOUBLE or CONST_INT for a value specified as
504e4b17023SJohn Marino    a double_int.  */
505e4b17023SJohn Marino 
506e4b17023SJohn Marino rtx
immed_double_int_const(double_int i,enum machine_mode mode)507e4b17023SJohn Marino immed_double_int_const (double_int i, enum machine_mode mode)
508e4b17023SJohn Marino {
509e4b17023SJohn Marino   return immed_double_const (i.low, i.high, mode);
510e4b17023SJohn Marino }
511e4b17023SJohn Marino 
512e4b17023SJohn Marino /* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair
513e4b17023SJohn Marino    of ints: I0 is the low-order word and I1 is the high-order word.
514e4b17023SJohn Marino    Do not use this routine for non-integer modes; convert to
515e4b17023SJohn Marino    REAL_VALUE_TYPE and use CONST_DOUBLE_FROM_REAL_VALUE.  */
516e4b17023SJohn Marino 
517e4b17023SJohn Marino rtx
immed_double_const(HOST_WIDE_INT i0,HOST_WIDE_INT i1,enum machine_mode mode)518e4b17023SJohn Marino immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, enum machine_mode mode)
519e4b17023SJohn Marino {
520e4b17023SJohn Marino   rtx value;
521e4b17023SJohn Marino   unsigned int i;
522e4b17023SJohn Marino 
523e4b17023SJohn Marino   /* There are the following cases (note that there are no modes with
524e4b17023SJohn Marino      HOST_BITS_PER_WIDE_INT < GET_MODE_BITSIZE (mode) < 2 * HOST_BITS_PER_WIDE_INT):
525e4b17023SJohn Marino 
526e4b17023SJohn Marino      1) If GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT, then we use
527e4b17023SJohn Marino 	gen_int_mode.
528e4b17023SJohn Marino      2) GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT, but the value of
529e4b17023SJohn Marino 	the integer fits into HOST_WIDE_INT anyway (i.e., i1 consists only
530e4b17023SJohn Marino 	from copies of the sign bit, and sign of i0 and i1 are the same),  then
531e4b17023SJohn Marino 	we return a CONST_INT for i0.
532e4b17023SJohn Marino      3) Otherwise, we create a CONST_DOUBLE for i0 and i1.  */
533e4b17023SJohn Marino   if (mode != VOIDmode)
534e4b17023SJohn Marino     {
535e4b17023SJohn Marino       gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
536e4b17023SJohn Marino 		  || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
537e4b17023SJohn Marino 		  /* We can get a 0 for an error mark.  */
538e4b17023SJohn Marino 		  || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
539e4b17023SJohn Marino 		  || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT);
540e4b17023SJohn Marino 
541e4b17023SJohn Marino       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
542e4b17023SJohn Marino 	return gen_int_mode (i0, mode);
543e4b17023SJohn Marino 
544e4b17023SJohn Marino       gcc_assert (GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT);
545e4b17023SJohn Marino     }
546e4b17023SJohn Marino 
547e4b17023SJohn Marino   /* If this integer fits in one word, return a CONST_INT.  */
548e4b17023SJohn Marino   if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
549e4b17023SJohn Marino     return GEN_INT (i0);
550e4b17023SJohn Marino 
551e4b17023SJohn Marino   /* We use VOIDmode for integers.  */
552e4b17023SJohn Marino   value = rtx_alloc (CONST_DOUBLE);
553e4b17023SJohn Marino   PUT_MODE (value, VOIDmode);
554e4b17023SJohn Marino 
555e4b17023SJohn Marino   CONST_DOUBLE_LOW (value) = i0;
556e4b17023SJohn Marino   CONST_DOUBLE_HIGH (value) = i1;
557e4b17023SJohn Marino 
558e4b17023SJohn Marino   for (i = 2; i < (sizeof CONST_DOUBLE_FORMAT - 1); i++)
559e4b17023SJohn Marino     XWINT (value, i) = 0;
560e4b17023SJohn Marino 
561e4b17023SJohn Marino   return lookup_const_double (value);
562e4b17023SJohn Marino }
563e4b17023SJohn Marino 
564e4b17023SJohn Marino rtx
gen_rtx_REG(enum machine_mode mode,unsigned int regno)565e4b17023SJohn Marino gen_rtx_REG (enum machine_mode mode, unsigned int regno)
566e4b17023SJohn Marino {
567e4b17023SJohn Marino   /* In case the MD file explicitly references the frame pointer, have
568e4b17023SJohn Marino      all such references point to the same frame pointer.  This is
569e4b17023SJohn Marino      used during frame pointer elimination to distinguish the explicit
570e4b17023SJohn Marino      references to these registers from pseudos that happened to be
571e4b17023SJohn Marino      assigned to them.
572e4b17023SJohn Marino 
573e4b17023SJohn Marino      If we have eliminated the frame pointer or arg pointer, we will
574e4b17023SJohn Marino      be using it as a normal register, for example as a spill
575e4b17023SJohn Marino      register.  In such cases, we might be accessing it in a mode that
576e4b17023SJohn Marino      is not Pmode and therefore cannot use the pre-allocated rtx.
577e4b17023SJohn Marino 
578e4b17023SJohn Marino      Also don't do this when we are making new REGs in reload, since
579e4b17023SJohn Marino      we don't want to get confused with the real pointers.  */
580e4b17023SJohn Marino 
581e4b17023SJohn Marino   if (mode == Pmode && !reload_in_progress)
582e4b17023SJohn Marino     {
583e4b17023SJohn Marino       if (regno == FRAME_POINTER_REGNUM
584e4b17023SJohn Marino 	  && (!reload_completed || frame_pointer_needed))
585e4b17023SJohn Marino 	return frame_pointer_rtx;
586e4b17023SJohn Marino #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
587e4b17023SJohn Marino       if (regno == HARD_FRAME_POINTER_REGNUM
588e4b17023SJohn Marino 	  && (!reload_completed || frame_pointer_needed))
589e4b17023SJohn Marino 	return hard_frame_pointer_rtx;
590e4b17023SJohn Marino #endif
591e4b17023SJohn Marino #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && !HARD_FRAME_POINTER_IS_ARG_POINTER
592e4b17023SJohn Marino       if (regno == ARG_POINTER_REGNUM)
593e4b17023SJohn Marino 	return arg_pointer_rtx;
594e4b17023SJohn Marino #endif
595e4b17023SJohn Marino #ifdef RETURN_ADDRESS_POINTER_REGNUM
596e4b17023SJohn Marino       if (regno == RETURN_ADDRESS_POINTER_REGNUM)
597e4b17023SJohn Marino 	return return_address_pointer_rtx;
598e4b17023SJohn Marino #endif
599e4b17023SJohn Marino       if (regno == (unsigned) PIC_OFFSET_TABLE_REGNUM
600e4b17023SJohn Marino 	  && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
601e4b17023SJohn Marino 	  && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
602e4b17023SJohn Marino 	return pic_offset_table_rtx;
603e4b17023SJohn Marino       if (regno == STACK_POINTER_REGNUM)
604e4b17023SJohn Marino 	return stack_pointer_rtx;
605e4b17023SJohn Marino     }
606e4b17023SJohn Marino 
607e4b17023SJohn Marino #if 0
608e4b17023SJohn Marino   /* If the per-function register table has been set up, try to re-use
609e4b17023SJohn Marino      an existing entry in that table to avoid useless generation of RTL.
610e4b17023SJohn Marino 
611e4b17023SJohn Marino      This code is disabled for now until we can fix the various backends
612e4b17023SJohn Marino      which depend on having non-shared hard registers in some cases.   Long
613e4b17023SJohn Marino      term we want to re-enable this code as it can significantly cut down
614e4b17023SJohn Marino      on the amount of useless RTL that gets generated.
615e4b17023SJohn Marino 
616e4b17023SJohn Marino      We'll also need to fix some code that runs after reload that wants to
617e4b17023SJohn Marino      set ORIGINAL_REGNO.  */
618e4b17023SJohn Marino 
619e4b17023SJohn Marino   if (cfun
620e4b17023SJohn Marino       && cfun->emit
621e4b17023SJohn Marino       && regno_reg_rtx
622e4b17023SJohn Marino       && regno < FIRST_PSEUDO_REGISTER
623e4b17023SJohn Marino       && reg_raw_mode[regno] == mode)
624e4b17023SJohn Marino     return regno_reg_rtx[regno];
625e4b17023SJohn Marino #endif
626e4b17023SJohn Marino 
627e4b17023SJohn Marino   return gen_raw_REG (mode, regno);
628e4b17023SJohn Marino }
629e4b17023SJohn Marino 
630e4b17023SJohn Marino rtx
gen_rtx_MEM(enum machine_mode mode,rtx addr)631e4b17023SJohn Marino gen_rtx_MEM (enum machine_mode mode, rtx addr)
632e4b17023SJohn Marino {
633e4b17023SJohn Marino   rtx rt = gen_rtx_raw_MEM (mode, addr);
634e4b17023SJohn Marino 
635e4b17023SJohn Marino   /* This field is not cleared by the mere allocation of the rtx, so
636e4b17023SJohn Marino      we clear it here.  */
637e4b17023SJohn Marino   MEM_ATTRS (rt) = 0;
638e4b17023SJohn Marino 
639e4b17023SJohn Marino   return rt;
640e4b17023SJohn Marino }
641e4b17023SJohn Marino 
642e4b17023SJohn Marino /* Generate a memory referring to non-trapping constant memory.  */
643e4b17023SJohn Marino 
644e4b17023SJohn Marino rtx
gen_const_mem(enum machine_mode mode,rtx addr)645e4b17023SJohn Marino gen_const_mem (enum machine_mode mode, rtx addr)
646e4b17023SJohn Marino {
647e4b17023SJohn Marino   rtx mem = gen_rtx_MEM (mode, addr);
648e4b17023SJohn Marino   MEM_READONLY_P (mem) = 1;
649e4b17023SJohn Marino   MEM_NOTRAP_P (mem) = 1;
650e4b17023SJohn Marino   return mem;
651e4b17023SJohn Marino }
652e4b17023SJohn Marino 
653e4b17023SJohn Marino /* Generate a MEM referring to fixed portions of the frame, e.g., register
654e4b17023SJohn Marino    save areas.  */
655e4b17023SJohn Marino 
656e4b17023SJohn Marino rtx
gen_frame_mem(enum machine_mode mode,rtx addr)657e4b17023SJohn Marino gen_frame_mem (enum machine_mode mode, rtx addr)
658e4b17023SJohn Marino {
659e4b17023SJohn Marino   rtx mem = gen_rtx_MEM (mode, addr);
660e4b17023SJohn Marino   MEM_NOTRAP_P (mem) = 1;
661e4b17023SJohn Marino   set_mem_alias_set (mem, get_frame_alias_set ());
662e4b17023SJohn Marino   return mem;
663e4b17023SJohn Marino }
664e4b17023SJohn Marino 
665e4b17023SJohn Marino /* Generate a MEM referring to a temporary use of the stack, not part
666e4b17023SJohn Marino     of the fixed stack frame.  For example, something which is pushed
667e4b17023SJohn Marino     by a target splitter.  */
668e4b17023SJohn Marino rtx
gen_tmp_stack_mem(enum machine_mode mode,rtx addr)669e4b17023SJohn Marino gen_tmp_stack_mem (enum machine_mode mode, rtx addr)
670e4b17023SJohn Marino {
671e4b17023SJohn Marino   rtx mem = gen_rtx_MEM (mode, addr);
672e4b17023SJohn Marino   MEM_NOTRAP_P (mem) = 1;
673e4b17023SJohn Marino   if (!cfun->calls_alloca)
674e4b17023SJohn Marino     set_mem_alias_set (mem, get_frame_alias_set ());
675e4b17023SJohn Marino   return mem;
676e4b17023SJohn Marino }
677e4b17023SJohn Marino 
678e4b17023SJohn Marino /* We want to create (subreg:OMODE (obj:IMODE) OFFSET).  Return true if
679e4b17023SJohn Marino    this construct would be valid, and false otherwise.  */
680e4b17023SJohn Marino 
681e4b17023SJohn Marino bool
validate_subreg(enum machine_mode omode,enum machine_mode imode,const_rtx reg,unsigned int offset)682e4b17023SJohn Marino validate_subreg (enum machine_mode omode, enum machine_mode imode,
683e4b17023SJohn Marino 		 const_rtx reg, unsigned int offset)
684e4b17023SJohn Marino {
685e4b17023SJohn Marino   unsigned int isize = GET_MODE_SIZE (imode);
686e4b17023SJohn Marino   unsigned int osize = GET_MODE_SIZE (omode);
687e4b17023SJohn Marino 
688e4b17023SJohn Marino   /* All subregs must be aligned.  */
689e4b17023SJohn Marino   if (offset % osize != 0)
690e4b17023SJohn Marino     return false;
691e4b17023SJohn Marino 
692e4b17023SJohn Marino   /* The subreg offset cannot be outside the inner object.  */
693e4b17023SJohn Marino   if (offset >= isize)
694e4b17023SJohn Marino     return false;
695e4b17023SJohn Marino 
696e4b17023SJohn Marino   /* ??? This should not be here.  Temporarily continue to allow word_mode
697e4b17023SJohn Marino      subregs of anything.  The most common offender is (subreg:SI (reg:DF)).
698e4b17023SJohn Marino      Generally, backends are doing something sketchy but it'll take time to
699e4b17023SJohn Marino      fix them all.  */
700e4b17023SJohn Marino   if (omode == word_mode)
701e4b17023SJohn Marino     ;
702e4b17023SJohn Marino   /* ??? Similarly, e.g. with (subreg:DF (reg:TI)).  Though store_bit_field
703e4b17023SJohn Marino      is the culprit here, and not the backends.  */
704e4b17023SJohn Marino   else if (osize >= UNITS_PER_WORD && isize >= osize)
705e4b17023SJohn Marino     ;
706e4b17023SJohn Marino   /* Allow component subregs of complex and vector.  Though given the below
707e4b17023SJohn Marino      extraction rules, it's not always clear what that means.  */
708e4b17023SJohn Marino   else if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
709e4b17023SJohn Marino 	   && GET_MODE_INNER (imode) == omode)
710e4b17023SJohn Marino     ;
711e4b17023SJohn Marino   /* ??? x86 sse code makes heavy use of *paradoxical* vector subregs,
712e4b17023SJohn Marino      i.e. (subreg:V4SF (reg:SF) 0).  This surely isn't the cleanest way to
713e4b17023SJohn Marino      represent this.  It's questionable if this ought to be represented at
714e4b17023SJohn Marino      all -- why can't this all be hidden in post-reload splitters that make
715e4b17023SJohn Marino      arbitrarily mode changes to the registers themselves.  */
716e4b17023SJohn Marino   else if (VECTOR_MODE_P (omode) && GET_MODE_INNER (omode) == imode)
717e4b17023SJohn Marino     ;
718e4b17023SJohn Marino   /* Subregs involving floating point modes are not allowed to
719e4b17023SJohn Marino      change size.  Therefore (subreg:DI (reg:DF) 0) is fine, but
720e4b17023SJohn Marino      (subreg:SI (reg:DF) 0) isn't.  */
721e4b17023SJohn Marino   else if (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))
722e4b17023SJohn Marino     {
723e4b17023SJohn Marino       if (isize != osize)
724e4b17023SJohn Marino 	return false;
725e4b17023SJohn Marino     }
726e4b17023SJohn Marino 
727e4b17023SJohn Marino   /* Paradoxical subregs must have offset zero.  */
728e4b17023SJohn Marino   if (osize > isize)
729e4b17023SJohn Marino     return offset == 0;
730e4b17023SJohn Marino 
731e4b17023SJohn Marino   /* This is a normal subreg.  Verify that the offset is representable.  */
732e4b17023SJohn Marino 
733e4b17023SJohn Marino   /* For hard registers, we already have most of these rules collected in
734e4b17023SJohn Marino      subreg_offset_representable_p.  */
735e4b17023SJohn Marino   if (reg && REG_P (reg) && HARD_REGISTER_P (reg))
736e4b17023SJohn Marino     {
737e4b17023SJohn Marino       unsigned int regno = REGNO (reg);
738e4b17023SJohn Marino 
739e4b17023SJohn Marino #ifdef CANNOT_CHANGE_MODE_CLASS
740e4b17023SJohn Marino       if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
741e4b17023SJohn Marino 	  && GET_MODE_INNER (imode) == omode)
742e4b17023SJohn Marino 	;
743e4b17023SJohn Marino       else if (REG_CANNOT_CHANGE_MODE_P (regno, imode, omode))
744e4b17023SJohn Marino 	return false;
745e4b17023SJohn Marino #endif
746e4b17023SJohn Marino 
747e4b17023SJohn Marino       return subreg_offset_representable_p (regno, imode, offset, omode);
748e4b17023SJohn Marino     }
749e4b17023SJohn Marino 
750e4b17023SJohn Marino   /* For pseudo registers, we want most of the same checks.  Namely:
751e4b17023SJohn Marino      If the register no larger than a word, the subreg must be lowpart.
752e4b17023SJohn Marino      If the register is larger than a word, the subreg must be the lowpart
753e4b17023SJohn Marino      of a subword.  A subreg does *not* perform arbitrary bit extraction.
754e4b17023SJohn Marino      Given that we've already checked mode/offset alignment, we only have
755e4b17023SJohn Marino      to check subword subregs here.  */
756e4b17023SJohn Marino   if (osize < UNITS_PER_WORD)
757e4b17023SJohn Marino     {
758e4b17023SJohn Marino       enum machine_mode wmode = isize > UNITS_PER_WORD ? word_mode : imode;
759e4b17023SJohn Marino       unsigned int low_off = subreg_lowpart_offset (omode, wmode);
760e4b17023SJohn Marino       if (offset % UNITS_PER_WORD != low_off)
761e4b17023SJohn Marino 	return false;
762e4b17023SJohn Marino     }
763e4b17023SJohn Marino   return true;
764e4b17023SJohn Marino }
765e4b17023SJohn Marino 
766e4b17023SJohn Marino rtx
gen_rtx_SUBREG(enum machine_mode mode,rtx reg,int offset)767e4b17023SJohn Marino gen_rtx_SUBREG (enum machine_mode mode, rtx reg, int offset)
768e4b17023SJohn Marino {
769e4b17023SJohn Marino   gcc_assert (validate_subreg (mode, GET_MODE (reg), reg, offset));
770e4b17023SJohn Marino   return gen_rtx_raw_SUBREG (mode, reg, offset);
771e4b17023SJohn Marino }
772e4b17023SJohn Marino 
773e4b17023SJohn Marino /* Generate a SUBREG representing the least-significant part of REG if MODE
774e4b17023SJohn Marino    is smaller than mode of REG, otherwise paradoxical SUBREG.  */
775e4b17023SJohn Marino 
776e4b17023SJohn Marino rtx
gen_lowpart_SUBREG(enum machine_mode mode,rtx reg)777e4b17023SJohn Marino gen_lowpart_SUBREG (enum machine_mode mode, rtx reg)
778e4b17023SJohn Marino {
779e4b17023SJohn Marino   enum machine_mode inmode;
780e4b17023SJohn Marino 
781e4b17023SJohn Marino   inmode = GET_MODE (reg);
782e4b17023SJohn Marino   if (inmode == VOIDmode)
783e4b17023SJohn Marino     inmode = mode;
784e4b17023SJohn Marino   return gen_rtx_SUBREG (mode, reg,
785e4b17023SJohn Marino 			 subreg_lowpart_offset (mode, inmode));
786e4b17023SJohn Marino }
787e4b17023SJohn Marino 
788e4b17023SJohn Marino 
789e4b17023SJohn Marino /* Create an rtvec and stores within it the RTXen passed in the arguments.  */
790e4b17023SJohn Marino 
791e4b17023SJohn Marino rtvec
gen_rtvec(int n,...)792e4b17023SJohn Marino gen_rtvec (int n, ...)
793e4b17023SJohn Marino {
794e4b17023SJohn Marino   int i;
795e4b17023SJohn Marino   rtvec rt_val;
796e4b17023SJohn Marino   va_list p;
797e4b17023SJohn Marino 
798e4b17023SJohn Marino   va_start (p, n);
799e4b17023SJohn Marino 
800e4b17023SJohn Marino   /* Don't allocate an empty rtvec...  */
801e4b17023SJohn Marino   if (n == 0)
802e4b17023SJohn Marino     {
803e4b17023SJohn Marino       va_end (p);
804e4b17023SJohn Marino       return NULL_RTVEC;
805e4b17023SJohn Marino     }
806e4b17023SJohn Marino 
807e4b17023SJohn Marino   rt_val = rtvec_alloc (n);
808e4b17023SJohn Marino 
809e4b17023SJohn Marino   for (i = 0; i < n; i++)
810e4b17023SJohn Marino     rt_val->elem[i] = va_arg (p, rtx);
811e4b17023SJohn Marino 
812e4b17023SJohn Marino   va_end (p);
813e4b17023SJohn Marino   return rt_val;
814e4b17023SJohn Marino }
815e4b17023SJohn Marino 
816e4b17023SJohn Marino rtvec
gen_rtvec_v(int n,rtx * argp)817e4b17023SJohn Marino gen_rtvec_v (int n, rtx *argp)
818e4b17023SJohn Marino {
819e4b17023SJohn Marino   int i;
820e4b17023SJohn Marino   rtvec rt_val;
821e4b17023SJohn Marino 
822e4b17023SJohn Marino   /* Don't allocate an empty rtvec...  */
823e4b17023SJohn Marino   if (n == 0)
824e4b17023SJohn Marino     return NULL_RTVEC;
825e4b17023SJohn Marino 
826e4b17023SJohn Marino   rt_val = rtvec_alloc (n);
827e4b17023SJohn Marino 
828e4b17023SJohn Marino   for (i = 0; i < n; i++)
829e4b17023SJohn Marino     rt_val->elem[i] = *argp++;
830e4b17023SJohn Marino 
831e4b17023SJohn Marino   return rt_val;
832e4b17023SJohn Marino }
833e4b17023SJohn Marino 
834e4b17023SJohn Marino /* Return the number of bytes between the start of an OUTER_MODE
835e4b17023SJohn Marino    in-memory value and the start of an INNER_MODE in-memory value,
836e4b17023SJohn Marino    given that the former is a lowpart of the latter.  It may be a
837e4b17023SJohn Marino    paradoxical lowpart, in which case the offset will be negative
838e4b17023SJohn Marino    on big-endian targets.  */
839e4b17023SJohn Marino 
840e4b17023SJohn Marino int
byte_lowpart_offset(enum machine_mode outer_mode,enum machine_mode inner_mode)841e4b17023SJohn Marino byte_lowpart_offset (enum machine_mode outer_mode,
842e4b17023SJohn Marino 		     enum machine_mode inner_mode)
843e4b17023SJohn Marino {
844e4b17023SJohn Marino   if (GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode))
845e4b17023SJohn Marino     return subreg_lowpart_offset (outer_mode, inner_mode);
846e4b17023SJohn Marino   else
847e4b17023SJohn Marino     return -subreg_lowpart_offset (inner_mode, outer_mode);
848e4b17023SJohn Marino }
849e4b17023SJohn Marino 
850e4b17023SJohn Marino /* Generate a REG rtx for a new pseudo register of mode MODE.
851e4b17023SJohn Marino    This pseudo is assigned the next sequential register number.  */
852e4b17023SJohn Marino 
853e4b17023SJohn Marino rtx
gen_reg_rtx(enum machine_mode mode)854e4b17023SJohn Marino gen_reg_rtx (enum machine_mode mode)
855e4b17023SJohn Marino {
856e4b17023SJohn Marino   rtx val;
857e4b17023SJohn Marino   unsigned int align = GET_MODE_ALIGNMENT (mode);
858e4b17023SJohn Marino 
859e4b17023SJohn Marino   gcc_assert (can_create_pseudo_p ());
860e4b17023SJohn Marino 
861e4b17023SJohn Marino   /* If a virtual register with bigger mode alignment is generated,
862e4b17023SJohn Marino      increase stack alignment estimation because it might be spilled
863e4b17023SJohn Marino      to stack later.  */
864e4b17023SJohn Marino   if (SUPPORTS_STACK_ALIGNMENT
865e4b17023SJohn Marino       && crtl->stack_alignment_estimated < align
866e4b17023SJohn Marino       && !crtl->stack_realign_processed)
867e4b17023SJohn Marino     {
868e4b17023SJohn Marino       unsigned int min_align = MINIMUM_ALIGNMENT (NULL, mode, align);
869e4b17023SJohn Marino       if (crtl->stack_alignment_estimated < min_align)
870e4b17023SJohn Marino 	crtl->stack_alignment_estimated = min_align;
871e4b17023SJohn Marino     }
872e4b17023SJohn Marino 
873e4b17023SJohn Marino   if (generating_concat_p
874e4b17023SJohn Marino       && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
875e4b17023SJohn Marino 	  || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT))
876e4b17023SJohn Marino     {
877e4b17023SJohn Marino       /* For complex modes, don't make a single pseudo.
878e4b17023SJohn Marino 	 Instead, make a CONCAT of two pseudos.
879e4b17023SJohn Marino 	 This allows noncontiguous allocation of the real and imaginary parts,
880e4b17023SJohn Marino 	 which makes much better code.  Besides, allocating DCmode
881e4b17023SJohn Marino 	 pseudos overstrains reload on some machines like the 386.  */
882e4b17023SJohn Marino       rtx realpart, imagpart;
883e4b17023SJohn Marino       enum machine_mode partmode = GET_MODE_INNER (mode);
884e4b17023SJohn Marino 
885e4b17023SJohn Marino       realpart = gen_reg_rtx (partmode);
886e4b17023SJohn Marino       imagpart = gen_reg_rtx (partmode);
887e4b17023SJohn Marino       return gen_rtx_CONCAT (mode, realpart, imagpart);
888e4b17023SJohn Marino     }
889e4b17023SJohn Marino 
890e4b17023SJohn Marino   /* Make sure regno_pointer_align, and regno_reg_rtx are large
891e4b17023SJohn Marino      enough to have an element for this pseudo reg number.  */
892e4b17023SJohn Marino 
893e4b17023SJohn Marino   if (reg_rtx_no == crtl->emit.regno_pointer_align_length)
894e4b17023SJohn Marino     {
895e4b17023SJohn Marino       int old_size = crtl->emit.regno_pointer_align_length;
896e4b17023SJohn Marino       char *tmp;
897e4b17023SJohn Marino       rtx *new1;
898e4b17023SJohn Marino 
899e4b17023SJohn Marino       tmp = XRESIZEVEC (char, crtl->emit.regno_pointer_align, old_size * 2);
900e4b17023SJohn Marino       memset (tmp + old_size, 0, old_size);
901e4b17023SJohn Marino       crtl->emit.regno_pointer_align = (unsigned char *) tmp;
902e4b17023SJohn Marino 
903e4b17023SJohn Marino       new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, old_size * 2);
904e4b17023SJohn Marino       memset (new1 + old_size, 0, old_size * sizeof (rtx));
905e4b17023SJohn Marino       regno_reg_rtx = new1;
906e4b17023SJohn Marino 
907e4b17023SJohn Marino       crtl->emit.regno_pointer_align_length = old_size * 2;
908e4b17023SJohn Marino     }
909e4b17023SJohn Marino 
910e4b17023SJohn Marino   val = gen_raw_REG (mode, reg_rtx_no);
911e4b17023SJohn Marino   regno_reg_rtx[reg_rtx_no++] = val;
912e4b17023SJohn Marino   return val;
913e4b17023SJohn Marino }
914e4b17023SJohn Marino 
915e4b17023SJohn Marino /* Update NEW with the same attributes as REG, but with OFFSET added
916e4b17023SJohn Marino    to the REG_OFFSET.  */
917e4b17023SJohn Marino 
918e4b17023SJohn Marino static void
update_reg_offset(rtx new_rtx,rtx reg,int offset)919e4b17023SJohn Marino update_reg_offset (rtx new_rtx, rtx reg, int offset)
920e4b17023SJohn Marino {
921e4b17023SJohn Marino   REG_ATTRS (new_rtx) = get_reg_attrs (REG_EXPR (reg),
922e4b17023SJohn Marino 				   REG_OFFSET (reg) + offset);
923e4b17023SJohn Marino }
924e4b17023SJohn Marino 
925e4b17023SJohn Marino /* Generate a register with same attributes as REG, but with OFFSET
926e4b17023SJohn Marino    added to the REG_OFFSET.  */
927e4b17023SJohn Marino 
928e4b17023SJohn Marino rtx
gen_rtx_REG_offset(rtx reg,enum machine_mode mode,unsigned int regno,int offset)929e4b17023SJohn Marino gen_rtx_REG_offset (rtx reg, enum machine_mode mode, unsigned int regno,
930e4b17023SJohn Marino 		    int offset)
931e4b17023SJohn Marino {
932e4b17023SJohn Marino   rtx new_rtx = gen_rtx_REG (mode, regno);
933e4b17023SJohn Marino 
934e4b17023SJohn Marino   update_reg_offset (new_rtx, reg, offset);
935e4b17023SJohn Marino   return new_rtx;
936e4b17023SJohn Marino }
937e4b17023SJohn Marino 
938e4b17023SJohn Marino /* Generate a new pseudo-register with the same attributes as REG, but
939e4b17023SJohn Marino    with OFFSET added to the REG_OFFSET.  */
940e4b17023SJohn Marino 
941e4b17023SJohn Marino rtx
gen_reg_rtx_offset(rtx reg,enum machine_mode mode,int offset)942e4b17023SJohn Marino gen_reg_rtx_offset (rtx reg, enum machine_mode mode, int offset)
943e4b17023SJohn Marino {
944e4b17023SJohn Marino   rtx new_rtx = gen_reg_rtx (mode);
945e4b17023SJohn Marino 
946e4b17023SJohn Marino   update_reg_offset (new_rtx, reg, offset);
947e4b17023SJohn Marino   return new_rtx;
948e4b17023SJohn Marino }
949e4b17023SJohn Marino 
950e4b17023SJohn Marino /* Adjust REG in-place so that it has mode MODE.  It is assumed that the
951e4b17023SJohn Marino    new register is a (possibly paradoxical) lowpart of the old one.  */
952e4b17023SJohn Marino 
953e4b17023SJohn Marino void
adjust_reg_mode(rtx reg,enum machine_mode mode)954e4b17023SJohn Marino adjust_reg_mode (rtx reg, enum machine_mode mode)
955e4b17023SJohn Marino {
956e4b17023SJohn Marino   update_reg_offset (reg, reg, byte_lowpart_offset (mode, GET_MODE (reg)));
957e4b17023SJohn Marino   PUT_MODE (reg, mode);
958e4b17023SJohn Marino }
959e4b17023SJohn Marino 
960e4b17023SJohn Marino /* Copy REG's attributes from X, if X has any attributes.  If REG and X
961e4b17023SJohn Marino    have different modes, REG is a (possibly paradoxical) lowpart of X.  */
962e4b17023SJohn Marino 
963e4b17023SJohn Marino void
set_reg_attrs_from_value(rtx reg,rtx x)964e4b17023SJohn Marino set_reg_attrs_from_value (rtx reg, rtx x)
965e4b17023SJohn Marino {
966e4b17023SJohn Marino   int offset;
967e4b17023SJohn Marino 
968e4b17023SJohn Marino   /* Hard registers can be reused for multiple purposes within the same
969e4b17023SJohn Marino      function, so setting REG_ATTRS, REG_POINTER and REG_POINTER_ALIGN
970e4b17023SJohn Marino      on them is wrong.  */
971e4b17023SJohn Marino   if (HARD_REGISTER_P (reg))
972e4b17023SJohn Marino     return;
973e4b17023SJohn Marino 
974e4b17023SJohn Marino   offset = byte_lowpart_offset (GET_MODE (reg), GET_MODE (x));
975e4b17023SJohn Marino   if (MEM_P (x))
976e4b17023SJohn Marino     {
977e4b17023SJohn Marino       if (MEM_OFFSET_KNOWN_P (x))
978e4b17023SJohn Marino 	REG_ATTRS (reg) = get_reg_attrs (MEM_EXPR (x),
979e4b17023SJohn Marino 					 MEM_OFFSET (x) + offset);
980e4b17023SJohn Marino       if (MEM_POINTER (x))
981e4b17023SJohn Marino 	mark_reg_pointer (reg, 0);
982e4b17023SJohn Marino     }
983e4b17023SJohn Marino   else if (REG_P (x))
984e4b17023SJohn Marino     {
985e4b17023SJohn Marino       if (REG_ATTRS (x))
986e4b17023SJohn Marino 	update_reg_offset (reg, x, offset);
987e4b17023SJohn Marino       if (REG_POINTER (x))
988e4b17023SJohn Marino 	mark_reg_pointer (reg, REGNO_POINTER_ALIGN (REGNO (x)));
989e4b17023SJohn Marino     }
990e4b17023SJohn Marino }
991e4b17023SJohn Marino 
992e4b17023SJohn Marino /* Generate a REG rtx for a new pseudo register, copying the mode
993e4b17023SJohn Marino    and attributes from X.  */
994e4b17023SJohn Marino 
995e4b17023SJohn Marino rtx
gen_reg_rtx_and_attrs(rtx x)996e4b17023SJohn Marino gen_reg_rtx_and_attrs (rtx x)
997e4b17023SJohn Marino {
998e4b17023SJohn Marino   rtx reg = gen_reg_rtx (GET_MODE (x));
999e4b17023SJohn Marino   set_reg_attrs_from_value (reg, x);
1000e4b17023SJohn Marino   return reg;
1001e4b17023SJohn Marino }
1002e4b17023SJohn Marino 
1003e4b17023SJohn Marino /* Set the register attributes for registers contained in PARM_RTX.
1004e4b17023SJohn Marino    Use needed values from memory attributes of MEM.  */
1005e4b17023SJohn Marino 
1006e4b17023SJohn Marino void
set_reg_attrs_for_parm(rtx parm_rtx,rtx mem)1007e4b17023SJohn Marino set_reg_attrs_for_parm (rtx parm_rtx, rtx mem)
1008e4b17023SJohn Marino {
1009e4b17023SJohn Marino   if (REG_P (parm_rtx))
1010e4b17023SJohn Marino     set_reg_attrs_from_value (parm_rtx, mem);
1011e4b17023SJohn Marino   else if (GET_CODE (parm_rtx) == PARALLEL)
1012e4b17023SJohn Marino     {
1013e4b17023SJohn Marino       /* Check for a NULL entry in the first slot, used to indicate that the
1014e4b17023SJohn Marino 	 parameter goes both on the stack and in registers.  */
1015e4b17023SJohn Marino       int i = XEXP (XVECEXP (parm_rtx, 0, 0), 0) ? 0 : 1;
1016e4b17023SJohn Marino       for (; i < XVECLEN (parm_rtx, 0); i++)
1017e4b17023SJohn Marino 	{
1018e4b17023SJohn Marino 	  rtx x = XVECEXP (parm_rtx, 0, i);
1019e4b17023SJohn Marino 	  if (REG_P (XEXP (x, 0)))
1020e4b17023SJohn Marino 	    REG_ATTRS (XEXP (x, 0))
1021e4b17023SJohn Marino 	      = get_reg_attrs (MEM_EXPR (mem),
1022e4b17023SJohn Marino 			       INTVAL (XEXP (x, 1)));
1023e4b17023SJohn Marino 	}
1024e4b17023SJohn Marino     }
1025e4b17023SJohn Marino }
1026e4b17023SJohn Marino 
1027e4b17023SJohn Marino /* Set the REG_ATTRS for registers in value X, given that X represents
1028e4b17023SJohn Marino    decl T.  */
1029e4b17023SJohn Marino 
1030e4b17023SJohn Marino void
set_reg_attrs_for_decl_rtl(tree t,rtx x)1031e4b17023SJohn Marino set_reg_attrs_for_decl_rtl (tree t, rtx x)
1032e4b17023SJohn Marino {
1033e4b17023SJohn Marino   if (GET_CODE (x) == SUBREG)
1034e4b17023SJohn Marino     {
1035e4b17023SJohn Marino       gcc_assert (subreg_lowpart_p (x));
1036e4b17023SJohn Marino       x = SUBREG_REG (x);
1037e4b17023SJohn Marino     }
1038e4b17023SJohn Marino   if (REG_P (x))
1039e4b17023SJohn Marino     REG_ATTRS (x)
1040e4b17023SJohn Marino       = get_reg_attrs (t, byte_lowpart_offset (GET_MODE (x),
1041e4b17023SJohn Marino 					       DECL_MODE (t)));
1042e4b17023SJohn Marino   if (GET_CODE (x) == CONCAT)
1043e4b17023SJohn Marino     {
1044e4b17023SJohn Marino       if (REG_P (XEXP (x, 0)))
1045e4b17023SJohn Marino         REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
1046e4b17023SJohn Marino       if (REG_P (XEXP (x, 1)))
1047e4b17023SJohn Marino 	REG_ATTRS (XEXP (x, 1))
1048e4b17023SJohn Marino 	  = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
1049e4b17023SJohn Marino     }
1050e4b17023SJohn Marino   if (GET_CODE (x) == PARALLEL)
1051e4b17023SJohn Marino     {
1052e4b17023SJohn Marino       int i, start;
1053e4b17023SJohn Marino 
1054e4b17023SJohn Marino       /* Check for a NULL entry, used to indicate that the parameter goes
1055e4b17023SJohn Marino 	 both on the stack and in registers.  */
1056e4b17023SJohn Marino       if (XEXP (XVECEXP (x, 0, 0), 0))
1057e4b17023SJohn Marino 	start = 0;
1058e4b17023SJohn Marino       else
1059e4b17023SJohn Marino 	start = 1;
1060e4b17023SJohn Marino 
1061e4b17023SJohn Marino       for (i = start; i < XVECLEN (x, 0); i++)
1062e4b17023SJohn Marino 	{
1063e4b17023SJohn Marino 	  rtx y = XVECEXP (x, 0, i);
1064e4b17023SJohn Marino 	  if (REG_P (XEXP (y, 0)))
1065e4b17023SJohn Marino 	    REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
1066e4b17023SJohn Marino 	}
1067e4b17023SJohn Marino     }
1068e4b17023SJohn Marino }
1069e4b17023SJohn Marino 
1070e4b17023SJohn Marino /* Assign the RTX X to declaration T.  */
1071e4b17023SJohn Marino 
1072e4b17023SJohn Marino void
set_decl_rtl(tree t,rtx x)1073e4b17023SJohn Marino set_decl_rtl (tree t, rtx x)
1074e4b17023SJohn Marino {
1075e4b17023SJohn Marino   DECL_WRTL_CHECK (t)->decl_with_rtl.rtl = x;
1076e4b17023SJohn Marino   if (x)
1077e4b17023SJohn Marino     set_reg_attrs_for_decl_rtl (t, x);
1078e4b17023SJohn Marino }
1079e4b17023SJohn Marino 
1080e4b17023SJohn Marino /* Assign the RTX X to parameter declaration T.  BY_REFERENCE_P is true
1081e4b17023SJohn Marino    if the ABI requires the parameter to be passed by reference.  */
1082e4b17023SJohn Marino 
1083e4b17023SJohn Marino void
set_decl_incoming_rtl(tree t,rtx x,bool by_reference_p)1084e4b17023SJohn Marino set_decl_incoming_rtl (tree t, rtx x, bool by_reference_p)
1085e4b17023SJohn Marino {
1086e4b17023SJohn Marino   DECL_INCOMING_RTL (t) = x;
1087e4b17023SJohn Marino   if (x && !by_reference_p)
1088e4b17023SJohn Marino     set_reg_attrs_for_decl_rtl (t, x);
1089e4b17023SJohn Marino }
1090e4b17023SJohn Marino 
1091e4b17023SJohn Marino /* Identify REG (which may be a CONCAT) as a user register.  */
1092e4b17023SJohn Marino 
1093e4b17023SJohn Marino void
mark_user_reg(rtx reg)1094e4b17023SJohn Marino mark_user_reg (rtx reg)
1095e4b17023SJohn Marino {
1096e4b17023SJohn Marino   if (GET_CODE (reg) == CONCAT)
1097e4b17023SJohn Marino     {
1098e4b17023SJohn Marino       REG_USERVAR_P (XEXP (reg, 0)) = 1;
1099e4b17023SJohn Marino       REG_USERVAR_P (XEXP (reg, 1)) = 1;
1100e4b17023SJohn Marino     }
1101e4b17023SJohn Marino   else
1102e4b17023SJohn Marino     {
1103e4b17023SJohn Marino       gcc_assert (REG_P (reg));
1104e4b17023SJohn Marino       REG_USERVAR_P (reg) = 1;
1105e4b17023SJohn Marino     }
1106e4b17023SJohn Marino }
1107e4b17023SJohn Marino 
1108e4b17023SJohn Marino /* Identify REG as a probable pointer register and show its alignment
1109e4b17023SJohn Marino    as ALIGN, if nonzero.  */
1110e4b17023SJohn Marino 
1111e4b17023SJohn Marino void
mark_reg_pointer(rtx reg,int align)1112e4b17023SJohn Marino mark_reg_pointer (rtx reg, int align)
1113e4b17023SJohn Marino {
1114e4b17023SJohn Marino   if (! REG_POINTER (reg))
1115e4b17023SJohn Marino     {
1116e4b17023SJohn Marino       REG_POINTER (reg) = 1;
1117e4b17023SJohn Marino 
1118e4b17023SJohn Marino       if (align)
1119e4b17023SJohn Marino 	REGNO_POINTER_ALIGN (REGNO (reg)) = align;
1120e4b17023SJohn Marino     }
1121e4b17023SJohn Marino   else if (align && align < REGNO_POINTER_ALIGN (REGNO (reg)))
1122e4b17023SJohn Marino     /* We can no-longer be sure just how aligned this pointer is.  */
1123e4b17023SJohn Marino     REGNO_POINTER_ALIGN (REGNO (reg)) = align;
1124e4b17023SJohn Marino }
1125e4b17023SJohn Marino 
1126e4b17023SJohn Marino /* Return 1 plus largest pseudo reg number used in the current function.  */
1127e4b17023SJohn Marino 
1128e4b17023SJohn Marino int
max_reg_num(void)1129e4b17023SJohn Marino max_reg_num (void)
1130e4b17023SJohn Marino {
1131e4b17023SJohn Marino   return reg_rtx_no;
1132e4b17023SJohn Marino }
1133e4b17023SJohn Marino 
1134e4b17023SJohn Marino /* Return 1 + the largest label number used so far in the current function.  */
1135e4b17023SJohn Marino 
1136e4b17023SJohn Marino int
max_label_num(void)1137e4b17023SJohn Marino max_label_num (void)
1138e4b17023SJohn Marino {
1139e4b17023SJohn Marino   return label_num;
1140e4b17023SJohn Marino }
1141e4b17023SJohn Marino 
1142e4b17023SJohn Marino /* Return first label number used in this function (if any were used).  */
1143e4b17023SJohn Marino 
1144e4b17023SJohn Marino int
get_first_label_num(void)1145e4b17023SJohn Marino get_first_label_num (void)
1146e4b17023SJohn Marino {
1147e4b17023SJohn Marino   return first_label_num;
1148e4b17023SJohn Marino }
1149e4b17023SJohn Marino 
1150e4b17023SJohn Marino /* If the rtx for label was created during the expansion of a nested
1151e4b17023SJohn Marino    function, then first_label_num won't include this label number.
1152e4b17023SJohn Marino    Fix this now so that array indices work later.  */
1153e4b17023SJohn Marino 
1154e4b17023SJohn Marino void
maybe_set_first_label_num(rtx x)1155e4b17023SJohn Marino maybe_set_first_label_num (rtx x)
1156e4b17023SJohn Marino {
1157e4b17023SJohn Marino   if (CODE_LABEL_NUMBER (x) < first_label_num)
1158e4b17023SJohn Marino     first_label_num = CODE_LABEL_NUMBER (x);
1159e4b17023SJohn Marino }
1160e4b17023SJohn Marino 
1161e4b17023SJohn Marino /* Return a value representing some low-order bits of X, where the number
1162e4b17023SJohn Marino    of low-order bits is given by MODE.  Note that no conversion is done
1163e4b17023SJohn Marino    between floating-point and fixed-point values, rather, the bit
1164e4b17023SJohn Marino    representation is returned.
1165e4b17023SJohn Marino 
1166e4b17023SJohn Marino    This function handles the cases in common between gen_lowpart, below,
1167e4b17023SJohn Marino    and two variants in cse.c and combine.c.  These are the cases that can
1168e4b17023SJohn Marino    be safely handled at all points in the compilation.
1169e4b17023SJohn Marino 
1170e4b17023SJohn Marino    If this is not a case we can handle, return 0.  */
1171e4b17023SJohn Marino 
1172e4b17023SJohn Marino rtx
gen_lowpart_common(enum machine_mode mode,rtx x)1173e4b17023SJohn Marino gen_lowpart_common (enum machine_mode mode, rtx x)
1174e4b17023SJohn Marino {
1175e4b17023SJohn Marino   int msize = GET_MODE_SIZE (mode);
1176e4b17023SJohn Marino   int xsize;
1177e4b17023SJohn Marino   int offset = 0;
1178e4b17023SJohn Marino   enum machine_mode innermode;
1179e4b17023SJohn Marino 
1180e4b17023SJohn Marino   /* Unfortunately, this routine doesn't take a parameter for the mode of X,
1181e4b17023SJohn Marino      so we have to make one up.  Yuk.  */
1182e4b17023SJohn Marino   innermode = GET_MODE (x);
1183e4b17023SJohn Marino   if (CONST_INT_P (x)
1184e4b17023SJohn Marino       && msize * BITS_PER_UNIT <= HOST_BITS_PER_WIDE_INT)
1185e4b17023SJohn Marino     innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
1186e4b17023SJohn Marino   else if (innermode == VOIDmode)
1187e4b17023SJohn Marino     innermode = mode_for_size (HOST_BITS_PER_WIDE_INT * 2, MODE_INT, 0);
1188e4b17023SJohn Marino 
1189e4b17023SJohn Marino   xsize = GET_MODE_SIZE (innermode);
1190e4b17023SJohn Marino 
1191e4b17023SJohn Marino   gcc_assert (innermode != VOIDmode && innermode != BLKmode);
1192e4b17023SJohn Marino 
1193e4b17023SJohn Marino   if (innermode == mode)
1194e4b17023SJohn Marino     return x;
1195e4b17023SJohn Marino 
1196e4b17023SJohn Marino   /* MODE must occupy no more words than the mode of X.  */
1197e4b17023SJohn Marino   if ((msize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD
1198e4b17023SJohn Marino       > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
1199e4b17023SJohn Marino     return 0;
1200e4b17023SJohn Marino 
1201e4b17023SJohn Marino   /* Don't allow generating paradoxical FLOAT_MODE subregs.  */
1202e4b17023SJohn Marino   if (SCALAR_FLOAT_MODE_P (mode) && msize > xsize)
1203e4b17023SJohn Marino     return 0;
1204e4b17023SJohn Marino 
1205e4b17023SJohn Marino   offset = subreg_lowpart_offset (mode, innermode);
1206e4b17023SJohn Marino 
1207e4b17023SJohn Marino   if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
1208e4b17023SJohn Marino       && (GET_MODE_CLASS (mode) == MODE_INT
1209e4b17023SJohn Marino 	  || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT))
1210e4b17023SJohn Marino     {
1211e4b17023SJohn Marino       /* If we are getting the low-order part of something that has been
1212e4b17023SJohn Marino 	 sign- or zero-extended, we can either just use the object being
1213e4b17023SJohn Marino 	 extended or make a narrower extension.  If we want an even smaller
1214e4b17023SJohn Marino 	 piece than the size of the object being extended, call ourselves
1215e4b17023SJohn Marino 	 recursively.
1216e4b17023SJohn Marino 
1217e4b17023SJohn Marino 	 This case is used mostly by combine and cse.  */
1218e4b17023SJohn Marino 
1219e4b17023SJohn Marino       if (GET_MODE (XEXP (x, 0)) == mode)
1220e4b17023SJohn Marino 	return XEXP (x, 0);
1221e4b17023SJohn Marino       else if (msize < GET_MODE_SIZE (GET_MODE (XEXP (x, 0))))
1222e4b17023SJohn Marino 	return gen_lowpart_common (mode, XEXP (x, 0));
1223e4b17023SJohn Marino       else if (msize < xsize)
1224e4b17023SJohn Marino 	return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
1225e4b17023SJohn Marino     }
1226e4b17023SJohn Marino   else if (GET_CODE (x) == SUBREG || REG_P (x)
1227e4b17023SJohn Marino 	   || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR
1228e4b17023SJohn Marino 	   || GET_CODE (x) == CONST_DOUBLE || CONST_INT_P (x))
1229e4b17023SJohn Marino     return simplify_gen_subreg (mode, x, innermode, offset);
1230e4b17023SJohn Marino 
1231e4b17023SJohn Marino   /* Otherwise, we can't do this.  */
1232e4b17023SJohn Marino   return 0;
1233e4b17023SJohn Marino }
1234e4b17023SJohn Marino 
1235e4b17023SJohn Marino rtx
gen_highpart(enum machine_mode mode,rtx x)1236e4b17023SJohn Marino gen_highpart (enum machine_mode mode, rtx x)
1237e4b17023SJohn Marino {
1238e4b17023SJohn Marino   unsigned int msize = GET_MODE_SIZE (mode);
1239e4b17023SJohn Marino   rtx result;
1240e4b17023SJohn Marino 
1241e4b17023SJohn Marino   /* This case loses if X is a subreg.  To catch bugs early,
1242e4b17023SJohn Marino      complain if an invalid MODE is used even in other cases.  */
1243e4b17023SJohn Marino   gcc_assert (msize <= UNITS_PER_WORD
1244e4b17023SJohn Marino 	      || msize == (unsigned int) GET_MODE_UNIT_SIZE (GET_MODE (x)));
1245e4b17023SJohn Marino 
1246e4b17023SJohn Marino   result = simplify_gen_subreg (mode, x, GET_MODE (x),
1247e4b17023SJohn Marino 				subreg_highpart_offset (mode, GET_MODE (x)));
1248e4b17023SJohn Marino   gcc_assert (result);
1249e4b17023SJohn Marino 
1250e4b17023SJohn Marino   /* simplify_gen_subreg is not guaranteed to return a valid operand for
1251e4b17023SJohn Marino      the target if we have a MEM.  gen_highpart must return a valid operand,
1252e4b17023SJohn Marino      emitting code if necessary to do so.  */
1253e4b17023SJohn Marino   if (MEM_P (result))
1254e4b17023SJohn Marino     {
1255e4b17023SJohn Marino       result = validize_mem (result);
1256e4b17023SJohn Marino       gcc_assert (result);
1257e4b17023SJohn Marino     }
1258e4b17023SJohn Marino 
1259e4b17023SJohn Marino   return result;
1260e4b17023SJohn Marino }
1261e4b17023SJohn Marino 
1262e4b17023SJohn Marino /* Like gen_highpart, but accept mode of EXP operand in case EXP can
1263e4b17023SJohn Marino    be VOIDmode constant.  */
1264e4b17023SJohn Marino rtx
gen_highpart_mode(enum machine_mode outermode,enum machine_mode innermode,rtx exp)1265e4b17023SJohn Marino gen_highpart_mode (enum machine_mode outermode, enum machine_mode innermode, rtx exp)
1266e4b17023SJohn Marino {
1267e4b17023SJohn Marino   if (GET_MODE (exp) != VOIDmode)
1268e4b17023SJohn Marino     {
1269e4b17023SJohn Marino       gcc_assert (GET_MODE (exp) == innermode);
1270e4b17023SJohn Marino       return gen_highpart (outermode, exp);
1271e4b17023SJohn Marino     }
1272e4b17023SJohn Marino   return simplify_gen_subreg (outermode, exp, innermode,
1273e4b17023SJohn Marino 			      subreg_highpart_offset (outermode, innermode));
1274e4b17023SJohn Marino }
1275e4b17023SJohn Marino 
1276e4b17023SJohn Marino /* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value.  */
1277e4b17023SJohn Marino 
1278e4b17023SJohn Marino unsigned int
subreg_lowpart_offset(enum machine_mode outermode,enum machine_mode innermode)1279e4b17023SJohn Marino subreg_lowpart_offset (enum machine_mode outermode, enum machine_mode innermode)
1280e4b17023SJohn Marino {
1281e4b17023SJohn Marino   unsigned int offset = 0;
1282e4b17023SJohn Marino   int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
1283e4b17023SJohn Marino 
1284e4b17023SJohn Marino   if (difference > 0)
1285e4b17023SJohn Marino     {
1286e4b17023SJohn Marino       if (WORDS_BIG_ENDIAN)
1287e4b17023SJohn Marino 	offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
1288e4b17023SJohn Marino       if (BYTES_BIG_ENDIAN)
1289e4b17023SJohn Marino 	offset += difference % UNITS_PER_WORD;
1290e4b17023SJohn Marino     }
1291e4b17023SJohn Marino 
1292e4b17023SJohn Marino   return offset;
1293e4b17023SJohn Marino }
1294e4b17023SJohn Marino 
1295e4b17023SJohn Marino /* Return offset in bytes to get OUTERMODE high part
1296e4b17023SJohn Marino    of the value in mode INNERMODE stored in memory in target format.  */
1297e4b17023SJohn Marino unsigned int
subreg_highpart_offset(enum machine_mode outermode,enum machine_mode innermode)1298e4b17023SJohn Marino subreg_highpart_offset (enum machine_mode outermode, enum machine_mode innermode)
1299e4b17023SJohn Marino {
1300e4b17023SJohn Marino   unsigned int offset = 0;
1301e4b17023SJohn Marino   int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
1302e4b17023SJohn Marino 
1303e4b17023SJohn Marino   gcc_assert (GET_MODE_SIZE (innermode) >= GET_MODE_SIZE (outermode));
1304e4b17023SJohn Marino 
1305e4b17023SJohn Marino   if (difference > 0)
1306e4b17023SJohn Marino     {
1307e4b17023SJohn Marino       if (! WORDS_BIG_ENDIAN)
1308e4b17023SJohn Marino 	offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
1309e4b17023SJohn Marino       if (! BYTES_BIG_ENDIAN)
1310e4b17023SJohn Marino 	offset += difference % UNITS_PER_WORD;
1311e4b17023SJohn Marino     }
1312e4b17023SJohn Marino 
1313e4b17023SJohn Marino   return offset;
1314e4b17023SJohn Marino }
1315e4b17023SJohn Marino 
1316e4b17023SJohn Marino /* Return 1 iff X, assumed to be a SUBREG,
1317e4b17023SJohn Marino    refers to the least significant part of its containing reg.
1318e4b17023SJohn Marino    If X is not a SUBREG, always return 1 (it is its own low part!).  */
1319e4b17023SJohn Marino 
1320e4b17023SJohn Marino int
subreg_lowpart_p(const_rtx x)1321e4b17023SJohn Marino subreg_lowpart_p (const_rtx x)
1322e4b17023SJohn Marino {
1323e4b17023SJohn Marino   if (GET_CODE (x) != SUBREG)
1324e4b17023SJohn Marino     return 1;
1325e4b17023SJohn Marino   else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
1326e4b17023SJohn Marino     return 0;
1327e4b17023SJohn Marino 
1328e4b17023SJohn Marino   return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
1329e4b17023SJohn Marino 	  == SUBREG_BYTE (x));
1330e4b17023SJohn Marino }
1331e4b17023SJohn Marino 
1332e4b17023SJohn Marino /* Return true if X is a paradoxical subreg, false otherwise.  */
1333e4b17023SJohn Marino bool
paradoxical_subreg_p(const_rtx x)1334e4b17023SJohn Marino paradoxical_subreg_p (const_rtx x)
1335e4b17023SJohn Marino {
1336e4b17023SJohn Marino   if (GET_CODE (x) != SUBREG)
1337e4b17023SJohn Marino     return false;
1338e4b17023SJohn Marino   return (GET_MODE_PRECISION (GET_MODE (x))
1339e4b17023SJohn Marino 	  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (x))));
1340e4b17023SJohn Marino }
1341e4b17023SJohn Marino 
1342e4b17023SJohn Marino /* Return subword OFFSET of operand OP.
1343e4b17023SJohn Marino    The word number, OFFSET, is interpreted as the word number starting
1344e4b17023SJohn Marino    at the low-order address.  OFFSET 0 is the low-order word if not
1345e4b17023SJohn Marino    WORDS_BIG_ENDIAN, otherwise it is the high-order word.
1346e4b17023SJohn Marino 
1347e4b17023SJohn Marino    If we cannot extract the required word, we return zero.  Otherwise,
1348e4b17023SJohn Marino    an rtx corresponding to the requested word will be returned.
1349e4b17023SJohn Marino 
1350e4b17023SJohn Marino    VALIDATE_ADDRESS is nonzero if the address should be validated.  Before
1351e4b17023SJohn Marino    reload has completed, a valid address will always be returned.  After
1352e4b17023SJohn Marino    reload, if a valid address cannot be returned, we return zero.
1353e4b17023SJohn Marino 
1354e4b17023SJohn Marino    If VALIDATE_ADDRESS is zero, we simply form the required address; validating
1355e4b17023SJohn Marino    it is the responsibility of the caller.
1356e4b17023SJohn Marino 
1357e4b17023SJohn Marino    MODE is the mode of OP in case it is a CONST_INT.
1358e4b17023SJohn Marino 
1359e4b17023SJohn Marino    ??? This is still rather broken for some cases.  The problem for the
1360e4b17023SJohn Marino    moment is that all callers of this thing provide no 'goal mode' to
1361e4b17023SJohn Marino    tell us to work with.  This exists because all callers were written
1362e4b17023SJohn Marino    in a word based SUBREG world.
1363e4b17023SJohn Marino    Now use of this function can be deprecated by simplify_subreg in most
1364e4b17023SJohn Marino    cases.
1365e4b17023SJohn Marino  */
1366e4b17023SJohn Marino 
1367e4b17023SJohn Marino rtx
operand_subword(rtx op,unsigned int offset,int validate_address,enum machine_mode mode)1368e4b17023SJohn Marino operand_subword (rtx op, unsigned int offset, int validate_address, enum machine_mode mode)
1369e4b17023SJohn Marino {
1370e4b17023SJohn Marino   if (mode == VOIDmode)
1371e4b17023SJohn Marino     mode = GET_MODE (op);
1372e4b17023SJohn Marino 
1373e4b17023SJohn Marino   gcc_assert (mode != VOIDmode);
1374e4b17023SJohn Marino 
1375e4b17023SJohn Marino   /* If OP is narrower than a word, fail.  */
1376e4b17023SJohn Marino   if (mode != BLKmode
1377e4b17023SJohn Marino       && (GET_MODE_SIZE (mode) < UNITS_PER_WORD))
1378e4b17023SJohn Marino     return 0;
1379e4b17023SJohn Marino 
1380e4b17023SJohn Marino   /* If we want a word outside OP, return zero.  */
1381e4b17023SJohn Marino   if (mode != BLKmode
1382e4b17023SJohn Marino       && (offset + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))
1383e4b17023SJohn Marino     return const0_rtx;
1384e4b17023SJohn Marino 
1385e4b17023SJohn Marino   /* Form a new MEM at the requested address.  */
1386e4b17023SJohn Marino   if (MEM_P (op))
1387e4b17023SJohn Marino     {
1388e4b17023SJohn Marino       rtx new_rtx = adjust_address_nv (op, word_mode, offset * UNITS_PER_WORD);
1389e4b17023SJohn Marino 
1390e4b17023SJohn Marino       if (! validate_address)
1391e4b17023SJohn Marino 	return new_rtx;
1392e4b17023SJohn Marino 
1393e4b17023SJohn Marino       else if (reload_completed)
1394e4b17023SJohn Marino 	{
1395e4b17023SJohn Marino 	  if (! strict_memory_address_addr_space_p (word_mode,
1396e4b17023SJohn Marino 						    XEXP (new_rtx, 0),
1397e4b17023SJohn Marino 						    MEM_ADDR_SPACE (op)))
1398e4b17023SJohn Marino 	    return 0;
1399e4b17023SJohn Marino 	}
1400e4b17023SJohn Marino       else
1401e4b17023SJohn Marino 	return replace_equiv_address (new_rtx, XEXP (new_rtx, 0));
1402e4b17023SJohn Marino     }
1403e4b17023SJohn Marino 
1404e4b17023SJohn Marino   /* Rest can be handled by simplify_subreg.  */
1405e4b17023SJohn Marino   return simplify_gen_subreg (word_mode, op, mode, (offset * UNITS_PER_WORD));
1406e4b17023SJohn Marino }
1407e4b17023SJohn Marino 
1408e4b17023SJohn Marino /* Similar to `operand_subword', but never return 0.  If we can't
1409e4b17023SJohn Marino    extract the required subword, put OP into a register and try again.
1410e4b17023SJohn Marino    The second attempt must succeed.  We always validate the address in
1411e4b17023SJohn Marino    this case.
1412e4b17023SJohn Marino 
1413e4b17023SJohn Marino    MODE is the mode of OP, in case it is CONST_INT.  */
1414e4b17023SJohn Marino 
1415e4b17023SJohn Marino rtx
operand_subword_force(rtx op,unsigned int offset,enum machine_mode mode)1416e4b17023SJohn Marino operand_subword_force (rtx op, unsigned int offset, enum machine_mode mode)
1417e4b17023SJohn Marino {
1418e4b17023SJohn Marino   rtx result = operand_subword (op, offset, 1, mode);
1419e4b17023SJohn Marino 
1420e4b17023SJohn Marino   if (result)
1421e4b17023SJohn Marino     return result;
1422e4b17023SJohn Marino 
1423e4b17023SJohn Marino   if (mode != BLKmode && mode != VOIDmode)
1424e4b17023SJohn Marino     {
1425e4b17023SJohn Marino       /* If this is a register which can not be accessed by words, copy it
1426e4b17023SJohn Marino 	 to a pseudo register.  */
1427e4b17023SJohn Marino       if (REG_P (op))
1428e4b17023SJohn Marino 	op = copy_to_reg (op);
1429e4b17023SJohn Marino       else
1430e4b17023SJohn Marino 	op = force_reg (mode, op);
1431e4b17023SJohn Marino     }
1432e4b17023SJohn Marino 
1433e4b17023SJohn Marino   result = operand_subword (op, offset, 1, mode);
1434e4b17023SJohn Marino   gcc_assert (result);
1435e4b17023SJohn Marino 
1436e4b17023SJohn Marino   return result;
1437e4b17023SJohn Marino }
1438e4b17023SJohn Marino 
1439e4b17023SJohn Marino /* Returns 1 if both MEM_EXPR can be considered equal
1440e4b17023SJohn Marino    and 0 otherwise.  */
1441e4b17023SJohn Marino 
1442e4b17023SJohn Marino int
mem_expr_equal_p(const_tree expr1,const_tree expr2)1443e4b17023SJohn Marino mem_expr_equal_p (const_tree expr1, const_tree expr2)
1444e4b17023SJohn Marino {
1445e4b17023SJohn Marino   if (expr1 == expr2)
1446e4b17023SJohn Marino     return 1;
1447e4b17023SJohn Marino 
1448e4b17023SJohn Marino   if (! expr1 || ! expr2)
1449e4b17023SJohn Marino     return 0;
1450e4b17023SJohn Marino 
1451e4b17023SJohn Marino   if (TREE_CODE (expr1) != TREE_CODE (expr2))
1452e4b17023SJohn Marino     return 0;
1453e4b17023SJohn Marino 
1454e4b17023SJohn Marino   return operand_equal_p (expr1, expr2, 0);
1455e4b17023SJohn Marino }
1456e4b17023SJohn Marino 
1457e4b17023SJohn Marino /* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN
1458e4b17023SJohn Marino    bits aligned for 0 <= OFFSET < ALIGN / BITS_PER_UNIT, or
1459e4b17023SJohn Marino    -1 if not known.  */
1460e4b17023SJohn Marino 
1461e4b17023SJohn Marino int
get_mem_align_offset(rtx mem,unsigned int align)1462e4b17023SJohn Marino get_mem_align_offset (rtx mem, unsigned int align)
1463e4b17023SJohn Marino {
1464e4b17023SJohn Marino   tree expr;
1465e4b17023SJohn Marino   unsigned HOST_WIDE_INT offset;
1466e4b17023SJohn Marino 
1467e4b17023SJohn Marino   /* This function can't use
1468e4b17023SJohn Marino      if (!MEM_EXPR (mem) || !MEM_OFFSET_KNOWN_P (mem)
1469e4b17023SJohn Marino 	 || (MAX (MEM_ALIGN (mem),
1470e4b17023SJohn Marino 	          MAX (align, get_object_alignment (MEM_EXPR (mem))))
1471e4b17023SJohn Marino 	     < align))
1472e4b17023SJohn Marino        return -1;
1473e4b17023SJohn Marino      else
1474e4b17023SJohn Marino        return (- MEM_OFFSET (mem)) & (align / BITS_PER_UNIT - 1);
1475e4b17023SJohn Marino      for two reasons:
1476e4b17023SJohn Marino      - COMPONENT_REFs in MEM_EXPR can have NULL first operand,
1477e4b17023SJohn Marino        for <variable>.  get_inner_reference doesn't handle it and
1478e4b17023SJohn Marino        even if it did, the alignment in that case needs to be determined
1479e4b17023SJohn Marino        from DECL_FIELD_CONTEXT's TYPE_ALIGN.
1480e4b17023SJohn Marino      - it would do suboptimal job for COMPONENT_REFs, even if MEM_EXPR
1481e4b17023SJohn Marino        isn't sufficiently aligned, the object it is in might be.  */
1482e4b17023SJohn Marino   gcc_assert (MEM_P (mem));
1483e4b17023SJohn Marino   expr = MEM_EXPR (mem);
1484e4b17023SJohn Marino   if (expr == NULL_TREE || !MEM_OFFSET_KNOWN_P (mem))
1485e4b17023SJohn Marino     return -1;
1486e4b17023SJohn Marino 
1487e4b17023SJohn Marino   offset = MEM_OFFSET (mem);
1488e4b17023SJohn Marino   if (DECL_P (expr))
1489e4b17023SJohn Marino     {
1490e4b17023SJohn Marino       if (DECL_ALIGN (expr) < align)
1491e4b17023SJohn Marino 	return -1;
1492e4b17023SJohn Marino     }
1493e4b17023SJohn Marino   else if (INDIRECT_REF_P (expr))
1494e4b17023SJohn Marino     {
1495e4b17023SJohn Marino       if (TYPE_ALIGN (TREE_TYPE (expr)) < (unsigned int) align)
1496e4b17023SJohn Marino 	return -1;
1497e4b17023SJohn Marino     }
1498e4b17023SJohn Marino   else if (TREE_CODE (expr) == COMPONENT_REF)
1499e4b17023SJohn Marino     {
1500e4b17023SJohn Marino       while (1)
1501e4b17023SJohn Marino 	{
1502e4b17023SJohn Marino 	  tree inner = TREE_OPERAND (expr, 0);
1503e4b17023SJohn Marino 	  tree field = TREE_OPERAND (expr, 1);
1504e4b17023SJohn Marino 	  tree byte_offset = component_ref_field_offset (expr);
1505e4b17023SJohn Marino 	  tree bit_offset = DECL_FIELD_BIT_OFFSET (field);
1506e4b17023SJohn Marino 
1507e4b17023SJohn Marino 	  if (!byte_offset
1508e4b17023SJohn Marino 	      || !host_integerp (byte_offset, 1)
1509e4b17023SJohn Marino 	      || !host_integerp (bit_offset, 1))
1510e4b17023SJohn Marino 	    return -1;
1511e4b17023SJohn Marino 
1512e4b17023SJohn Marino 	  offset += tree_low_cst (byte_offset, 1);
1513e4b17023SJohn Marino 	  offset += tree_low_cst (bit_offset, 1) / BITS_PER_UNIT;
1514e4b17023SJohn Marino 
1515e4b17023SJohn Marino 	  if (inner == NULL_TREE)
1516e4b17023SJohn Marino 	    {
1517e4b17023SJohn Marino 	      if (TYPE_ALIGN (DECL_FIELD_CONTEXT (field))
1518e4b17023SJohn Marino 		  < (unsigned int) align)
1519e4b17023SJohn Marino 		return -1;
1520e4b17023SJohn Marino 	      break;
1521e4b17023SJohn Marino 	    }
1522e4b17023SJohn Marino 	  else if (DECL_P (inner))
1523e4b17023SJohn Marino 	    {
1524e4b17023SJohn Marino 	      if (DECL_ALIGN (inner) < align)
1525e4b17023SJohn Marino 		return -1;
1526e4b17023SJohn Marino 	      break;
1527e4b17023SJohn Marino 	    }
1528e4b17023SJohn Marino 	  else if (TREE_CODE (inner) != COMPONENT_REF)
1529e4b17023SJohn Marino 	    return -1;
1530e4b17023SJohn Marino 	  expr = inner;
1531e4b17023SJohn Marino 	}
1532e4b17023SJohn Marino     }
1533e4b17023SJohn Marino   else
1534e4b17023SJohn Marino     return -1;
1535e4b17023SJohn Marino 
1536e4b17023SJohn Marino   return offset & ((align / BITS_PER_UNIT) - 1);
1537e4b17023SJohn Marino }
1538e4b17023SJohn Marino 
1539e4b17023SJohn Marino /* Given REF (a MEM) and T, either the type of X or the expression
1540e4b17023SJohn Marino    corresponding to REF, set the memory attributes.  OBJECTP is nonzero
1541e4b17023SJohn Marino    if we are making a new object of this type.  BITPOS is nonzero if
1542e4b17023SJohn Marino    there is an offset outstanding on T that will be applied later.  */
1543e4b17023SJohn Marino 
1544e4b17023SJohn Marino void
set_mem_attributes_minus_bitpos(rtx ref,tree t,int objectp,HOST_WIDE_INT bitpos)1545e4b17023SJohn Marino set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
1546e4b17023SJohn Marino 				 HOST_WIDE_INT bitpos)
1547e4b17023SJohn Marino {
1548e4b17023SJohn Marino   HOST_WIDE_INT apply_bitpos = 0;
1549e4b17023SJohn Marino   tree type;
1550e4b17023SJohn Marino   struct mem_attrs attrs, *defattrs, *refattrs;
1551e4b17023SJohn Marino   addr_space_t as;
1552e4b17023SJohn Marino 
1553e4b17023SJohn Marino   /* It can happen that type_for_mode was given a mode for which there
1554e4b17023SJohn Marino      is no language-level type.  In which case it returns NULL, which
1555e4b17023SJohn Marino      we can see here.  */
1556e4b17023SJohn Marino   if (t == NULL_TREE)
1557e4b17023SJohn Marino     return;
1558e4b17023SJohn Marino 
1559e4b17023SJohn Marino   type = TYPE_P (t) ? t : TREE_TYPE (t);
1560e4b17023SJohn Marino   if (type == error_mark_node)
1561e4b17023SJohn Marino     return;
1562e4b17023SJohn Marino 
1563e4b17023SJohn Marino   /* If we have already set DECL_RTL = ref, get_alias_set will get the
1564e4b17023SJohn Marino      wrong answer, as it assumes that DECL_RTL already has the right alias
1565e4b17023SJohn Marino      info.  Callers should not set DECL_RTL until after the call to
1566e4b17023SJohn Marino      set_mem_attributes.  */
1567e4b17023SJohn Marino   gcc_assert (!DECL_P (t) || ref != DECL_RTL_IF_SET (t));
1568e4b17023SJohn Marino 
1569e4b17023SJohn Marino   memset (&attrs, 0, sizeof (attrs));
1570e4b17023SJohn Marino 
1571e4b17023SJohn Marino   /* Get the alias set from the expression or type (perhaps using a
1572e4b17023SJohn Marino      front-end routine) and use it.  */
1573e4b17023SJohn Marino   attrs.alias = get_alias_set (t);
1574e4b17023SJohn Marino 
1575e4b17023SJohn Marino   MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
1576e4b17023SJohn Marino   MEM_POINTER (ref) = POINTER_TYPE_P (type);
1577e4b17023SJohn Marino 
1578e4b17023SJohn Marino   /* Default values from pre-existing memory attributes if present.  */
1579e4b17023SJohn Marino   refattrs = MEM_ATTRS (ref);
1580e4b17023SJohn Marino   if (refattrs)
1581e4b17023SJohn Marino     {
1582e4b17023SJohn Marino       /* ??? Can this ever happen?  Calling this routine on a MEM that
1583e4b17023SJohn Marino 	 already carries memory attributes should probably be invalid.  */
1584e4b17023SJohn Marino       attrs.expr = refattrs->expr;
1585e4b17023SJohn Marino       attrs.offset_known_p = refattrs->offset_known_p;
1586e4b17023SJohn Marino       attrs.offset = refattrs->offset;
1587e4b17023SJohn Marino       attrs.size_known_p = refattrs->size_known_p;
1588e4b17023SJohn Marino       attrs.size = refattrs->size;
1589e4b17023SJohn Marino       attrs.align = refattrs->align;
1590e4b17023SJohn Marino     }
1591e4b17023SJohn Marino 
1592e4b17023SJohn Marino   /* Otherwise, default values from the mode of the MEM reference.  */
1593e4b17023SJohn Marino   else
1594e4b17023SJohn Marino     {
1595e4b17023SJohn Marino       defattrs = mode_mem_attrs[(int) GET_MODE (ref)];
1596e4b17023SJohn Marino       gcc_assert (!defattrs->expr);
1597e4b17023SJohn Marino       gcc_assert (!defattrs->offset_known_p);
1598e4b17023SJohn Marino 
1599e4b17023SJohn Marino       /* Respect mode size.  */
1600e4b17023SJohn Marino       attrs.size_known_p = defattrs->size_known_p;
1601e4b17023SJohn Marino       attrs.size = defattrs->size;
1602e4b17023SJohn Marino       /* ??? Is this really necessary?  We probably should always get
1603e4b17023SJohn Marino 	 the size from the type below.  */
1604e4b17023SJohn Marino 
1605e4b17023SJohn Marino       /* Respect mode alignment for STRICT_ALIGNMENT targets if T is a type;
1606e4b17023SJohn Marino          if T is an object, always compute the object alignment below.  */
1607e4b17023SJohn Marino       if (TYPE_P (t))
1608e4b17023SJohn Marino 	attrs.align = defattrs->align;
1609e4b17023SJohn Marino       else
1610e4b17023SJohn Marino 	attrs.align = BITS_PER_UNIT;
1611e4b17023SJohn Marino       /* ??? If T is a type, respecting mode alignment may *also* be wrong
1612e4b17023SJohn Marino 	 e.g. if the type carries an alignment attribute.  Should we be
1613e4b17023SJohn Marino 	 able to simply always use TYPE_ALIGN?  */
1614e4b17023SJohn Marino     }
1615e4b17023SJohn Marino 
1616e4b17023SJohn Marino   /* We can set the alignment from the type if we are making an object,
1617e4b17023SJohn Marino      this is an INDIRECT_REF, or if TYPE_ALIGN_OK.  */
1618e4b17023SJohn Marino   if (objectp || TREE_CODE (t) == INDIRECT_REF || TYPE_ALIGN_OK (type))
1619e4b17023SJohn Marino     attrs.align = MAX (attrs.align, TYPE_ALIGN (type));
1620e4b17023SJohn Marino 
1621e4b17023SJohn Marino   else if (TREE_CODE (t) == MEM_REF)
1622e4b17023SJohn Marino     {
1623e4b17023SJohn Marino       tree op0 = TREE_OPERAND (t, 0);
1624e4b17023SJohn Marino       if (TREE_CODE (op0) == ADDR_EXPR
1625e4b17023SJohn Marino 	  && (DECL_P (TREE_OPERAND (op0, 0))
1626e4b17023SJohn Marino 	      || CONSTANT_CLASS_P (TREE_OPERAND (op0, 0))))
1627e4b17023SJohn Marino 	{
1628e4b17023SJohn Marino 	  if (DECL_P (TREE_OPERAND (op0, 0)))
1629e4b17023SJohn Marino 	    attrs.align = DECL_ALIGN (TREE_OPERAND (op0, 0));
1630e4b17023SJohn Marino 	  else if (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)))
1631e4b17023SJohn Marino 	    {
1632e4b17023SJohn Marino 	      attrs.align = TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (op0, 0)));
1633e4b17023SJohn Marino #ifdef CONSTANT_ALIGNMENT
1634e4b17023SJohn Marino 	      attrs.align = CONSTANT_ALIGNMENT (TREE_OPERAND (op0, 0),
1635e4b17023SJohn Marino 						attrs.align);
1636e4b17023SJohn Marino #endif
1637e4b17023SJohn Marino 	    }
1638e4b17023SJohn Marino 	  if (TREE_INT_CST_LOW (TREE_OPERAND (t, 1)) != 0)
1639e4b17023SJohn Marino 	    {
1640e4b17023SJohn Marino 	      unsigned HOST_WIDE_INT ioff
1641e4b17023SJohn Marino 		= TREE_INT_CST_LOW (TREE_OPERAND (t, 1));
1642e4b17023SJohn Marino 	      unsigned HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT;
1643e4b17023SJohn Marino 	      attrs.align = MIN (aoff, attrs.align);
1644e4b17023SJohn Marino 	    }
1645e4b17023SJohn Marino 	}
1646e4b17023SJohn Marino       else
1647e4b17023SJohn Marino 	/* ??? This isn't fully correct, we can't set the alignment from the
1648e4b17023SJohn Marino 	   type in all cases.  */
1649e4b17023SJohn Marino 	attrs.align = MAX (attrs.align, TYPE_ALIGN (type));
1650e4b17023SJohn Marino     }
1651e4b17023SJohn Marino 
1652e4b17023SJohn Marino   else if (TREE_CODE (t) == TARGET_MEM_REF)
1653e4b17023SJohn Marino     /* ??? This isn't fully correct, we can't set the alignment from the
1654e4b17023SJohn Marino        type in all cases.  */
1655e4b17023SJohn Marino     attrs.align = MAX (attrs.align, TYPE_ALIGN (type));
1656e4b17023SJohn Marino 
1657e4b17023SJohn Marino   /* If the size is known, we can set that.  */
1658e4b17023SJohn Marino   if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
1659e4b17023SJohn Marino     {
1660e4b17023SJohn Marino       attrs.size_known_p = true;
1661e4b17023SJohn Marino       attrs.size = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
1662e4b17023SJohn Marino     }
1663e4b17023SJohn Marino 
1664e4b17023SJohn Marino   /* If T is not a type, we may be able to deduce some more information about
1665e4b17023SJohn Marino      the expression.  */
1666e4b17023SJohn Marino   if (! TYPE_P (t))
1667e4b17023SJohn Marino     {
1668e4b17023SJohn Marino       tree base;
1669e4b17023SJohn Marino       bool align_computed = false;
1670e4b17023SJohn Marino 
1671e4b17023SJohn Marino       if (TREE_THIS_VOLATILE (t))
1672e4b17023SJohn Marino 	MEM_VOLATILE_P (ref) = 1;
1673e4b17023SJohn Marino 
1674e4b17023SJohn Marino       /* Now remove any conversions: they don't change what the underlying
1675e4b17023SJohn Marino 	 object is.  Likewise for SAVE_EXPR.  */
1676e4b17023SJohn Marino       while (CONVERT_EXPR_P (t)
1677e4b17023SJohn Marino 	     || TREE_CODE (t) == VIEW_CONVERT_EXPR
1678e4b17023SJohn Marino 	     || TREE_CODE (t) == SAVE_EXPR)
1679e4b17023SJohn Marino 	t = TREE_OPERAND (t, 0);
1680e4b17023SJohn Marino 
1681e4b17023SJohn Marino       /* Note whether this expression can trap.  */
1682e4b17023SJohn Marino       MEM_NOTRAP_P (ref) = !tree_could_trap_p (t);
1683e4b17023SJohn Marino 
1684e4b17023SJohn Marino       base = get_base_address (t);
1685e4b17023SJohn Marino       if (base)
1686e4b17023SJohn Marino 	{
1687e4b17023SJohn Marino 	  if (DECL_P (base)
1688e4b17023SJohn Marino 	      && TREE_READONLY (base)
1689e4b17023SJohn Marino 	      && (TREE_STATIC (base) || DECL_EXTERNAL (base))
1690e4b17023SJohn Marino 	      && !TREE_THIS_VOLATILE (base))
1691e4b17023SJohn Marino 	    MEM_READONLY_P (ref) = 1;
1692e4b17023SJohn Marino 
1693e4b17023SJohn Marino 	  /* Mark static const strings readonly as well.  */
1694e4b17023SJohn Marino 	  if (TREE_CODE (base) == STRING_CST
1695e4b17023SJohn Marino 	      && TREE_READONLY (base)
1696e4b17023SJohn Marino 	      && TREE_STATIC (base))
1697e4b17023SJohn Marino 	    MEM_READONLY_P (ref) = 1;
1698e4b17023SJohn Marino 
1699e4b17023SJohn Marino 	  if (TREE_CODE (base) == MEM_REF
1700e4b17023SJohn Marino 	      || TREE_CODE (base) == TARGET_MEM_REF)
1701e4b17023SJohn Marino 	    as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (base,
1702e4b17023SJohn Marino 								      0))));
1703e4b17023SJohn Marino 	  else
1704e4b17023SJohn Marino 	    as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1705e4b17023SJohn Marino 	}
1706e4b17023SJohn Marino       else
1707e4b17023SJohn Marino 	as = TYPE_ADDR_SPACE (type);
1708e4b17023SJohn Marino 
1709e4b17023SJohn Marino       /* If this expression uses it's parent's alias set, mark it such
1710e4b17023SJohn Marino 	 that we won't change it.  */
1711e4b17023SJohn Marino       if (component_uses_parent_alias_set (t))
1712e4b17023SJohn Marino 	MEM_KEEP_ALIAS_SET_P (ref) = 1;
1713e4b17023SJohn Marino 
1714e4b17023SJohn Marino       /* If this is a decl, set the attributes of the MEM from it.  */
1715e4b17023SJohn Marino       if (DECL_P (t))
1716e4b17023SJohn Marino 	{
1717e4b17023SJohn Marino 	  attrs.expr = t;
1718e4b17023SJohn Marino 	  attrs.offset_known_p = true;
1719e4b17023SJohn Marino 	  attrs.offset = 0;
1720e4b17023SJohn Marino 	  apply_bitpos = bitpos;
1721e4b17023SJohn Marino 	  if (DECL_SIZE_UNIT (t) && host_integerp (DECL_SIZE_UNIT (t), 1))
1722e4b17023SJohn Marino 	    {
1723e4b17023SJohn Marino 	      attrs.size_known_p = true;
1724e4b17023SJohn Marino 	      attrs.size = tree_low_cst (DECL_SIZE_UNIT (t), 1);
1725e4b17023SJohn Marino 	    }
1726e4b17023SJohn Marino 	  else
1727e4b17023SJohn Marino 	    attrs.size_known_p = false;
1728e4b17023SJohn Marino 	  attrs.align = DECL_ALIGN (t);
1729e4b17023SJohn Marino 	  align_computed = true;
1730e4b17023SJohn Marino 	}
1731e4b17023SJohn Marino 
1732e4b17023SJohn Marino       /* If this is a constant, we know the alignment.  */
1733e4b17023SJohn Marino       else if (CONSTANT_CLASS_P (t))
1734e4b17023SJohn Marino 	{
1735e4b17023SJohn Marino 	  attrs.align = TYPE_ALIGN (type);
1736e4b17023SJohn Marino #ifdef CONSTANT_ALIGNMENT
1737e4b17023SJohn Marino 	  attrs.align = CONSTANT_ALIGNMENT (t, attrs.align);
1738e4b17023SJohn Marino #endif
1739e4b17023SJohn Marino 	  align_computed = true;
1740e4b17023SJohn Marino 	}
1741e4b17023SJohn Marino 
1742e4b17023SJohn Marino       /* If this is a field reference and not a bit-field, record it.  */
1743e4b17023SJohn Marino       /* ??? There is some information that can be gleaned from bit-fields,
1744e4b17023SJohn Marino 	 such as the word offset in the structure that might be modified.
1745e4b17023SJohn Marino 	 But skip it for now.  */
1746e4b17023SJohn Marino       else if (TREE_CODE (t) == COMPONENT_REF
1747e4b17023SJohn Marino 	       && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
1748e4b17023SJohn Marino 	{
1749e4b17023SJohn Marino 	  attrs.expr = t;
1750e4b17023SJohn Marino 	  attrs.offset_known_p = true;
1751e4b17023SJohn Marino 	  attrs.offset = 0;
1752e4b17023SJohn Marino 	  apply_bitpos = bitpos;
1753e4b17023SJohn Marino 	  /* ??? Any reason the field size would be different than
1754e4b17023SJohn Marino 	     the size we got from the type?  */
1755e4b17023SJohn Marino 	}
1756e4b17023SJohn Marino 
1757e4b17023SJohn Marino       /* If this is an array reference, look for an outer field reference.  */
1758e4b17023SJohn Marino       else if (TREE_CODE (t) == ARRAY_REF)
1759e4b17023SJohn Marino 	{
1760e4b17023SJohn Marino 	  tree off_tree = size_zero_node;
1761e4b17023SJohn Marino 	  /* We can't modify t, because we use it at the end of the
1762e4b17023SJohn Marino 	     function.  */
1763e4b17023SJohn Marino 	  tree t2 = t;
1764e4b17023SJohn Marino 
1765e4b17023SJohn Marino 	  do
1766e4b17023SJohn Marino 	    {
1767e4b17023SJohn Marino 	      tree index = TREE_OPERAND (t2, 1);
1768e4b17023SJohn Marino 	      tree low_bound = array_ref_low_bound (t2);
1769e4b17023SJohn Marino 	      tree unit_size = array_ref_element_size (t2);
1770e4b17023SJohn Marino 
1771e4b17023SJohn Marino 	      /* We assume all arrays have sizes that are a multiple of a byte.
1772e4b17023SJohn Marino 		 First subtract the lower bound, if any, in the type of the
1773e4b17023SJohn Marino 		 index, then convert to sizetype and multiply by the size of
1774e4b17023SJohn Marino 		 the array element.  */
1775e4b17023SJohn Marino 	      if (! integer_zerop (low_bound))
1776e4b17023SJohn Marino 		index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
1777e4b17023SJohn Marino 				     index, low_bound);
1778e4b17023SJohn Marino 
1779e4b17023SJohn Marino 	      off_tree = size_binop (PLUS_EXPR,
1780e4b17023SJohn Marino 				     size_binop (MULT_EXPR,
1781e4b17023SJohn Marino 						 fold_convert (sizetype,
1782e4b17023SJohn Marino 							       index),
1783e4b17023SJohn Marino 						 unit_size),
1784e4b17023SJohn Marino 				     off_tree);
1785e4b17023SJohn Marino 	      t2 = TREE_OPERAND (t2, 0);
1786e4b17023SJohn Marino 	    }
1787e4b17023SJohn Marino 	  while (TREE_CODE (t2) == ARRAY_REF);
1788e4b17023SJohn Marino 
1789e4b17023SJohn Marino 	  if (DECL_P (t2))
1790e4b17023SJohn Marino 	    {
1791e4b17023SJohn Marino 	      attrs.expr = t2;
1792e4b17023SJohn Marino 	      attrs.offset_known_p = false;
1793e4b17023SJohn Marino 	      if (host_integerp (off_tree, 1))
1794e4b17023SJohn Marino 		{
1795e4b17023SJohn Marino 		  HOST_WIDE_INT ioff = tree_low_cst (off_tree, 1);
1796e4b17023SJohn Marino 		  HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT;
1797e4b17023SJohn Marino 		  attrs.align = DECL_ALIGN (t2);
1798e4b17023SJohn Marino 		  if (aoff && (unsigned HOST_WIDE_INT) aoff < attrs.align)
1799e4b17023SJohn Marino 	            attrs.align = aoff;
1800e4b17023SJohn Marino 		  align_computed = true;
1801e4b17023SJohn Marino 		  attrs.offset_known_p = true;
1802e4b17023SJohn Marino 		  attrs.offset = ioff;
1803e4b17023SJohn Marino 		  apply_bitpos = bitpos;
1804e4b17023SJohn Marino 		}
1805e4b17023SJohn Marino 	    }
1806e4b17023SJohn Marino 	  else if (TREE_CODE (t2) == COMPONENT_REF)
1807e4b17023SJohn Marino 	    {
1808e4b17023SJohn Marino 	      attrs.expr = t2;
1809e4b17023SJohn Marino 	      attrs.offset_known_p = false;
1810e4b17023SJohn Marino 	      if (host_integerp (off_tree, 1))
1811e4b17023SJohn Marino 		{
1812e4b17023SJohn Marino 		  attrs.offset_known_p = true;
1813e4b17023SJohn Marino 		  attrs.offset = tree_low_cst (off_tree, 1);
1814e4b17023SJohn Marino 		  apply_bitpos = bitpos;
1815e4b17023SJohn Marino 		}
1816e4b17023SJohn Marino 	      /* ??? Any reason the field size would be different than
1817e4b17023SJohn Marino 		 the size we got from the type?  */
1818e4b17023SJohn Marino 	    }
1819e4b17023SJohn Marino 
1820e4b17023SJohn Marino 	  /* If this is an indirect reference, record it.  */
1821e4b17023SJohn Marino 	  else if (TREE_CODE (t) == MEM_REF)
1822e4b17023SJohn Marino 	    {
1823e4b17023SJohn Marino 	      attrs.expr = t;
1824e4b17023SJohn Marino 	      attrs.offset_known_p = true;
1825e4b17023SJohn Marino 	      attrs.offset = 0;
1826e4b17023SJohn Marino 	      apply_bitpos = bitpos;
1827e4b17023SJohn Marino 	    }
1828e4b17023SJohn Marino 	}
1829e4b17023SJohn Marino 
1830e4b17023SJohn Marino       /* If this is an indirect reference, record it.  */
1831e4b17023SJohn Marino       else if (TREE_CODE (t) == MEM_REF
1832e4b17023SJohn Marino 	       || TREE_CODE (t) == TARGET_MEM_REF)
1833e4b17023SJohn Marino 	{
1834e4b17023SJohn Marino 	  attrs.expr = t;
1835e4b17023SJohn Marino 	  attrs.offset_known_p = true;
1836e4b17023SJohn Marino 	  attrs.offset = 0;
1837e4b17023SJohn Marino 	  apply_bitpos = bitpos;
1838e4b17023SJohn Marino 	}
1839e4b17023SJohn Marino 
1840e4b17023SJohn Marino       if (!align_computed)
1841e4b17023SJohn Marino 	{
1842*5ce9237cSJohn Marino 	  unsigned int obj_align;
1843*5ce9237cSJohn Marino 	  unsigned HOST_WIDE_INT obj_bitpos;
1844*5ce9237cSJohn Marino 	  obj_align = get_object_alignment_1 (t, &obj_bitpos);
1845*5ce9237cSJohn Marino 	  obj_bitpos = (obj_bitpos - bitpos) & (obj_align - 1);
1846*5ce9237cSJohn Marino 	  if (obj_bitpos != 0)
1847*5ce9237cSJohn Marino 	    obj_align = (obj_bitpos & -obj_bitpos);
1848e4b17023SJohn Marino 	  attrs.align = MAX (attrs.align, obj_align);
1849e4b17023SJohn Marino 	}
1850e4b17023SJohn Marino     }
1851e4b17023SJohn Marino   else
1852e4b17023SJohn Marino     as = TYPE_ADDR_SPACE (type);
1853e4b17023SJohn Marino 
1854e4b17023SJohn Marino   /* If we modified OFFSET based on T, then subtract the outstanding
1855e4b17023SJohn Marino      bit position offset.  Similarly, increase the size of the accessed
1856e4b17023SJohn Marino      object to contain the negative offset.  */
1857e4b17023SJohn Marino   if (apply_bitpos)
1858e4b17023SJohn Marino     {
1859e4b17023SJohn Marino       gcc_assert (attrs.offset_known_p);
1860e4b17023SJohn Marino       attrs.offset -= apply_bitpos / BITS_PER_UNIT;
1861e4b17023SJohn Marino       if (attrs.size_known_p)
1862e4b17023SJohn Marino 	attrs.size += apply_bitpos / BITS_PER_UNIT;
1863e4b17023SJohn Marino     }
1864e4b17023SJohn Marino 
1865e4b17023SJohn Marino   /* Now set the attributes we computed above.  */
1866e4b17023SJohn Marino   attrs.addrspace = as;
1867e4b17023SJohn Marino   set_mem_attrs (ref, &attrs);
1868e4b17023SJohn Marino }
1869e4b17023SJohn Marino 
1870e4b17023SJohn Marino void
set_mem_attributes(rtx ref,tree t,int objectp)1871e4b17023SJohn Marino set_mem_attributes (rtx ref, tree t, int objectp)
1872e4b17023SJohn Marino {
1873e4b17023SJohn Marino   set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
1874e4b17023SJohn Marino }
1875e4b17023SJohn Marino 
1876e4b17023SJohn Marino /* Set the alias set of MEM to SET.  */
1877e4b17023SJohn Marino 
1878e4b17023SJohn Marino void
set_mem_alias_set(rtx mem,alias_set_type set)1879e4b17023SJohn Marino set_mem_alias_set (rtx mem, alias_set_type set)
1880e4b17023SJohn Marino {
1881e4b17023SJohn Marino   struct mem_attrs attrs;
1882e4b17023SJohn Marino 
1883e4b17023SJohn Marino   /* If the new and old alias sets don't conflict, something is wrong.  */
1884e4b17023SJohn Marino   gcc_checking_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
1885e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1886e4b17023SJohn Marino   attrs.alias = set;
1887e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1888e4b17023SJohn Marino }
1889e4b17023SJohn Marino 
1890e4b17023SJohn Marino /* Set the address space of MEM to ADDRSPACE (target-defined).  */
1891e4b17023SJohn Marino 
1892e4b17023SJohn Marino void
set_mem_addr_space(rtx mem,addr_space_t addrspace)1893e4b17023SJohn Marino set_mem_addr_space (rtx mem, addr_space_t addrspace)
1894e4b17023SJohn Marino {
1895e4b17023SJohn Marino   struct mem_attrs attrs;
1896e4b17023SJohn Marino 
1897e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1898e4b17023SJohn Marino   attrs.addrspace = addrspace;
1899e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1900e4b17023SJohn Marino }
1901e4b17023SJohn Marino 
1902e4b17023SJohn Marino /* Set the alignment of MEM to ALIGN bits.  */
1903e4b17023SJohn Marino 
1904e4b17023SJohn Marino void
set_mem_align(rtx mem,unsigned int align)1905e4b17023SJohn Marino set_mem_align (rtx mem, unsigned int align)
1906e4b17023SJohn Marino {
1907e4b17023SJohn Marino   struct mem_attrs attrs;
1908e4b17023SJohn Marino 
1909e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1910e4b17023SJohn Marino   attrs.align = align;
1911e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1912e4b17023SJohn Marino }
1913e4b17023SJohn Marino 
1914e4b17023SJohn Marino /* Set the expr for MEM to EXPR.  */
1915e4b17023SJohn Marino 
1916e4b17023SJohn Marino void
set_mem_expr(rtx mem,tree expr)1917e4b17023SJohn Marino set_mem_expr (rtx mem, tree expr)
1918e4b17023SJohn Marino {
1919e4b17023SJohn Marino   struct mem_attrs attrs;
1920e4b17023SJohn Marino 
1921e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1922e4b17023SJohn Marino   attrs.expr = expr;
1923e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1924e4b17023SJohn Marino }
1925e4b17023SJohn Marino 
1926e4b17023SJohn Marino /* Set the offset of MEM to OFFSET.  */
1927e4b17023SJohn Marino 
1928e4b17023SJohn Marino void
set_mem_offset(rtx mem,HOST_WIDE_INT offset)1929e4b17023SJohn Marino set_mem_offset (rtx mem, HOST_WIDE_INT offset)
1930e4b17023SJohn Marino {
1931e4b17023SJohn Marino   struct mem_attrs attrs;
1932e4b17023SJohn Marino 
1933e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1934e4b17023SJohn Marino   attrs.offset_known_p = true;
1935e4b17023SJohn Marino   attrs.offset = offset;
1936e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1937e4b17023SJohn Marino }
1938e4b17023SJohn Marino 
1939e4b17023SJohn Marino /* Clear the offset of MEM.  */
1940e4b17023SJohn Marino 
1941e4b17023SJohn Marino void
clear_mem_offset(rtx mem)1942e4b17023SJohn Marino clear_mem_offset (rtx mem)
1943e4b17023SJohn Marino {
1944e4b17023SJohn Marino   struct mem_attrs attrs;
1945e4b17023SJohn Marino 
1946e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1947e4b17023SJohn Marino   attrs.offset_known_p = false;
1948e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1949e4b17023SJohn Marino }
1950e4b17023SJohn Marino 
1951e4b17023SJohn Marino /* Set the size of MEM to SIZE.  */
1952e4b17023SJohn Marino 
1953e4b17023SJohn Marino void
set_mem_size(rtx mem,HOST_WIDE_INT size)1954e4b17023SJohn Marino set_mem_size (rtx mem, HOST_WIDE_INT size)
1955e4b17023SJohn Marino {
1956e4b17023SJohn Marino   struct mem_attrs attrs;
1957e4b17023SJohn Marino 
1958e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1959e4b17023SJohn Marino   attrs.size_known_p = true;
1960e4b17023SJohn Marino   attrs.size = size;
1961e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1962e4b17023SJohn Marino }
1963e4b17023SJohn Marino 
1964e4b17023SJohn Marino /* Clear the size of MEM.  */
1965e4b17023SJohn Marino 
1966e4b17023SJohn Marino void
clear_mem_size(rtx mem)1967e4b17023SJohn Marino clear_mem_size (rtx mem)
1968e4b17023SJohn Marino {
1969e4b17023SJohn Marino   struct mem_attrs attrs;
1970e4b17023SJohn Marino 
1971e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
1972e4b17023SJohn Marino   attrs.size_known_p = false;
1973e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
1974e4b17023SJohn Marino }
1975e4b17023SJohn Marino 
1976e4b17023SJohn Marino /* Return a memory reference like MEMREF, but with its mode changed to MODE
1977e4b17023SJohn Marino    and its address changed to ADDR.  (VOIDmode means don't change the mode.
1978e4b17023SJohn Marino    NULL for ADDR means don't change the address.)  VALIDATE is nonzero if the
1979e4b17023SJohn Marino    returned memory location is required to be valid.  The memory
1980e4b17023SJohn Marino    attributes are not changed.  */
1981e4b17023SJohn Marino 
1982e4b17023SJohn Marino static rtx
change_address_1(rtx memref,enum machine_mode mode,rtx addr,int validate)1983e4b17023SJohn Marino change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
1984e4b17023SJohn Marino {
1985e4b17023SJohn Marino   addr_space_t as;
1986e4b17023SJohn Marino   rtx new_rtx;
1987e4b17023SJohn Marino 
1988e4b17023SJohn Marino   gcc_assert (MEM_P (memref));
1989e4b17023SJohn Marino   as = MEM_ADDR_SPACE (memref);
1990e4b17023SJohn Marino   if (mode == VOIDmode)
1991e4b17023SJohn Marino     mode = GET_MODE (memref);
1992e4b17023SJohn Marino   if (addr == 0)
1993e4b17023SJohn Marino     addr = XEXP (memref, 0);
1994e4b17023SJohn Marino   if (mode == GET_MODE (memref) && addr == XEXP (memref, 0)
1995e4b17023SJohn Marino       && (!validate || memory_address_addr_space_p (mode, addr, as)))
1996e4b17023SJohn Marino     return memref;
1997e4b17023SJohn Marino 
1998e4b17023SJohn Marino   if (validate)
1999e4b17023SJohn Marino     {
2000e4b17023SJohn Marino       if (reload_in_progress || reload_completed)
2001e4b17023SJohn Marino 	gcc_assert (memory_address_addr_space_p (mode, addr, as));
2002e4b17023SJohn Marino       else
2003e4b17023SJohn Marino 	addr = memory_address_addr_space (mode, addr, as);
2004e4b17023SJohn Marino     }
2005e4b17023SJohn Marino 
2006e4b17023SJohn Marino   if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
2007e4b17023SJohn Marino     return memref;
2008e4b17023SJohn Marino 
2009e4b17023SJohn Marino   new_rtx = gen_rtx_MEM (mode, addr);
2010e4b17023SJohn Marino   MEM_COPY_ATTRIBUTES (new_rtx, memref);
2011e4b17023SJohn Marino   return new_rtx;
2012e4b17023SJohn Marino }
2013e4b17023SJohn Marino 
2014e4b17023SJohn Marino /* Like change_address_1 with VALIDATE nonzero, but we are not saying in what
2015e4b17023SJohn Marino    way we are changing MEMREF, so we only preserve the alias set.  */
2016e4b17023SJohn Marino 
2017e4b17023SJohn Marino rtx
change_address(rtx memref,enum machine_mode mode,rtx addr)2018e4b17023SJohn Marino change_address (rtx memref, enum machine_mode mode, rtx addr)
2019e4b17023SJohn Marino {
2020e4b17023SJohn Marino   rtx new_rtx = change_address_1 (memref, mode, addr, 1);
2021e4b17023SJohn Marino   enum machine_mode mmode = GET_MODE (new_rtx);
2022e4b17023SJohn Marino   struct mem_attrs attrs, *defattrs;
2023e4b17023SJohn Marino 
2024e4b17023SJohn Marino   attrs = *get_mem_attrs (memref);
2025e4b17023SJohn Marino   defattrs = mode_mem_attrs[(int) mmode];
2026e4b17023SJohn Marino   attrs.expr = NULL_TREE;
2027e4b17023SJohn Marino   attrs.offset_known_p = false;
2028e4b17023SJohn Marino   attrs.size_known_p = defattrs->size_known_p;
2029e4b17023SJohn Marino   attrs.size = defattrs->size;
2030e4b17023SJohn Marino   attrs.align = defattrs->align;
2031e4b17023SJohn Marino 
2032e4b17023SJohn Marino   /* If there are no changes, just return the original memory reference.  */
2033e4b17023SJohn Marino   if (new_rtx == memref)
2034e4b17023SJohn Marino     {
2035e4b17023SJohn Marino       if (mem_attrs_eq_p (get_mem_attrs (memref), &attrs))
2036e4b17023SJohn Marino 	return new_rtx;
2037e4b17023SJohn Marino 
2038e4b17023SJohn Marino       new_rtx = gen_rtx_MEM (mmode, XEXP (memref, 0));
2039e4b17023SJohn Marino       MEM_COPY_ATTRIBUTES (new_rtx, memref);
2040e4b17023SJohn Marino     }
2041e4b17023SJohn Marino 
2042e4b17023SJohn Marino   set_mem_attrs (new_rtx, &attrs);
2043e4b17023SJohn Marino   return new_rtx;
2044e4b17023SJohn Marino }
2045e4b17023SJohn Marino 
2046e4b17023SJohn Marino /* Return a memory reference like MEMREF, but with its mode changed
2047e4b17023SJohn Marino    to MODE and its address offset by OFFSET bytes.  If VALIDATE is
2048e4b17023SJohn Marino    nonzero, the memory address is forced to be valid.
2049e4b17023SJohn Marino    If ADJUST is zero, OFFSET is only used to update MEM_ATTRS
2050e4b17023SJohn Marino    and caller is responsible for adjusting MEMREF base register.  */
2051e4b17023SJohn Marino 
2052e4b17023SJohn Marino rtx
adjust_address_1(rtx memref,enum machine_mode mode,HOST_WIDE_INT offset,int validate,int adjust)2053e4b17023SJohn Marino adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
2054e4b17023SJohn Marino 		  int validate, int adjust)
2055e4b17023SJohn Marino {
2056e4b17023SJohn Marino   rtx addr = XEXP (memref, 0);
2057e4b17023SJohn Marino   rtx new_rtx;
2058e4b17023SJohn Marino   enum machine_mode address_mode;
2059e4b17023SJohn Marino   int pbits;
2060e4b17023SJohn Marino   struct mem_attrs attrs, *defattrs;
2061e4b17023SJohn Marino   unsigned HOST_WIDE_INT max_align;
2062e4b17023SJohn Marino 
2063e4b17023SJohn Marino   attrs = *get_mem_attrs (memref);
2064e4b17023SJohn Marino 
2065e4b17023SJohn Marino   /* If there are no changes, just return the original memory reference.  */
2066e4b17023SJohn Marino   if (mode == GET_MODE (memref) && !offset
2067e4b17023SJohn Marino       && (!validate || memory_address_addr_space_p (mode, addr,
2068e4b17023SJohn Marino 						    attrs.addrspace)))
2069e4b17023SJohn Marino     return memref;
2070e4b17023SJohn Marino 
2071e4b17023SJohn Marino   /* ??? Prefer to create garbage instead of creating shared rtl.
2072e4b17023SJohn Marino      This may happen even if offset is nonzero -- consider
2073e4b17023SJohn Marino      (plus (plus reg reg) const_int) -- so do this always.  */
2074e4b17023SJohn Marino   addr = copy_rtx (addr);
2075e4b17023SJohn Marino 
2076e4b17023SJohn Marino   /* Convert a possibly large offset to a signed value within the
2077e4b17023SJohn Marino      range of the target address space.  */
2078e4b17023SJohn Marino   address_mode = targetm.addr_space.address_mode (attrs.addrspace);
2079e4b17023SJohn Marino   pbits = GET_MODE_BITSIZE (address_mode);
2080e4b17023SJohn Marino   if (HOST_BITS_PER_WIDE_INT > pbits)
2081e4b17023SJohn Marino     {
2082e4b17023SJohn Marino       int shift = HOST_BITS_PER_WIDE_INT - pbits;
2083e4b17023SJohn Marino       offset = (((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) offset << shift))
2084e4b17023SJohn Marino 		>> shift);
2085e4b17023SJohn Marino     }
2086e4b17023SJohn Marino 
2087e4b17023SJohn Marino   if (adjust)
2088e4b17023SJohn Marino     {
2089e4b17023SJohn Marino       /* If MEMREF is a LO_SUM and the offset is within the alignment of the
2090e4b17023SJohn Marino 	 object, we can merge it into the LO_SUM.  */
2091e4b17023SJohn Marino       if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM
2092e4b17023SJohn Marino 	  && offset >= 0
2093e4b17023SJohn Marino 	  && (unsigned HOST_WIDE_INT) offset
2094e4b17023SJohn Marino 	      < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
2095e4b17023SJohn Marino 	addr = gen_rtx_LO_SUM (address_mode, XEXP (addr, 0),
2096e4b17023SJohn Marino 			       plus_constant (XEXP (addr, 1), offset));
2097e4b17023SJohn Marino       else
2098e4b17023SJohn Marino 	addr = plus_constant (addr, offset);
2099e4b17023SJohn Marino     }
2100e4b17023SJohn Marino 
2101e4b17023SJohn Marino   new_rtx = change_address_1 (memref, mode, addr, validate);
2102e4b17023SJohn Marino 
2103e4b17023SJohn Marino   /* If the address is a REG, change_address_1 rightfully returns memref,
2104e4b17023SJohn Marino      but this would destroy memref's MEM_ATTRS.  */
2105e4b17023SJohn Marino   if (new_rtx == memref && offset != 0)
2106e4b17023SJohn Marino     new_rtx = copy_rtx (new_rtx);
2107e4b17023SJohn Marino 
2108e4b17023SJohn Marino   /* Compute the new values of the memory attributes due to this adjustment.
2109e4b17023SJohn Marino      We add the offsets and update the alignment.  */
2110e4b17023SJohn Marino   if (attrs.offset_known_p)
2111e4b17023SJohn Marino     attrs.offset += offset;
2112e4b17023SJohn Marino 
2113e4b17023SJohn Marino   /* Compute the new alignment by taking the MIN of the alignment and the
2114e4b17023SJohn Marino      lowest-order set bit in OFFSET, but don't change the alignment if OFFSET
2115e4b17023SJohn Marino      if zero.  */
2116e4b17023SJohn Marino   if (offset != 0)
2117e4b17023SJohn Marino     {
2118e4b17023SJohn Marino       max_align = (offset & -offset) * BITS_PER_UNIT;
2119e4b17023SJohn Marino       attrs.align = MIN (attrs.align, max_align);
2120e4b17023SJohn Marino     }
2121e4b17023SJohn Marino 
2122e4b17023SJohn Marino   /* We can compute the size in a number of ways.  */
2123e4b17023SJohn Marino   defattrs = mode_mem_attrs[(int) GET_MODE (new_rtx)];
2124e4b17023SJohn Marino   if (defattrs->size_known_p)
2125e4b17023SJohn Marino     {
2126e4b17023SJohn Marino       attrs.size_known_p = true;
2127e4b17023SJohn Marino       attrs.size = defattrs->size;
2128e4b17023SJohn Marino     }
2129e4b17023SJohn Marino   else if (attrs.size_known_p)
2130e4b17023SJohn Marino     attrs.size -= offset;
2131e4b17023SJohn Marino 
2132e4b17023SJohn Marino   set_mem_attrs (new_rtx, &attrs);
2133e4b17023SJohn Marino 
2134e4b17023SJohn Marino   /* At some point, we should validate that this offset is within the object,
2135e4b17023SJohn Marino      if all the appropriate values are known.  */
2136e4b17023SJohn Marino   return new_rtx;
2137e4b17023SJohn Marino }
2138e4b17023SJohn Marino 
2139e4b17023SJohn Marino /* Return a memory reference like MEMREF, but with its mode changed
2140e4b17023SJohn Marino    to MODE and its address changed to ADDR, which is assumed to be
2141e4b17023SJohn Marino    MEMREF offset by OFFSET bytes.  If VALIDATE is
2142e4b17023SJohn Marino    nonzero, the memory address is forced to be valid.  */
2143e4b17023SJohn Marino 
2144e4b17023SJohn Marino rtx
adjust_automodify_address_1(rtx memref,enum machine_mode mode,rtx addr,HOST_WIDE_INT offset,int validate)2145e4b17023SJohn Marino adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
2146e4b17023SJohn Marino 			     HOST_WIDE_INT offset, int validate)
2147e4b17023SJohn Marino {
2148e4b17023SJohn Marino   memref = change_address_1 (memref, VOIDmode, addr, validate);
2149e4b17023SJohn Marino   return adjust_address_1 (memref, mode, offset, validate, 0);
2150e4b17023SJohn Marino }
2151e4b17023SJohn Marino 
2152e4b17023SJohn Marino /* Return a memory reference like MEMREF, but whose address is changed by
2153e4b17023SJohn Marino    adding OFFSET, an RTX, to it.  POW2 is the highest power of two factor
2154e4b17023SJohn Marino    known to be in OFFSET (possibly 1).  */
2155e4b17023SJohn Marino 
2156e4b17023SJohn Marino rtx
offset_address(rtx memref,rtx offset,unsigned HOST_WIDE_INT pow2)2157e4b17023SJohn Marino offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
2158e4b17023SJohn Marino {
2159e4b17023SJohn Marino   rtx new_rtx, addr = XEXP (memref, 0);
2160e4b17023SJohn Marino   enum machine_mode address_mode;
2161e4b17023SJohn Marino   struct mem_attrs attrs, *defattrs;
2162e4b17023SJohn Marino 
2163e4b17023SJohn Marino   attrs = *get_mem_attrs (memref);
2164e4b17023SJohn Marino   address_mode = targetm.addr_space.address_mode (attrs.addrspace);
2165e4b17023SJohn Marino   new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
2166e4b17023SJohn Marino 
2167e4b17023SJohn Marino   /* At this point we don't know _why_ the address is invalid.  It
2168e4b17023SJohn Marino      could have secondary memory references, multiplies or anything.
2169e4b17023SJohn Marino 
2170e4b17023SJohn Marino      However, if we did go and rearrange things, we can wind up not
2171e4b17023SJohn Marino      being able to recognize the magic around pic_offset_table_rtx.
2172e4b17023SJohn Marino      This stuff is fragile, and is yet another example of why it is
2173e4b17023SJohn Marino      bad to expose PIC machinery too early.  */
2174e4b17023SJohn Marino   if (! memory_address_addr_space_p (GET_MODE (memref), new_rtx,
2175e4b17023SJohn Marino 				     attrs.addrspace)
2176e4b17023SJohn Marino       && GET_CODE (addr) == PLUS
2177e4b17023SJohn Marino       && XEXP (addr, 0) == pic_offset_table_rtx)
2178e4b17023SJohn Marino     {
2179e4b17023SJohn Marino       addr = force_reg (GET_MODE (addr), addr);
2180e4b17023SJohn Marino       new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
2181e4b17023SJohn Marino     }
2182e4b17023SJohn Marino 
2183e4b17023SJohn Marino   update_temp_slot_address (XEXP (memref, 0), new_rtx);
2184e4b17023SJohn Marino   new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1);
2185e4b17023SJohn Marino 
2186e4b17023SJohn Marino   /* If there are no changes, just return the original memory reference.  */
2187e4b17023SJohn Marino   if (new_rtx == memref)
2188e4b17023SJohn Marino     return new_rtx;
2189e4b17023SJohn Marino 
2190e4b17023SJohn Marino   /* Update the alignment to reflect the offset.  Reset the offset, which
2191e4b17023SJohn Marino      we don't know.  */
2192e4b17023SJohn Marino   defattrs = mode_mem_attrs[(int) GET_MODE (new_rtx)];
2193e4b17023SJohn Marino   attrs.offset_known_p = false;
2194e4b17023SJohn Marino   attrs.size_known_p = defattrs->size_known_p;
2195e4b17023SJohn Marino   attrs.size = defattrs->size;
2196e4b17023SJohn Marino   attrs.align = MIN (attrs.align, pow2 * BITS_PER_UNIT);
2197e4b17023SJohn Marino   set_mem_attrs (new_rtx, &attrs);
2198e4b17023SJohn Marino   return new_rtx;
2199e4b17023SJohn Marino }
2200e4b17023SJohn Marino 
2201e4b17023SJohn Marino /* Return a memory reference like MEMREF, but with its address changed to
2202e4b17023SJohn Marino    ADDR.  The caller is asserting that the actual piece of memory pointed
2203e4b17023SJohn Marino    to is the same, just the form of the address is being changed, such as
2204e4b17023SJohn Marino    by putting something into a register.  */
2205e4b17023SJohn Marino 
2206e4b17023SJohn Marino rtx
replace_equiv_address(rtx memref,rtx addr)2207e4b17023SJohn Marino replace_equiv_address (rtx memref, rtx addr)
2208e4b17023SJohn Marino {
2209e4b17023SJohn Marino   /* change_address_1 copies the memory attribute structure without change
2210e4b17023SJohn Marino      and that's exactly what we want here.  */
2211e4b17023SJohn Marino   update_temp_slot_address (XEXP (memref, 0), addr);
2212e4b17023SJohn Marino   return change_address_1 (memref, VOIDmode, addr, 1);
2213e4b17023SJohn Marino }
2214e4b17023SJohn Marino 
2215e4b17023SJohn Marino /* Likewise, but the reference is not required to be valid.  */
2216e4b17023SJohn Marino 
2217e4b17023SJohn Marino rtx
replace_equiv_address_nv(rtx memref,rtx addr)2218e4b17023SJohn Marino replace_equiv_address_nv (rtx memref, rtx addr)
2219e4b17023SJohn Marino {
2220e4b17023SJohn Marino   return change_address_1 (memref, VOIDmode, addr, 0);
2221e4b17023SJohn Marino }
2222e4b17023SJohn Marino 
2223e4b17023SJohn Marino /* Return a memory reference like MEMREF, but with its mode widened to
2224e4b17023SJohn Marino    MODE and offset by OFFSET.  This would be used by targets that e.g.
2225e4b17023SJohn Marino    cannot issue QImode memory operations and have to use SImode memory
2226e4b17023SJohn Marino    operations plus masking logic.  */
2227e4b17023SJohn Marino 
2228e4b17023SJohn Marino rtx
widen_memory_access(rtx memref,enum machine_mode mode,HOST_WIDE_INT offset)2229e4b17023SJohn Marino widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
2230e4b17023SJohn Marino {
2231e4b17023SJohn Marino   rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1);
2232e4b17023SJohn Marino   struct mem_attrs attrs;
2233e4b17023SJohn Marino   unsigned int size = GET_MODE_SIZE (mode);
2234e4b17023SJohn Marino 
2235e4b17023SJohn Marino   /* If there are no changes, just return the original memory reference.  */
2236e4b17023SJohn Marino   if (new_rtx == memref)
2237e4b17023SJohn Marino     return new_rtx;
2238e4b17023SJohn Marino 
2239e4b17023SJohn Marino   attrs = *get_mem_attrs (new_rtx);
2240e4b17023SJohn Marino 
2241e4b17023SJohn Marino   /* If we don't know what offset we were at within the expression, then
2242e4b17023SJohn Marino      we can't know if we've overstepped the bounds.  */
2243e4b17023SJohn Marino   if (! attrs.offset_known_p)
2244e4b17023SJohn Marino     attrs.expr = NULL_TREE;
2245e4b17023SJohn Marino 
2246e4b17023SJohn Marino   while (attrs.expr)
2247e4b17023SJohn Marino     {
2248e4b17023SJohn Marino       if (TREE_CODE (attrs.expr) == COMPONENT_REF)
2249e4b17023SJohn Marino 	{
2250e4b17023SJohn Marino 	  tree field = TREE_OPERAND (attrs.expr, 1);
2251e4b17023SJohn Marino 	  tree offset = component_ref_field_offset (attrs.expr);
2252e4b17023SJohn Marino 
2253e4b17023SJohn Marino 	  if (! DECL_SIZE_UNIT (field))
2254e4b17023SJohn Marino 	    {
2255e4b17023SJohn Marino 	      attrs.expr = NULL_TREE;
2256e4b17023SJohn Marino 	      break;
2257e4b17023SJohn Marino 	    }
2258e4b17023SJohn Marino 
2259e4b17023SJohn Marino 	  /* Is the field at least as large as the access?  If so, ok,
2260e4b17023SJohn Marino 	     otherwise strip back to the containing structure.  */
2261e4b17023SJohn Marino 	  if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST
2262e4b17023SJohn Marino 	      && compare_tree_int (DECL_SIZE_UNIT (field), size) >= 0
2263e4b17023SJohn Marino 	      && attrs.offset >= 0)
2264e4b17023SJohn Marino 	    break;
2265e4b17023SJohn Marino 
2266e4b17023SJohn Marino 	  if (! host_integerp (offset, 1))
2267e4b17023SJohn Marino 	    {
2268e4b17023SJohn Marino 	      attrs.expr = NULL_TREE;
2269e4b17023SJohn Marino 	      break;
2270e4b17023SJohn Marino 	    }
2271e4b17023SJohn Marino 
2272e4b17023SJohn Marino 	  attrs.expr = TREE_OPERAND (attrs.expr, 0);
2273e4b17023SJohn Marino 	  attrs.offset += tree_low_cst (offset, 1);
2274e4b17023SJohn Marino 	  attrs.offset += (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
2275e4b17023SJohn Marino 			   / BITS_PER_UNIT);
2276e4b17023SJohn Marino 	}
2277e4b17023SJohn Marino       /* Similarly for the decl.  */
2278e4b17023SJohn Marino       else if (DECL_P (attrs.expr)
2279e4b17023SJohn Marino 	       && DECL_SIZE_UNIT (attrs.expr)
2280e4b17023SJohn Marino 	       && TREE_CODE (DECL_SIZE_UNIT (attrs.expr)) == INTEGER_CST
2281e4b17023SJohn Marino 	       && compare_tree_int (DECL_SIZE_UNIT (attrs.expr), size) >= 0
2282e4b17023SJohn Marino 	       && (! attrs.offset_known_p || attrs.offset >= 0))
2283e4b17023SJohn Marino 	break;
2284e4b17023SJohn Marino       else
2285e4b17023SJohn Marino 	{
2286e4b17023SJohn Marino 	  /* The widened memory access overflows the expression, which means
2287e4b17023SJohn Marino 	     that it could alias another expression.  Zap it.  */
2288e4b17023SJohn Marino 	  attrs.expr = NULL_TREE;
2289e4b17023SJohn Marino 	  break;
2290e4b17023SJohn Marino 	}
2291e4b17023SJohn Marino     }
2292e4b17023SJohn Marino 
2293e4b17023SJohn Marino   if (! attrs.expr)
2294e4b17023SJohn Marino     attrs.offset_known_p = false;
2295e4b17023SJohn Marino 
2296e4b17023SJohn Marino   /* The widened memory may alias other stuff, so zap the alias set.  */
2297e4b17023SJohn Marino   /* ??? Maybe use get_alias_set on any remaining expression.  */
2298e4b17023SJohn Marino   attrs.alias = 0;
2299e4b17023SJohn Marino   attrs.size_known_p = true;
2300e4b17023SJohn Marino   attrs.size = size;
2301e4b17023SJohn Marino   set_mem_attrs (new_rtx, &attrs);
2302e4b17023SJohn Marino   return new_rtx;
2303e4b17023SJohn Marino }
2304e4b17023SJohn Marino 
2305e4b17023SJohn Marino /* A fake decl that is used as the MEM_EXPR of spill slots.  */
2306e4b17023SJohn Marino static GTY(()) tree spill_slot_decl;
2307e4b17023SJohn Marino 
2308e4b17023SJohn Marino tree
get_spill_slot_decl(bool force_build_p)2309e4b17023SJohn Marino get_spill_slot_decl (bool force_build_p)
2310e4b17023SJohn Marino {
2311e4b17023SJohn Marino   tree d = spill_slot_decl;
2312e4b17023SJohn Marino   rtx rd;
2313e4b17023SJohn Marino   struct mem_attrs attrs;
2314e4b17023SJohn Marino 
2315e4b17023SJohn Marino   if (d || !force_build_p)
2316e4b17023SJohn Marino     return d;
2317e4b17023SJohn Marino 
2318e4b17023SJohn Marino   d = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
2319e4b17023SJohn Marino 		  VAR_DECL, get_identifier ("%sfp"), void_type_node);
2320e4b17023SJohn Marino   DECL_ARTIFICIAL (d) = 1;
2321e4b17023SJohn Marino   DECL_IGNORED_P (d) = 1;
2322e4b17023SJohn Marino   TREE_USED (d) = 1;
2323e4b17023SJohn Marino   spill_slot_decl = d;
2324e4b17023SJohn Marino 
2325e4b17023SJohn Marino   rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
2326e4b17023SJohn Marino   MEM_NOTRAP_P (rd) = 1;
2327e4b17023SJohn Marino   attrs = *mode_mem_attrs[(int) BLKmode];
2328e4b17023SJohn Marino   attrs.alias = new_alias_set ();
2329e4b17023SJohn Marino   attrs.expr = d;
2330e4b17023SJohn Marino   set_mem_attrs (rd, &attrs);
2331e4b17023SJohn Marino   SET_DECL_RTL (d, rd);
2332e4b17023SJohn Marino 
2333e4b17023SJohn Marino   return d;
2334e4b17023SJohn Marino }
2335e4b17023SJohn Marino 
2336e4b17023SJohn Marino /* Given MEM, a result from assign_stack_local, fill in the memory
2337e4b17023SJohn Marino    attributes as appropriate for a register allocator spill slot.
2338e4b17023SJohn Marino    These slots are not aliasable by other memory.  We arrange for
2339e4b17023SJohn Marino    them all to use a single MEM_EXPR, so that the aliasing code can
2340e4b17023SJohn Marino    work properly in the case of shared spill slots.  */
2341e4b17023SJohn Marino 
2342e4b17023SJohn Marino void
set_mem_attrs_for_spill(rtx mem)2343e4b17023SJohn Marino set_mem_attrs_for_spill (rtx mem)
2344e4b17023SJohn Marino {
2345e4b17023SJohn Marino   struct mem_attrs attrs;
2346e4b17023SJohn Marino   rtx addr;
2347e4b17023SJohn Marino 
2348e4b17023SJohn Marino   attrs = *get_mem_attrs (mem);
2349e4b17023SJohn Marino   attrs.expr = get_spill_slot_decl (true);
2350e4b17023SJohn Marino   attrs.alias = MEM_ALIAS_SET (DECL_RTL (attrs.expr));
2351e4b17023SJohn Marino   attrs.addrspace = ADDR_SPACE_GENERIC;
2352e4b17023SJohn Marino 
2353e4b17023SJohn Marino   /* We expect the incoming memory to be of the form:
2354e4b17023SJohn Marino 	(mem:MODE (plus (reg sfp) (const_int offset)))
2355e4b17023SJohn Marino      with perhaps the plus missing for offset = 0.  */
2356e4b17023SJohn Marino   addr = XEXP (mem, 0);
2357e4b17023SJohn Marino   attrs.offset_known_p = true;
2358e4b17023SJohn Marino   attrs.offset = 0;
2359e4b17023SJohn Marino   if (GET_CODE (addr) == PLUS
2360e4b17023SJohn Marino       && CONST_INT_P (XEXP (addr, 1)))
2361e4b17023SJohn Marino     attrs.offset = INTVAL (XEXP (addr, 1));
2362e4b17023SJohn Marino 
2363e4b17023SJohn Marino   set_mem_attrs (mem, &attrs);
2364e4b17023SJohn Marino   MEM_NOTRAP_P (mem) = 1;
2365e4b17023SJohn Marino }
2366e4b17023SJohn Marino 
2367e4b17023SJohn Marino /* Return a newly created CODE_LABEL rtx with a unique label number.  */
2368e4b17023SJohn Marino 
2369e4b17023SJohn Marino rtx
gen_label_rtx(void)2370e4b17023SJohn Marino gen_label_rtx (void)
2371e4b17023SJohn Marino {
2372e4b17023SJohn Marino   return gen_rtx_CODE_LABEL (VOIDmode, 0, NULL_RTX, NULL_RTX,
2373e4b17023SJohn Marino 			     NULL, label_num++, NULL);
2374e4b17023SJohn Marino }
2375e4b17023SJohn Marino 
2376e4b17023SJohn Marino /* For procedure integration.  */
2377e4b17023SJohn Marino 
2378e4b17023SJohn Marino /* Install new pointers to the first and last insns in the chain.
2379e4b17023SJohn Marino    Also, set cur_insn_uid to one higher than the last in use.
2380e4b17023SJohn Marino    Used for an inline-procedure after copying the insn chain.  */
2381e4b17023SJohn Marino 
2382e4b17023SJohn Marino void
set_new_first_and_last_insn(rtx first,rtx last)2383e4b17023SJohn Marino set_new_first_and_last_insn (rtx first, rtx last)
2384e4b17023SJohn Marino {
2385e4b17023SJohn Marino   rtx insn;
2386e4b17023SJohn Marino 
2387e4b17023SJohn Marino   set_first_insn (first);
2388e4b17023SJohn Marino   set_last_insn (last);
2389e4b17023SJohn Marino   cur_insn_uid = 0;
2390e4b17023SJohn Marino 
2391e4b17023SJohn Marino   if (MIN_NONDEBUG_INSN_UID || MAY_HAVE_DEBUG_INSNS)
2392e4b17023SJohn Marino     {
2393e4b17023SJohn Marino       int debug_count = 0;
2394e4b17023SJohn Marino 
2395e4b17023SJohn Marino       cur_insn_uid = MIN_NONDEBUG_INSN_UID - 1;
2396e4b17023SJohn Marino       cur_debug_insn_uid = 0;
2397e4b17023SJohn Marino 
2398e4b17023SJohn Marino       for (insn = first; insn; insn = NEXT_INSN (insn))
2399e4b17023SJohn Marino 	if (INSN_UID (insn) < MIN_NONDEBUG_INSN_UID)
2400e4b17023SJohn Marino 	  cur_debug_insn_uid = MAX (cur_debug_insn_uid, INSN_UID (insn));
2401e4b17023SJohn Marino 	else
2402e4b17023SJohn Marino 	  {
2403e4b17023SJohn Marino 	    cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
2404e4b17023SJohn Marino 	    if (DEBUG_INSN_P (insn))
2405e4b17023SJohn Marino 	      debug_count++;
2406e4b17023SJohn Marino 	  }
2407e4b17023SJohn Marino 
2408e4b17023SJohn Marino       if (debug_count)
2409e4b17023SJohn Marino 	cur_debug_insn_uid = MIN_NONDEBUG_INSN_UID + debug_count;
2410e4b17023SJohn Marino       else
2411e4b17023SJohn Marino 	cur_debug_insn_uid++;
2412e4b17023SJohn Marino     }
2413e4b17023SJohn Marino   else
2414e4b17023SJohn Marino     for (insn = first; insn; insn = NEXT_INSN (insn))
2415e4b17023SJohn Marino       cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
2416e4b17023SJohn Marino 
2417e4b17023SJohn Marino   cur_insn_uid++;
2418e4b17023SJohn Marino }
2419e4b17023SJohn Marino 
2420e4b17023SJohn Marino /* Go through all the RTL insn bodies and copy any invalid shared
2421e4b17023SJohn Marino    structure.  This routine should only be called once.  */
2422e4b17023SJohn Marino 
2423e4b17023SJohn Marino static void
unshare_all_rtl_1(rtx insn)2424e4b17023SJohn Marino unshare_all_rtl_1 (rtx insn)
2425e4b17023SJohn Marino {
2426e4b17023SJohn Marino   /* Unshare just about everything else.  */
2427e4b17023SJohn Marino   unshare_all_rtl_in_chain (insn);
2428e4b17023SJohn Marino 
2429e4b17023SJohn Marino   /* Make sure the addresses of stack slots found outside the insn chain
2430e4b17023SJohn Marino      (such as, in DECL_RTL of a variable) are not shared
2431e4b17023SJohn Marino      with the insn chain.
2432e4b17023SJohn Marino 
2433e4b17023SJohn Marino      This special care is necessary when the stack slot MEM does not
2434e4b17023SJohn Marino      actually appear in the insn chain.  If it does appear, its address
2435e4b17023SJohn Marino      is unshared from all else at that point.  */
2436e4b17023SJohn Marino   stack_slot_list = copy_rtx_if_shared (stack_slot_list);
2437e4b17023SJohn Marino }
2438e4b17023SJohn Marino 
2439e4b17023SJohn Marino /* Go through all the RTL insn bodies and copy any invalid shared
2440e4b17023SJohn Marino    structure, again.  This is a fairly expensive thing to do so it
2441e4b17023SJohn Marino    should be done sparingly.  */
2442e4b17023SJohn Marino 
2443e4b17023SJohn Marino void
unshare_all_rtl_again(rtx insn)2444e4b17023SJohn Marino unshare_all_rtl_again (rtx insn)
2445e4b17023SJohn Marino {
2446e4b17023SJohn Marino   rtx p;
2447e4b17023SJohn Marino   tree decl;
2448e4b17023SJohn Marino 
2449e4b17023SJohn Marino   for (p = insn; p; p = NEXT_INSN (p))
2450e4b17023SJohn Marino     if (INSN_P (p))
2451e4b17023SJohn Marino       {
2452e4b17023SJohn Marino 	reset_used_flags (PATTERN (p));
2453e4b17023SJohn Marino 	reset_used_flags (REG_NOTES (p));
2454e4b17023SJohn Marino 	if (CALL_P (p))
2455e4b17023SJohn Marino 	  reset_used_flags (CALL_INSN_FUNCTION_USAGE (p));
2456e4b17023SJohn Marino       }
2457e4b17023SJohn Marino 
2458e4b17023SJohn Marino   /* Make sure that virtual stack slots are not shared.  */
2459e4b17023SJohn Marino   set_used_decls (DECL_INITIAL (cfun->decl));
2460e4b17023SJohn Marino 
2461e4b17023SJohn Marino   /* Make sure that virtual parameters are not shared.  */
2462e4b17023SJohn Marino   for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = DECL_CHAIN (decl))
2463e4b17023SJohn Marino     set_used_flags (DECL_RTL (decl));
2464e4b17023SJohn Marino 
2465e4b17023SJohn Marino   reset_used_flags (stack_slot_list);
2466e4b17023SJohn Marino 
2467e4b17023SJohn Marino   unshare_all_rtl_1 (insn);
2468e4b17023SJohn Marino }
2469e4b17023SJohn Marino 
2470e4b17023SJohn Marino unsigned int
unshare_all_rtl(void)2471e4b17023SJohn Marino unshare_all_rtl (void)
2472e4b17023SJohn Marino {
2473e4b17023SJohn Marino   unshare_all_rtl_1 (get_insns ());
2474e4b17023SJohn Marino   return 0;
2475e4b17023SJohn Marino }
2476e4b17023SJohn Marino 
2477e4b17023SJohn Marino struct rtl_opt_pass pass_unshare_all_rtl =
2478e4b17023SJohn Marino {
2479e4b17023SJohn Marino  {
2480e4b17023SJohn Marino   RTL_PASS,
2481e4b17023SJohn Marino   "unshare",                            /* name */
2482e4b17023SJohn Marino   NULL,                                 /* gate */
2483e4b17023SJohn Marino   unshare_all_rtl,                      /* execute */
2484e4b17023SJohn Marino   NULL,                                 /* sub */
2485e4b17023SJohn Marino   NULL,                                 /* next */
2486e4b17023SJohn Marino   0,                                    /* static_pass_number */
2487e4b17023SJohn Marino   TV_NONE,                              /* tv_id */
2488e4b17023SJohn Marino   0,                                    /* properties_required */
2489e4b17023SJohn Marino   0,                                    /* properties_provided */
2490e4b17023SJohn Marino   0,                                    /* properties_destroyed */
2491e4b17023SJohn Marino   0,                                    /* todo_flags_start */
2492e4b17023SJohn Marino   TODO_verify_rtl_sharing               /* todo_flags_finish */
2493e4b17023SJohn Marino  }
2494e4b17023SJohn Marino };
2495e4b17023SJohn Marino 
2496e4b17023SJohn Marino 
2497e4b17023SJohn Marino /* Check that ORIG is not marked when it should not be and mark ORIG as in use,
2498e4b17023SJohn Marino    Recursively does the same for subexpressions.  */
2499e4b17023SJohn Marino 
2500e4b17023SJohn Marino static void
verify_rtx_sharing(rtx orig,rtx insn)2501e4b17023SJohn Marino verify_rtx_sharing (rtx orig, rtx insn)
2502e4b17023SJohn Marino {
2503e4b17023SJohn Marino   rtx x = orig;
2504e4b17023SJohn Marino   int i;
2505e4b17023SJohn Marino   enum rtx_code code;
2506e4b17023SJohn Marino   const char *format_ptr;
2507e4b17023SJohn Marino 
2508e4b17023SJohn Marino   if (x == 0)
2509e4b17023SJohn Marino     return;
2510e4b17023SJohn Marino 
2511e4b17023SJohn Marino   code = GET_CODE (x);
2512e4b17023SJohn Marino 
2513e4b17023SJohn Marino   /* These types may be freely shared.  */
2514e4b17023SJohn Marino 
2515e4b17023SJohn Marino   switch (code)
2516e4b17023SJohn Marino     {
2517e4b17023SJohn Marino     case REG:
2518e4b17023SJohn Marino     case DEBUG_EXPR:
2519e4b17023SJohn Marino     case VALUE:
2520e4b17023SJohn Marino     case CONST_INT:
2521e4b17023SJohn Marino     case CONST_DOUBLE:
2522e4b17023SJohn Marino     case CONST_FIXED:
2523e4b17023SJohn Marino     case CONST_VECTOR:
2524e4b17023SJohn Marino     case SYMBOL_REF:
2525e4b17023SJohn Marino     case LABEL_REF:
2526e4b17023SJohn Marino     case CODE_LABEL:
2527e4b17023SJohn Marino     case PC:
2528e4b17023SJohn Marino     case CC0:
2529e4b17023SJohn Marino     case RETURN:
2530e4b17023SJohn Marino     case SIMPLE_RETURN:
2531e4b17023SJohn Marino     case SCRATCH:
2532e4b17023SJohn Marino       return;
2533e4b17023SJohn Marino       /* SCRATCH must be shared because they represent distinct values.  */
2534e4b17023SJohn Marino     case CLOBBER:
2535e4b17023SJohn Marino       if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
2536e4b17023SJohn Marino 	return;
2537e4b17023SJohn Marino       break;
2538e4b17023SJohn Marino 
2539e4b17023SJohn Marino     case CONST:
2540e4b17023SJohn Marino       if (shared_const_p (orig))
2541e4b17023SJohn Marino 	return;
2542e4b17023SJohn Marino       break;
2543e4b17023SJohn Marino 
2544e4b17023SJohn Marino     case MEM:
2545e4b17023SJohn Marino       /* A MEM is allowed to be shared if its address is constant.  */
2546e4b17023SJohn Marino       if (CONSTANT_ADDRESS_P (XEXP (x, 0))
2547e4b17023SJohn Marino 	  || reload_completed || reload_in_progress)
2548e4b17023SJohn Marino 	return;
2549e4b17023SJohn Marino 
2550e4b17023SJohn Marino       break;
2551e4b17023SJohn Marino 
2552e4b17023SJohn Marino     default:
2553e4b17023SJohn Marino       break;
2554e4b17023SJohn Marino     }
2555e4b17023SJohn Marino 
2556e4b17023SJohn Marino   /* This rtx may not be shared.  If it has already been seen,
2557e4b17023SJohn Marino      replace it with a copy of itself.  */
2558e4b17023SJohn Marino #ifdef ENABLE_CHECKING
2559e4b17023SJohn Marino   if (RTX_FLAG (x, used))
2560e4b17023SJohn Marino     {
2561e4b17023SJohn Marino       error ("invalid rtl sharing found in the insn");
2562e4b17023SJohn Marino       debug_rtx (insn);
2563e4b17023SJohn Marino       error ("shared rtx");
2564e4b17023SJohn Marino       debug_rtx (x);
2565e4b17023SJohn Marino       internal_error ("internal consistency failure");
2566e4b17023SJohn Marino     }
2567e4b17023SJohn Marino #endif
2568e4b17023SJohn Marino   gcc_assert (!RTX_FLAG (x, used));
2569e4b17023SJohn Marino 
2570e4b17023SJohn Marino   RTX_FLAG (x, used) = 1;
2571e4b17023SJohn Marino 
2572e4b17023SJohn Marino   /* Now scan the subexpressions recursively.  */
2573e4b17023SJohn Marino 
2574e4b17023SJohn Marino   format_ptr = GET_RTX_FORMAT (code);
2575e4b17023SJohn Marino 
2576e4b17023SJohn Marino   for (i = 0; i < GET_RTX_LENGTH (code); i++)
2577e4b17023SJohn Marino     {
2578e4b17023SJohn Marino       switch (*format_ptr++)
2579e4b17023SJohn Marino 	{
2580e4b17023SJohn Marino 	case 'e':
2581e4b17023SJohn Marino 	  verify_rtx_sharing (XEXP (x, i), insn);
2582e4b17023SJohn Marino 	  break;
2583e4b17023SJohn Marino 
2584e4b17023SJohn Marino 	case 'E':
2585e4b17023SJohn Marino 	  if (XVEC (x, i) != NULL)
2586e4b17023SJohn Marino 	    {
2587e4b17023SJohn Marino 	      int j;
2588e4b17023SJohn Marino 	      int len = XVECLEN (x, i);
2589e4b17023SJohn Marino 
2590e4b17023SJohn Marino 	      for (j = 0; j < len; j++)
2591e4b17023SJohn Marino 		{
2592e4b17023SJohn Marino 		  /* We allow sharing of ASM_OPERANDS inside single
2593e4b17023SJohn Marino 		     instruction.  */
2594e4b17023SJohn Marino 		  if (j && GET_CODE (XVECEXP (x, i, j)) == SET
2595e4b17023SJohn Marino 		      && (GET_CODE (SET_SRC (XVECEXP (x, i, j)))
2596e4b17023SJohn Marino 			  == ASM_OPERANDS))
2597e4b17023SJohn Marino 		    verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
2598e4b17023SJohn Marino 		  else
2599e4b17023SJohn Marino 		    verify_rtx_sharing (XVECEXP (x, i, j), insn);
2600e4b17023SJohn Marino 		}
2601e4b17023SJohn Marino 	    }
2602e4b17023SJohn Marino 	  break;
2603e4b17023SJohn Marino 	}
2604e4b17023SJohn Marino     }
2605e4b17023SJohn Marino   return;
2606e4b17023SJohn Marino }
2607e4b17023SJohn Marino 
2608e4b17023SJohn Marino /* Go through all the RTL insn bodies and check that there is no unexpected
2609e4b17023SJohn Marino    sharing in between the subexpressions.  */
2610e4b17023SJohn Marino 
2611e4b17023SJohn Marino DEBUG_FUNCTION void
verify_rtl_sharing(void)2612e4b17023SJohn Marino verify_rtl_sharing (void)
2613e4b17023SJohn Marino {
2614e4b17023SJohn Marino   rtx p;
2615e4b17023SJohn Marino 
2616e4b17023SJohn Marino   timevar_push (TV_VERIFY_RTL_SHARING);
2617e4b17023SJohn Marino 
2618e4b17023SJohn Marino   for (p = get_insns (); p; p = NEXT_INSN (p))
2619e4b17023SJohn Marino     if (INSN_P (p))
2620e4b17023SJohn Marino       {
2621e4b17023SJohn Marino 	reset_used_flags (PATTERN (p));
2622e4b17023SJohn Marino 	reset_used_flags (REG_NOTES (p));
2623e4b17023SJohn Marino 	if (CALL_P (p))
2624e4b17023SJohn Marino 	  reset_used_flags (CALL_INSN_FUNCTION_USAGE (p));
2625e4b17023SJohn Marino 	if (GET_CODE (PATTERN (p)) == SEQUENCE)
2626e4b17023SJohn Marino 	  {
2627e4b17023SJohn Marino 	    int i;
2628e4b17023SJohn Marino 	    rtx q, sequence = PATTERN (p);
2629e4b17023SJohn Marino 
2630e4b17023SJohn Marino 	    for (i = 0; i < XVECLEN (sequence, 0); i++)
2631e4b17023SJohn Marino 	      {
2632e4b17023SJohn Marino 		q = XVECEXP (sequence, 0, i);
2633e4b17023SJohn Marino 		gcc_assert (INSN_P (q));
2634e4b17023SJohn Marino 		reset_used_flags (PATTERN (q));
2635e4b17023SJohn Marino 		reset_used_flags (REG_NOTES (q));
2636e4b17023SJohn Marino 		if (CALL_P (q))
2637e4b17023SJohn Marino 		  reset_used_flags (CALL_INSN_FUNCTION_USAGE (q));
2638e4b17023SJohn Marino 	      }
2639e4b17023SJohn Marino 	  }
2640e4b17023SJohn Marino       }
2641e4b17023SJohn Marino 
2642e4b17023SJohn Marino   for (p = get_insns (); p; p = NEXT_INSN (p))
2643e4b17023SJohn Marino     if (INSN_P (p))
2644e4b17023SJohn Marino       {
2645e4b17023SJohn Marino 	verify_rtx_sharing (PATTERN (p), p);
2646e4b17023SJohn Marino 	verify_rtx_sharing (REG_NOTES (p), p);
2647e4b17023SJohn Marino 	if (CALL_P (p))
2648e4b17023SJohn Marino 	  verify_rtx_sharing (CALL_INSN_FUNCTION_USAGE (p), p);
2649e4b17023SJohn Marino       }
2650e4b17023SJohn Marino 
2651e4b17023SJohn Marino   timevar_pop (TV_VERIFY_RTL_SHARING);
2652e4b17023SJohn Marino }
2653e4b17023SJohn Marino 
2654e4b17023SJohn Marino /* Go through all the RTL insn bodies and copy any invalid shared structure.
2655e4b17023SJohn Marino    Assumes the mark bits are cleared at entry.  */
2656e4b17023SJohn Marino 
2657e4b17023SJohn Marino void
unshare_all_rtl_in_chain(rtx insn)2658e4b17023SJohn Marino unshare_all_rtl_in_chain (rtx insn)
2659e4b17023SJohn Marino {
2660e4b17023SJohn Marino   for (; insn; insn = NEXT_INSN (insn))
2661e4b17023SJohn Marino     if (INSN_P (insn))
2662e4b17023SJohn Marino       {
2663e4b17023SJohn Marino 	PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
2664e4b17023SJohn Marino 	REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
2665e4b17023SJohn Marino 	if (CALL_P (insn))
2666e4b17023SJohn Marino 	  CALL_INSN_FUNCTION_USAGE (insn)
2667e4b17023SJohn Marino 	    = copy_rtx_if_shared (CALL_INSN_FUNCTION_USAGE (insn));
2668e4b17023SJohn Marino       }
2669e4b17023SJohn Marino }
2670e4b17023SJohn Marino 
2671e4b17023SJohn Marino /* Go through all virtual stack slots of a function and mark them as
2672e4b17023SJohn Marino    shared.  We never replace the DECL_RTLs themselves with a copy,
2673e4b17023SJohn Marino    but expressions mentioned into a DECL_RTL cannot be shared with
2674e4b17023SJohn Marino    expressions in the instruction stream.
2675e4b17023SJohn Marino 
2676e4b17023SJohn Marino    Note that reload may convert pseudo registers into memories in-place.
2677e4b17023SJohn Marino    Pseudo registers are always shared, but MEMs never are.  Thus if we
2678e4b17023SJohn Marino    reset the used flags on MEMs in the instruction stream, we must set
2679e4b17023SJohn Marino    them again on MEMs that appear in DECL_RTLs.  */
2680e4b17023SJohn Marino 
2681e4b17023SJohn Marino static void
set_used_decls(tree blk)2682e4b17023SJohn Marino set_used_decls (tree blk)
2683e4b17023SJohn Marino {
2684e4b17023SJohn Marino   tree t;
2685e4b17023SJohn Marino 
2686e4b17023SJohn Marino   /* Mark decls.  */
2687e4b17023SJohn Marino   for (t = BLOCK_VARS (blk); t; t = DECL_CHAIN (t))
2688e4b17023SJohn Marino     if (DECL_RTL_SET_P (t))
2689e4b17023SJohn Marino       set_used_flags (DECL_RTL (t));
2690e4b17023SJohn Marino 
2691e4b17023SJohn Marino   /* Now process sub-blocks.  */
2692e4b17023SJohn Marino   for (t = BLOCK_SUBBLOCKS (blk); t; t = BLOCK_CHAIN (t))
2693e4b17023SJohn Marino     set_used_decls (t);
2694e4b17023SJohn Marino }
2695e4b17023SJohn Marino 
2696e4b17023SJohn Marino /* Mark ORIG as in use, and return a copy of it if it was already in use.
2697e4b17023SJohn Marino    Recursively does the same for subexpressions.  Uses
2698e4b17023SJohn Marino    copy_rtx_if_shared_1 to reduce stack space.  */
2699e4b17023SJohn Marino 
2700e4b17023SJohn Marino rtx
copy_rtx_if_shared(rtx orig)2701e4b17023SJohn Marino copy_rtx_if_shared (rtx orig)
2702e4b17023SJohn Marino {
2703e4b17023SJohn Marino   copy_rtx_if_shared_1 (&orig);
2704e4b17023SJohn Marino   return orig;
2705e4b17023SJohn Marino }
2706e4b17023SJohn Marino 
2707e4b17023SJohn Marino /* Mark *ORIG1 as in use, and set it to a copy of it if it was already in
2708e4b17023SJohn Marino    use.  Recursively does the same for subexpressions.  */
2709e4b17023SJohn Marino 
2710e4b17023SJohn Marino static void
copy_rtx_if_shared_1(rtx * orig1)2711e4b17023SJohn Marino copy_rtx_if_shared_1 (rtx *orig1)
2712e4b17023SJohn Marino {
2713e4b17023SJohn Marino   rtx x;
2714e4b17023SJohn Marino   int i;
2715e4b17023SJohn Marino   enum rtx_code code;
2716e4b17023SJohn Marino   rtx *last_ptr;
2717e4b17023SJohn Marino   const char *format_ptr;
2718e4b17023SJohn Marino   int copied = 0;
2719e4b17023SJohn Marino   int length;
2720e4b17023SJohn Marino 
2721e4b17023SJohn Marino   /* Repeat is used to turn tail-recursion into iteration.  */
2722e4b17023SJohn Marino repeat:
2723e4b17023SJohn Marino   x = *orig1;
2724e4b17023SJohn Marino 
2725e4b17023SJohn Marino   if (x == 0)
2726e4b17023SJohn Marino     return;
2727e4b17023SJohn Marino 
2728e4b17023SJohn Marino   code = GET_CODE (x);
2729e4b17023SJohn Marino 
2730e4b17023SJohn Marino   /* These types may be freely shared.  */
2731e4b17023SJohn Marino 
2732e4b17023SJohn Marino   switch (code)
2733e4b17023SJohn Marino     {
2734e4b17023SJohn Marino     case REG:
2735e4b17023SJohn Marino     case DEBUG_EXPR:
2736e4b17023SJohn Marino     case VALUE:
2737e4b17023SJohn Marino     case CONST_INT:
2738e4b17023SJohn Marino     case CONST_DOUBLE:
2739e4b17023SJohn Marino     case CONST_FIXED:
2740e4b17023SJohn Marino     case CONST_VECTOR:
2741e4b17023SJohn Marino     case SYMBOL_REF:
2742e4b17023SJohn Marino     case LABEL_REF:
2743e4b17023SJohn Marino     case CODE_LABEL:
2744e4b17023SJohn Marino     case PC:
2745e4b17023SJohn Marino     case CC0:
2746e4b17023SJohn Marino     case RETURN:
2747e4b17023SJohn Marino     case SIMPLE_RETURN:
2748e4b17023SJohn Marino     case SCRATCH:
2749e4b17023SJohn Marino       /* SCRATCH must be shared because they represent distinct values.  */
2750e4b17023SJohn Marino       return;
2751e4b17023SJohn Marino     case CLOBBER:
2752e4b17023SJohn Marino       if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
2753e4b17023SJohn Marino 	return;
2754e4b17023SJohn Marino       break;
2755e4b17023SJohn Marino 
2756e4b17023SJohn Marino     case CONST:
2757e4b17023SJohn Marino       if (shared_const_p (x))
2758e4b17023SJohn Marino 	return;
2759e4b17023SJohn Marino       break;
2760e4b17023SJohn Marino 
2761e4b17023SJohn Marino     case DEBUG_INSN:
2762e4b17023SJohn Marino     case INSN:
2763e4b17023SJohn Marino     case JUMP_INSN:
2764e4b17023SJohn Marino     case CALL_INSN:
2765e4b17023SJohn Marino     case NOTE:
2766e4b17023SJohn Marino     case BARRIER:
2767e4b17023SJohn Marino       /* The chain of insns is not being copied.  */
2768e4b17023SJohn Marino       return;
2769e4b17023SJohn Marino 
2770e4b17023SJohn Marino     default:
2771e4b17023SJohn Marino       break;
2772e4b17023SJohn Marino     }
2773e4b17023SJohn Marino 
2774e4b17023SJohn Marino   /* This rtx may not be shared.  If it has already been seen,
2775e4b17023SJohn Marino      replace it with a copy of itself.  */
2776e4b17023SJohn Marino 
2777e4b17023SJohn Marino   if (RTX_FLAG (x, used))
2778e4b17023SJohn Marino     {
2779e4b17023SJohn Marino       x = shallow_copy_rtx (x);
2780e4b17023SJohn Marino       copied = 1;
2781e4b17023SJohn Marino     }
2782e4b17023SJohn Marino   RTX_FLAG (x, used) = 1;
2783e4b17023SJohn Marino 
2784e4b17023SJohn Marino   /* Now scan the subexpressions recursively.
2785e4b17023SJohn Marino      We can store any replaced subexpressions directly into X
2786e4b17023SJohn Marino      since we know X is not shared!  Any vectors in X
2787e4b17023SJohn Marino      must be copied if X was copied.  */
2788e4b17023SJohn Marino 
2789e4b17023SJohn Marino   format_ptr = GET_RTX_FORMAT (code);
2790e4b17023SJohn Marino   length = GET_RTX_LENGTH (code);
2791e4b17023SJohn Marino   last_ptr = NULL;
2792e4b17023SJohn Marino 
2793e4b17023SJohn Marino   for (i = 0; i < length; i++)
2794e4b17023SJohn Marino     {
2795e4b17023SJohn Marino       switch (*format_ptr++)
2796e4b17023SJohn Marino 	{
2797e4b17023SJohn Marino 	case 'e':
2798e4b17023SJohn Marino           if (last_ptr)
2799e4b17023SJohn Marino             copy_rtx_if_shared_1 (last_ptr);
2800e4b17023SJohn Marino 	  last_ptr = &XEXP (x, i);
2801e4b17023SJohn Marino 	  break;
2802e4b17023SJohn Marino 
2803e4b17023SJohn Marino 	case 'E':
2804e4b17023SJohn Marino 	  if (XVEC (x, i) != NULL)
2805e4b17023SJohn Marino 	    {
2806e4b17023SJohn Marino 	      int j;
2807e4b17023SJohn Marino 	      int len = XVECLEN (x, i);
2808e4b17023SJohn Marino 
2809e4b17023SJohn Marino               /* Copy the vector iff I copied the rtx and the length
2810e4b17023SJohn Marino 		 is nonzero.  */
2811e4b17023SJohn Marino 	      if (copied && len > 0)
2812e4b17023SJohn Marino 		XVEC (x, i) = gen_rtvec_v (len, XVEC (x, i)->elem);
2813e4b17023SJohn Marino 
2814e4b17023SJohn Marino               /* Call recursively on all inside the vector.  */
2815e4b17023SJohn Marino 	      for (j = 0; j < len; j++)
2816e4b17023SJohn Marino                 {
2817e4b17023SJohn Marino 		  if (last_ptr)
2818e4b17023SJohn Marino 		    copy_rtx_if_shared_1 (last_ptr);
2819e4b17023SJohn Marino                   last_ptr = &XVECEXP (x, i, j);
2820e4b17023SJohn Marino                 }
2821e4b17023SJohn Marino 	    }
2822e4b17023SJohn Marino 	  break;
2823e4b17023SJohn Marino 	}
2824e4b17023SJohn Marino     }
2825e4b17023SJohn Marino   *orig1 = x;
2826e4b17023SJohn Marino   if (last_ptr)
2827e4b17023SJohn Marino     {
2828e4b17023SJohn Marino       orig1 = last_ptr;
2829e4b17023SJohn Marino       goto repeat;
2830e4b17023SJohn Marino     }
2831e4b17023SJohn Marino   return;
2832e4b17023SJohn Marino }
2833e4b17023SJohn Marino 
2834e4b17023SJohn Marino /* Set the USED bit in X and its non-shareable subparts to FLAG.  */
2835e4b17023SJohn Marino 
2836e4b17023SJohn Marino static void
mark_used_flags(rtx x,int flag)2837e4b17023SJohn Marino mark_used_flags (rtx x, int flag)
2838e4b17023SJohn Marino {
2839e4b17023SJohn Marino   int i, j;
2840e4b17023SJohn Marino   enum rtx_code code;
2841e4b17023SJohn Marino   const char *format_ptr;
2842e4b17023SJohn Marino   int length;
2843e4b17023SJohn Marino 
2844e4b17023SJohn Marino   /* Repeat is used to turn tail-recursion into iteration.  */
2845e4b17023SJohn Marino repeat:
2846e4b17023SJohn Marino   if (x == 0)
2847e4b17023SJohn Marino     return;
2848e4b17023SJohn Marino 
2849e4b17023SJohn Marino   code = GET_CODE (x);
2850e4b17023SJohn Marino 
2851e4b17023SJohn Marino   /* These types may be freely shared so we needn't do any resetting
2852e4b17023SJohn Marino      for them.  */
2853e4b17023SJohn Marino 
2854e4b17023SJohn Marino   switch (code)
2855e4b17023SJohn Marino     {
2856e4b17023SJohn Marino     case REG:
2857e4b17023SJohn Marino     case DEBUG_EXPR:
2858e4b17023SJohn Marino     case VALUE:
2859e4b17023SJohn Marino     case CONST_INT:
2860e4b17023SJohn Marino     case CONST_DOUBLE:
2861e4b17023SJohn Marino     case CONST_FIXED:
2862e4b17023SJohn Marino     case CONST_VECTOR:
2863e4b17023SJohn Marino     case SYMBOL_REF:
2864e4b17023SJohn Marino     case CODE_LABEL:
2865e4b17023SJohn Marino     case PC:
2866e4b17023SJohn Marino     case CC0:
2867e4b17023SJohn Marino     case RETURN:
2868e4b17023SJohn Marino     case SIMPLE_RETURN:
2869e4b17023SJohn Marino       return;
2870e4b17023SJohn Marino 
2871e4b17023SJohn Marino     case DEBUG_INSN:
2872e4b17023SJohn Marino     case INSN:
2873e4b17023SJohn Marino     case JUMP_INSN:
2874e4b17023SJohn Marino     case CALL_INSN:
2875e4b17023SJohn Marino     case NOTE:
2876e4b17023SJohn Marino     case LABEL_REF:
2877e4b17023SJohn Marino     case BARRIER:
2878e4b17023SJohn Marino       /* The chain of insns is not being copied.  */
2879e4b17023SJohn Marino       return;
2880e4b17023SJohn Marino 
2881e4b17023SJohn Marino     default:
2882e4b17023SJohn Marino       break;
2883e4b17023SJohn Marino     }
2884e4b17023SJohn Marino 
2885e4b17023SJohn Marino   RTX_FLAG (x, used) = flag;
2886e4b17023SJohn Marino 
2887e4b17023SJohn Marino   format_ptr = GET_RTX_FORMAT (code);
2888e4b17023SJohn Marino   length = GET_RTX_LENGTH (code);
2889e4b17023SJohn Marino 
2890e4b17023SJohn Marino   for (i = 0; i < length; i++)
2891e4b17023SJohn Marino     {
2892e4b17023SJohn Marino       switch (*format_ptr++)
2893e4b17023SJohn Marino 	{
2894e4b17023SJohn Marino 	case 'e':
2895e4b17023SJohn Marino           if (i == length-1)
2896e4b17023SJohn Marino             {
2897e4b17023SJohn Marino               x = XEXP (x, i);
2898e4b17023SJohn Marino 	      goto repeat;
2899e4b17023SJohn Marino             }
2900e4b17023SJohn Marino 	  mark_used_flags (XEXP (x, i), flag);
2901e4b17023SJohn Marino 	  break;
2902e4b17023SJohn Marino 
2903e4b17023SJohn Marino 	case 'E':
2904e4b17023SJohn Marino 	  for (j = 0; j < XVECLEN (x, i); j++)
2905e4b17023SJohn Marino 	    mark_used_flags (XVECEXP (x, i, j), flag);
2906e4b17023SJohn Marino 	  break;
2907e4b17023SJohn Marino 	}
2908e4b17023SJohn Marino     }
2909e4b17023SJohn Marino }
2910e4b17023SJohn Marino 
2911e4b17023SJohn Marino /* Clear all the USED bits in X to allow copy_rtx_if_shared to be used
2912e4b17023SJohn Marino    to look for shared sub-parts.  */
2913e4b17023SJohn Marino 
2914e4b17023SJohn Marino void
reset_used_flags(rtx x)2915e4b17023SJohn Marino reset_used_flags (rtx x)
2916e4b17023SJohn Marino {
2917e4b17023SJohn Marino   mark_used_flags (x, 0);
2918e4b17023SJohn Marino }
2919e4b17023SJohn Marino 
2920e4b17023SJohn Marino /* Set all the USED bits in X to allow copy_rtx_if_shared to be used
2921e4b17023SJohn Marino    to look for shared sub-parts.  */
2922e4b17023SJohn Marino 
2923e4b17023SJohn Marino void
set_used_flags(rtx x)2924e4b17023SJohn Marino set_used_flags (rtx x)
2925e4b17023SJohn Marino {
2926e4b17023SJohn Marino   mark_used_flags (x, 1);
2927e4b17023SJohn Marino }
2928e4b17023SJohn Marino 
2929e4b17023SJohn Marino /* Copy X if necessary so that it won't be altered by changes in OTHER.
2930e4b17023SJohn Marino    Return X or the rtx for the pseudo reg the value of X was copied into.
2931e4b17023SJohn Marino    OTHER must be valid as a SET_DEST.  */
2932e4b17023SJohn Marino 
2933e4b17023SJohn Marino rtx
make_safe_from(rtx x,rtx other)2934e4b17023SJohn Marino make_safe_from (rtx x, rtx other)
2935e4b17023SJohn Marino {
2936e4b17023SJohn Marino   while (1)
2937e4b17023SJohn Marino     switch (GET_CODE (other))
2938e4b17023SJohn Marino       {
2939e4b17023SJohn Marino       case SUBREG:
2940e4b17023SJohn Marino 	other = SUBREG_REG (other);
2941e4b17023SJohn Marino 	break;
2942e4b17023SJohn Marino       case STRICT_LOW_PART:
2943e4b17023SJohn Marino       case SIGN_EXTEND:
2944e4b17023SJohn Marino       case ZERO_EXTEND:
2945e4b17023SJohn Marino 	other = XEXP (other, 0);
2946e4b17023SJohn Marino 	break;
2947e4b17023SJohn Marino       default:
2948e4b17023SJohn Marino 	goto done;
2949e4b17023SJohn Marino       }
2950e4b17023SJohn Marino  done:
2951e4b17023SJohn Marino   if ((MEM_P (other)
2952e4b17023SJohn Marino        && ! CONSTANT_P (x)
2953e4b17023SJohn Marino        && !REG_P (x)
2954e4b17023SJohn Marino        && GET_CODE (x) != SUBREG)
2955e4b17023SJohn Marino       || (REG_P (other)
2956e4b17023SJohn Marino 	  && (REGNO (other) < FIRST_PSEUDO_REGISTER
2957e4b17023SJohn Marino 	      || reg_mentioned_p (other, x))))
2958e4b17023SJohn Marino     {
2959e4b17023SJohn Marino       rtx temp = gen_reg_rtx (GET_MODE (x));
2960e4b17023SJohn Marino       emit_move_insn (temp, x);
2961e4b17023SJohn Marino       return temp;
2962e4b17023SJohn Marino     }
2963e4b17023SJohn Marino   return x;
2964e4b17023SJohn Marino }
2965e4b17023SJohn Marino 
2966e4b17023SJohn Marino /* Emission of insns (adding them to the doubly-linked list).  */
2967e4b17023SJohn Marino 
2968e4b17023SJohn Marino /* Return the last insn emitted, even if it is in a sequence now pushed.  */
2969e4b17023SJohn Marino 
2970e4b17023SJohn Marino rtx
get_last_insn_anywhere(void)2971e4b17023SJohn Marino get_last_insn_anywhere (void)
2972e4b17023SJohn Marino {
2973e4b17023SJohn Marino   struct sequence_stack *stack;
2974e4b17023SJohn Marino   if (get_last_insn ())
2975e4b17023SJohn Marino     return get_last_insn ();
2976e4b17023SJohn Marino   for (stack = seq_stack; stack; stack = stack->next)
2977e4b17023SJohn Marino     if (stack->last != 0)
2978e4b17023SJohn Marino       return stack->last;
2979e4b17023SJohn Marino   return 0;
2980e4b17023SJohn Marino }
2981e4b17023SJohn Marino 
2982e4b17023SJohn Marino /* Return the first nonnote insn emitted in current sequence or current
2983e4b17023SJohn Marino    function.  This routine looks inside SEQUENCEs.  */
2984e4b17023SJohn Marino 
2985e4b17023SJohn Marino rtx
get_first_nonnote_insn(void)2986e4b17023SJohn Marino get_first_nonnote_insn (void)
2987e4b17023SJohn Marino {
2988e4b17023SJohn Marino   rtx insn = get_insns ();
2989e4b17023SJohn Marino 
2990e4b17023SJohn Marino   if (insn)
2991e4b17023SJohn Marino     {
2992e4b17023SJohn Marino       if (NOTE_P (insn))
2993e4b17023SJohn Marino 	for (insn = next_insn (insn);
2994e4b17023SJohn Marino 	     insn && NOTE_P (insn);
2995e4b17023SJohn Marino 	     insn = next_insn (insn))
2996e4b17023SJohn Marino 	  continue;
2997e4b17023SJohn Marino       else
2998e4b17023SJohn Marino 	{
2999e4b17023SJohn Marino 	  if (NONJUMP_INSN_P (insn)
3000e4b17023SJohn Marino 	      && GET_CODE (PATTERN (insn)) == SEQUENCE)
3001e4b17023SJohn Marino 	    insn = XVECEXP (PATTERN (insn), 0, 0);
3002e4b17023SJohn Marino 	}
3003e4b17023SJohn Marino     }
3004e4b17023SJohn Marino 
3005e4b17023SJohn Marino   return insn;
3006e4b17023SJohn Marino }
3007e4b17023SJohn Marino 
3008e4b17023SJohn Marino /* Return the last nonnote insn emitted in current sequence or current
3009e4b17023SJohn Marino    function.  This routine looks inside SEQUENCEs.  */
3010e4b17023SJohn Marino 
3011e4b17023SJohn Marino rtx
get_last_nonnote_insn(void)3012e4b17023SJohn Marino get_last_nonnote_insn (void)
3013e4b17023SJohn Marino {
3014e4b17023SJohn Marino   rtx insn = get_last_insn ();
3015e4b17023SJohn Marino 
3016e4b17023SJohn Marino   if (insn)
3017e4b17023SJohn Marino     {
3018e4b17023SJohn Marino       if (NOTE_P (insn))
3019e4b17023SJohn Marino 	for (insn = previous_insn (insn);
3020e4b17023SJohn Marino 	     insn && NOTE_P (insn);
3021e4b17023SJohn Marino 	     insn = previous_insn (insn))
3022e4b17023SJohn Marino 	  continue;
3023e4b17023SJohn Marino       else
3024e4b17023SJohn Marino 	{
3025e4b17023SJohn Marino 	  if (NONJUMP_INSN_P (insn)
3026e4b17023SJohn Marino 	      && GET_CODE (PATTERN (insn)) == SEQUENCE)
3027e4b17023SJohn Marino 	    insn = XVECEXP (PATTERN (insn), 0,
3028e4b17023SJohn Marino 			    XVECLEN (PATTERN (insn), 0) - 1);
3029e4b17023SJohn Marino 	}
3030e4b17023SJohn Marino     }
3031e4b17023SJohn Marino 
3032e4b17023SJohn Marino   return insn;
3033e4b17023SJohn Marino }
3034e4b17023SJohn Marino 
3035e4b17023SJohn Marino /* Return the number of actual (non-debug) insns emitted in this
3036e4b17023SJohn Marino    function.  */
3037e4b17023SJohn Marino 
3038e4b17023SJohn Marino int
get_max_insn_count(void)3039e4b17023SJohn Marino get_max_insn_count (void)
3040e4b17023SJohn Marino {
3041e4b17023SJohn Marino   int n = cur_insn_uid;
3042e4b17023SJohn Marino 
3043e4b17023SJohn Marino   /* The table size must be stable across -g, to avoid codegen
3044e4b17023SJohn Marino      differences due to debug insns, and not be affected by
3045e4b17023SJohn Marino      -fmin-insn-uid, to avoid excessive table size and to simplify
3046e4b17023SJohn Marino      debugging of -fcompare-debug failures.  */
3047e4b17023SJohn Marino   if (cur_debug_insn_uid > MIN_NONDEBUG_INSN_UID)
3048e4b17023SJohn Marino     n -= cur_debug_insn_uid;
3049e4b17023SJohn Marino   else
3050e4b17023SJohn Marino     n -= MIN_NONDEBUG_INSN_UID;
3051e4b17023SJohn Marino 
3052e4b17023SJohn Marino   return n;
3053e4b17023SJohn Marino }
3054e4b17023SJohn Marino 
3055e4b17023SJohn Marino 
3056e4b17023SJohn Marino /* Return the next insn.  If it is a SEQUENCE, return the first insn
3057e4b17023SJohn Marino    of the sequence.  */
3058e4b17023SJohn Marino 
3059e4b17023SJohn Marino rtx
next_insn(rtx insn)3060e4b17023SJohn Marino next_insn (rtx insn)
3061e4b17023SJohn Marino {
3062e4b17023SJohn Marino   if (insn)
3063e4b17023SJohn Marino     {
3064e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3065e4b17023SJohn Marino       if (insn && NONJUMP_INSN_P (insn)
3066e4b17023SJohn Marino 	  && GET_CODE (PATTERN (insn)) == SEQUENCE)
3067e4b17023SJohn Marino 	insn = XVECEXP (PATTERN (insn), 0, 0);
3068e4b17023SJohn Marino     }
3069e4b17023SJohn Marino 
3070e4b17023SJohn Marino   return insn;
3071e4b17023SJohn Marino }
3072e4b17023SJohn Marino 
3073e4b17023SJohn Marino /* Return the previous insn.  If it is a SEQUENCE, return the last insn
3074e4b17023SJohn Marino    of the sequence.  */
3075e4b17023SJohn Marino 
3076e4b17023SJohn Marino rtx
previous_insn(rtx insn)3077e4b17023SJohn Marino previous_insn (rtx insn)
3078e4b17023SJohn Marino {
3079e4b17023SJohn Marino   if (insn)
3080e4b17023SJohn Marino     {
3081e4b17023SJohn Marino       insn = PREV_INSN (insn);
3082e4b17023SJohn Marino       if (insn && NONJUMP_INSN_P (insn)
3083e4b17023SJohn Marino 	  && GET_CODE (PATTERN (insn)) == SEQUENCE)
3084e4b17023SJohn Marino 	insn = XVECEXP (PATTERN (insn), 0, XVECLEN (PATTERN (insn), 0) - 1);
3085e4b17023SJohn Marino     }
3086e4b17023SJohn Marino 
3087e4b17023SJohn Marino   return insn;
3088e4b17023SJohn Marino }
3089e4b17023SJohn Marino 
3090e4b17023SJohn Marino /* Return the next insn after INSN that is not a NOTE.  This routine does not
3091e4b17023SJohn Marino    look inside SEQUENCEs.  */
3092e4b17023SJohn Marino 
3093e4b17023SJohn Marino rtx
next_nonnote_insn(rtx insn)3094e4b17023SJohn Marino next_nonnote_insn (rtx insn)
3095e4b17023SJohn Marino {
3096e4b17023SJohn Marino   while (insn)
3097e4b17023SJohn Marino     {
3098e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3099e4b17023SJohn Marino       if (insn == 0 || !NOTE_P (insn))
3100e4b17023SJohn Marino 	break;
3101e4b17023SJohn Marino     }
3102e4b17023SJohn Marino 
3103e4b17023SJohn Marino   return insn;
3104e4b17023SJohn Marino }
3105e4b17023SJohn Marino 
3106e4b17023SJohn Marino /* Return the next insn after INSN that is not a NOTE, but stop the
3107e4b17023SJohn Marino    search before we enter another basic block.  This routine does not
3108e4b17023SJohn Marino    look inside SEQUENCEs.  */
3109e4b17023SJohn Marino 
3110e4b17023SJohn Marino rtx
next_nonnote_insn_bb(rtx insn)3111e4b17023SJohn Marino next_nonnote_insn_bb (rtx insn)
3112e4b17023SJohn Marino {
3113e4b17023SJohn Marino   while (insn)
3114e4b17023SJohn Marino     {
3115e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3116e4b17023SJohn Marino       if (insn == 0 || !NOTE_P (insn))
3117e4b17023SJohn Marino 	break;
3118e4b17023SJohn Marino       if (NOTE_INSN_BASIC_BLOCK_P (insn))
3119e4b17023SJohn Marino 	return NULL_RTX;
3120e4b17023SJohn Marino     }
3121e4b17023SJohn Marino 
3122e4b17023SJohn Marino   return insn;
3123e4b17023SJohn Marino }
3124e4b17023SJohn Marino 
3125e4b17023SJohn Marino /* Return the previous insn before INSN that is not a NOTE.  This routine does
3126e4b17023SJohn Marino    not look inside SEQUENCEs.  */
3127e4b17023SJohn Marino 
3128e4b17023SJohn Marino rtx
prev_nonnote_insn(rtx insn)3129e4b17023SJohn Marino prev_nonnote_insn (rtx insn)
3130e4b17023SJohn Marino {
3131e4b17023SJohn Marino   while (insn)
3132e4b17023SJohn Marino     {
3133e4b17023SJohn Marino       insn = PREV_INSN (insn);
3134e4b17023SJohn Marino       if (insn == 0 || !NOTE_P (insn))
3135e4b17023SJohn Marino 	break;
3136e4b17023SJohn Marino     }
3137e4b17023SJohn Marino 
3138e4b17023SJohn Marino   return insn;
3139e4b17023SJohn Marino }
3140e4b17023SJohn Marino 
3141e4b17023SJohn Marino /* Return the previous insn before INSN that is not a NOTE, but stop
3142e4b17023SJohn Marino    the search before we enter another basic block.  This routine does
3143e4b17023SJohn Marino    not look inside SEQUENCEs.  */
3144e4b17023SJohn Marino 
3145e4b17023SJohn Marino rtx
prev_nonnote_insn_bb(rtx insn)3146e4b17023SJohn Marino prev_nonnote_insn_bb (rtx insn)
3147e4b17023SJohn Marino {
3148e4b17023SJohn Marino   while (insn)
3149e4b17023SJohn Marino     {
3150e4b17023SJohn Marino       insn = PREV_INSN (insn);
3151e4b17023SJohn Marino       if (insn == 0 || !NOTE_P (insn))
3152e4b17023SJohn Marino 	break;
3153e4b17023SJohn Marino       if (NOTE_INSN_BASIC_BLOCK_P (insn))
3154e4b17023SJohn Marino 	return NULL_RTX;
3155e4b17023SJohn Marino     }
3156e4b17023SJohn Marino 
3157e4b17023SJohn Marino   return insn;
3158e4b17023SJohn Marino }
3159e4b17023SJohn Marino 
3160e4b17023SJohn Marino /* Return the next insn after INSN that is not a DEBUG_INSN.  This
3161e4b17023SJohn Marino    routine does not look inside SEQUENCEs.  */
3162e4b17023SJohn Marino 
3163e4b17023SJohn Marino rtx
next_nondebug_insn(rtx insn)3164e4b17023SJohn Marino next_nondebug_insn (rtx insn)
3165e4b17023SJohn Marino {
3166e4b17023SJohn Marino   while (insn)
3167e4b17023SJohn Marino     {
3168e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3169e4b17023SJohn Marino       if (insn == 0 || !DEBUG_INSN_P (insn))
3170e4b17023SJohn Marino 	break;
3171e4b17023SJohn Marino     }
3172e4b17023SJohn Marino 
3173e4b17023SJohn Marino   return insn;
3174e4b17023SJohn Marino }
3175e4b17023SJohn Marino 
3176e4b17023SJohn Marino /* Return the previous insn before INSN that is not a DEBUG_INSN.
3177e4b17023SJohn Marino    This routine does not look inside SEQUENCEs.  */
3178e4b17023SJohn Marino 
3179e4b17023SJohn Marino rtx
prev_nondebug_insn(rtx insn)3180e4b17023SJohn Marino prev_nondebug_insn (rtx insn)
3181e4b17023SJohn Marino {
3182e4b17023SJohn Marino   while (insn)
3183e4b17023SJohn Marino     {
3184e4b17023SJohn Marino       insn = PREV_INSN (insn);
3185e4b17023SJohn Marino       if (insn == 0 || !DEBUG_INSN_P (insn))
3186e4b17023SJohn Marino 	break;
3187e4b17023SJohn Marino     }
3188e4b17023SJohn Marino 
3189e4b17023SJohn Marino   return insn;
3190e4b17023SJohn Marino }
3191e4b17023SJohn Marino 
3192e4b17023SJohn Marino /* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN.
3193e4b17023SJohn Marino    This routine does not look inside SEQUENCEs.  */
3194e4b17023SJohn Marino 
3195e4b17023SJohn Marino rtx
next_nonnote_nondebug_insn(rtx insn)3196e4b17023SJohn Marino next_nonnote_nondebug_insn (rtx insn)
3197e4b17023SJohn Marino {
3198e4b17023SJohn Marino   while (insn)
3199e4b17023SJohn Marino     {
3200e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3201e4b17023SJohn Marino       if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
3202e4b17023SJohn Marino 	break;
3203e4b17023SJohn Marino     }
3204e4b17023SJohn Marino 
3205e4b17023SJohn Marino   return insn;
3206e4b17023SJohn Marino }
3207e4b17023SJohn Marino 
3208e4b17023SJohn Marino /* Return the previous insn before INSN that is not a NOTE nor DEBUG_INSN.
3209e4b17023SJohn Marino    This routine does not look inside SEQUENCEs.  */
3210e4b17023SJohn Marino 
3211e4b17023SJohn Marino rtx
prev_nonnote_nondebug_insn(rtx insn)3212e4b17023SJohn Marino prev_nonnote_nondebug_insn (rtx insn)
3213e4b17023SJohn Marino {
3214e4b17023SJohn Marino   while (insn)
3215e4b17023SJohn Marino     {
3216e4b17023SJohn Marino       insn = PREV_INSN (insn);
3217e4b17023SJohn Marino       if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
3218e4b17023SJohn Marino 	break;
3219e4b17023SJohn Marino     }
3220e4b17023SJohn Marino 
3221e4b17023SJohn Marino   return insn;
3222e4b17023SJohn Marino }
3223e4b17023SJohn Marino 
3224e4b17023SJohn Marino /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
3225e4b17023SJohn Marino    or 0, if there is none.  This routine does not look inside
3226e4b17023SJohn Marino    SEQUENCEs.  */
3227e4b17023SJohn Marino 
3228e4b17023SJohn Marino rtx
next_real_insn(rtx insn)3229e4b17023SJohn Marino next_real_insn (rtx insn)
3230e4b17023SJohn Marino {
3231e4b17023SJohn Marino   while (insn)
3232e4b17023SJohn Marino     {
3233e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3234e4b17023SJohn Marino       if (insn == 0 || INSN_P (insn))
3235e4b17023SJohn Marino 	break;
3236e4b17023SJohn Marino     }
3237e4b17023SJohn Marino 
3238e4b17023SJohn Marino   return insn;
3239e4b17023SJohn Marino }
3240e4b17023SJohn Marino 
3241e4b17023SJohn Marino /* Return the last INSN, CALL_INSN or JUMP_INSN before INSN;
3242e4b17023SJohn Marino    or 0, if there is none.  This routine does not look inside
3243e4b17023SJohn Marino    SEQUENCEs.  */
3244e4b17023SJohn Marino 
3245e4b17023SJohn Marino rtx
prev_real_insn(rtx insn)3246e4b17023SJohn Marino prev_real_insn (rtx insn)
3247e4b17023SJohn Marino {
3248e4b17023SJohn Marino   while (insn)
3249e4b17023SJohn Marino     {
3250e4b17023SJohn Marino       insn = PREV_INSN (insn);
3251e4b17023SJohn Marino       if (insn == 0 || INSN_P (insn))
3252e4b17023SJohn Marino 	break;
3253e4b17023SJohn Marino     }
3254e4b17023SJohn Marino 
3255e4b17023SJohn Marino   return insn;
3256e4b17023SJohn Marino }
3257e4b17023SJohn Marino 
3258e4b17023SJohn Marino /* Return the last CALL_INSN in the current list, or 0 if there is none.
3259e4b17023SJohn Marino    This routine does not look inside SEQUENCEs.  */
3260e4b17023SJohn Marino 
3261e4b17023SJohn Marino rtx
last_call_insn(void)3262e4b17023SJohn Marino last_call_insn (void)
3263e4b17023SJohn Marino {
3264e4b17023SJohn Marino   rtx insn;
3265e4b17023SJohn Marino 
3266e4b17023SJohn Marino   for (insn = get_last_insn ();
3267e4b17023SJohn Marino        insn && !CALL_P (insn);
3268e4b17023SJohn Marino        insn = PREV_INSN (insn))
3269e4b17023SJohn Marino     ;
3270e4b17023SJohn Marino 
3271e4b17023SJohn Marino   return insn;
3272e4b17023SJohn Marino }
3273e4b17023SJohn Marino 
3274e4b17023SJohn Marino /* Find the next insn after INSN that really does something.  This routine
3275e4b17023SJohn Marino    does not look inside SEQUENCEs.  After reload this also skips over
3276e4b17023SJohn Marino    standalone USE and CLOBBER insn.  */
3277e4b17023SJohn Marino 
3278e4b17023SJohn Marino int
active_insn_p(const_rtx insn)3279e4b17023SJohn Marino active_insn_p (const_rtx insn)
3280e4b17023SJohn Marino {
3281e4b17023SJohn Marino   return (CALL_P (insn) || JUMP_P (insn)
3282e4b17023SJohn Marino 	  || (NONJUMP_INSN_P (insn)
3283e4b17023SJohn Marino 	      && (! reload_completed
3284e4b17023SJohn Marino 		  || (GET_CODE (PATTERN (insn)) != USE
3285e4b17023SJohn Marino 		      && GET_CODE (PATTERN (insn)) != CLOBBER))));
3286e4b17023SJohn Marino }
3287e4b17023SJohn Marino 
3288e4b17023SJohn Marino rtx
next_active_insn(rtx insn)3289e4b17023SJohn Marino next_active_insn (rtx insn)
3290e4b17023SJohn Marino {
3291e4b17023SJohn Marino   while (insn)
3292e4b17023SJohn Marino     {
3293e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3294e4b17023SJohn Marino       if (insn == 0 || active_insn_p (insn))
3295e4b17023SJohn Marino 	break;
3296e4b17023SJohn Marino     }
3297e4b17023SJohn Marino 
3298e4b17023SJohn Marino   return insn;
3299e4b17023SJohn Marino }
3300e4b17023SJohn Marino 
3301e4b17023SJohn Marino /* Find the last insn before INSN that really does something.  This routine
3302e4b17023SJohn Marino    does not look inside SEQUENCEs.  After reload this also skips over
3303e4b17023SJohn Marino    standalone USE and CLOBBER insn.  */
3304e4b17023SJohn Marino 
3305e4b17023SJohn Marino rtx
prev_active_insn(rtx insn)3306e4b17023SJohn Marino prev_active_insn (rtx insn)
3307e4b17023SJohn Marino {
3308e4b17023SJohn Marino   while (insn)
3309e4b17023SJohn Marino     {
3310e4b17023SJohn Marino       insn = PREV_INSN (insn);
3311e4b17023SJohn Marino       if (insn == 0 || active_insn_p (insn))
3312e4b17023SJohn Marino 	break;
3313e4b17023SJohn Marino     }
3314e4b17023SJohn Marino 
3315e4b17023SJohn Marino   return insn;
3316e4b17023SJohn Marino }
3317e4b17023SJohn Marino 
3318e4b17023SJohn Marino /* Return the next CODE_LABEL after the insn INSN, or 0 if there is none.  */
3319e4b17023SJohn Marino 
3320e4b17023SJohn Marino rtx
next_label(rtx insn)3321e4b17023SJohn Marino next_label (rtx insn)
3322e4b17023SJohn Marino {
3323e4b17023SJohn Marino   while (insn)
3324e4b17023SJohn Marino     {
3325e4b17023SJohn Marino       insn = NEXT_INSN (insn);
3326e4b17023SJohn Marino       if (insn == 0 || LABEL_P (insn))
3327e4b17023SJohn Marino 	break;
3328e4b17023SJohn Marino     }
3329e4b17023SJohn Marino 
3330e4b17023SJohn Marino   return insn;
3331e4b17023SJohn Marino }
3332e4b17023SJohn Marino 
3333e4b17023SJohn Marino /* Return the last label to mark the same position as LABEL.  Return LABEL
3334e4b17023SJohn Marino    itself if it is null or any return rtx.  */
3335e4b17023SJohn Marino 
3336e4b17023SJohn Marino rtx
skip_consecutive_labels(rtx label)3337e4b17023SJohn Marino skip_consecutive_labels (rtx label)
3338e4b17023SJohn Marino {
3339e4b17023SJohn Marino   rtx insn;
3340e4b17023SJohn Marino 
3341e4b17023SJohn Marino   if (label && ANY_RETURN_P (label))
3342e4b17023SJohn Marino     return label;
3343e4b17023SJohn Marino 
3344e4b17023SJohn Marino   for (insn = label; insn != 0 && !INSN_P (insn); insn = NEXT_INSN (insn))
3345e4b17023SJohn Marino     if (LABEL_P (insn))
3346e4b17023SJohn Marino       label = insn;
3347e4b17023SJohn Marino 
3348e4b17023SJohn Marino   return label;
3349e4b17023SJohn Marino }
3350e4b17023SJohn Marino 
3351e4b17023SJohn Marino #ifdef HAVE_cc0
3352e4b17023SJohn Marino /* INSN uses CC0 and is being moved into a delay slot.  Set up REG_CC_SETTER
3353e4b17023SJohn Marino    and REG_CC_USER notes so we can find it.  */
3354e4b17023SJohn Marino 
3355e4b17023SJohn Marino void
link_cc0_insns(rtx insn)3356e4b17023SJohn Marino link_cc0_insns (rtx insn)
3357e4b17023SJohn Marino {
3358e4b17023SJohn Marino   rtx user = next_nonnote_insn (insn);
3359e4b17023SJohn Marino 
3360e4b17023SJohn Marino   if (NONJUMP_INSN_P (user) && GET_CODE (PATTERN (user)) == SEQUENCE)
3361e4b17023SJohn Marino     user = XVECEXP (PATTERN (user), 0, 0);
3362e4b17023SJohn Marino 
3363e4b17023SJohn Marino   add_reg_note (user, REG_CC_SETTER, insn);
3364e4b17023SJohn Marino   add_reg_note (insn, REG_CC_USER, user);
3365e4b17023SJohn Marino }
3366e4b17023SJohn Marino 
3367e4b17023SJohn Marino /* Return the next insn that uses CC0 after INSN, which is assumed to
3368e4b17023SJohn Marino    set it.  This is the inverse of prev_cc0_setter (i.e., prev_cc0_setter
3369e4b17023SJohn Marino    applied to the result of this function should yield INSN).
3370e4b17023SJohn Marino 
3371e4b17023SJohn Marino    Normally, this is simply the next insn.  However, if a REG_CC_USER note
3372e4b17023SJohn Marino    is present, it contains the insn that uses CC0.
3373e4b17023SJohn Marino 
3374e4b17023SJohn Marino    Return 0 if we can't find the insn.  */
3375e4b17023SJohn Marino 
3376e4b17023SJohn Marino rtx
next_cc0_user(rtx insn)3377e4b17023SJohn Marino next_cc0_user (rtx insn)
3378e4b17023SJohn Marino {
3379e4b17023SJohn Marino   rtx note = find_reg_note (insn, REG_CC_USER, NULL_RTX);
3380e4b17023SJohn Marino 
3381e4b17023SJohn Marino   if (note)
3382e4b17023SJohn Marino     return XEXP (note, 0);
3383e4b17023SJohn Marino 
3384e4b17023SJohn Marino   insn = next_nonnote_insn (insn);
3385e4b17023SJohn Marino   if (insn && NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
3386e4b17023SJohn Marino     insn = XVECEXP (PATTERN (insn), 0, 0);
3387e4b17023SJohn Marino 
3388e4b17023SJohn Marino   if (insn && INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
3389e4b17023SJohn Marino     return insn;
3390e4b17023SJohn Marino 
3391e4b17023SJohn Marino   return 0;
3392e4b17023SJohn Marino }
3393e4b17023SJohn Marino 
3394e4b17023SJohn Marino /* Find the insn that set CC0 for INSN.  Unless INSN has a REG_CC_SETTER
3395e4b17023SJohn Marino    note, it is the previous insn.  */
3396e4b17023SJohn Marino 
3397e4b17023SJohn Marino rtx
prev_cc0_setter(rtx insn)3398e4b17023SJohn Marino prev_cc0_setter (rtx insn)
3399e4b17023SJohn Marino {
3400e4b17023SJohn Marino   rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
3401e4b17023SJohn Marino 
3402e4b17023SJohn Marino   if (note)
3403e4b17023SJohn Marino     return XEXP (note, 0);
3404e4b17023SJohn Marino 
3405e4b17023SJohn Marino   insn = prev_nonnote_insn (insn);
3406e4b17023SJohn Marino   gcc_assert (sets_cc0_p (PATTERN (insn)));
3407e4b17023SJohn Marino 
3408e4b17023SJohn Marino   return insn;
3409e4b17023SJohn Marino }
3410e4b17023SJohn Marino #endif
3411e4b17023SJohn Marino 
3412e4b17023SJohn Marino #ifdef AUTO_INC_DEC
3413e4b17023SJohn Marino /* Find a RTX_AUTOINC class rtx which matches DATA.  */
3414e4b17023SJohn Marino 
3415e4b17023SJohn Marino static int
find_auto_inc(rtx * xp,void * data)3416e4b17023SJohn Marino find_auto_inc (rtx *xp, void *data)
3417e4b17023SJohn Marino {
3418e4b17023SJohn Marino   rtx x = *xp;
3419e4b17023SJohn Marino   rtx reg = (rtx) data;
3420e4b17023SJohn Marino 
3421e4b17023SJohn Marino   if (GET_RTX_CLASS (GET_CODE (x)) != RTX_AUTOINC)
3422e4b17023SJohn Marino     return 0;
3423e4b17023SJohn Marino 
3424e4b17023SJohn Marino   switch (GET_CODE (x))
3425e4b17023SJohn Marino     {
3426e4b17023SJohn Marino       case PRE_DEC:
3427e4b17023SJohn Marino       case PRE_INC:
3428e4b17023SJohn Marino       case POST_DEC:
3429e4b17023SJohn Marino       case POST_INC:
3430e4b17023SJohn Marino       case PRE_MODIFY:
3431e4b17023SJohn Marino       case POST_MODIFY:
3432e4b17023SJohn Marino 	if (rtx_equal_p (reg, XEXP (x, 0)))
3433e4b17023SJohn Marino 	  return 1;
3434e4b17023SJohn Marino 	break;
3435e4b17023SJohn Marino 
3436e4b17023SJohn Marino       default:
3437e4b17023SJohn Marino 	gcc_unreachable ();
3438e4b17023SJohn Marino     }
3439e4b17023SJohn Marino   return -1;
3440e4b17023SJohn Marino }
3441e4b17023SJohn Marino #endif
3442e4b17023SJohn Marino 
3443e4b17023SJohn Marino /* Increment the label uses for all labels present in rtx.  */
3444e4b17023SJohn Marino 
3445e4b17023SJohn Marino static void
mark_label_nuses(rtx x)3446e4b17023SJohn Marino mark_label_nuses (rtx x)
3447e4b17023SJohn Marino {
3448e4b17023SJohn Marino   enum rtx_code code;
3449e4b17023SJohn Marino   int i, j;
3450e4b17023SJohn Marino   const char *fmt;
3451e4b17023SJohn Marino 
3452e4b17023SJohn Marino   code = GET_CODE (x);
3453e4b17023SJohn Marino   if (code == LABEL_REF && LABEL_P (XEXP (x, 0)))
3454e4b17023SJohn Marino     LABEL_NUSES (XEXP (x, 0))++;
3455e4b17023SJohn Marino 
3456e4b17023SJohn Marino   fmt = GET_RTX_FORMAT (code);
3457e4b17023SJohn Marino   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3458e4b17023SJohn Marino     {
3459e4b17023SJohn Marino       if (fmt[i] == 'e')
3460e4b17023SJohn Marino 	mark_label_nuses (XEXP (x, i));
3461e4b17023SJohn Marino       else if (fmt[i] == 'E')
3462e4b17023SJohn Marino 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3463e4b17023SJohn Marino 	  mark_label_nuses (XVECEXP (x, i, j));
3464e4b17023SJohn Marino     }
3465e4b17023SJohn Marino }
3466e4b17023SJohn Marino 
3467e4b17023SJohn Marino 
3468e4b17023SJohn Marino /* Try splitting insns that can be split for better scheduling.
3469e4b17023SJohn Marino    PAT is the pattern which might split.
3470e4b17023SJohn Marino    TRIAL is the insn providing PAT.
3471e4b17023SJohn Marino    LAST is nonzero if we should return the last insn of the sequence produced.
3472e4b17023SJohn Marino 
3473e4b17023SJohn Marino    If this routine succeeds in splitting, it returns the first or last
3474e4b17023SJohn Marino    replacement insn depending on the value of LAST.  Otherwise, it
3475e4b17023SJohn Marino    returns TRIAL.  If the insn to be returned can be split, it will be.  */
3476e4b17023SJohn Marino 
3477e4b17023SJohn Marino rtx
try_split(rtx pat,rtx trial,int last)3478e4b17023SJohn Marino try_split (rtx pat, rtx trial, int last)
3479e4b17023SJohn Marino {
3480e4b17023SJohn Marino   rtx before = PREV_INSN (trial);
3481e4b17023SJohn Marino   rtx after = NEXT_INSN (trial);
3482e4b17023SJohn Marino   int has_barrier = 0;
3483e4b17023SJohn Marino   rtx note, seq, tem;
3484e4b17023SJohn Marino   int probability;
3485e4b17023SJohn Marino   rtx insn_last, insn;
3486e4b17023SJohn Marino   int njumps = 0;
3487e4b17023SJohn Marino 
3488e4b17023SJohn Marino   /* We're not good at redistributing frame information.  */
3489e4b17023SJohn Marino   if (RTX_FRAME_RELATED_P (trial))
3490e4b17023SJohn Marino     return trial;
3491e4b17023SJohn Marino 
3492e4b17023SJohn Marino   if (any_condjump_p (trial)
3493e4b17023SJohn Marino       && (note = find_reg_note (trial, REG_BR_PROB, 0)))
3494e4b17023SJohn Marino     split_branch_probability = INTVAL (XEXP (note, 0));
3495e4b17023SJohn Marino   probability = split_branch_probability;
3496e4b17023SJohn Marino 
3497e4b17023SJohn Marino   seq = split_insns (pat, trial);
3498e4b17023SJohn Marino 
3499e4b17023SJohn Marino   split_branch_probability = -1;
3500e4b17023SJohn Marino 
3501e4b17023SJohn Marino   /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER.
3502e4b17023SJohn Marino      We may need to handle this specially.  */
3503e4b17023SJohn Marino   if (after && BARRIER_P (after))
3504e4b17023SJohn Marino     {
3505e4b17023SJohn Marino       has_barrier = 1;
3506e4b17023SJohn Marino       after = NEXT_INSN (after);
3507e4b17023SJohn Marino     }
3508e4b17023SJohn Marino 
3509e4b17023SJohn Marino   if (!seq)
3510e4b17023SJohn Marino     return trial;
3511e4b17023SJohn Marino 
3512e4b17023SJohn Marino   /* Avoid infinite loop if any insn of the result matches
3513e4b17023SJohn Marino      the original pattern.  */
3514e4b17023SJohn Marino   insn_last = seq;
3515e4b17023SJohn Marino   while (1)
3516e4b17023SJohn Marino     {
3517e4b17023SJohn Marino       if (INSN_P (insn_last)
3518e4b17023SJohn Marino 	  && rtx_equal_p (PATTERN (insn_last), pat))
3519e4b17023SJohn Marino 	return trial;
3520e4b17023SJohn Marino       if (!NEXT_INSN (insn_last))
3521e4b17023SJohn Marino 	break;
3522e4b17023SJohn Marino       insn_last = NEXT_INSN (insn_last);
3523e4b17023SJohn Marino     }
3524e4b17023SJohn Marino 
3525e4b17023SJohn Marino   /* We will be adding the new sequence to the function.  The splitters
3526e4b17023SJohn Marino      may have introduced invalid RTL sharing, so unshare the sequence now.  */
3527e4b17023SJohn Marino   unshare_all_rtl_in_chain (seq);
3528e4b17023SJohn Marino 
3529e4b17023SJohn Marino   /* Mark labels.  */
3530e4b17023SJohn Marino   for (insn = insn_last; insn ; insn = PREV_INSN (insn))
3531e4b17023SJohn Marino     {
3532e4b17023SJohn Marino       if (JUMP_P (insn))
3533e4b17023SJohn Marino 	{
3534e4b17023SJohn Marino 	  mark_jump_label (PATTERN (insn), insn, 0);
3535e4b17023SJohn Marino 	  njumps++;
3536e4b17023SJohn Marino 	  if (probability != -1
3537e4b17023SJohn Marino 	      && any_condjump_p (insn)
3538e4b17023SJohn Marino 	      && !find_reg_note (insn, REG_BR_PROB, 0))
3539e4b17023SJohn Marino 	    {
3540e4b17023SJohn Marino 	      /* We can preserve the REG_BR_PROB notes only if exactly
3541e4b17023SJohn Marino 		 one jump is created, otherwise the machine description
3542e4b17023SJohn Marino 		 is responsible for this step using
3543e4b17023SJohn Marino 		 split_branch_probability variable.  */
3544e4b17023SJohn Marino 	      gcc_assert (njumps == 1);
3545e4b17023SJohn Marino 	      add_reg_note (insn, REG_BR_PROB, GEN_INT (probability));
3546e4b17023SJohn Marino 	    }
3547e4b17023SJohn Marino 	}
3548e4b17023SJohn Marino     }
3549e4b17023SJohn Marino 
3550e4b17023SJohn Marino   /* If we are splitting a CALL_INSN, look for the CALL_INSN
3551e4b17023SJohn Marino      in SEQ and copy any additional information across.  */
3552e4b17023SJohn Marino   if (CALL_P (trial))
3553e4b17023SJohn Marino     {
3554e4b17023SJohn Marino       for (insn = insn_last; insn ; insn = PREV_INSN (insn))
3555e4b17023SJohn Marino 	if (CALL_P (insn))
3556e4b17023SJohn Marino 	  {
3557e4b17023SJohn Marino 	    rtx next, *p;
3558e4b17023SJohn Marino 
3559e4b17023SJohn Marino 	    /* Add the old CALL_INSN_FUNCTION_USAGE to whatever the
3560e4b17023SJohn Marino 	       target may have explicitly specified.  */
3561e4b17023SJohn Marino 	    p = &CALL_INSN_FUNCTION_USAGE (insn);
3562e4b17023SJohn Marino 	    while (*p)
3563e4b17023SJohn Marino 	      p = &XEXP (*p, 1);
3564e4b17023SJohn Marino 	    *p = CALL_INSN_FUNCTION_USAGE (trial);
3565e4b17023SJohn Marino 
3566e4b17023SJohn Marino 	    /* If the old call was a sibling call, the new one must
3567e4b17023SJohn Marino 	       be too.  */
3568e4b17023SJohn Marino 	    SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
3569e4b17023SJohn Marino 
3570e4b17023SJohn Marino 	    /* If the new call is the last instruction in the sequence,
3571e4b17023SJohn Marino 	       it will effectively replace the old call in-situ.  Otherwise
3572e4b17023SJohn Marino 	       we must move any following NOTE_INSN_CALL_ARG_LOCATION note
3573e4b17023SJohn Marino 	       so that it comes immediately after the new call.  */
3574e4b17023SJohn Marino 	    if (NEXT_INSN (insn))
3575e4b17023SJohn Marino 	      for (next = NEXT_INSN (trial);
3576e4b17023SJohn Marino 		   next && NOTE_P (next);
3577e4b17023SJohn Marino 		   next = NEXT_INSN (next))
3578e4b17023SJohn Marino 		if (NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
3579e4b17023SJohn Marino 		  {
3580e4b17023SJohn Marino 		    remove_insn (next);
3581e4b17023SJohn Marino 		    add_insn_after (next, insn, NULL);
3582e4b17023SJohn Marino 		    break;
3583e4b17023SJohn Marino 		  }
3584e4b17023SJohn Marino 	  }
3585e4b17023SJohn Marino     }
3586e4b17023SJohn Marino 
3587e4b17023SJohn Marino   /* Copy notes, particularly those related to the CFG.  */
3588e4b17023SJohn Marino   for (note = REG_NOTES (trial); note; note = XEXP (note, 1))
3589e4b17023SJohn Marino     {
3590e4b17023SJohn Marino       switch (REG_NOTE_KIND (note))
3591e4b17023SJohn Marino 	{
3592e4b17023SJohn Marino 	case REG_EH_REGION:
3593e4b17023SJohn Marino 	  copy_reg_eh_region_note_backward (note, insn_last, NULL);
3594e4b17023SJohn Marino 	  break;
3595e4b17023SJohn Marino 
3596e4b17023SJohn Marino 	case REG_NORETURN:
3597e4b17023SJohn Marino 	case REG_SETJMP:
3598e4b17023SJohn Marino 	case REG_TM:
3599e4b17023SJohn Marino 	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
3600e4b17023SJohn Marino 	    {
3601e4b17023SJohn Marino 	      if (CALL_P (insn))
3602e4b17023SJohn Marino 		add_reg_note (insn, REG_NOTE_KIND (note), XEXP (note, 0));
3603e4b17023SJohn Marino 	    }
3604e4b17023SJohn Marino 	  break;
3605e4b17023SJohn Marino 
3606e4b17023SJohn Marino 	case REG_NON_LOCAL_GOTO:
3607e4b17023SJohn Marino 	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
3608e4b17023SJohn Marino 	    {
3609e4b17023SJohn Marino 	      if (JUMP_P (insn))
3610e4b17023SJohn Marino 		add_reg_note (insn, REG_NOTE_KIND (note), XEXP (note, 0));
3611e4b17023SJohn Marino 	    }
3612e4b17023SJohn Marino 	  break;
3613e4b17023SJohn Marino 
3614e4b17023SJohn Marino #ifdef AUTO_INC_DEC
3615e4b17023SJohn Marino 	case REG_INC:
3616e4b17023SJohn Marino 	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
3617e4b17023SJohn Marino 	    {
3618e4b17023SJohn Marino 	      rtx reg = XEXP (note, 0);
3619e4b17023SJohn Marino 	      if (!FIND_REG_INC_NOTE (insn, reg)
3620e4b17023SJohn Marino 		  && for_each_rtx (&PATTERN (insn), find_auto_inc, reg) > 0)
3621e4b17023SJohn Marino 		add_reg_note (insn, REG_INC, reg);
3622e4b17023SJohn Marino 	    }
3623e4b17023SJohn Marino 	  break;
3624e4b17023SJohn Marino #endif
3625e4b17023SJohn Marino 
3626e4b17023SJohn Marino 	case REG_ARGS_SIZE:
3627e4b17023SJohn Marino 	  fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0)));
3628e4b17023SJohn Marino 	  break;
3629e4b17023SJohn Marino 
3630e4b17023SJohn Marino 	default:
3631e4b17023SJohn Marino 	  break;
3632e4b17023SJohn Marino 	}
3633e4b17023SJohn Marino     }
3634e4b17023SJohn Marino 
3635e4b17023SJohn Marino   /* If there are LABELS inside the split insns increment the
3636e4b17023SJohn Marino      usage count so we don't delete the label.  */
3637e4b17023SJohn Marino   if (INSN_P (trial))
3638e4b17023SJohn Marino     {
3639e4b17023SJohn Marino       insn = insn_last;
3640e4b17023SJohn Marino       while (insn != NULL_RTX)
3641e4b17023SJohn Marino 	{
3642e4b17023SJohn Marino 	  /* JUMP_P insns have already been "marked" above.  */
3643e4b17023SJohn Marino 	  if (NONJUMP_INSN_P (insn))
3644e4b17023SJohn Marino 	    mark_label_nuses (PATTERN (insn));
3645e4b17023SJohn Marino 
3646e4b17023SJohn Marino 	  insn = PREV_INSN (insn);
3647e4b17023SJohn Marino 	}
3648e4b17023SJohn Marino     }
3649e4b17023SJohn Marino 
3650e4b17023SJohn Marino   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));
3651e4b17023SJohn Marino 
3652e4b17023SJohn Marino   delete_insn (trial);
3653e4b17023SJohn Marino   if (has_barrier)
3654e4b17023SJohn Marino     emit_barrier_after (tem);
3655e4b17023SJohn Marino 
3656e4b17023SJohn Marino   /* Recursively call try_split for each new insn created; by the
3657e4b17023SJohn Marino      time control returns here that insn will be fully split, so
3658e4b17023SJohn Marino      set LAST and continue from the insn after the one returned.
3659e4b17023SJohn Marino      We can't use next_active_insn here since AFTER may be a note.
3660e4b17023SJohn Marino      Ignore deleted insns, which can be occur if not optimizing.  */
3661e4b17023SJohn Marino   for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
3662e4b17023SJohn Marino     if (! INSN_DELETED_P (tem) && INSN_P (tem))
3663e4b17023SJohn Marino       tem = try_split (PATTERN (tem), tem, 1);
3664e4b17023SJohn Marino 
3665e4b17023SJohn Marino   /* Return either the first or the last insn, depending on which was
3666e4b17023SJohn Marino      requested.  */
3667e4b17023SJohn Marino   return last
3668e4b17023SJohn Marino     ? (after ? PREV_INSN (after) : get_last_insn ())
3669e4b17023SJohn Marino     : NEXT_INSN (before);
3670e4b17023SJohn Marino }
3671e4b17023SJohn Marino 
3672e4b17023SJohn Marino /* Make and return an INSN rtx, initializing all its slots.
3673e4b17023SJohn Marino    Store PATTERN in the pattern slots.  */
3674e4b17023SJohn Marino 
3675e4b17023SJohn Marino rtx
make_insn_raw(rtx pattern)3676e4b17023SJohn Marino make_insn_raw (rtx pattern)
3677e4b17023SJohn Marino {
3678e4b17023SJohn Marino   rtx insn;
3679e4b17023SJohn Marino 
3680e4b17023SJohn Marino   insn = rtx_alloc (INSN);
3681e4b17023SJohn Marino 
3682e4b17023SJohn Marino   INSN_UID (insn) = cur_insn_uid++;
3683e4b17023SJohn Marino   PATTERN (insn) = pattern;
3684e4b17023SJohn Marino   INSN_CODE (insn) = -1;
3685e4b17023SJohn Marino   REG_NOTES (insn) = NULL;
3686e4b17023SJohn Marino   INSN_LOCATOR (insn) = curr_insn_locator ();
3687e4b17023SJohn Marino   BLOCK_FOR_INSN (insn) = NULL;
3688e4b17023SJohn Marino 
3689e4b17023SJohn Marino #ifdef ENABLE_RTL_CHECKING
3690e4b17023SJohn Marino   if (insn
3691e4b17023SJohn Marino       && INSN_P (insn)
3692e4b17023SJohn Marino       && (returnjump_p (insn)
3693e4b17023SJohn Marino 	  || (GET_CODE (insn) == SET
3694e4b17023SJohn Marino 	      && SET_DEST (insn) == pc_rtx)))
3695e4b17023SJohn Marino     {
3696e4b17023SJohn Marino       warning (0, "ICE: emit_insn used where emit_jump_insn needed:\n");
3697e4b17023SJohn Marino       debug_rtx (insn);
3698e4b17023SJohn Marino     }
3699e4b17023SJohn Marino #endif
3700e4b17023SJohn Marino 
3701e4b17023SJohn Marino   return insn;
3702e4b17023SJohn Marino }
3703e4b17023SJohn Marino 
3704e4b17023SJohn Marino /* Like `make_insn_raw' but make a DEBUG_INSN instead of an insn.  */
3705e4b17023SJohn Marino 
3706e4b17023SJohn Marino rtx
make_debug_insn_raw(rtx pattern)3707e4b17023SJohn Marino make_debug_insn_raw (rtx pattern)
3708e4b17023SJohn Marino {
3709e4b17023SJohn Marino   rtx insn;
3710e4b17023SJohn Marino 
3711e4b17023SJohn Marino   insn = rtx_alloc (DEBUG_INSN);
3712e4b17023SJohn Marino   INSN_UID (insn) = cur_debug_insn_uid++;
3713e4b17023SJohn Marino   if (cur_debug_insn_uid > MIN_NONDEBUG_INSN_UID)
3714e4b17023SJohn Marino     INSN_UID (insn) = cur_insn_uid++;
3715e4b17023SJohn Marino 
3716e4b17023SJohn Marino   PATTERN (insn) = pattern;
3717e4b17023SJohn Marino   INSN_CODE (insn) = -1;
3718e4b17023SJohn Marino   REG_NOTES (insn) = NULL;
3719e4b17023SJohn Marino   INSN_LOCATOR (insn) = curr_insn_locator ();
3720e4b17023SJohn Marino   BLOCK_FOR_INSN (insn) = NULL;
3721e4b17023SJohn Marino 
3722e4b17023SJohn Marino   return insn;
3723e4b17023SJohn Marino }
3724e4b17023SJohn Marino 
3725e4b17023SJohn Marino /* Like `make_insn_raw' but make a JUMP_INSN instead of an insn.  */
3726e4b17023SJohn Marino 
3727e4b17023SJohn Marino rtx
make_jump_insn_raw(rtx pattern)3728e4b17023SJohn Marino make_jump_insn_raw (rtx pattern)
3729e4b17023SJohn Marino {
3730e4b17023SJohn Marino   rtx insn;
3731e4b17023SJohn Marino 
3732e4b17023SJohn Marino   insn = rtx_alloc (JUMP_INSN);
3733e4b17023SJohn Marino   INSN_UID (insn) = cur_insn_uid++;
3734e4b17023SJohn Marino 
3735e4b17023SJohn Marino   PATTERN (insn) = pattern;
3736e4b17023SJohn Marino   INSN_CODE (insn) = -1;
3737e4b17023SJohn Marino   REG_NOTES (insn) = NULL;
3738e4b17023SJohn Marino   JUMP_LABEL (insn) = NULL;
3739e4b17023SJohn Marino   INSN_LOCATOR (insn) = curr_insn_locator ();
3740e4b17023SJohn Marino   BLOCK_FOR_INSN (insn) = NULL;
3741e4b17023SJohn Marino 
3742e4b17023SJohn Marino   return insn;
3743e4b17023SJohn Marino }
3744e4b17023SJohn Marino 
3745e4b17023SJohn Marino /* Like `make_insn_raw' but make a CALL_INSN instead of an insn.  */
3746e4b17023SJohn Marino 
3747e4b17023SJohn Marino static rtx
make_call_insn_raw(rtx pattern)3748e4b17023SJohn Marino make_call_insn_raw (rtx pattern)
3749e4b17023SJohn Marino {
3750e4b17023SJohn Marino   rtx insn;
3751e4b17023SJohn Marino 
3752e4b17023SJohn Marino   insn = rtx_alloc (CALL_INSN);
3753e4b17023SJohn Marino   INSN_UID (insn) = cur_insn_uid++;
3754e4b17023SJohn Marino 
3755e4b17023SJohn Marino   PATTERN (insn) = pattern;
3756e4b17023SJohn Marino   INSN_CODE (insn) = -1;
3757e4b17023SJohn Marino   REG_NOTES (insn) = NULL;
3758e4b17023SJohn Marino   CALL_INSN_FUNCTION_USAGE (insn) = NULL;
3759e4b17023SJohn Marino   INSN_LOCATOR (insn) = curr_insn_locator ();
3760e4b17023SJohn Marino   BLOCK_FOR_INSN (insn) = NULL;
3761e4b17023SJohn Marino 
3762e4b17023SJohn Marino   return insn;
3763e4b17023SJohn Marino }
3764e4b17023SJohn Marino 
3765e4b17023SJohn Marino /* Add INSN to the end of the doubly-linked list.
3766e4b17023SJohn Marino    INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE.  */
3767e4b17023SJohn Marino 
3768e4b17023SJohn Marino void
add_insn(rtx insn)3769e4b17023SJohn Marino add_insn (rtx insn)
3770e4b17023SJohn Marino {
3771e4b17023SJohn Marino   PREV_INSN (insn) = get_last_insn();
3772e4b17023SJohn Marino   NEXT_INSN (insn) = 0;
3773e4b17023SJohn Marino 
3774e4b17023SJohn Marino   if (NULL != get_last_insn())
3775e4b17023SJohn Marino     NEXT_INSN (get_last_insn ()) = insn;
3776e4b17023SJohn Marino 
3777e4b17023SJohn Marino   if (NULL == get_insns ())
3778e4b17023SJohn Marino     set_first_insn (insn);
3779e4b17023SJohn Marino 
3780e4b17023SJohn Marino   set_last_insn (insn);
3781e4b17023SJohn Marino }
3782e4b17023SJohn Marino 
3783e4b17023SJohn Marino /* Add INSN into the doubly-linked list after insn AFTER.  This and
3784e4b17023SJohn Marino    the next should be the only functions called to insert an insn once
3785e4b17023SJohn Marino    delay slots have been filled since only they know how to update a
3786e4b17023SJohn Marino    SEQUENCE.  */
3787e4b17023SJohn Marino 
3788e4b17023SJohn Marino void
add_insn_after(rtx insn,rtx after,basic_block bb)3789e4b17023SJohn Marino add_insn_after (rtx insn, rtx after, basic_block bb)
3790e4b17023SJohn Marino {
3791e4b17023SJohn Marino   rtx next = NEXT_INSN (after);
3792e4b17023SJohn Marino 
3793e4b17023SJohn Marino   gcc_assert (!optimize || !INSN_DELETED_P (after));
3794e4b17023SJohn Marino 
3795e4b17023SJohn Marino   NEXT_INSN (insn) = next;
3796e4b17023SJohn Marino   PREV_INSN (insn) = after;
3797e4b17023SJohn Marino 
3798e4b17023SJohn Marino   if (next)
3799e4b17023SJohn Marino     {
3800e4b17023SJohn Marino       PREV_INSN (next) = insn;
3801e4b17023SJohn Marino       if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
3802e4b17023SJohn Marino 	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;
3803e4b17023SJohn Marino     }
3804e4b17023SJohn Marino   else if (get_last_insn () == after)
3805e4b17023SJohn Marino     set_last_insn (insn);
3806e4b17023SJohn Marino   else
3807e4b17023SJohn Marino     {
3808e4b17023SJohn Marino       struct sequence_stack *stack = seq_stack;
3809e4b17023SJohn Marino       /* Scan all pending sequences too.  */
3810e4b17023SJohn Marino       for (; stack; stack = stack->next)
3811e4b17023SJohn Marino 	if (after == stack->last)
3812e4b17023SJohn Marino 	  {
3813e4b17023SJohn Marino 	    stack->last = insn;
3814e4b17023SJohn Marino 	    break;
3815e4b17023SJohn Marino 	  }
3816e4b17023SJohn Marino 
3817e4b17023SJohn Marino       gcc_assert (stack);
3818e4b17023SJohn Marino     }
3819e4b17023SJohn Marino 
3820e4b17023SJohn Marino   if (!BARRIER_P (after)
3821e4b17023SJohn Marino       && !BARRIER_P (insn)
3822e4b17023SJohn Marino       && (bb = BLOCK_FOR_INSN (after)))
3823e4b17023SJohn Marino     {
3824e4b17023SJohn Marino       set_block_for_insn (insn, bb);
3825e4b17023SJohn Marino       if (INSN_P (insn))
3826e4b17023SJohn Marino 	df_insn_rescan (insn);
3827e4b17023SJohn Marino       /* Should not happen as first in the BB is always
3828e4b17023SJohn Marino 	 either NOTE or LABEL.  */
3829e4b17023SJohn Marino       if (BB_END (bb) == after
3830e4b17023SJohn Marino 	  /* Avoid clobbering of structure when creating new BB.  */
3831e4b17023SJohn Marino 	  && !BARRIER_P (insn)
3832e4b17023SJohn Marino 	  && !NOTE_INSN_BASIC_BLOCK_P (insn))
3833e4b17023SJohn Marino 	BB_END (bb) = insn;
3834e4b17023SJohn Marino     }
3835e4b17023SJohn Marino 
3836e4b17023SJohn Marino   NEXT_INSN (after) = insn;
3837e4b17023SJohn Marino   if (NONJUMP_INSN_P (after) && GET_CODE (PATTERN (after)) == SEQUENCE)
3838e4b17023SJohn Marino     {
3839e4b17023SJohn Marino       rtx sequence = PATTERN (after);
3840e4b17023SJohn Marino       NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
3841e4b17023SJohn Marino     }
3842e4b17023SJohn Marino }
3843e4b17023SJohn Marino 
3844e4b17023SJohn Marino /* Add INSN into the doubly-linked list before insn BEFORE.  This and
3845e4b17023SJohn Marino    the previous should be the only functions called to insert an insn
3846e4b17023SJohn Marino    once delay slots have been filled since only they know how to
3847e4b17023SJohn Marino    update a SEQUENCE.  If BB is NULL, an attempt is made to infer the
3848e4b17023SJohn Marino    bb from before.  */
3849e4b17023SJohn Marino 
3850e4b17023SJohn Marino void
add_insn_before(rtx insn,rtx before,basic_block bb)3851e4b17023SJohn Marino add_insn_before (rtx insn, rtx before, basic_block bb)
3852e4b17023SJohn Marino {
3853e4b17023SJohn Marino   rtx prev = PREV_INSN (before);
3854e4b17023SJohn Marino 
3855e4b17023SJohn Marino   gcc_assert (!optimize || !INSN_DELETED_P (before));
3856e4b17023SJohn Marino 
3857e4b17023SJohn Marino   PREV_INSN (insn) = prev;
3858e4b17023SJohn Marino   NEXT_INSN (insn) = before;
3859e4b17023SJohn Marino 
3860e4b17023SJohn Marino   if (prev)
3861e4b17023SJohn Marino     {
3862e4b17023SJohn Marino       NEXT_INSN (prev) = insn;
3863e4b17023SJohn Marino       if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
3864e4b17023SJohn Marino 	{
3865e4b17023SJohn Marino 	  rtx sequence = PATTERN (prev);
3866e4b17023SJohn Marino 	  NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
3867e4b17023SJohn Marino 	}
3868e4b17023SJohn Marino     }
3869e4b17023SJohn Marino   else if (get_insns () == before)
3870e4b17023SJohn Marino     set_first_insn (insn);
3871e4b17023SJohn Marino   else
3872e4b17023SJohn Marino     {
3873e4b17023SJohn Marino       struct sequence_stack *stack = seq_stack;
3874e4b17023SJohn Marino       /* Scan all pending sequences too.  */
3875e4b17023SJohn Marino       for (; stack; stack = stack->next)
3876e4b17023SJohn Marino 	if (before == stack->first)
3877e4b17023SJohn Marino 	  {
3878e4b17023SJohn Marino 	    stack->first = insn;
3879e4b17023SJohn Marino 	    break;
3880e4b17023SJohn Marino 	  }
3881e4b17023SJohn Marino 
3882e4b17023SJohn Marino       gcc_assert (stack);
3883e4b17023SJohn Marino     }
3884e4b17023SJohn Marino 
3885e4b17023SJohn Marino   if (!bb
3886e4b17023SJohn Marino       && !BARRIER_P (before)
3887e4b17023SJohn Marino       && !BARRIER_P (insn))
3888e4b17023SJohn Marino     bb = BLOCK_FOR_INSN (before);
3889e4b17023SJohn Marino 
3890e4b17023SJohn Marino   if (bb)
3891e4b17023SJohn Marino     {
3892e4b17023SJohn Marino       set_block_for_insn (insn, bb);
3893e4b17023SJohn Marino       if (INSN_P (insn))
3894e4b17023SJohn Marino 	df_insn_rescan (insn);
3895e4b17023SJohn Marino       /* Should not happen as first in the BB is always either NOTE or
3896e4b17023SJohn Marino 	 LABEL.  */
3897e4b17023SJohn Marino       gcc_assert (BB_HEAD (bb) != insn
3898e4b17023SJohn Marino 		  /* Avoid clobbering of structure when creating new BB.  */
3899e4b17023SJohn Marino 		  || BARRIER_P (insn)
3900e4b17023SJohn Marino 		  || NOTE_INSN_BASIC_BLOCK_P (insn));
3901e4b17023SJohn Marino     }
3902e4b17023SJohn Marino 
3903e4b17023SJohn Marino   PREV_INSN (before) = insn;
3904e4b17023SJohn Marino   if (NONJUMP_INSN_P (before) && GET_CODE (PATTERN (before)) == SEQUENCE)
3905e4b17023SJohn Marino     PREV_INSN (XVECEXP (PATTERN (before), 0, 0)) = insn;
3906e4b17023SJohn Marino }
3907e4b17023SJohn Marino 
3908e4b17023SJohn Marino 
3909e4b17023SJohn Marino /* Replace insn with an deleted instruction note.  */
3910e4b17023SJohn Marino 
3911e4b17023SJohn Marino void
set_insn_deleted(rtx insn)3912e4b17023SJohn Marino set_insn_deleted (rtx insn)
3913e4b17023SJohn Marino {
3914e4b17023SJohn Marino   df_insn_delete (BLOCK_FOR_INSN (insn), INSN_UID (insn));
3915e4b17023SJohn Marino   PUT_CODE (insn, NOTE);
3916e4b17023SJohn Marino   NOTE_KIND (insn) = NOTE_INSN_DELETED;
3917e4b17023SJohn Marino }
3918e4b17023SJohn Marino 
3919e4b17023SJohn Marino 
3920e4b17023SJohn Marino /* Remove an insn from its doubly-linked list.  This function knows how
3921e4b17023SJohn Marino    to handle sequences.  */
3922e4b17023SJohn Marino void
remove_insn(rtx insn)3923e4b17023SJohn Marino remove_insn (rtx insn)
3924e4b17023SJohn Marino {
3925e4b17023SJohn Marino   rtx next = NEXT_INSN (insn);
3926e4b17023SJohn Marino   rtx prev = PREV_INSN (insn);
3927e4b17023SJohn Marino   basic_block bb;
3928e4b17023SJohn Marino 
3929e4b17023SJohn Marino   /* Later in the code, the block will be marked dirty.  */
3930e4b17023SJohn Marino   df_insn_delete (NULL, INSN_UID (insn));
3931e4b17023SJohn Marino 
3932e4b17023SJohn Marino   if (prev)
3933e4b17023SJohn Marino     {
3934e4b17023SJohn Marino       NEXT_INSN (prev) = next;
3935e4b17023SJohn Marino       if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
3936e4b17023SJohn Marino 	{
3937e4b17023SJohn Marino 	  rtx sequence = PATTERN (prev);
3938e4b17023SJohn Marino 	  NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next;
3939e4b17023SJohn Marino 	}
3940e4b17023SJohn Marino     }
3941e4b17023SJohn Marino   else if (get_insns () == insn)
3942e4b17023SJohn Marino     {
3943e4b17023SJohn Marino       if (next)
3944e4b17023SJohn Marino         PREV_INSN (next) = NULL;
3945e4b17023SJohn Marino       set_first_insn (next);
3946e4b17023SJohn Marino     }
3947e4b17023SJohn Marino   else
3948e4b17023SJohn Marino     {
3949e4b17023SJohn Marino       struct sequence_stack *stack = seq_stack;
3950e4b17023SJohn Marino       /* Scan all pending sequences too.  */
3951e4b17023SJohn Marino       for (; stack; stack = stack->next)
3952e4b17023SJohn Marino 	if (insn == stack->first)
3953e4b17023SJohn Marino 	  {
3954e4b17023SJohn Marino 	    stack->first = next;
3955e4b17023SJohn Marino 	    break;
3956e4b17023SJohn Marino 	  }
3957e4b17023SJohn Marino 
3958e4b17023SJohn Marino       gcc_assert (stack);
3959e4b17023SJohn Marino     }
3960e4b17023SJohn Marino 
3961e4b17023SJohn Marino   if (next)
3962e4b17023SJohn Marino     {
3963e4b17023SJohn Marino       PREV_INSN (next) = prev;
3964e4b17023SJohn Marino       if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
3965e4b17023SJohn Marino 	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
3966e4b17023SJohn Marino     }
3967e4b17023SJohn Marino   else if (get_last_insn () == insn)
3968e4b17023SJohn Marino     set_last_insn (prev);
3969e4b17023SJohn Marino   else
3970e4b17023SJohn Marino     {
3971e4b17023SJohn Marino       struct sequence_stack *stack = seq_stack;
3972e4b17023SJohn Marino       /* Scan all pending sequences too.  */
3973e4b17023SJohn Marino       for (; stack; stack = stack->next)
3974e4b17023SJohn Marino 	if (insn == stack->last)
3975e4b17023SJohn Marino 	  {
3976e4b17023SJohn Marino 	    stack->last = prev;
3977e4b17023SJohn Marino 	    break;
3978e4b17023SJohn Marino 	  }
3979e4b17023SJohn Marino 
3980e4b17023SJohn Marino       gcc_assert (stack);
3981e4b17023SJohn Marino     }
3982e4b17023SJohn Marino   if (!BARRIER_P (insn)
3983e4b17023SJohn Marino       && (bb = BLOCK_FOR_INSN (insn)))
3984e4b17023SJohn Marino     {
3985e4b17023SJohn Marino       if (NONDEBUG_INSN_P (insn))
3986e4b17023SJohn Marino 	df_set_bb_dirty (bb);
3987e4b17023SJohn Marino       if (BB_HEAD (bb) == insn)
3988e4b17023SJohn Marino 	{
3989e4b17023SJohn Marino 	  /* Never ever delete the basic block note without deleting whole
3990e4b17023SJohn Marino 	     basic block.  */
3991e4b17023SJohn Marino 	  gcc_assert (!NOTE_P (insn));
3992e4b17023SJohn Marino 	  BB_HEAD (bb) = next;
3993e4b17023SJohn Marino 	}
3994e4b17023SJohn Marino       if (BB_END (bb) == insn)
3995e4b17023SJohn Marino 	BB_END (bb) = prev;
3996e4b17023SJohn Marino     }
3997e4b17023SJohn Marino }
3998e4b17023SJohn Marino 
3999e4b17023SJohn Marino /* Append CALL_FUSAGE to the CALL_INSN_FUNCTION_USAGE for CALL_INSN.  */
4000e4b17023SJohn Marino 
4001e4b17023SJohn Marino void
add_function_usage_to(rtx call_insn,rtx call_fusage)4002e4b17023SJohn Marino add_function_usage_to (rtx call_insn, rtx call_fusage)
4003e4b17023SJohn Marino {
4004e4b17023SJohn Marino   gcc_assert (call_insn && CALL_P (call_insn));
4005e4b17023SJohn Marino 
4006e4b17023SJohn Marino   /* Put the register usage information on the CALL.  If there is already
4007e4b17023SJohn Marino      some usage information, put ours at the end.  */
4008e4b17023SJohn Marino   if (CALL_INSN_FUNCTION_USAGE (call_insn))
4009e4b17023SJohn Marino     {
4010e4b17023SJohn Marino       rtx link;
4011e4b17023SJohn Marino 
4012e4b17023SJohn Marino       for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
4013e4b17023SJohn Marino 	   link = XEXP (link, 1))
4014e4b17023SJohn Marino 	;
4015e4b17023SJohn Marino 
4016e4b17023SJohn Marino       XEXP (link, 1) = call_fusage;
4017e4b17023SJohn Marino     }
4018e4b17023SJohn Marino   else
4019e4b17023SJohn Marino     CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
4020e4b17023SJohn Marino }
4021e4b17023SJohn Marino 
4022e4b17023SJohn Marino /* Delete all insns made since FROM.
4023e4b17023SJohn Marino    FROM becomes the new last instruction.  */
4024e4b17023SJohn Marino 
4025e4b17023SJohn Marino void
delete_insns_since(rtx from)4026e4b17023SJohn Marino delete_insns_since (rtx from)
4027e4b17023SJohn Marino {
4028e4b17023SJohn Marino   if (from == 0)
4029e4b17023SJohn Marino     set_first_insn (0);
4030e4b17023SJohn Marino   else
4031e4b17023SJohn Marino     NEXT_INSN (from) = 0;
4032e4b17023SJohn Marino   set_last_insn (from);
4033e4b17023SJohn Marino }
4034e4b17023SJohn Marino 
4035e4b17023SJohn Marino /* This function is deprecated, please use sequences instead.
4036e4b17023SJohn Marino 
4037e4b17023SJohn Marino    Move a consecutive bunch of insns to a different place in the chain.
4038e4b17023SJohn Marino    The insns to be moved are those between FROM and TO.
4039e4b17023SJohn Marino    They are moved to a new position after the insn AFTER.
4040e4b17023SJohn Marino    AFTER must not be FROM or TO or any insn in between.
4041e4b17023SJohn Marino 
4042e4b17023SJohn Marino    This function does not know about SEQUENCEs and hence should not be
4043e4b17023SJohn Marino    called after delay-slot filling has been done.  */
4044e4b17023SJohn Marino 
4045e4b17023SJohn Marino void
reorder_insns_nobb(rtx from,rtx to,rtx after)4046e4b17023SJohn Marino reorder_insns_nobb (rtx from, rtx to, rtx after)
4047e4b17023SJohn Marino {
4048e4b17023SJohn Marino #ifdef ENABLE_CHECKING
4049e4b17023SJohn Marino   rtx x;
4050e4b17023SJohn Marino   for (x = from; x != to; x = NEXT_INSN (x))
4051e4b17023SJohn Marino     gcc_assert (after != x);
4052e4b17023SJohn Marino   gcc_assert (after != to);
4053e4b17023SJohn Marino #endif
4054e4b17023SJohn Marino 
4055e4b17023SJohn Marino   /* Splice this bunch out of where it is now.  */
4056e4b17023SJohn Marino   if (PREV_INSN (from))
4057e4b17023SJohn Marino     NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);
4058e4b17023SJohn Marino   if (NEXT_INSN (to))
4059e4b17023SJohn Marino     PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);
4060e4b17023SJohn Marino   if (get_last_insn () == to)
4061e4b17023SJohn Marino     set_last_insn (PREV_INSN (from));
4062e4b17023SJohn Marino   if (get_insns () == from)
4063e4b17023SJohn Marino     set_first_insn (NEXT_INSN (to));
4064e4b17023SJohn Marino 
4065e4b17023SJohn Marino   /* Make the new neighbors point to it and it to them.  */
4066e4b17023SJohn Marino   if (NEXT_INSN (after))
4067e4b17023SJohn Marino     PREV_INSN (NEXT_INSN (after)) = to;
4068e4b17023SJohn Marino 
4069e4b17023SJohn Marino   NEXT_INSN (to) = NEXT_INSN (after);
4070e4b17023SJohn Marino   PREV_INSN (from) = after;
4071e4b17023SJohn Marino   NEXT_INSN (after) = from;
4072e4b17023SJohn Marino   if (after == get_last_insn())
4073e4b17023SJohn Marino     set_last_insn (to);
4074e4b17023SJohn Marino }
4075e4b17023SJohn Marino 
4076e4b17023SJohn Marino /* Same as function above, but take care to update BB boundaries.  */
4077e4b17023SJohn Marino void
reorder_insns(rtx from,rtx to,rtx after)4078e4b17023SJohn Marino reorder_insns (rtx from, rtx to, rtx after)
4079e4b17023SJohn Marino {
4080e4b17023SJohn Marino   rtx prev = PREV_INSN (from);
4081e4b17023SJohn Marino   basic_block bb, bb2;
4082e4b17023SJohn Marino 
4083e4b17023SJohn Marino   reorder_insns_nobb (from, to, after);
4084e4b17023SJohn Marino 
4085e4b17023SJohn Marino   if (!BARRIER_P (after)
4086e4b17023SJohn Marino       && (bb = BLOCK_FOR_INSN (after)))
4087e4b17023SJohn Marino     {
4088e4b17023SJohn Marino       rtx x;
4089e4b17023SJohn Marino       df_set_bb_dirty (bb);
4090e4b17023SJohn Marino 
4091e4b17023SJohn Marino       if (!BARRIER_P (from)
4092e4b17023SJohn Marino 	  && (bb2 = BLOCK_FOR_INSN (from)))
4093e4b17023SJohn Marino 	{
4094e4b17023SJohn Marino 	  if (BB_END (bb2) == to)
4095e4b17023SJohn Marino 	    BB_END (bb2) = prev;
4096e4b17023SJohn Marino 	  df_set_bb_dirty (bb2);
4097e4b17023SJohn Marino 	}
4098e4b17023SJohn Marino 
4099e4b17023SJohn Marino       if (BB_END (bb) == after)
4100e4b17023SJohn Marino 	BB_END (bb) = to;
4101e4b17023SJohn Marino 
4102e4b17023SJohn Marino       for (x = from; x != NEXT_INSN (to); x = NEXT_INSN (x))
4103e4b17023SJohn Marino 	if (!BARRIER_P (x))
4104e4b17023SJohn Marino 	  df_insn_change_bb (x, bb);
4105e4b17023SJohn Marino     }
4106e4b17023SJohn Marino }
4107e4b17023SJohn Marino 
4108e4b17023SJohn Marino 
4109e4b17023SJohn Marino /* Emit insn(s) of given code and pattern
4110e4b17023SJohn Marino    at a specified place within the doubly-linked list.
4111e4b17023SJohn Marino 
4112e4b17023SJohn Marino    All of the emit_foo global entry points accept an object
4113e4b17023SJohn Marino    X which is either an insn list or a PATTERN of a single
4114e4b17023SJohn Marino    instruction.
4115e4b17023SJohn Marino 
4116e4b17023SJohn Marino    There are thus a few canonical ways to generate code and
4117e4b17023SJohn Marino    emit it at a specific place in the instruction stream.  For
4118e4b17023SJohn Marino    example, consider the instruction named SPOT and the fact that
4119e4b17023SJohn Marino    we would like to emit some instructions before SPOT.  We might
4120e4b17023SJohn Marino    do it like this:
4121e4b17023SJohn Marino 
4122e4b17023SJohn Marino 	start_sequence ();
4123e4b17023SJohn Marino 	... emit the new instructions ...
4124e4b17023SJohn Marino 	insns_head = get_insns ();
4125e4b17023SJohn Marino 	end_sequence ();
4126e4b17023SJohn Marino 
4127e4b17023SJohn Marino 	emit_insn_before (insns_head, SPOT);
4128e4b17023SJohn Marino 
4129e4b17023SJohn Marino    It used to be common to generate SEQUENCE rtl instead, but that
4130e4b17023SJohn Marino    is a relic of the past which no longer occurs.  The reason is that
4131e4b17023SJohn Marino    SEQUENCE rtl results in much fragmented RTL memory since the SEQUENCE
4132e4b17023SJohn Marino    generated would almost certainly die right after it was created.  */
4133e4b17023SJohn Marino 
4134e4b17023SJohn Marino static rtx
emit_pattern_before_noloc(rtx x,rtx before,rtx last,basic_block bb,rtx (* make_raw)(rtx))4135e4b17023SJohn Marino emit_pattern_before_noloc (rtx x, rtx before, rtx last, basic_block bb,
4136e4b17023SJohn Marino                            rtx (*make_raw) (rtx))
4137e4b17023SJohn Marino {
4138e4b17023SJohn Marino   rtx insn;
4139e4b17023SJohn Marino 
4140e4b17023SJohn Marino   gcc_assert (before);
4141e4b17023SJohn Marino 
4142e4b17023SJohn Marino   if (x == NULL_RTX)
4143e4b17023SJohn Marino     return last;
4144e4b17023SJohn Marino 
4145e4b17023SJohn Marino   switch (GET_CODE (x))
4146e4b17023SJohn Marino     {
4147e4b17023SJohn Marino     case DEBUG_INSN:
4148e4b17023SJohn Marino     case INSN:
4149e4b17023SJohn Marino     case JUMP_INSN:
4150e4b17023SJohn Marino     case CALL_INSN:
4151e4b17023SJohn Marino     case CODE_LABEL:
4152e4b17023SJohn Marino     case BARRIER:
4153e4b17023SJohn Marino     case NOTE:
4154e4b17023SJohn Marino       insn = x;
4155e4b17023SJohn Marino       while (insn)
4156e4b17023SJohn Marino 	{
4157e4b17023SJohn Marino 	  rtx next = NEXT_INSN (insn);
4158e4b17023SJohn Marino 	  add_insn_before (insn, before, bb);
4159e4b17023SJohn Marino 	  last = insn;
4160e4b17023SJohn Marino 	  insn = next;
4161e4b17023SJohn Marino 	}
4162e4b17023SJohn Marino       break;
4163e4b17023SJohn Marino 
4164e4b17023SJohn Marino #ifdef ENABLE_RTL_CHECKING
4165e4b17023SJohn Marino     case SEQUENCE:
4166e4b17023SJohn Marino       gcc_unreachable ();
4167e4b17023SJohn Marino       break;
4168e4b17023SJohn Marino #endif
4169e4b17023SJohn Marino 
4170e4b17023SJohn Marino     default:
4171e4b17023SJohn Marino       last = (*make_raw) (x);
4172e4b17023SJohn Marino       add_insn_before (last, before, bb);
4173e4b17023SJohn Marino       break;
4174e4b17023SJohn Marino     }
4175e4b17023SJohn Marino 
4176e4b17023SJohn Marino   return last;
4177e4b17023SJohn Marino }
4178e4b17023SJohn Marino 
4179e4b17023SJohn Marino /* Make X be output before the instruction BEFORE.  */
4180e4b17023SJohn Marino 
4181e4b17023SJohn Marino rtx
emit_insn_before_noloc(rtx x,rtx before,basic_block bb)4182e4b17023SJohn Marino emit_insn_before_noloc (rtx x, rtx before, basic_block bb)
4183e4b17023SJohn Marino {
4184e4b17023SJohn Marino   return emit_pattern_before_noloc (x, before, before, bb, make_insn_raw);
4185e4b17023SJohn Marino }
4186e4b17023SJohn Marino 
4187e4b17023SJohn Marino /* Make an instruction with body X and code JUMP_INSN
4188e4b17023SJohn Marino    and output it before the instruction BEFORE.  */
4189e4b17023SJohn Marino 
4190e4b17023SJohn Marino rtx
emit_jump_insn_before_noloc(rtx x,rtx before)4191e4b17023SJohn Marino emit_jump_insn_before_noloc (rtx x, rtx before)
4192e4b17023SJohn Marino {
4193e4b17023SJohn Marino   return emit_pattern_before_noloc (x, before, NULL_RTX, NULL,
4194e4b17023SJohn Marino 				    make_jump_insn_raw);
4195e4b17023SJohn Marino }
4196e4b17023SJohn Marino 
4197e4b17023SJohn Marino /* Make an instruction with body X and code CALL_INSN
4198e4b17023SJohn Marino    and output it before the instruction BEFORE.  */
4199e4b17023SJohn Marino 
4200e4b17023SJohn Marino rtx
emit_call_insn_before_noloc(rtx x,rtx before)4201e4b17023SJohn Marino emit_call_insn_before_noloc (rtx x, rtx before)
4202e4b17023SJohn Marino {
4203e4b17023SJohn Marino   return emit_pattern_before_noloc (x, before, NULL_RTX, NULL,
4204e4b17023SJohn Marino 				    make_call_insn_raw);
4205e4b17023SJohn Marino }
4206e4b17023SJohn Marino 
4207e4b17023SJohn Marino /* Make an instruction with body X and code DEBUG_INSN
4208e4b17023SJohn Marino    and output it before the instruction BEFORE.  */
4209e4b17023SJohn Marino 
4210e4b17023SJohn Marino rtx
emit_debug_insn_before_noloc(rtx x,rtx before)4211e4b17023SJohn Marino emit_debug_insn_before_noloc (rtx x, rtx before)
4212e4b17023SJohn Marino {
4213e4b17023SJohn Marino   return emit_pattern_before_noloc (x, before, NULL_RTX, NULL,
4214e4b17023SJohn Marino 				    make_debug_insn_raw);
4215e4b17023SJohn Marino }
4216e4b17023SJohn Marino 
4217e4b17023SJohn Marino /* Make an insn of code BARRIER
4218e4b17023SJohn Marino    and output it before the insn BEFORE.  */
4219e4b17023SJohn Marino 
4220e4b17023SJohn Marino rtx
emit_barrier_before(rtx before)4221e4b17023SJohn Marino emit_barrier_before (rtx before)
4222e4b17023SJohn Marino {
4223e4b17023SJohn Marino   rtx insn = rtx_alloc (BARRIER);
4224e4b17023SJohn Marino 
4225e4b17023SJohn Marino   INSN_UID (insn) = cur_insn_uid++;
4226e4b17023SJohn Marino 
4227e4b17023SJohn Marino   add_insn_before (insn, before, NULL);
4228e4b17023SJohn Marino   return insn;
4229e4b17023SJohn Marino }
4230e4b17023SJohn Marino 
4231e4b17023SJohn Marino /* Emit the label LABEL before the insn BEFORE.  */
4232e4b17023SJohn Marino 
4233e4b17023SJohn Marino rtx
emit_label_before(rtx label,rtx before)4234e4b17023SJohn Marino emit_label_before (rtx label, rtx before)
4235e4b17023SJohn Marino {
4236e4b17023SJohn Marino   /* This can be called twice for the same label as a result of the
4237e4b17023SJohn Marino      confusion that follows a syntax error!  So make it harmless.  */
4238e4b17023SJohn Marino   if (INSN_UID (label) == 0)
4239e4b17023SJohn Marino     {
4240e4b17023SJohn Marino       INSN_UID (label) = cur_insn_uid++;
4241e4b17023SJohn Marino       add_insn_before (label, before, NULL);
4242e4b17023SJohn Marino     }
4243e4b17023SJohn Marino 
4244e4b17023SJohn Marino   return label;
4245e4b17023SJohn Marino }
4246e4b17023SJohn Marino 
4247e4b17023SJohn Marino /* Emit a note of subtype SUBTYPE before the insn BEFORE.  */
4248e4b17023SJohn Marino 
4249e4b17023SJohn Marino rtx
emit_note_before(enum insn_note subtype,rtx before)4250e4b17023SJohn Marino emit_note_before (enum insn_note subtype, rtx before)
4251e4b17023SJohn Marino {
4252e4b17023SJohn Marino   rtx note = rtx_alloc (NOTE);
4253e4b17023SJohn Marino   INSN_UID (note) = cur_insn_uid++;
4254e4b17023SJohn Marino   NOTE_KIND (note) = subtype;
4255e4b17023SJohn Marino   BLOCK_FOR_INSN (note) = NULL;
4256e4b17023SJohn Marino   memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
4257e4b17023SJohn Marino 
4258e4b17023SJohn Marino   add_insn_before (note, before, NULL);
4259e4b17023SJohn Marino   return note;
4260e4b17023SJohn Marino }
4261e4b17023SJohn Marino 
4262e4b17023SJohn Marino /* Helper for emit_insn_after, handles lists of instructions
4263e4b17023SJohn Marino    efficiently.  */
4264e4b17023SJohn Marino 
4265e4b17023SJohn Marino static rtx
emit_insn_after_1(rtx first,rtx after,basic_block bb)4266e4b17023SJohn Marino emit_insn_after_1 (rtx first, rtx after, basic_block bb)
4267e4b17023SJohn Marino {
4268e4b17023SJohn Marino   rtx last;
4269e4b17023SJohn Marino   rtx after_after;
4270e4b17023SJohn Marino   if (!bb && !BARRIER_P (after))
4271e4b17023SJohn Marino     bb = BLOCK_FOR_INSN (after);
4272e4b17023SJohn Marino 
4273e4b17023SJohn Marino   if (bb)
4274e4b17023SJohn Marino     {
4275e4b17023SJohn Marino       df_set_bb_dirty (bb);
4276e4b17023SJohn Marino       for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
4277e4b17023SJohn Marino 	if (!BARRIER_P (last))
4278e4b17023SJohn Marino 	  {
4279e4b17023SJohn Marino 	    set_block_for_insn (last, bb);
4280e4b17023SJohn Marino 	    df_insn_rescan (last);
4281e4b17023SJohn Marino 	  }
4282e4b17023SJohn Marino       if (!BARRIER_P (last))
4283e4b17023SJohn Marino 	{
4284e4b17023SJohn Marino 	  set_block_for_insn (last, bb);
4285e4b17023SJohn Marino 	  df_insn_rescan (last);
4286e4b17023SJohn Marino 	}
4287e4b17023SJohn Marino       if (BB_END (bb) == after)
4288e4b17023SJohn Marino 	BB_END (bb) = last;
4289e4b17023SJohn Marino     }
4290e4b17023SJohn Marino   else
4291e4b17023SJohn Marino     for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
4292e4b17023SJohn Marino       continue;
4293e4b17023SJohn Marino 
4294e4b17023SJohn Marino   after_after = NEXT_INSN (after);
4295e4b17023SJohn Marino 
4296e4b17023SJohn Marino   NEXT_INSN (after) = first;
4297e4b17023SJohn Marino   PREV_INSN (first) = after;
4298e4b17023SJohn Marino   NEXT_INSN (last) = after_after;
4299e4b17023SJohn Marino   if (after_after)
4300e4b17023SJohn Marino     PREV_INSN (after_after) = last;
4301e4b17023SJohn Marino 
4302e4b17023SJohn Marino   if (after == get_last_insn())
4303e4b17023SJohn Marino     set_last_insn (last);
4304e4b17023SJohn Marino 
4305e4b17023SJohn Marino   return last;
4306e4b17023SJohn Marino }
4307e4b17023SJohn Marino 
4308e4b17023SJohn Marino static rtx
emit_pattern_after_noloc(rtx x,rtx after,basic_block bb,rtx (* make_raw)(rtx))4309e4b17023SJohn Marino emit_pattern_after_noloc (rtx x, rtx after, basic_block bb,
4310e4b17023SJohn Marino 			  rtx (*make_raw)(rtx))
4311e4b17023SJohn Marino {
4312e4b17023SJohn Marino   rtx last = after;
4313e4b17023SJohn Marino 
4314e4b17023SJohn Marino   gcc_assert (after);
4315e4b17023SJohn Marino 
4316e4b17023SJohn Marino   if (x == NULL_RTX)
4317e4b17023SJohn Marino     return last;
4318e4b17023SJohn Marino 
4319e4b17023SJohn Marino   switch (GET_CODE (x))
4320e4b17023SJohn Marino     {
4321e4b17023SJohn Marino     case DEBUG_INSN:
4322e4b17023SJohn Marino     case INSN:
4323e4b17023SJohn Marino     case JUMP_INSN:
4324e4b17023SJohn Marino     case CALL_INSN:
4325e4b17023SJohn Marino     case CODE_LABEL:
4326e4b17023SJohn Marino     case BARRIER:
4327e4b17023SJohn Marino     case NOTE:
4328e4b17023SJohn Marino       last = emit_insn_after_1 (x, after, bb);
4329e4b17023SJohn Marino       break;
4330e4b17023SJohn Marino 
4331e4b17023SJohn Marino #ifdef ENABLE_RTL_CHECKING
4332e4b17023SJohn Marino     case SEQUENCE:
4333e4b17023SJohn Marino       gcc_unreachable ();
4334e4b17023SJohn Marino       break;
4335e4b17023SJohn Marino #endif
4336e4b17023SJohn Marino 
4337e4b17023SJohn Marino     default:
4338e4b17023SJohn Marino       last = (*make_raw) (x);
4339e4b17023SJohn Marino       add_insn_after (last, after, bb);
4340e4b17023SJohn Marino       break;
4341e4b17023SJohn Marino     }
4342e4b17023SJohn Marino 
4343e4b17023SJohn Marino   return last;
4344e4b17023SJohn Marino }
4345e4b17023SJohn Marino 
4346e4b17023SJohn Marino /* Make X be output after the insn AFTER and set the BB of insn.  If
4347e4b17023SJohn Marino    BB is NULL, an attempt is made to infer the BB from AFTER.  */
4348e4b17023SJohn Marino 
4349e4b17023SJohn Marino rtx
emit_insn_after_noloc(rtx x,rtx after,basic_block bb)4350e4b17023SJohn Marino emit_insn_after_noloc (rtx x, rtx after, basic_block bb)
4351e4b17023SJohn Marino {
4352e4b17023SJohn Marino   return emit_pattern_after_noloc (x, after, bb, make_insn_raw);
4353e4b17023SJohn Marino }
4354e4b17023SJohn Marino 
4355e4b17023SJohn Marino 
4356e4b17023SJohn Marino /* Make an insn of code JUMP_INSN with body X
4357e4b17023SJohn Marino    and output it after the insn AFTER.  */
4358e4b17023SJohn Marino 
4359e4b17023SJohn Marino rtx
emit_jump_insn_after_noloc(rtx x,rtx after)4360e4b17023SJohn Marino emit_jump_insn_after_noloc (rtx x, rtx after)
4361e4b17023SJohn Marino {
4362e4b17023SJohn Marino   return emit_pattern_after_noloc (x, after, NULL, make_jump_insn_raw);
4363e4b17023SJohn Marino }
4364e4b17023SJohn Marino 
4365e4b17023SJohn Marino /* Make an instruction with body X and code CALL_INSN
4366e4b17023SJohn Marino    and output it after the instruction AFTER.  */
4367e4b17023SJohn Marino 
4368e4b17023SJohn Marino rtx
emit_call_insn_after_noloc(rtx x,rtx after)4369e4b17023SJohn Marino emit_call_insn_after_noloc (rtx x, rtx after)
4370e4b17023SJohn Marino {
4371e4b17023SJohn Marino   return emit_pattern_after_noloc (x, after, NULL, make_call_insn_raw);
4372e4b17023SJohn Marino }
4373e4b17023SJohn Marino 
4374e4b17023SJohn Marino /* Make an instruction with body X and code CALL_INSN
4375e4b17023SJohn Marino    and output it after the instruction AFTER.  */
4376e4b17023SJohn Marino 
4377e4b17023SJohn Marino rtx
emit_debug_insn_after_noloc(rtx x,rtx after)4378e4b17023SJohn Marino emit_debug_insn_after_noloc (rtx x, rtx after)
4379e4b17023SJohn Marino {
4380e4b17023SJohn Marino   return emit_pattern_after_noloc (x, after, NULL, make_debug_insn_raw);
4381e4b17023SJohn Marino }
4382e4b17023SJohn Marino 
4383e4b17023SJohn Marino /* Make an insn of code BARRIER
4384e4b17023SJohn Marino    and output it after the insn AFTER.  */
4385e4b17023SJohn Marino 
4386e4b17023SJohn Marino rtx
emit_barrier_after(rtx after)4387e4b17023SJohn Marino emit_barrier_after (rtx after)
4388e4b17023SJohn Marino {
4389e4b17023SJohn Marino   rtx insn = rtx_alloc (BARRIER);
4390e4b17023SJohn Marino 
4391e4b17023SJohn Marino   INSN_UID (insn) = cur_insn_uid++;
4392e4b17023SJohn Marino 
4393e4b17023SJohn Marino   add_insn_after (insn, after, NULL);
4394e4b17023SJohn Marino   return insn;
4395e4b17023SJohn Marino }
4396e4b17023SJohn Marino 
4397e4b17023SJohn Marino /* Emit the label LABEL after the insn AFTER.  */
4398e4b17023SJohn Marino 
4399e4b17023SJohn Marino rtx
emit_label_after(rtx label,rtx after)4400e4b17023SJohn Marino emit_label_after (rtx label, rtx after)
4401e4b17023SJohn Marino {
4402e4b17023SJohn Marino   /* This can be called twice for the same label
4403e4b17023SJohn Marino      as a result of the confusion that follows a syntax error!
4404e4b17023SJohn Marino      So make it harmless.  */
4405e4b17023SJohn Marino   if (INSN_UID (label) == 0)
4406e4b17023SJohn Marino     {
4407e4b17023SJohn Marino       INSN_UID (label) = cur_insn_uid++;
4408e4b17023SJohn Marino       add_insn_after (label, after, NULL);
4409e4b17023SJohn Marino     }
4410e4b17023SJohn Marino 
4411e4b17023SJohn Marino   return label;
4412e4b17023SJohn Marino }
4413e4b17023SJohn Marino 
4414e4b17023SJohn Marino /* Emit a note of subtype SUBTYPE after the insn AFTER.  */
4415e4b17023SJohn Marino 
4416e4b17023SJohn Marino rtx
emit_note_after(enum insn_note subtype,rtx after)4417e4b17023SJohn Marino emit_note_after (enum insn_note subtype, rtx after)
4418e4b17023SJohn Marino {
4419e4b17023SJohn Marino   rtx note = rtx_alloc (NOTE);
4420e4b17023SJohn Marino   INSN_UID (note) = cur_insn_uid++;
4421e4b17023SJohn Marino   NOTE_KIND (note) = subtype;
4422e4b17023SJohn Marino   BLOCK_FOR_INSN (note) = NULL;
4423e4b17023SJohn Marino   memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
4424e4b17023SJohn Marino   add_insn_after (note, after, NULL);
4425e4b17023SJohn Marino   return note;
4426e4b17023SJohn Marino }
4427e4b17023SJohn Marino 
4428e4b17023SJohn Marino /* Insert PATTERN after AFTER, setting its INSN_LOCATION to LOC.
4429e4b17023SJohn Marino    MAKE_RAW indicates how to turn PATTERN into a real insn.  */
4430e4b17023SJohn Marino 
4431e4b17023SJohn Marino static rtx
emit_pattern_after_setloc(rtx pattern,rtx after,int loc,rtx (* make_raw)(rtx))4432e4b17023SJohn Marino emit_pattern_after_setloc (rtx pattern, rtx after, int loc,
4433e4b17023SJohn Marino 			   rtx (*make_raw) (rtx))
4434e4b17023SJohn Marino {
4435e4b17023SJohn Marino   rtx last = emit_pattern_after_noloc (pattern, after, NULL, make_raw);
4436e4b17023SJohn Marino 
4437e4b17023SJohn Marino   if (pattern == NULL_RTX || !loc)
4438e4b17023SJohn Marino     return last;
4439e4b17023SJohn Marino 
4440e4b17023SJohn Marino   after = NEXT_INSN (after);
4441e4b17023SJohn Marino   while (1)
4442e4b17023SJohn Marino     {
4443e4b17023SJohn Marino       if (active_insn_p (after) && !INSN_LOCATOR (after))
4444e4b17023SJohn Marino 	INSN_LOCATOR (after) = loc;
4445e4b17023SJohn Marino       if (after == last)
4446e4b17023SJohn Marino 	break;
4447e4b17023SJohn Marino       after = NEXT_INSN (after);
4448e4b17023SJohn Marino     }
4449e4b17023SJohn Marino   return last;
4450e4b17023SJohn Marino }
4451e4b17023SJohn Marino 
4452e4b17023SJohn Marino /* Insert PATTERN after AFTER.  MAKE_RAW indicates how to turn PATTERN
4453e4b17023SJohn Marino    into a real insn.  SKIP_DEBUG_INSNS indicates whether to insert after
4454e4b17023SJohn Marino    any DEBUG_INSNs.  */
4455e4b17023SJohn Marino 
4456e4b17023SJohn Marino static rtx
emit_pattern_after(rtx pattern,rtx after,bool skip_debug_insns,rtx (* make_raw)(rtx))4457e4b17023SJohn Marino emit_pattern_after (rtx pattern, rtx after, bool skip_debug_insns,
4458e4b17023SJohn Marino 		    rtx (*make_raw) (rtx))
4459e4b17023SJohn Marino {
4460e4b17023SJohn Marino   rtx prev = after;
4461e4b17023SJohn Marino 
4462e4b17023SJohn Marino   if (skip_debug_insns)
4463e4b17023SJohn Marino     while (DEBUG_INSN_P (prev))
4464e4b17023SJohn Marino       prev = PREV_INSN (prev);
4465e4b17023SJohn Marino 
4466e4b17023SJohn Marino   if (INSN_P (prev))
4467e4b17023SJohn Marino     return emit_pattern_after_setloc (pattern, after, INSN_LOCATOR (prev),
4468e4b17023SJohn Marino 				      make_raw);
4469e4b17023SJohn Marino   else
4470e4b17023SJohn Marino     return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
4471e4b17023SJohn Marino }
4472e4b17023SJohn Marino 
4473e4b17023SJohn Marino /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
4474e4b17023SJohn Marino rtx
emit_insn_after_setloc(rtx pattern,rtx after,int loc)4475e4b17023SJohn Marino emit_insn_after_setloc (rtx pattern, rtx after, int loc)
4476e4b17023SJohn Marino {
4477e4b17023SJohn Marino   return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
4478e4b17023SJohn Marino }
4479e4b17023SJohn Marino 
4480e4b17023SJohn Marino /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
4481e4b17023SJohn Marino rtx
emit_insn_after(rtx pattern,rtx after)4482e4b17023SJohn Marino emit_insn_after (rtx pattern, rtx after)
4483e4b17023SJohn Marino {
4484e4b17023SJohn Marino   return emit_pattern_after (pattern, after, true, make_insn_raw);
4485e4b17023SJohn Marino }
4486e4b17023SJohn Marino 
4487e4b17023SJohn Marino /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
4488e4b17023SJohn Marino rtx
emit_jump_insn_after_setloc(rtx pattern,rtx after,int loc)4489e4b17023SJohn Marino emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
4490e4b17023SJohn Marino {
4491e4b17023SJohn Marino   return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
4492e4b17023SJohn Marino }
4493e4b17023SJohn Marino 
4494e4b17023SJohn Marino /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
4495e4b17023SJohn Marino rtx
emit_jump_insn_after(rtx pattern,rtx after)4496e4b17023SJohn Marino emit_jump_insn_after (rtx pattern, rtx after)
4497e4b17023SJohn Marino {
4498e4b17023SJohn Marino   return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
4499e4b17023SJohn Marino }
4500e4b17023SJohn Marino 
4501e4b17023SJohn Marino /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
4502e4b17023SJohn Marino rtx
emit_call_insn_after_setloc(rtx pattern,rtx after,int loc)4503e4b17023SJohn Marino emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
4504e4b17023SJohn Marino {
4505e4b17023SJohn Marino   return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
4506e4b17023SJohn Marino }
4507e4b17023SJohn Marino 
4508e4b17023SJohn Marino /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
4509e4b17023SJohn Marino rtx
emit_call_insn_after(rtx pattern,rtx after)4510e4b17023SJohn Marino emit_call_insn_after (rtx pattern, rtx after)
4511e4b17023SJohn Marino {
4512e4b17023SJohn Marino   return emit_pattern_after (pattern, after, true, make_call_insn_raw);
4513e4b17023SJohn Marino }
4514e4b17023SJohn Marino 
4515e4b17023SJohn Marino /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
4516e4b17023SJohn Marino rtx
emit_debug_insn_after_setloc(rtx pattern,rtx after,int loc)4517e4b17023SJohn Marino emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
4518e4b17023SJohn Marino {
4519e4b17023SJohn Marino   return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
4520e4b17023SJohn Marino }
4521e4b17023SJohn Marino 
4522e4b17023SJohn Marino /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
4523e4b17023SJohn Marino rtx
emit_debug_insn_after(rtx pattern,rtx after)4524e4b17023SJohn Marino emit_debug_insn_after (rtx pattern, rtx after)
4525e4b17023SJohn Marino {
4526e4b17023SJohn Marino   return emit_pattern_after (pattern, after, false, make_debug_insn_raw);
4527e4b17023SJohn Marino }
4528e4b17023SJohn Marino 
4529e4b17023SJohn Marino /* Insert PATTERN before BEFORE, setting its INSN_LOCATION to LOC.
4530e4b17023SJohn Marino    MAKE_RAW indicates how to turn PATTERN into a real insn.  INSNP
4531e4b17023SJohn Marino    indicates if PATTERN is meant for an INSN as opposed to a JUMP_INSN,
4532e4b17023SJohn Marino    CALL_INSN, etc.  */
4533e4b17023SJohn Marino 
4534e4b17023SJohn Marino static rtx
emit_pattern_before_setloc(rtx pattern,rtx before,int loc,bool insnp,rtx (* make_raw)(rtx))4535e4b17023SJohn Marino emit_pattern_before_setloc (rtx pattern, rtx before, int loc, bool insnp,
4536e4b17023SJohn Marino 			    rtx (*make_raw) (rtx))
4537e4b17023SJohn Marino {
4538e4b17023SJohn Marino   rtx first = PREV_INSN (before);
4539e4b17023SJohn Marino   rtx last = emit_pattern_before_noloc (pattern, before,
4540e4b17023SJohn Marino                                         insnp ? before : NULL_RTX,
4541e4b17023SJohn Marino                                         NULL, make_raw);
4542e4b17023SJohn Marino 
4543e4b17023SJohn Marino   if (pattern == NULL_RTX || !loc)
4544e4b17023SJohn Marino     return last;
4545e4b17023SJohn Marino 
4546e4b17023SJohn Marino   if (!first)
4547e4b17023SJohn Marino     first = get_insns ();
4548e4b17023SJohn Marino   else
4549e4b17023SJohn Marino     first = NEXT_INSN (first);
4550e4b17023SJohn Marino   while (1)
4551e4b17023SJohn Marino     {
4552e4b17023SJohn Marino       if (active_insn_p (first) && !INSN_LOCATOR (first))
4553e4b17023SJohn Marino 	INSN_LOCATOR (first) = loc;
4554e4b17023SJohn Marino       if (first == last)
4555e4b17023SJohn Marino 	break;
4556e4b17023SJohn Marino       first = NEXT_INSN (first);
4557e4b17023SJohn Marino     }
4558e4b17023SJohn Marino   return last;
4559e4b17023SJohn Marino }
4560e4b17023SJohn Marino 
4561e4b17023SJohn Marino /* Insert PATTERN before BEFORE.  MAKE_RAW indicates how to turn PATTERN
4562e4b17023SJohn Marino    into a real insn.  SKIP_DEBUG_INSNS indicates whether to insert
4563e4b17023SJohn Marino    before any DEBUG_INSNs.  INSNP indicates if PATTERN is meant for an
4564e4b17023SJohn Marino    INSN as opposed to a JUMP_INSN, CALL_INSN, etc.  */
4565e4b17023SJohn Marino 
4566e4b17023SJohn Marino static rtx
emit_pattern_before(rtx pattern,rtx before,bool skip_debug_insns,bool insnp,rtx (* make_raw)(rtx))4567e4b17023SJohn Marino emit_pattern_before (rtx pattern, rtx before, bool skip_debug_insns,
4568e4b17023SJohn Marino 		     bool insnp, rtx (*make_raw) (rtx))
4569e4b17023SJohn Marino {
4570e4b17023SJohn Marino   rtx next = before;
4571e4b17023SJohn Marino 
4572e4b17023SJohn Marino   if (skip_debug_insns)
4573e4b17023SJohn Marino     while (DEBUG_INSN_P (next))
4574e4b17023SJohn Marino       next = PREV_INSN (next);
4575e4b17023SJohn Marino 
4576e4b17023SJohn Marino   if (INSN_P (next))
4577e4b17023SJohn Marino     return emit_pattern_before_setloc (pattern, before, INSN_LOCATOR (next),
4578e4b17023SJohn Marino 				       insnp, make_raw);
4579e4b17023SJohn Marino   else
4580e4b17023SJohn Marino     return emit_pattern_before_noloc (pattern, before,
4581e4b17023SJohn Marino                                       insnp ? before : NULL_RTX,
4582e4b17023SJohn Marino                                       NULL, make_raw);
4583e4b17023SJohn Marino }
4584e4b17023SJohn Marino 
4585e4b17023SJohn Marino /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
4586e4b17023SJohn Marino rtx
emit_insn_before_setloc(rtx pattern,rtx before,int loc)4587e4b17023SJohn Marino emit_insn_before_setloc (rtx pattern, rtx before, int loc)
4588e4b17023SJohn Marino {
4589e4b17023SJohn Marino   return emit_pattern_before_setloc (pattern, before, loc, true,
4590e4b17023SJohn Marino 				     make_insn_raw);
4591e4b17023SJohn Marino }
4592e4b17023SJohn Marino 
4593e4b17023SJohn Marino /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
4594e4b17023SJohn Marino rtx
emit_insn_before(rtx pattern,rtx before)4595e4b17023SJohn Marino emit_insn_before (rtx pattern, rtx before)
4596e4b17023SJohn Marino {
4597e4b17023SJohn Marino   return emit_pattern_before (pattern, before, true, true, make_insn_raw);
4598e4b17023SJohn Marino }
4599e4b17023SJohn Marino 
4600e4b17023SJohn Marino /* like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
4601e4b17023SJohn Marino rtx
emit_jump_insn_before_setloc(rtx pattern,rtx before,int loc)4602e4b17023SJohn Marino emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
4603e4b17023SJohn Marino {
4604e4b17023SJohn Marino   return emit_pattern_before_setloc (pattern, before, loc, false,
4605e4b17023SJohn Marino 				     make_jump_insn_raw);
4606e4b17023SJohn Marino }
4607e4b17023SJohn Marino 
4608e4b17023SJohn Marino /* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
4609e4b17023SJohn Marino rtx
emit_jump_insn_before(rtx pattern,rtx before)4610e4b17023SJohn Marino emit_jump_insn_before (rtx pattern, rtx before)
4611e4b17023SJohn Marino {
4612e4b17023SJohn Marino   return emit_pattern_before (pattern, before, true, false,
4613e4b17023SJohn Marino 			      make_jump_insn_raw);
4614e4b17023SJohn Marino }
4615e4b17023SJohn Marino 
4616e4b17023SJohn Marino /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
4617e4b17023SJohn Marino rtx
emit_call_insn_before_setloc(rtx pattern,rtx before,int loc)4618e4b17023SJohn Marino emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
4619e4b17023SJohn Marino {
4620e4b17023SJohn Marino   return emit_pattern_before_setloc (pattern, before, loc, false,
4621e4b17023SJohn Marino 				     make_call_insn_raw);
4622e4b17023SJohn Marino }
4623e4b17023SJohn Marino 
4624e4b17023SJohn Marino /* Like emit_call_insn_before_noloc,
4625e4b17023SJohn Marino    but set insn_locator according to BEFORE.  */
4626e4b17023SJohn Marino rtx
emit_call_insn_before(rtx pattern,rtx before)4627e4b17023SJohn Marino emit_call_insn_before (rtx pattern, rtx before)
4628e4b17023SJohn Marino {
4629e4b17023SJohn Marino   return emit_pattern_before (pattern, before, true, false,
4630e4b17023SJohn Marino 			      make_call_insn_raw);
4631e4b17023SJohn Marino }
4632e4b17023SJohn Marino 
4633e4b17023SJohn Marino /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
4634e4b17023SJohn Marino rtx
emit_debug_insn_before_setloc(rtx pattern,rtx before,int loc)4635e4b17023SJohn Marino emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
4636e4b17023SJohn Marino {
4637e4b17023SJohn Marino   return emit_pattern_before_setloc (pattern, before, loc, false,
4638e4b17023SJohn Marino 				     make_debug_insn_raw);
4639e4b17023SJohn Marino }
4640e4b17023SJohn Marino 
4641e4b17023SJohn Marino /* Like emit_debug_insn_before_noloc,
4642e4b17023SJohn Marino    but set insn_locator according to BEFORE.  */
4643e4b17023SJohn Marino rtx
emit_debug_insn_before(rtx pattern,rtx before)4644e4b17023SJohn Marino emit_debug_insn_before (rtx pattern, rtx before)
4645e4b17023SJohn Marino {
4646e4b17023SJohn Marino   return emit_pattern_before (pattern, before, false, false,
4647e4b17023SJohn Marino 			      make_debug_insn_raw);
4648e4b17023SJohn Marino }
4649e4b17023SJohn Marino 
4650e4b17023SJohn Marino /* Take X and emit it at the end of the doubly-linked
4651e4b17023SJohn Marino    INSN list.
4652e4b17023SJohn Marino 
4653e4b17023SJohn Marino    Returns the last insn emitted.  */
4654e4b17023SJohn Marino 
4655e4b17023SJohn Marino rtx
emit_insn(rtx x)4656e4b17023SJohn Marino emit_insn (rtx x)
4657e4b17023SJohn Marino {
4658e4b17023SJohn Marino   rtx last = get_last_insn();
4659e4b17023SJohn Marino   rtx insn;
4660e4b17023SJohn Marino 
4661e4b17023SJohn Marino   if (x == NULL_RTX)
4662e4b17023SJohn Marino     return last;
4663e4b17023SJohn Marino 
4664e4b17023SJohn Marino   switch (GET_CODE (x))
4665e4b17023SJohn Marino     {
4666e4b17023SJohn Marino     case DEBUG_INSN:
4667e4b17023SJohn Marino     case INSN:
4668e4b17023SJohn Marino     case JUMP_INSN:
4669e4b17023SJohn Marino     case CALL_INSN:
4670e4b17023SJohn Marino     case CODE_LABEL:
4671e4b17023SJohn Marino     case BARRIER:
4672e4b17023SJohn Marino     case NOTE:
4673e4b17023SJohn Marino       insn = x;
4674e4b17023SJohn Marino       while (insn)
4675e4b17023SJohn Marino 	{
4676e4b17023SJohn Marino 	  rtx next = NEXT_INSN (insn);
4677e4b17023SJohn Marino 	  add_insn (insn);
4678e4b17023SJohn Marino 	  last = insn;
4679e4b17023SJohn Marino 	  insn = next;
4680e4b17023SJohn Marino 	}
4681e4b17023SJohn Marino       break;
4682e4b17023SJohn Marino 
4683e4b17023SJohn Marino #ifdef ENABLE_RTL_CHECKING
4684e4b17023SJohn Marino     case SEQUENCE:
4685e4b17023SJohn Marino       gcc_unreachable ();
4686e4b17023SJohn Marino       break;
4687e4b17023SJohn Marino #endif
4688e4b17023SJohn Marino 
4689e4b17023SJohn Marino     default:
4690e4b17023SJohn Marino       last = make_insn_raw (x);
4691e4b17023SJohn Marino       add_insn (last);
4692e4b17023SJohn Marino       break;
4693e4b17023SJohn Marino     }
4694e4b17023SJohn Marino 
4695e4b17023SJohn Marino   return last;
4696e4b17023SJohn Marino }
4697e4b17023SJohn Marino 
4698e4b17023SJohn Marino /* Make an insn of code DEBUG_INSN with pattern X
4699e4b17023SJohn Marino    and add it to the end of the doubly-linked list.  */
4700e4b17023SJohn Marino 
4701e4b17023SJohn Marino rtx
emit_debug_insn(rtx x)4702e4b17023SJohn Marino emit_debug_insn (rtx x)
4703e4b17023SJohn Marino {
4704e4b17023SJohn Marino   rtx last = get_last_insn();
4705e4b17023SJohn Marino   rtx insn;
4706e4b17023SJohn Marino 
4707e4b17023SJohn Marino   if (x == NULL_RTX)
4708e4b17023SJohn Marino     return last;
4709e4b17023SJohn Marino 
4710e4b17023SJohn Marino   switch (GET_CODE (x))
4711e4b17023SJohn Marino     {
4712e4b17023SJohn Marino     case DEBUG_INSN:
4713e4b17023SJohn Marino     case INSN:
4714e4b17023SJohn Marino     case JUMP_INSN:
4715e4b17023SJohn Marino     case CALL_INSN:
4716e4b17023SJohn Marino     case CODE_LABEL:
4717e4b17023SJohn Marino     case BARRIER:
4718e4b17023SJohn Marino     case NOTE:
4719e4b17023SJohn Marino       insn = x;
4720e4b17023SJohn Marino       while (insn)
4721e4b17023SJohn Marino 	{
4722e4b17023SJohn Marino 	  rtx next = NEXT_INSN (insn);
4723e4b17023SJohn Marino 	  add_insn (insn);
4724e4b17023SJohn Marino 	  last = insn;
4725e4b17023SJohn Marino 	  insn = next;
4726e4b17023SJohn Marino 	}
4727e4b17023SJohn Marino       break;
4728e4b17023SJohn Marino 
4729e4b17023SJohn Marino #ifdef ENABLE_RTL_CHECKING
4730e4b17023SJohn Marino     case SEQUENCE:
4731e4b17023SJohn Marino       gcc_unreachable ();
4732e4b17023SJohn Marino       break;
4733e4b17023SJohn Marino #endif
4734e4b17023SJohn Marino 
4735e4b17023SJohn Marino     default:
4736e4b17023SJohn Marino       last = make_debug_insn_raw (x);
4737e4b17023SJohn Marino       add_insn (last);
4738e4b17023SJohn Marino       break;
4739e4b17023SJohn Marino     }
4740e4b17023SJohn Marino 
4741e4b17023SJohn Marino   return last;
4742e4b17023SJohn Marino }
4743e4b17023SJohn Marino 
4744e4b17023SJohn Marino /* Make an insn of code JUMP_INSN with pattern X
4745e4b17023SJohn Marino    and add it to the end of the doubly-linked list.  */
4746e4b17023SJohn Marino 
4747e4b17023SJohn Marino rtx
emit_jump_insn(rtx x)4748e4b17023SJohn Marino emit_jump_insn (rtx x)
4749e4b17023SJohn Marino {
4750e4b17023SJohn Marino   rtx last = NULL_RTX, insn;
4751e4b17023SJohn Marino 
4752e4b17023SJohn Marino   switch (GET_CODE (x))
4753e4b17023SJohn Marino     {
4754e4b17023SJohn Marino     case DEBUG_INSN:
4755e4b17023SJohn Marino     case INSN:
4756e4b17023SJohn Marino     case JUMP_INSN:
4757e4b17023SJohn Marino     case CALL_INSN:
4758e4b17023SJohn Marino     case CODE_LABEL:
4759e4b17023SJohn Marino     case BARRIER:
4760e4b17023SJohn Marino     case NOTE:
4761e4b17023SJohn Marino       insn = x;
4762e4b17023SJohn Marino       while (insn)
4763e4b17023SJohn Marino 	{
4764e4b17023SJohn Marino 	  rtx next = NEXT_INSN (insn);
4765e4b17023SJohn Marino 	  add_insn (insn);
4766e4b17023SJohn Marino 	  last = insn;
4767e4b17023SJohn Marino 	  insn = next;
4768e4b17023SJohn Marino 	}
4769e4b17023SJohn Marino       break;
4770e4b17023SJohn Marino 
4771e4b17023SJohn Marino #ifdef ENABLE_RTL_CHECKING
4772e4b17023SJohn Marino     case SEQUENCE:
4773e4b17023SJohn Marino       gcc_unreachable ();
4774e4b17023SJohn Marino       break;
4775e4b17023SJohn Marino #endif
4776e4b17023SJohn Marino 
4777e4b17023SJohn Marino     default:
4778e4b17023SJohn Marino       last = make_jump_insn_raw (x);
4779e4b17023SJohn Marino       add_insn (last);
4780e4b17023SJohn Marino       break;
4781e4b17023SJohn Marino     }
4782e4b17023SJohn Marino 
4783e4b17023SJohn Marino   return last;
4784e4b17023SJohn Marino }
4785e4b17023SJohn Marino 
4786e4b17023SJohn Marino /* Make an insn of code CALL_INSN with pattern X
4787e4b17023SJohn Marino    and add it to the end of the doubly-linked list.  */
4788e4b17023SJohn Marino 
4789e4b17023SJohn Marino rtx
emit_call_insn(rtx x)4790e4b17023SJohn Marino emit_call_insn (rtx x)
4791e4b17023SJohn Marino {
4792e4b17023SJohn Marino   rtx insn;
4793e4b17023SJohn Marino 
4794e4b17023SJohn Marino   switch (GET_CODE (x))
4795e4b17023SJohn Marino     {
4796e4b17023SJohn Marino     case DEBUG_INSN:
4797e4b17023SJohn Marino     case INSN:
4798e4b17023SJohn Marino     case JUMP_INSN:
4799e4b17023SJohn Marino     case CALL_INSN:
4800e4b17023SJohn Marino     case CODE_LABEL:
4801e4b17023SJohn Marino     case BARRIER:
4802e4b17023SJohn Marino     case NOTE:
4803e4b17023SJohn Marino       insn = emit_insn (x);
4804e4b17023SJohn Marino       break;
4805e4b17023SJohn Marino 
4806e4b17023SJohn Marino #ifdef ENABLE_RTL_CHECKING
4807e4b17023SJohn Marino     case SEQUENCE:
4808e4b17023SJohn Marino       gcc_unreachable ();
4809e4b17023SJohn Marino       break;
4810e4b17023SJohn Marino #endif
4811e4b17023SJohn Marino 
4812e4b17023SJohn Marino     default:
4813e4b17023SJohn Marino       insn = make_call_insn_raw (x);
4814e4b17023SJohn Marino       add_insn (insn);
4815e4b17023SJohn Marino       break;
4816e4b17023SJohn Marino     }
4817e4b17023SJohn Marino 
4818e4b17023SJohn Marino   return insn;
4819e4b17023SJohn Marino }
4820e4b17023SJohn Marino 
4821e4b17023SJohn Marino /* Add the label LABEL to the end of the doubly-linked list.  */
4822e4b17023SJohn Marino 
4823e4b17023SJohn Marino rtx
emit_label(rtx label)4824e4b17023SJohn Marino emit_label (rtx label)
4825e4b17023SJohn Marino {
4826e4b17023SJohn Marino   /* This can be called twice for the same label
4827e4b17023SJohn Marino      as a result of the confusion that follows a syntax error!
4828e4b17023SJohn Marino      So make it harmless.  */
4829e4b17023SJohn Marino   if (INSN_UID (label) == 0)
4830e4b17023SJohn Marino     {
4831e4b17023SJohn Marino       INSN_UID (label) = cur_insn_uid++;
4832e4b17023SJohn Marino       add_insn (label);
4833e4b17023SJohn Marino     }
4834e4b17023SJohn Marino   return label;
4835e4b17023SJohn Marino }
4836e4b17023SJohn Marino 
4837e4b17023SJohn Marino /* Make an insn of code BARRIER
4838e4b17023SJohn Marino    and add it to the end of the doubly-linked list.  */
4839e4b17023SJohn Marino 
4840e4b17023SJohn Marino rtx
emit_barrier(void)4841e4b17023SJohn Marino emit_barrier (void)
4842e4b17023SJohn Marino {
4843e4b17023SJohn Marino   rtx barrier = rtx_alloc (BARRIER);
4844e4b17023SJohn Marino   INSN_UID (barrier) = cur_insn_uid++;
4845e4b17023SJohn Marino   add_insn (barrier);
4846e4b17023SJohn Marino   return barrier;
4847e4b17023SJohn Marino }
4848e4b17023SJohn Marino 
4849e4b17023SJohn Marino /* Emit a copy of note ORIG.  */
4850e4b17023SJohn Marino 
4851e4b17023SJohn Marino rtx
emit_note_copy(rtx orig)4852e4b17023SJohn Marino emit_note_copy (rtx orig)
4853e4b17023SJohn Marino {
4854e4b17023SJohn Marino   rtx note;
4855e4b17023SJohn Marino 
4856e4b17023SJohn Marino   note = rtx_alloc (NOTE);
4857e4b17023SJohn Marino 
4858e4b17023SJohn Marino   INSN_UID (note) = cur_insn_uid++;
4859e4b17023SJohn Marino   NOTE_DATA (note) = NOTE_DATA (orig);
4860e4b17023SJohn Marino   NOTE_KIND (note) = NOTE_KIND (orig);
4861e4b17023SJohn Marino   BLOCK_FOR_INSN (note) = NULL;
4862e4b17023SJohn Marino   add_insn (note);
4863e4b17023SJohn Marino 
4864e4b17023SJohn Marino   return note;
4865e4b17023SJohn Marino }
4866e4b17023SJohn Marino 
4867e4b17023SJohn Marino /* Make an insn of code NOTE or type NOTE_NO
4868e4b17023SJohn Marino    and add it to the end of the doubly-linked list.  */
4869e4b17023SJohn Marino 
4870e4b17023SJohn Marino rtx
emit_note(enum insn_note kind)4871e4b17023SJohn Marino emit_note (enum insn_note kind)
4872e4b17023SJohn Marino {
4873e4b17023SJohn Marino   rtx note;
4874e4b17023SJohn Marino 
4875e4b17023SJohn Marino   note = rtx_alloc (NOTE);
4876e4b17023SJohn Marino   INSN_UID (note) = cur_insn_uid++;
4877e4b17023SJohn Marino   NOTE_KIND (note) = kind;
4878e4b17023SJohn Marino   memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
4879e4b17023SJohn Marino   BLOCK_FOR_INSN (note) = NULL;
4880e4b17023SJohn Marino   add_insn (note);
4881e4b17023SJohn Marino   return note;
4882e4b17023SJohn Marino }
4883e4b17023SJohn Marino 
4884e4b17023SJohn Marino /* Emit a clobber of lvalue X.  */
4885e4b17023SJohn Marino 
4886e4b17023SJohn Marino rtx
emit_clobber(rtx x)4887e4b17023SJohn Marino emit_clobber (rtx x)
4888e4b17023SJohn Marino {
4889e4b17023SJohn Marino   /* CONCATs should not appear in the insn stream.  */
4890e4b17023SJohn Marino   if (GET_CODE (x) == CONCAT)
4891e4b17023SJohn Marino     {
4892e4b17023SJohn Marino       emit_clobber (XEXP (x, 0));
4893e4b17023SJohn Marino       return emit_clobber (XEXP (x, 1));
4894e4b17023SJohn Marino     }
4895e4b17023SJohn Marino   return emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
4896e4b17023SJohn Marino }
4897e4b17023SJohn Marino 
4898e4b17023SJohn Marino /* Return a sequence of insns to clobber lvalue X.  */
4899e4b17023SJohn Marino 
4900e4b17023SJohn Marino rtx
gen_clobber(rtx x)4901e4b17023SJohn Marino gen_clobber (rtx x)
4902e4b17023SJohn Marino {
4903e4b17023SJohn Marino   rtx seq;
4904e4b17023SJohn Marino 
4905e4b17023SJohn Marino   start_sequence ();
4906e4b17023SJohn Marino   emit_clobber (x);
4907e4b17023SJohn Marino   seq = get_insns ();
4908e4b17023SJohn Marino   end_sequence ();
4909e4b17023SJohn Marino   return seq;
4910e4b17023SJohn Marino }
4911e4b17023SJohn Marino 
4912e4b17023SJohn Marino /* Emit a use of rvalue X.  */
4913e4b17023SJohn Marino 
4914e4b17023SJohn Marino rtx
emit_use(rtx x)4915e4b17023SJohn Marino emit_use (rtx x)
4916e4b17023SJohn Marino {
4917e4b17023SJohn Marino   /* CONCATs should not appear in the insn stream.  */
4918e4b17023SJohn Marino   if (GET_CODE (x) == CONCAT)
4919e4b17023SJohn Marino     {
4920e4b17023SJohn Marino       emit_use (XEXP (x, 0));
4921e4b17023SJohn Marino       return emit_use (XEXP (x, 1));
4922e4b17023SJohn Marino     }
4923e4b17023SJohn Marino   return emit_insn (gen_rtx_USE (VOIDmode, x));
4924e4b17023SJohn Marino }
4925e4b17023SJohn Marino 
4926e4b17023SJohn Marino /* Return a sequence of insns to use rvalue X.  */
4927e4b17023SJohn Marino 
4928e4b17023SJohn Marino rtx
gen_use(rtx x)4929e4b17023SJohn Marino gen_use (rtx x)
4930e4b17023SJohn Marino {
4931e4b17023SJohn Marino   rtx seq;
4932e4b17023SJohn Marino 
4933e4b17023SJohn Marino   start_sequence ();
4934e4b17023SJohn Marino   emit_use (x);
4935e4b17023SJohn Marino   seq = get_insns ();
4936e4b17023SJohn Marino   end_sequence ();
4937e4b17023SJohn Marino   return seq;
4938e4b17023SJohn Marino }
4939e4b17023SJohn Marino 
4940e4b17023SJohn Marino /* Cause next statement to emit a line note even if the line number
4941e4b17023SJohn Marino    has not changed.  */
4942e4b17023SJohn Marino 
4943e4b17023SJohn Marino void
force_next_line_note(void)4944e4b17023SJohn Marino force_next_line_note (void)
4945e4b17023SJohn Marino {
4946e4b17023SJohn Marino   last_location = -1;
4947e4b17023SJohn Marino }
4948e4b17023SJohn Marino 
4949e4b17023SJohn Marino /* Place a note of KIND on insn INSN with DATUM as the datum. If a
4950e4b17023SJohn Marino    note of this type already exists, remove it first.  */
4951e4b17023SJohn Marino 
4952e4b17023SJohn Marino rtx
set_unique_reg_note(rtx insn,enum reg_note kind,rtx datum)4953e4b17023SJohn Marino set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
4954e4b17023SJohn Marino {
4955e4b17023SJohn Marino   rtx note = find_reg_note (insn, kind, NULL_RTX);
4956e4b17023SJohn Marino 
4957e4b17023SJohn Marino   switch (kind)
4958e4b17023SJohn Marino     {
4959e4b17023SJohn Marino     case REG_EQUAL:
4960e4b17023SJohn Marino     case REG_EQUIV:
4961e4b17023SJohn Marino       /* Don't add REG_EQUAL/REG_EQUIV notes if the insn
4962e4b17023SJohn Marino 	 has multiple sets (some callers assume single_set
4963e4b17023SJohn Marino 	 means the insn only has one set, when in fact it
4964e4b17023SJohn Marino 	 means the insn only has one * useful * set).  */
4965e4b17023SJohn Marino       if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
4966e4b17023SJohn Marino 	{
4967e4b17023SJohn Marino 	  gcc_assert (!note);
4968e4b17023SJohn Marino 	  return NULL_RTX;
4969e4b17023SJohn Marino 	}
4970e4b17023SJohn Marino 
4971e4b17023SJohn Marino       /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
4972e4b17023SJohn Marino 	 It serves no useful purpose and breaks eliminate_regs.  */
4973e4b17023SJohn Marino       if (GET_CODE (datum) == ASM_OPERANDS)
4974e4b17023SJohn Marino 	return NULL_RTX;
4975e4b17023SJohn Marino 
4976e4b17023SJohn Marino       if (note)
4977e4b17023SJohn Marino 	{
4978e4b17023SJohn Marino 	  XEXP (note, 0) = datum;
4979e4b17023SJohn Marino 	  df_notes_rescan (insn);
4980e4b17023SJohn Marino 	  return note;
4981e4b17023SJohn Marino 	}
4982e4b17023SJohn Marino       break;
4983e4b17023SJohn Marino 
4984e4b17023SJohn Marino     default:
4985e4b17023SJohn Marino       if (note)
4986e4b17023SJohn Marino 	{
4987e4b17023SJohn Marino 	  XEXP (note, 0) = datum;
4988e4b17023SJohn Marino 	  return note;
4989e4b17023SJohn Marino 	}
4990e4b17023SJohn Marino       break;
4991e4b17023SJohn Marino     }
4992e4b17023SJohn Marino 
4993e4b17023SJohn Marino   add_reg_note (insn, kind, datum);
4994e4b17023SJohn Marino 
4995e4b17023SJohn Marino   switch (kind)
4996e4b17023SJohn Marino     {
4997e4b17023SJohn Marino     case REG_EQUAL:
4998e4b17023SJohn Marino     case REG_EQUIV:
4999e4b17023SJohn Marino       df_notes_rescan (insn);
5000e4b17023SJohn Marino       break;
5001e4b17023SJohn Marino     default:
5002e4b17023SJohn Marino       break;
5003e4b17023SJohn Marino     }
5004e4b17023SJohn Marino 
5005e4b17023SJohn Marino   return REG_NOTES (insn);
5006e4b17023SJohn Marino }
5007e4b17023SJohn Marino 
5008e4b17023SJohn Marino /* Like set_unique_reg_note, but don't do anything unless INSN sets DST.  */
5009e4b17023SJohn Marino rtx
set_dst_reg_note(rtx insn,enum reg_note kind,rtx datum,rtx dst)5010e4b17023SJohn Marino set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst)
5011e4b17023SJohn Marino {
5012e4b17023SJohn Marino   rtx set = single_set (insn);
5013e4b17023SJohn Marino 
5014e4b17023SJohn Marino   if (set && SET_DEST (set) == dst)
5015e4b17023SJohn Marino     return set_unique_reg_note (insn, kind, datum);
5016e4b17023SJohn Marino   return NULL_RTX;
5017e4b17023SJohn Marino }
5018e4b17023SJohn Marino 
5019e4b17023SJohn Marino /* Return an indication of which type of insn should have X as a body.
5020e4b17023SJohn Marino    The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN.  */
5021e4b17023SJohn Marino 
5022e4b17023SJohn Marino static enum rtx_code
classify_insn(rtx x)5023e4b17023SJohn Marino classify_insn (rtx x)
5024e4b17023SJohn Marino {
5025e4b17023SJohn Marino   if (LABEL_P (x))
5026e4b17023SJohn Marino     return CODE_LABEL;
5027e4b17023SJohn Marino   if (GET_CODE (x) == CALL)
5028e4b17023SJohn Marino     return CALL_INSN;
5029e4b17023SJohn Marino   if (ANY_RETURN_P (x))
5030e4b17023SJohn Marino     return JUMP_INSN;
5031e4b17023SJohn Marino   if (GET_CODE (x) == SET)
5032e4b17023SJohn Marino     {
5033e4b17023SJohn Marino       if (SET_DEST (x) == pc_rtx)
5034e4b17023SJohn Marino 	return JUMP_INSN;
5035e4b17023SJohn Marino       else if (GET_CODE (SET_SRC (x)) == CALL)
5036e4b17023SJohn Marino 	return CALL_INSN;
5037e4b17023SJohn Marino       else
5038e4b17023SJohn Marino 	return INSN;
5039e4b17023SJohn Marino     }
5040e4b17023SJohn Marino   if (GET_CODE (x) == PARALLEL)
5041e4b17023SJohn Marino     {
5042e4b17023SJohn Marino       int j;
5043e4b17023SJohn Marino       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
5044e4b17023SJohn Marino 	if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
5045e4b17023SJohn Marino 	  return CALL_INSN;
5046e4b17023SJohn Marino 	else if (GET_CODE (XVECEXP (x, 0, j)) == SET
5047e4b17023SJohn Marino 		 && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx)
5048e4b17023SJohn Marino 	  return JUMP_INSN;
5049e4b17023SJohn Marino 	else if (GET_CODE (XVECEXP (x, 0, j)) == SET
5050e4b17023SJohn Marino 		 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
5051e4b17023SJohn Marino 	  return CALL_INSN;
5052e4b17023SJohn Marino     }
5053e4b17023SJohn Marino   return INSN;
5054e4b17023SJohn Marino }
5055e4b17023SJohn Marino 
5056e4b17023SJohn Marino /* Emit the rtl pattern X as an appropriate kind of insn.
5057e4b17023SJohn Marino    If X is a label, it is simply added into the insn chain.  */
5058e4b17023SJohn Marino 
5059e4b17023SJohn Marino rtx
emit(rtx x)5060e4b17023SJohn Marino emit (rtx x)
5061e4b17023SJohn Marino {
5062e4b17023SJohn Marino   enum rtx_code code = classify_insn (x);
5063e4b17023SJohn Marino 
5064e4b17023SJohn Marino   switch (code)
5065e4b17023SJohn Marino     {
5066e4b17023SJohn Marino     case CODE_LABEL:
5067e4b17023SJohn Marino       return emit_label (x);
5068e4b17023SJohn Marino     case INSN:
5069e4b17023SJohn Marino       return emit_insn (x);
5070e4b17023SJohn Marino     case  JUMP_INSN:
5071e4b17023SJohn Marino       {
5072e4b17023SJohn Marino 	rtx insn = emit_jump_insn (x);
5073e4b17023SJohn Marino 	if (any_uncondjump_p (insn) || GET_CODE (x) == RETURN)
5074e4b17023SJohn Marino 	  return emit_barrier ();
5075e4b17023SJohn Marino 	return insn;
5076e4b17023SJohn Marino       }
5077e4b17023SJohn Marino     case CALL_INSN:
5078e4b17023SJohn Marino       return emit_call_insn (x);
5079e4b17023SJohn Marino     case DEBUG_INSN:
5080e4b17023SJohn Marino       return emit_debug_insn (x);
5081e4b17023SJohn Marino     default:
5082e4b17023SJohn Marino       gcc_unreachable ();
5083e4b17023SJohn Marino     }
5084e4b17023SJohn Marino }
5085e4b17023SJohn Marino 
5086e4b17023SJohn Marino /* Space for free sequence stack entries.  */
5087e4b17023SJohn Marino static GTY ((deletable)) struct sequence_stack *free_sequence_stack;
5088e4b17023SJohn Marino 
5089e4b17023SJohn Marino /* Begin emitting insns to a sequence.  If this sequence will contain
5090e4b17023SJohn Marino    something that might cause the compiler to pop arguments to function
5091e4b17023SJohn Marino    calls (because those pops have previously been deferred; see
5092e4b17023SJohn Marino    INHIBIT_DEFER_POP for more details), use do_pending_stack_adjust
5093e4b17023SJohn Marino    before calling this function.  That will ensure that the deferred
5094e4b17023SJohn Marino    pops are not accidentally emitted in the middle of this sequence.  */
5095e4b17023SJohn Marino 
5096e4b17023SJohn Marino void
start_sequence(void)5097e4b17023SJohn Marino start_sequence (void)
5098e4b17023SJohn Marino {
5099e4b17023SJohn Marino   struct sequence_stack *tem;
5100e4b17023SJohn Marino 
5101e4b17023SJohn Marino   if (free_sequence_stack != NULL)
5102e4b17023SJohn Marino     {
5103e4b17023SJohn Marino       tem = free_sequence_stack;
5104e4b17023SJohn Marino       free_sequence_stack = tem->next;
5105e4b17023SJohn Marino     }
5106e4b17023SJohn Marino   else
5107e4b17023SJohn Marino     tem = ggc_alloc_sequence_stack ();
5108e4b17023SJohn Marino 
5109e4b17023SJohn Marino   tem->next = seq_stack;
5110e4b17023SJohn Marino   tem->first = get_insns ();
5111e4b17023SJohn Marino   tem->last = get_last_insn ();
5112e4b17023SJohn Marino 
5113e4b17023SJohn Marino   seq_stack = tem;
5114e4b17023SJohn Marino 
5115e4b17023SJohn Marino   set_first_insn (0);
5116e4b17023SJohn Marino   set_last_insn (0);
5117e4b17023SJohn Marino }
5118e4b17023SJohn Marino 
5119e4b17023SJohn Marino /* Set up the insn chain starting with FIRST as the current sequence,
5120e4b17023SJohn Marino    saving the previously current one.  See the documentation for
5121e4b17023SJohn Marino    start_sequence for more information about how to use this function.  */
5122e4b17023SJohn Marino 
5123e4b17023SJohn Marino void
push_to_sequence(rtx first)5124e4b17023SJohn Marino push_to_sequence (rtx first)
5125e4b17023SJohn Marino {
5126e4b17023SJohn Marino   rtx last;
5127e4b17023SJohn Marino 
5128e4b17023SJohn Marino   start_sequence ();
5129e4b17023SJohn Marino 
5130e4b17023SJohn Marino   for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last))
5131e4b17023SJohn Marino     ;
5132e4b17023SJohn Marino 
5133e4b17023SJohn Marino   set_first_insn (first);
5134e4b17023SJohn Marino   set_last_insn (last);
5135e4b17023SJohn Marino }
5136e4b17023SJohn Marino 
5137e4b17023SJohn Marino /* Like push_to_sequence, but take the last insn as an argument to avoid
5138e4b17023SJohn Marino    looping through the list.  */
5139e4b17023SJohn Marino 
5140e4b17023SJohn Marino void
push_to_sequence2(rtx first,rtx last)5141e4b17023SJohn Marino push_to_sequence2 (rtx first, rtx last)
5142e4b17023SJohn Marino {
5143e4b17023SJohn Marino   start_sequence ();
5144e4b17023SJohn Marino 
5145e4b17023SJohn Marino   set_first_insn (first);
5146e4b17023SJohn Marino   set_last_insn (last);
5147e4b17023SJohn Marino }
5148e4b17023SJohn Marino 
5149e4b17023SJohn Marino /* Set up the outer-level insn chain
5150e4b17023SJohn Marino    as the current sequence, saving the previously current one.  */
5151e4b17023SJohn Marino 
5152e4b17023SJohn Marino void
push_topmost_sequence(void)5153e4b17023SJohn Marino push_topmost_sequence (void)
5154e4b17023SJohn Marino {
5155e4b17023SJohn Marino   struct sequence_stack *stack, *top = NULL;
5156e4b17023SJohn Marino 
5157e4b17023SJohn Marino   start_sequence ();
5158e4b17023SJohn Marino 
5159e4b17023SJohn Marino   for (stack = seq_stack; stack; stack = stack->next)
5160e4b17023SJohn Marino     top = stack;
5161e4b17023SJohn Marino 
5162e4b17023SJohn Marino   set_first_insn (top->first);
5163e4b17023SJohn Marino   set_last_insn (top->last);
5164e4b17023SJohn Marino }
5165e4b17023SJohn Marino 
5166e4b17023SJohn Marino /* After emitting to the outer-level insn chain, update the outer-level
5167e4b17023SJohn Marino    insn chain, and restore the previous saved state.  */
5168e4b17023SJohn Marino 
5169e4b17023SJohn Marino void
pop_topmost_sequence(void)5170e4b17023SJohn Marino pop_topmost_sequence (void)
5171e4b17023SJohn Marino {
5172e4b17023SJohn Marino   struct sequence_stack *stack, *top = NULL;
5173e4b17023SJohn Marino 
5174e4b17023SJohn Marino   for (stack = seq_stack; stack; stack = stack->next)
5175e4b17023SJohn Marino     top = stack;
5176e4b17023SJohn Marino 
5177e4b17023SJohn Marino   top->first = get_insns ();
5178e4b17023SJohn Marino   top->last = get_last_insn ();
5179e4b17023SJohn Marino 
5180e4b17023SJohn Marino   end_sequence ();
5181e4b17023SJohn Marino }
5182e4b17023SJohn Marino 
5183e4b17023SJohn Marino /* After emitting to a sequence, restore previous saved state.
5184e4b17023SJohn Marino 
5185e4b17023SJohn Marino    To get the contents of the sequence just made, you must call
5186e4b17023SJohn Marino    `get_insns' *before* calling here.
5187e4b17023SJohn Marino 
5188e4b17023SJohn Marino    If the compiler might have deferred popping arguments while
5189e4b17023SJohn Marino    generating this sequence, and this sequence will not be immediately
5190e4b17023SJohn Marino    inserted into the instruction stream, use do_pending_stack_adjust
5191e4b17023SJohn Marino    before calling get_insns.  That will ensure that the deferred
5192e4b17023SJohn Marino    pops are inserted into this sequence, and not into some random
5193e4b17023SJohn Marino    location in the instruction stream.  See INHIBIT_DEFER_POP for more
5194e4b17023SJohn Marino    information about deferred popping of arguments.  */
5195e4b17023SJohn Marino 
5196e4b17023SJohn Marino void
end_sequence(void)5197e4b17023SJohn Marino end_sequence (void)
5198e4b17023SJohn Marino {
5199e4b17023SJohn Marino   struct sequence_stack *tem = seq_stack;
5200e4b17023SJohn Marino 
5201e4b17023SJohn Marino   set_first_insn (tem->first);
5202e4b17023SJohn Marino   set_last_insn (tem->last);
5203e4b17023SJohn Marino   seq_stack = tem->next;
5204e4b17023SJohn Marino 
5205e4b17023SJohn Marino   memset (tem, 0, sizeof (*tem));
5206e4b17023SJohn Marino   tem->next = free_sequence_stack;
5207e4b17023SJohn Marino   free_sequence_stack = tem;
5208e4b17023SJohn Marino }
5209e4b17023SJohn Marino 
5210e4b17023SJohn Marino /* Return 1 if currently emitting into a sequence.  */
5211e4b17023SJohn Marino 
5212e4b17023SJohn Marino int
in_sequence_p(void)5213e4b17023SJohn Marino in_sequence_p (void)
5214e4b17023SJohn Marino {
5215e4b17023SJohn Marino   return seq_stack != 0;
5216e4b17023SJohn Marino }
5217e4b17023SJohn Marino 
5218e4b17023SJohn Marino /* Put the various virtual registers into REGNO_REG_RTX.  */
5219e4b17023SJohn Marino 
5220e4b17023SJohn Marino static void
init_virtual_regs(void)5221e4b17023SJohn Marino init_virtual_regs (void)
5222e4b17023SJohn Marino {
5223e4b17023SJohn Marino   regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
5224e4b17023SJohn Marino   regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
5225e4b17023SJohn Marino   regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
5226e4b17023SJohn Marino   regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
5227e4b17023SJohn Marino   regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
5228e4b17023SJohn Marino   regno_reg_rtx[VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM]
5229e4b17023SJohn Marino     = virtual_preferred_stack_boundary_rtx;
5230e4b17023SJohn Marino }
5231e4b17023SJohn Marino 
5232e4b17023SJohn Marino 
5233e4b17023SJohn Marino /* Used by copy_insn_1 to avoid copying SCRATCHes more than once.  */
5234e4b17023SJohn Marino static rtx copy_insn_scratch_in[MAX_RECOG_OPERANDS];
5235e4b17023SJohn Marino static rtx copy_insn_scratch_out[MAX_RECOG_OPERANDS];
5236e4b17023SJohn Marino static int copy_insn_n_scratches;
5237e4b17023SJohn Marino 
5238e4b17023SJohn Marino /* When an insn is being copied by copy_insn_1, this is nonzero if we have
5239e4b17023SJohn Marino    copied an ASM_OPERANDS.
5240e4b17023SJohn Marino    In that case, it is the original input-operand vector.  */
5241e4b17023SJohn Marino static rtvec orig_asm_operands_vector;
5242e4b17023SJohn Marino 
5243e4b17023SJohn Marino /* When an insn is being copied by copy_insn_1, this is nonzero if we have
5244e4b17023SJohn Marino    copied an ASM_OPERANDS.
5245e4b17023SJohn Marino    In that case, it is the copied input-operand vector.  */
5246e4b17023SJohn Marino static rtvec copy_asm_operands_vector;
5247e4b17023SJohn Marino 
5248e4b17023SJohn Marino /* Likewise for the constraints vector.  */
5249e4b17023SJohn Marino static rtvec orig_asm_constraints_vector;
5250e4b17023SJohn Marino static rtvec copy_asm_constraints_vector;
5251e4b17023SJohn Marino 
5252e4b17023SJohn Marino /* Recursively create a new copy of an rtx for copy_insn.
5253e4b17023SJohn Marino    This function differs from copy_rtx in that it handles SCRATCHes and
5254e4b17023SJohn Marino    ASM_OPERANDs properly.
5255e4b17023SJohn Marino    Normally, this function is not used directly; use copy_insn as front end.
5256e4b17023SJohn Marino    However, you could first copy an insn pattern with copy_insn and then use
5257e4b17023SJohn Marino    this function afterwards to properly copy any REG_NOTEs containing
5258e4b17023SJohn Marino    SCRATCHes.  */
5259e4b17023SJohn Marino 
5260e4b17023SJohn Marino rtx
copy_insn_1(rtx orig)5261e4b17023SJohn Marino copy_insn_1 (rtx orig)
5262e4b17023SJohn Marino {
5263e4b17023SJohn Marino   rtx copy;
5264e4b17023SJohn Marino   int i, j;
5265e4b17023SJohn Marino   RTX_CODE code;
5266e4b17023SJohn Marino   const char *format_ptr;
5267e4b17023SJohn Marino 
5268e4b17023SJohn Marino   if (orig == NULL)
5269e4b17023SJohn Marino     return NULL;
5270e4b17023SJohn Marino 
5271e4b17023SJohn Marino   code = GET_CODE (orig);
5272e4b17023SJohn Marino 
5273e4b17023SJohn Marino   switch (code)
5274e4b17023SJohn Marino     {
5275e4b17023SJohn Marino     case REG:
5276e4b17023SJohn Marino     case DEBUG_EXPR:
5277e4b17023SJohn Marino     case CONST_INT:
5278e4b17023SJohn Marino     case CONST_DOUBLE:
5279e4b17023SJohn Marino     case CONST_FIXED:
5280e4b17023SJohn Marino     case CONST_VECTOR:
5281e4b17023SJohn Marino     case SYMBOL_REF:
5282e4b17023SJohn Marino     case CODE_LABEL:
5283e4b17023SJohn Marino     case PC:
5284e4b17023SJohn Marino     case CC0:
5285e4b17023SJohn Marino     case RETURN:
5286e4b17023SJohn Marino     case SIMPLE_RETURN:
5287e4b17023SJohn Marino       return orig;
5288e4b17023SJohn Marino     case CLOBBER:
5289e4b17023SJohn Marino       if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
5290e4b17023SJohn Marino 	return orig;
5291e4b17023SJohn Marino       break;
5292e4b17023SJohn Marino 
5293e4b17023SJohn Marino     case SCRATCH:
5294e4b17023SJohn Marino       for (i = 0; i < copy_insn_n_scratches; i++)
5295e4b17023SJohn Marino 	if (copy_insn_scratch_in[i] == orig)
5296e4b17023SJohn Marino 	  return copy_insn_scratch_out[i];
5297e4b17023SJohn Marino       break;
5298e4b17023SJohn Marino 
5299e4b17023SJohn Marino     case CONST:
5300e4b17023SJohn Marino       if (shared_const_p (orig))
5301e4b17023SJohn Marino 	return orig;
5302e4b17023SJohn Marino       break;
5303e4b17023SJohn Marino 
5304e4b17023SJohn Marino       /* A MEM with a constant address is not sharable.  The problem is that
5305e4b17023SJohn Marino 	 the constant address may need to be reloaded.  If the mem is shared,
5306e4b17023SJohn Marino 	 then reloading one copy of this mem will cause all copies to appear
5307e4b17023SJohn Marino 	 to have been reloaded.  */
5308e4b17023SJohn Marino 
5309e4b17023SJohn Marino     default:
5310e4b17023SJohn Marino       break;
5311e4b17023SJohn Marino     }
5312e4b17023SJohn Marino 
5313e4b17023SJohn Marino   /* Copy the various flags, fields, and other information.  We assume
5314e4b17023SJohn Marino      that all fields need copying, and then clear the fields that should
5315e4b17023SJohn Marino      not be copied.  That is the sensible default behavior, and forces
5316e4b17023SJohn Marino      us to explicitly document why we are *not* copying a flag.  */
5317e4b17023SJohn Marino   copy = shallow_copy_rtx (orig);
5318e4b17023SJohn Marino 
5319e4b17023SJohn Marino   /* We do not copy the USED flag, which is used as a mark bit during
5320e4b17023SJohn Marino      walks over the RTL.  */
5321e4b17023SJohn Marino   RTX_FLAG (copy, used) = 0;
5322e4b17023SJohn Marino 
5323e4b17023SJohn Marino   /* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs.  */
5324e4b17023SJohn Marino   if (INSN_P (orig))
5325e4b17023SJohn Marino     {
5326e4b17023SJohn Marino       RTX_FLAG (copy, jump) = 0;
5327e4b17023SJohn Marino       RTX_FLAG (copy, call) = 0;
5328e4b17023SJohn Marino       RTX_FLAG (copy, frame_related) = 0;
5329e4b17023SJohn Marino     }
5330e4b17023SJohn Marino 
5331e4b17023SJohn Marino   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
5332e4b17023SJohn Marino 
5333e4b17023SJohn Marino   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
5334e4b17023SJohn Marino     switch (*format_ptr++)
5335e4b17023SJohn Marino       {
5336e4b17023SJohn Marino       case 'e':
5337e4b17023SJohn Marino 	if (XEXP (orig, i) != NULL)
5338e4b17023SJohn Marino 	  XEXP (copy, i) = copy_insn_1 (XEXP (orig, i));
5339e4b17023SJohn Marino 	break;
5340e4b17023SJohn Marino 
5341e4b17023SJohn Marino       case 'E':
5342e4b17023SJohn Marino       case 'V':
5343e4b17023SJohn Marino 	if (XVEC (orig, i) == orig_asm_constraints_vector)
5344e4b17023SJohn Marino 	  XVEC (copy, i) = copy_asm_constraints_vector;
5345e4b17023SJohn Marino 	else if (XVEC (orig, i) == orig_asm_operands_vector)
5346e4b17023SJohn Marino 	  XVEC (copy, i) = copy_asm_operands_vector;
5347e4b17023SJohn Marino 	else if (XVEC (orig, i) != NULL)
5348e4b17023SJohn Marino 	  {
5349e4b17023SJohn Marino 	    XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
5350e4b17023SJohn Marino 	    for (j = 0; j < XVECLEN (copy, i); j++)
5351e4b17023SJohn Marino 	      XVECEXP (copy, i, j) = copy_insn_1 (XVECEXP (orig, i, j));
5352e4b17023SJohn Marino 	  }
5353e4b17023SJohn Marino 	break;
5354e4b17023SJohn Marino 
5355e4b17023SJohn Marino       case 't':
5356e4b17023SJohn Marino       case 'w':
5357e4b17023SJohn Marino       case 'i':
5358e4b17023SJohn Marino       case 's':
5359e4b17023SJohn Marino       case 'S':
5360e4b17023SJohn Marino       case 'u':
5361e4b17023SJohn Marino       case '0':
5362e4b17023SJohn Marino 	/* These are left unchanged.  */
5363e4b17023SJohn Marino 	break;
5364e4b17023SJohn Marino 
5365e4b17023SJohn Marino       default:
5366e4b17023SJohn Marino 	gcc_unreachable ();
5367e4b17023SJohn Marino       }
5368e4b17023SJohn Marino 
5369e4b17023SJohn Marino   if (code == SCRATCH)
5370e4b17023SJohn Marino     {
5371e4b17023SJohn Marino       i = copy_insn_n_scratches++;
5372e4b17023SJohn Marino       gcc_assert (i < MAX_RECOG_OPERANDS);
5373e4b17023SJohn Marino       copy_insn_scratch_in[i] = orig;
5374e4b17023SJohn Marino       copy_insn_scratch_out[i] = copy;
5375e4b17023SJohn Marino     }
5376e4b17023SJohn Marino   else if (code == ASM_OPERANDS)
5377e4b17023SJohn Marino     {
5378e4b17023SJohn Marino       orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
5379e4b17023SJohn Marino       copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
5380e4b17023SJohn Marino       orig_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (orig);
5381e4b17023SJohn Marino       copy_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
5382e4b17023SJohn Marino     }
5383e4b17023SJohn Marino 
5384e4b17023SJohn Marino   return copy;
5385e4b17023SJohn Marino }
5386e4b17023SJohn Marino 
5387e4b17023SJohn Marino /* Create a new copy of an rtx.
5388e4b17023SJohn Marino    This function differs from copy_rtx in that it handles SCRATCHes and
5389e4b17023SJohn Marino    ASM_OPERANDs properly.
5390e4b17023SJohn Marino    INSN doesn't really have to be a full INSN; it could be just the
5391e4b17023SJohn Marino    pattern.  */
5392e4b17023SJohn Marino rtx
copy_insn(rtx insn)5393e4b17023SJohn Marino copy_insn (rtx insn)
5394e4b17023SJohn Marino {
5395e4b17023SJohn Marino   copy_insn_n_scratches = 0;
5396e4b17023SJohn Marino   orig_asm_operands_vector = 0;
5397e4b17023SJohn Marino   orig_asm_constraints_vector = 0;
5398e4b17023SJohn Marino   copy_asm_operands_vector = 0;
5399e4b17023SJohn Marino   copy_asm_constraints_vector = 0;
5400e4b17023SJohn Marino   return copy_insn_1 (insn);
5401e4b17023SJohn Marino }
5402e4b17023SJohn Marino 
5403e4b17023SJohn Marino /* Initialize data structures and variables in this file
5404e4b17023SJohn Marino    before generating rtl for each function.  */
5405e4b17023SJohn Marino 
5406e4b17023SJohn Marino void
init_emit(void)5407e4b17023SJohn Marino init_emit (void)
5408e4b17023SJohn Marino {
5409e4b17023SJohn Marino   set_first_insn (NULL);
5410e4b17023SJohn Marino   set_last_insn (NULL);
5411e4b17023SJohn Marino   if (MIN_NONDEBUG_INSN_UID)
5412e4b17023SJohn Marino     cur_insn_uid = MIN_NONDEBUG_INSN_UID;
5413e4b17023SJohn Marino   else
5414e4b17023SJohn Marino     cur_insn_uid = 1;
5415e4b17023SJohn Marino   cur_debug_insn_uid = 1;
5416e4b17023SJohn Marino   reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
5417e4b17023SJohn Marino   last_location = UNKNOWN_LOCATION;
5418e4b17023SJohn Marino   first_label_num = label_num;
5419e4b17023SJohn Marino   seq_stack = NULL;
5420e4b17023SJohn Marino 
5421e4b17023SJohn Marino   /* Init the tables that describe all the pseudo regs.  */
5422e4b17023SJohn Marino 
5423e4b17023SJohn Marino   crtl->emit.regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
5424e4b17023SJohn Marino 
5425e4b17023SJohn Marino   crtl->emit.regno_pointer_align
5426e4b17023SJohn Marino     = XCNEWVEC (unsigned char, crtl->emit.regno_pointer_align_length);
5427e4b17023SJohn Marino 
5428e4b17023SJohn Marino   regno_reg_rtx = ggc_alloc_vec_rtx (crtl->emit.regno_pointer_align_length);
5429e4b17023SJohn Marino 
5430e4b17023SJohn Marino   /* Put copies of all the hard registers into regno_reg_rtx.  */
5431e4b17023SJohn Marino   memcpy (regno_reg_rtx,
5432e4b17023SJohn Marino 	  initial_regno_reg_rtx,
5433e4b17023SJohn Marino 	  FIRST_PSEUDO_REGISTER * sizeof (rtx));
5434e4b17023SJohn Marino 
5435e4b17023SJohn Marino   /* Put copies of all the virtual register rtx into regno_reg_rtx.  */
5436e4b17023SJohn Marino   init_virtual_regs ();
5437e4b17023SJohn Marino 
5438e4b17023SJohn Marino   /* Indicate that the virtual registers and stack locations are
5439e4b17023SJohn Marino      all pointers.  */
5440e4b17023SJohn Marino   REG_POINTER (stack_pointer_rtx) = 1;
5441e4b17023SJohn Marino   REG_POINTER (frame_pointer_rtx) = 1;
5442e4b17023SJohn Marino   REG_POINTER (hard_frame_pointer_rtx) = 1;
5443e4b17023SJohn Marino   REG_POINTER (arg_pointer_rtx) = 1;
5444e4b17023SJohn Marino 
5445e4b17023SJohn Marino   REG_POINTER (virtual_incoming_args_rtx) = 1;
5446e4b17023SJohn Marino   REG_POINTER (virtual_stack_vars_rtx) = 1;
5447e4b17023SJohn Marino   REG_POINTER (virtual_stack_dynamic_rtx) = 1;
5448e4b17023SJohn Marino   REG_POINTER (virtual_outgoing_args_rtx) = 1;
5449e4b17023SJohn Marino   REG_POINTER (virtual_cfa_rtx) = 1;
5450e4b17023SJohn Marino 
5451e4b17023SJohn Marino #ifdef STACK_BOUNDARY
5452e4b17023SJohn Marino   REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
5453e4b17023SJohn Marino   REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
5454e4b17023SJohn Marino   REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
5455e4b17023SJohn Marino   REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
5456e4b17023SJohn Marino 
5457e4b17023SJohn Marino   REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
5458e4b17023SJohn Marino   REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
5459e4b17023SJohn Marino   REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
5460e4b17023SJohn Marino   REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
5461e4b17023SJohn Marino   REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
5462e4b17023SJohn Marino #endif
5463e4b17023SJohn Marino 
5464e4b17023SJohn Marino #ifdef INIT_EXPANDERS
5465e4b17023SJohn Marino   INIT_EXPANDERS;
5466e4b17023SJohn Marino #endif
5467e4b17023SJohn Marino }
5468e4b17023SJohn Marino 
5469e4b17023SJohn Marino /* Generate a vector constant for mode MODE and constant value CONSTANT.  */
5470e4b17023SJohn Marino 
5471e4b17023SJohn Marino static rtx
gen_const_vector(enum machine_mode mode,int constant)5472e4b17023SJohn Marino gen_const_vector (enum machine_mode mode, int constant)
5473e4b17023SJohn Marino {
5474e4b17023SJohn Marino   rtx tem;
5475e4b17023SJohn Marino   rtvec v;
5476e4b17023SJohn Marino   int units, i;
5477e4b17023SJohn Marino   enum machine_mode inner;
5478e4b17023SJohn Marino 
5479e4b17023SJohn Marino   units = GET_MODE_NUNITS (mode);
5480e4b17023SJohn Marino   inner = GET_MODE_INNER (mode);
5481e4b17023SJohn Marino 
5482e4b17023SJohn Marino   gcc_assert (!DECIMAL_FLOAT_MODE_P (inner));
5483e4b17023SJohn Marino 
5484e4b17023SJohn Marino   v = rtvec_alloc (units);
5485e4b17023SJohn Marino 
5486e4b17023SJohn Marino   /* We need to call this function after we set the scalar const_tiny_rtx
5487e4b17023SJohn Marino      entries.  */
5488e4b17023SJohn Marino   gcc_assert (const_tiny_rtx[constant][(int) inner]);
5489e4b17023SJohn Marino 
5490e4b17023SJohn Marino   for (i = 0; i < units; ++i)
5491e4b17023SJohn Marino     RTVEC_ELT (v, i) = const_tiny_rtx[constant][(int) inner];
5492e4b17023SJohn Marino 
5493e4b17023SJohn Marino   tem = gen_rtx_raw_CONST_VECTOR (mode, v);
5494e4b17023SJohn Marino   return tem;
5495e4b17023SJohn Marino }
5496e4b17023SJohn Marino 
5497e4b17023SJohn Marino /* Generate a vector like gen_rtx_raw_CONST_VEC, but use the zero vector when
5498e4b17023SJohn Marino    all elements are zero, and the one vector when all elements are one.  */
5499e4b17023SJohn Marino rtx
gen_rtx_CONST_VECTOR(enum machine_mode mode,rtvec v)5500e4b17023SJohn Marino gen_rtx_CONST_VECTOR (enum machine_mode mode, rtvec v)
5501e4b17023SJohn Marino {
5502e4b17023SJohn Marino   enum machine_mode inner = GET_MODE_INNER (mode);
5503e4b17023SJohn Marino   int nunits = GET_MODE_NUNITS (mode);
5504e4b17023SJohn Marino   rtx x;
5505e4b17023SJohn Marino   int i;
5506e4b17023SJohn Marino 
5507e4b17023SJohn Marino   /* Check to see if all of the elements have the same value.  */
5508e4b17023SJohn Marino   x = RTVEC_ELT (v, nunits - 1);
5509e4b17023SJohn Marino   for (i = nunits - 2; i >= 0; i--)
5510e4b17023SJohn Marino     if (RTVEC_ELT (v, i) != x)
5511e4b17023SJohn Marino       break;
5512e4b17023SJohn Marino 
5513e4b17023SJohn Marino   /* If the values are all the same, check to see if we can use one of the
5514e4b17023SJohn Marino      standard constant vectors.  */
5515e4b17023SJohn Marino   if (i == -1)
5516e4b17023SJohn Marino     {
5517e4b17023SJohn Marino       if (x == CONST0_RTX (inner))
5518e4b17023SJohn Marino 	return CONST0_RTX (mode);
5519e4b17023SJohn Marino       else if (x == CONST1_RTX (inner))
5520e4b17023SJohn Marino 	return CONST1_RTX (mode);
5521e4b17023SJohn Marino       else if (x == CONSTM1_RTX (inner))
5522e4b17023SJohn Marino 	return CONSTM1_RTX (mode);
5523e4b17023SJohn Marino     }
5524e4b17023SJohn Marino 
5525e4b17023SJohn Marino   return gen_rtx_raw_CONST_VECTOR (mode, v);
5526e4b17023SJohn Marino }
5527e4b17023SJohn Marino 
5528e4b17023SJohn Marino /* Initialise global register information required by all functions.  */
5529e4b17023SJohn Marino 
5530e4b17023SJohn Marino void
init_emit_regs(void)5531e4b17023SJohn Marino init_emit_regs (void)
5532e4b17023SJohn Marino {
5533e4b17023SJohn Marino   int i;
5534e4b17023SJohn Marino   enum machine_mode mode;
5535e4b17023SJohn Marino   mem_attrs *attrs;
5536e4b17023SJohn Marino 
5537e4b17023SJohn Marino   /* Reset register attributes */
5538e4b17023SJohn Marino   htab_empty (reg_attrs_htab);
5539e4b17023SJohn Marino 
5540e4b17023SJohn Marino   /* We need reg_raw_mode, so initialize the modes now.  */
5541e4b17023SJohn Marino   init_reg_modes_target ();
5542e4b17023SJohn Marino 
5543e4b17023SJohn Marino   /* Assign register numbers to the globally defined register rtx.  */
5544e4b17023SJohn Marino   pc_rtx = gen_rtx_fmt_ (PC, VOIDmode);
5545e4b17023SJohn Marino   ret_rtx = gen_rtx_fmt_ (RETURN, VOIDmode);
5546e4b17023SJohn Marino   simple_return_rtx = gen_rtx_fmt_ (SIMPLE_RETURN, VOIDmode);
5547e4b17023SJohn Marino   cc0_rtx = gen_rtx_fmt_ (CC0, VOIDmode);
5548e4b17023SJohn Marino   stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
5549e4b17023SJohn Marino   frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
5550e4b17023SJohn Marino   hard_frame_pointer_rtx = gen_raw_REG (Pmode, HARD_FRAME_POINTER_REGNUM);
5551e4b17023SJohn Marino   arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM);
5552e4b17023SJohn Marino   virtual_incoming_args_rtx =
5553e4b17023SJohn Marino     gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM);
5554e4b17023SJohn Marino   virtual_stack_vars_rtx =
5555e4b17023SJohn Marino     gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM);
5556e4b17023SJohn Marino   virtual_stack_dynamic_rtx =
5557e4b17023SJohn Marino     gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM);
5558e4b17023SJohn Marino   virtual_outgoing_args_rtx =
5559e4b17023SJohn Marino     gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
5560e4b17023SJohn Marino   virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
5561e4b17023SJohn Marino   virtual_preferred_stack_boundary_rtx =
5562e4b17023SJohn Marino     gen_raw_REG (Pmode, VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM);
5563e4b17023SJohn Marino 
5564e4b17023SJohn Marino   /* Initialize RTL for commonly used hard registers.  These are
5565e4b17023SJohn Marino      copied into regno_reg_rtx as we begin to compile each function.  */
5566e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5567e4b17023SJohn Marino     initial_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
5568e4b17023SJohn Marino 
5569e4b17023SJohn Marino #ifdef RETURN_ADDRESS_POINTER_REGNUM
5570e4b17023SJohn Marino   return_address_pointer_rtx
5571e4b17023SJohn Marino     = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
5572e4b17023SJohn Marino #endif
5573e4b17023SJohn Marino 
5574e4b17023SJohn Marino   if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5575e4b17023SJohn Marino     pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
5576e4b17023SJohn Marino   else
5577e4b17023SJohn Marino     pic_offset_table_rtx = NULL_RTX;
5578e4b17023SJohn Marino 
5579e4b17023SJohn Marino   for (i = 0; i < (int) MAX_MACHINE_MODE; i++)
5580e4b17023SJohn Marino     {
5581e4b17023SJohn Marino       mode = (enum machine_mode) i;
5582e4b17023SJohn Marino       attrs = ggc_alloc_cleared_mem_attrs ();
5583e4b17023SJohn Marino       attrs->align = BITS_PER_UNIT;
5584e4b17023SJohn Marino       attrs->addrspace = ADDR_SPACE_GENERIC;
5585e4b17023SJohn Marino       if (mode != BLKmode)
5586e4b17023SJohn Marino 	{
5587e4b17023SJohn Marino 	  attrs->size_known_p = true;
5588e4b17023SJohn Marino 	  attrs->size = GET_MODE_SIZE (mode);
5589e4b17023SJohn Marino 	  if (STRICT_ALIGNMENT)
5590e4b17023SJohn Marino 	    attrs->align = GET_MODE_ALIGNMENT (mode);
5591e4b17023SJohn Marino 	}
5592e4b17023SJohn Marino       mode_mem_attrs[i] = attrs;
5593e4b17023SJohn Marino     }
5594e4b17023SJohn Marino }
5595e4b17023SJohn Marino 
5596e4b17023SJohn Marino /* Create some permanent unique rtl objects shared between all functions.  */
5597e4b17023SJohn Marino 
5598e4b17023SJohn Marino void
init_emit_once(void)5599e4b17023SJohn Marino init_emit_once (void)
5600e4b17023SJohn Marino {
5601e4b17023SJohn Marino   int i;
5602e4b17023SJohn Marino   enum machine_mode mode;
5603e4b17023SJohn Marino   enum machine_mode double_mode;
5604e4b17023SJohn Marino 
5605e4b17023SJohn Marino   /* Initialize the CONST_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute
5606e4b17023SJohn Marino      hash tables.  */
5607e4b17023SJohn Marino   const_int_htab = htab_create_ggc (37, const_int_htab_hash,
5608e4b17023SJohn Marino 				    const_int_htab_eq, NULL);
5609e4b17023SJohn Marino 
5610e4b17023SJohn Marino   const_double_htab = htab_create_ggc (37, const_double_htab_hash,
5611e4b17023SJohn Marino 				       const_double_htab_eq, NULL);
5612e4b17023SJohn Marino 
5613e4b17023SJohn Marino   const_fixed_htab = htab_create_ggc (37, const_fixed_htab_hash,
5614e4b17023SJohn Marino 				      const_fixed_htab_eq, NULL);
5615e4b17023SJohn Marino 
5616e4b17023SJohn Marino   mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash,
5617e4b17023SJohn Marino 				    mem_attrs_htab_eq, NULL);
5618e4b17023SJohn Marino   reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash,
5619e4b17023SJohn Marino 				    reg_attrs_htab_eq, NULL);
5620e4b17023SJohn Marino 
5621e4b17023SJohn Marino   /* Compute the word and byte modes.  */
5622e4b17023SJohn Marino 
5623e4b17023SJohn Marino   byte_mode = VOIDmode;
5624e4b17023SJohn Marino   word_mode = VOIDmode;
5625e4b17023SJohn Marino   double_mode = VOIDmode;
5626e4b17023SJohn Marino 
5627e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
5628e4b17023SJohn Marino        mode != VOIDmode;
5629e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5630e4b17023SJohn Marino     {
5631e4b17023SJohn Marino       if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
5632e4b17023SJohn Marino 	  && byte_mode == VOIDmode)
5633e4b17023SJohn Marino 	byte_mode = mode;
5634e4b17023SJohn Marino 
5635e4b17023SJohn Marino       if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD
5636e4b17023SJohn Marino 	  && word_mode == VOIDmode)
5637e4b17023SJohn Marino 	word_mode = mode;
5638e4b17023SJohn Marino     }
5639e4b17023SJohn Marino 
5640e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
5641e4b17023SJohn Marino        mode != VOIDmode;
5642e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5643e4b17023SJohn Marino     {
5644e4b17023SJohn Marino       if (GET_MODE_BITSIZE (mode) == DOUBLE_TYPE_SIZE
5645e4b17023SJohn Marino 	  && double_mode == VOIDmode)
5646e4b17023SJohn Marino 	double_mode = mode;
5647e4b17023SJohn Marino     }
5648e4b17023SJohn Marino 
5649e4b17023SJohn Marino   ptr_mode = mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0);
5650e4b17023SJohn Marino 
5651e4b17023SJohn Marino #ifdef INIT_EXPANDERS
5652e4b17023SJohn Marino   /* This is to initialize {init|mark|free}_machine_status before the first
5653e4b17023SJohn Marino      call to push_function_context_to.  This is needed by the Chill front
5654e4b17023SJohn Marino      end which calls push_function_context_to before the first call to
5655e4b17023SJohn Marino      init_function_start.  */
5656e4b17023SJohn Marino   INIT_EXPANDERS;
5657e4b17023SJohn Marino #endif
5658e4b17023SJohn Marino 
5659e4b17023SJohn Marino   /* Create the unique rtx's for certain rtx codes and operand values.  */
5660e4b17023SJohn Marino 
5661e4b17023SJohn Marino   /* Don't use gen_rtx_CONST_INT here since gen_rtx_CONST_INT in this case
5662e4b17023SJohn Marino      tries to use these variables.  */
5663e4b17023SJohn Marino   for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
5664e4b17023SJohn Marino     const_int_rtx[i + MAX_SAVED_CONST_INT] =
5665e4b17023SJohn Marino       gen_rtx_raw_CONST_INT (VOIDmode, (HOST_WIDE_INT) i);
5666e4b17023SJohn Marino 
5667e4b17023SJohn Marino   if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT
5668e4b17023SJohn Marino       && STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT)
5669e4b17023SJohn Marino     const_true_rtx = const_int_rtx[STORE_FLAG_VALUE + MAX_SAVED_CONST_INT];
5670e4b17023SJohn Marino   else
5671e4b17023SJohn Marino     const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
5672e4b17023SJohn Marino 
5673e4b17023SJohn Marino   REAL_VALUE_FROM_INT (dconst0,   0,  0, double_mode);
5674e4b17023SJohn Marino   REAL_VALUE_FROM_INT (dconst1,   1,  0, double_mode);
5675e4b17023SJohn Marino   REAL_VALUE_FROM_INT (dconst2,   2,  0, double_mode);
5676e4b17023SJohn Marino 
5677e4b17023SJohn Marino   dconstm1 = dconst1;
5678e4b17023SJohn Marino   dconstm1.sign = 1;
5679e4b17023SJohn Marino 
5680e4b17023SJohn Marino   dconsthalf = dconst1;
5681e4b17023SJohn Marino   SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);
5682e4b17023SJohn Marino 
5683e4b17023SJohn Marino   for (i = 0; i < 3; i++)
5684e4b17023SJohn Marino     {
5685e4b17023SJohn Marino       const REAL_VALUE_TYPE *const r =
5686e4b17023SJohn Marino 	(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
5687e4b17023SJohn Marino 
5688e4b17023SJohn Marino       for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
5689e4b17023SJohn Marino 	   mode != VOIDmode;
5690e4b17023SJohn Marino 	   mode = GET_MODE_WIDER_MODE (mode))
5691e4b17023SJohn Marino 	const_tiny_rtx[i][(int) mode] =
5692e4b17023SJohn Marino 	  CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
5693e4b17023SJohn Marino 
5694e4b17023SJohn Marino       for (mode = GET_CLASS_NARROWEST_MODE (MODE_DECIMAL_FLOAT);
5695e4b17023SJohn Marino 	   mode != VOIDmode;
5696e4b17023SJohn Marino 	   mode = GET_MODE_WIDER_MODE (mode))
5697e4b17023SJohn Marino 	const_tiny_rtx[i][(int) mode] =
5698e4b17023SJohn Marino 	  CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
5699e4b17023SJohn Marino 
5700e4b17023SJohn Marino       const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);
5701e4b17023SJohn Marino 
5702e4b17023SJohn Marino       for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
5703e4b17023SJohn Marino 	   mode != VOIDmode;
5704e4b17023SJohn Marino 	   mode = GET_MODE_WIDER_MODE (mode))
5705e4b17023SJohn Marino 	const_tiny_rtx[i][(int) mode] = GEN_INT (i);
5706e4b17023SJohn Marino 
5707e4b17023SJohn Marino       for (mode = GET_CLASS_NARROWEST_MODE (MODE_PARTIAL_INT);
5708e4b17023SJohn Marino 	   mode != VOIDmode;
5709e4b17023SJohn Marino 	   mode = GET_MODE_WIDER_MODE (mode))
5710e4b17023SJohn Marino 	const_tiny_rtx[i][(int) mode] = GEN_INT (i);
5711e4b17023SJohn Marino     }
5712e4b17023SJohn Marino 
5713e4b17023SJohn Marino   const_tiny_rtx[3][(int) VOIDmode] = constm1_rtx;
5714e4b17023SJohn Marino 
5715e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
5716e4b17023SJohn Marino        mode != VOIDmode;
5717e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5718e4b17023SJohn Marino     const_tiny_rtx[3][(int) mode] = constm1_rtx;
5719e4b17023SJohn Marino 
5720e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_PARTIAL_INT);
5721e4b17023SJohn Marino        mode != VOIDmode;
5722e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5723e4b17023SJohn Marino     const_tiny_rtx[3][(int) mode] = constm1_rtx;
5724e4b17023SJohn Marino 
5725e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_INT);
5726e4b17023SJohn Marino        mode != VOIDmode;
5727e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5728e4b17023SJohn Marino     {
5729e4b17023SJohn Marino       rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
5730e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
5731e4b17023SJohn Marino     }
5732e4b17023SJohn Marino 
5733e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
5734e4b17023SJohn Marino        mode != VOIDmode;
5735e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5736e4b17023SJohn Marino     {
5737e4b17023SJohn Marino       rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
5738e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
5739e4b17023SJohn Marino     }
5740e4b17023SJohn Marino 
5741e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
5742e4b17023SJohn Marino        mode != VOIDmode;
5743e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5744e4b17023SJohn Marino     {
5745e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5746e4b17023SJohn Marino       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
5747e4b17023SJohn Marino       const_tiny_rtx[3][(int) mode] = gen_const_vector (mode, 3);
5748e4b17023SJohn Marino     }
5749e4b17023SJohn Marino 
5750e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
5751e4b17023SJohn Marino        mode != VOIDmode;
5752e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5753e4b17023SJohn Marino     {
5754e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5755e4b17023SJohn Marino       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
5756e4b17023SJohn Marino     }
5757e4b17023SJohn Marino 
5758e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FRACT);
5759e4b17023SJohn Marino        mode != VOIDmode;
5760e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5761e4b17023SJohn Marino     {
5762e4b17023SJohn Marino       FCONST0(mode).data.high = 0;
5763e4b17023SJohn Marino       FCONST0(mode).data.low = 0;
5764e4b17023SJohn Marino       FCONST0(mode).mode = mode;
5765e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
5766e4b17023SJohn Marino 				      FCONST0 (mode), mode);
5767e4b17023SJohn Marino     }
5768e4b17023SJohn Marino 
5769e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_UFRACT);
5770e4b17023SJohn Marino        mode != VOIDmode;
5771e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5772e4b17023SJohn Marino     {
5773e4b17023SJohn Marino       FCONST0(mode).data.high = 0;
5774e4b17023SJohn Marino       FCONST0(mode).data.low = 0;
5775e4b17023SJohn Marino       FCONST0(mode).mode = mode;
5776e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
5777e4b17023SJohn Marino 				      FCONST0 (mode), mode);
5778e4b17023SJohn Marino     }
5779e4b17023SJohn Marino 
5780e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_ACCUM);
5781e4b17023SJohn Marino        mode != VOIDmode;
5782e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5783e4b17023SJohn Marino     {
5784e4b17023SJohn Marino       FCONST0(mode).data.high = 0;
5785e4b17023SJohn Marino       FCONST0(mode).data.low = 0;
5786e4b17023SJohn Marino       FCONST0(mode).mode = mode;
5787e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
5788e4b17023SJohn Marino 				      FCONST0 (mode), mode);
5789e4b17023SJohn Marino 
5790e4b17023SJohn Marino       /* We store the value 1.  */
5791e4b17023SJohn Marino       FCONST1(mode).data.high = 0;
5792e4b17023SJohn Marino       FCONST1(mode).data.low = 0;
5793e4b17023SJohn Marino       FCONST1(mode).mode = mode;
5794e4b17023SJohn Marino       lshift_double (1, 0, GET_MODE_FBIT (mode),
5795e4b17023SJohn Marino                      2 * HOST_BITS_PER_WIDE_INT,
5796e4b17023SJohn Marino                      &FCONST1(mode).data.low,
5797e4b17023SJohn Marino 		     &FCONST1(mode).data.high,
5798e4b17023SJohn Marino                      SIGNED_FIXED_POINT_MODE_P (mode));
5799e4b17023SJohn Marino       const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
5800e4b17023SJohn Marino 				      FCONST1 (mode), mode);
5801e4b17023SJohn Marino     }
5802e4b17023SJohn Marino 
5803e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_UACCUM);
5804e4b17023SJohn Marino        mode != VOIDmode;
5805e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5806e4b17023SJohn Marino     {
5807e4b17023SJohn Marino       FCONST0(mode).data.high = 0;
5808e4b17023SJohn Marino       FCONST0(mode).data.low = 0;
5809e4b17023SJohn Marino       FCONST0(mode).mode = mode;
5810e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
5811e4b17023SJohn Marino 				      FCONST0 (mode), mode);
5812e4b17023SJohn Marino 
5813e4b17023SJohn Marino       /* We store the value 1.  */
5814e4b17023SJohn Marino       FCONST1(mode).data.high = 0;
5815e4b17023SJohn Marino       FCONST1(mode).data.low = 0;
5816e4b17023SJohn Marino       FCONST1(mode).mode = mode;
5817e4b17023SJohn Marino       lshift_double (1, 0, GET_MODE_FBIT (mode),
5818e4b17023SJohn Marino                      2 * HOST_BITS_PER_WIDE_INT,
5819e4b17023SJohn Marino                      &FCONST1(mode).data.low,
5820e4b17023SJohn Marino 		     &FCONST1(mode).data.high,
5821e4b17023SJohn Marino                      SIGNED_FIXED_POINT_MODE_P (mode));
5822e4b17023SJohn Marino       const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
5823e4b17023SJohn Marino 				      FCONST1 (mode), mode);
5824e4b17023SJohn Marino     }
5825e4b17023SJohn Marino 
5826e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FRACT);
5827e4b17023SJohn Marino        mode != VOIDmode;
5828e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5829e4b17023SJohn Marino     {
5830e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5831e4b17023SJohn Marino     }
5832e4b17023SJohn Marino 
5833e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UFRACT);
5834e4b17023SJohn Marino        mode != VOIDmode;
5835e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5836e4b17023SJohn Marino     {
5837e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5838e4b17023SJohn Marino     }
5839e4b17023SJohn Marino 
5840e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_ACCUM);
5841e4b17023SJohn Marino        mode != VOIDmode;
5842e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5843e4b17023SJohn Marino     {
5844e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5845e4b17023SJohn Marino       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
5846e4b17023SJohn Marino     }
5847e4b17023SJohn Marino 
5848e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UACCUM);
5849e4b17023SJohn Marino        mode != VOIDmode;
5850e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
5851e4b17023SJohn Marino     {
5852e4b17023SJohn Marino       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5853e4b17023SJohn Marino       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
5854e4b17023SJohn Marino     }
5855e4b17023SJohn Marino 
5856e4b17023SJohn Marino   for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
5857e4b17023SJohn Marino     if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)
5858e4b17023SJohn Marino       const_tiny_rtx[0][i] = const0_rtx;
5859e4b17023SJohn Marino 
5860e4b17023SJohn Marino   const_tiny_rtx[0][(int) BImode] = const0_rtx;
5861e4b17023SJohn Marino   if (STORE_FLAG_VALUE == 1)
5862e4b17023SJohn Marino     const_tiny_rtx[1][(int) BImode] = const1_rtx;
5863e4b17023SJohn Marino }
5864e4b17023SJohn Marino 
5865e4b17023SJohn Marino /* Produce exact duplicate of insn INSN after AFTER.
5866e4b17023SJohn Marino    Care updating of libcall regions if present.  */
5867e4b17023SJohn Marino 
5868e4b17023SJohn Marino rtx
emit_copy_of_insn_after(rtx insn,rtx after)5869e4b17023SJohn Marino emit_copy_of_insn_after (rtx insn, rtx after)
5870e4b17023SJohn Marino {
5871e4b17023SJohn Marino   rtx new_rtx, link;
5872e4b17023SJohn Marino 
5873e4b17023SJohn Marino   switch (GET_CODE (insn))
5874e4b17023SJohn Marino     {
5875e4b17023SJohn Marino     case INSN:
5876e4b17023SJohn Marino       new_rtx = emit_insn_after (copy_insn (PATTERN (insn)), after);
5877e4b17023SJohn Marino       break;
5878e4b17023SJohn Marino 
5879e4b17023SJohn Marino     case JUMP_INSN:
5880e4b17023SJohn Marino       new_rtx = emit_jump_insn_after (copy_insn (PATTERN (insn)), after);
5881e4b17023SJohn Marino       break;
5882e4b17023SJohn Marino 
5883e4b17023SJohn Marino     case DEBUG_INSN:
5884e4b17023SJohn Marino       new_rtx = emit_debug_insn_after (copy_insn (PATTERN (insn)), after);
5885e4b17023SJohn Marino       break;
5886e4b17023SJohn Marino 
5887e4b17023SJohn Marino     case CALL_INSN:
5888e4b17023SJohn Marino       new_rtx = emit_call_insn_after (copy_insn (PATTERN (insn)), after);
5889e4b17023SJohn Marino       if (CALL_INSN_FUNCTION_USAGE (insn))
5890e4b17023SJohn Marino 	CALL_INSN_FUNCTION_USAGE (new_rtx)
5891e4b17023SJohn Marino 	  = copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
5892e4b17023SJohn Marino       SIBLING_CALL_P (new_rtx) = SIBLING_CALL_P (insn);
5893e4b17023SJohn Marino       RTL_CONST_CALL_P (new_rtx) = RTL_CONST_CALL_P (insn);
5894e4b17023SJohn Marino       RTL_PURE_CALL_P (new_rtx) = RTL_PURE_CALL_P (insn);
5895e4b17023SJohn Marino       RTL_LOOPING_CONST_OR_PURE_CALL_P (new_rtx)
5896e4b17023SJohn Marino 	= RTL_LOOPING_CONST_OR_PURE_CALL_P (insn);
5897e4b17023SJohn Marino       break;
5898e4b17023SJohn Marino 
5899e4b17023SJohn Marino     default:
5900e4b17023SJohn Marino       gcc_unreachable ();
5901e4b17023SJohn Marino     }
5902e4b17023SJohn Marino 
5903e4b17023SJohn Marino   /* Update LABEL_NUSES.  */
5904e4b17023SJohn Marino   mark_jump_label (PATTERN (new_rtx), new_rtx, 0);
5905e4b17023SJohn Marino 
5906e4b17023SJohn Marino   INSN_LOCATOR (new_rtx) = INSN_LOCATOR (insn);
5907e4b17023SJohn Marino 
5908e4b17023SJohn Marino   /* If the old insn is frame related, then so is the new one.  This is
5909e4b17023SJohn Marino      primarily needed for IA-64 unwind info which marks epilogue insns,
5910e4b17023SJohn Marino      which may be duplicated by the basic block reordering code.  */
5911e4b17023SJohn Marino   RTX_FRAME_RELATED_P (new_rtx) = RTX_FRAME_RELATED_P (insn);
5912e4b17023SJohn Marino 
5913e4b17023SJohn Marino   /* Copy all REG_NOTES except REG_LABEL_OPERAND since mark_jump_label
5914e4b17023SJohn Marino      will make them.  REG_LABEL_TARGETs are created there too, but are
5915e4b17023SJohn Marino      supposed to be sticky, so we copy them.  */
5916e4b17023SJohn Marino   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
5917e4b17023SJohn Marino     if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
5918e4b17023SJohn Marino       {
5919e4b17023SJohn Marino 	if (GET_CODE (link) == EXPR_LIST)
5920e4b17023SJohn Marino 	  add_reg_note (new_rtx, REG_NOTE_KIND (link),
5921e4b17023SJohn Marino 			copy_insn_1 (XEXP (link, 0)));
5922e4b17023SJohn Marino 	else
5923e4b17023SJohn Marino 	  add_reg_note (new_rtx, REG_NOTE_KIND (link), XEXP (link, 0));
5924e4b17023SJohn Marino       }
5925e4b17023SJohn Marino 
5926e4b17023SJohn Marino   INSN_CODE (new_rtx) = INSN_CODE (insn);
5927e4b17023SJohn Marino   return new_rtx;
5928e4b17023SJohn Marino }
5929e4b17023SJohn Marino 
5930e4b17023SJohn Marino static GTY((deletable)) rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
5931e4b17023SJohn Marino rtx
gen_hard_reg_clobber(enum machine_mode mode,unsigned int regno)5932e4b17023SJohn Marino gen_hard_reg_clobber (enum machine_mode mode, unsigned int regno)
5933e4b17023SJohn Marino {
5934e4b17023SJohn Marino   if (hard_reg_clobbers[mode][regno])
5935e4b17023SJohn Marino     return hard_reg_clobbers[mode][regno];
5936e4b17023SJohn Marino   else
5937e4b17023SJohn Marino     return (hard_reg_clobbers[mode][regno] =
5938e4b17023SJohn Marino 	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
5939e4b17023SJohn Marino }
5940e4b17023SJohn Marino 
5941e4b17023SJohn Marino #include "gt-emit-rtl.h"
5942