1132727Skan/* Emit RTL for the GCC expander.
290075Sobrien   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3169699Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
4169699Skan   Free Software Foundation, Inc.
518334Speter
690075SobrienThis file is part of GCC.
718334Speter
890075SobrienGCC is free software; you can redistribute it and/or modify it under
990075Sobrienthe terms of the GNU General Public License as published by the Free
1090075SobrienSoftware Foundation; either version 2, or (at your option) any later
1190075Sobrienversion.
1218334Speter
1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1590075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1690075Sobrienfor more details.
1718334Speter
1818334SpeterYou should have received a copy of the GNU General Public License
1990075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
20169699SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169699Skan02110-1301, USA.  */
2218334Speter
2318334Speter
2418334Speter/* Middle-to-low level generation of rtx code and insns.
2518334Speter
26169699Skan   This file contains support functions for creating rtl expressions
27169699Skan   and manipulating them in the doubly-linked chain of insns.
2818334Speter
2918334Speter   The patterns of the insns are created by machine-dependent
3018334Speter   routines in insn-emit.c, which is generated automatically from
31169699Skan   the machine description.  These routines make the individual rtx's
32169699Skan   of the pattern with `gen_rtx_fmt_ee' and others in genrtl.[ch],
33169699Skan   which are automatically generated from rtl.def; what is machine
34169699Skan   dependent is the kind of rtx's they make and what arguments they
35169699Skan   use.  */
3618334Speter
3718334Speter#include "config.h"
3850397Sobrien#include "system.h"
39132727Skan#include "coretypes.h"
40132727Skan#include "tm.h"
4152284Sobrien#include "toplev.h"
4218334Speter#include "rtl.h"
4318334Speter#include "tree.h"
4490075Sobrien#include "tm_p.h"
4518334Speter#include "flags.h"
4618334Speter#include "function.h"
4718334Speter#include "expr.h"
4818334Speter#include "regs.h"
4950397Sobrien#include "hard-reg-set.h"
5090075Sobrien#include "hashtab.h"
5118334Speter#include "insn-config.h"
5250397Sobrien#include "recog.h"
5318334Speter#include "real.h"
5450397Sobrien#include "bitmap.h"
5590075Sobrien#include "basic-block.h"
5690075Sobrien#include "ggc.h"
5790075Sobrien#include "debug.h"
5890075Sobrien#include "langhooks.h"
59169699Skan#include "tree-pass.h"
6018334Speter
6118334Speter/* Commonly used modes.  */
6218334Speter
6350397Sobrienenum machine_mode byte_mode;	/* Mode whose width is BITS_PER_UNIT.  */
6450397Sobrienenum machine_mode word_mode;	/* Mode whose width is BITS_PER_WORD.  */
6550397Sobrienenum machine_mode double_mode;	/* Mode whose width is DOUBLE_TYPE_SIZE.  */
6650397Sobrienenum machine_mode ptr_mode;	/* Mode whose width is POINTER_SIZE.  */
6718334Speter
6818334Speter
6918334Speter/* This is *not* reset after each function.  It gives each CODE_LABEL
7018334Speter   in the entire compilation a unique label number.  */
7118334Speter
72132727Skanstatic GTY(()) int label_num = 1;
7318334Speter
7418334Speter/* Nonzero means do not generate NOTEs for source line numbers.  */
7518334Speter
7618334Speterstatic int no_line_numbers;
7718334Speter
7818334Speter/* Commonly used rtx's, so that we only need space for one copy.
7918334Speter   These are initialized once for the entire compilation.
80117404Skan   All of these are unique; no other rtx-object will be equal to any
81117404Skan   of these.  */
8218334Speter
8390075Sobrienrtx global_rtl[GR_MAX];
8452284Sobrien
85117404Skan/* Commonly used RTL for hard registers.  These objects are not necessarily
86117404Skan   unique, so we allocate them separately from global_rtl.  They are
87117404Skan   initialized once per compilation unit, then copied into regno_reg_rtx
88117404Skan   at the beginning of each function.  */
89117404Skanstatic GTY(()) rtx static_regno_reg_rtx[FIRST_PSEUDO_REGISTER];
90117404Skan
9118334Speter/* We record floating-point CONST_DOUBLEs in each floating-point mode for
9218334Speter   the values of 0, 1, and 2.  For the integer entries and VOIDmode, we
9318334Speter   record a copy of const[012]_rtx.  */
9418334Speter
9518334Speterrtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
9618334Speter
9750397Sobrienrtx const_true_rtx;
9850397Sobrien
9918334SpeterREAL_VALUE_TYPE dconst0;
10018334SpeterREAL_VALUE_TYPE dconst1;
10118334SpeterREAL_VALUE_TYPE dconst2;
102132727SkanREAL_VALUE_TYPE dconst3;
103132727SkanREAL_VALUE_TYPE dconst10;
10418334SpeterREAL_VALUE_TYPE dconstm1;
105132727SkanREAL_VALUE_TYPE dconstm2;
106132727SkanREAL_VALUE_TYPE dconsthalf;
107132727SkanREAL_VALUE_TYPE dconstthird;
108132727SkanREAL_VALUE_TYPE dconstpi;
109132727SkanREAL_VALUE_TYPE dconste;
11018334Speter
11118334Speter/* All references to the following fixed hard registers go through
11218334Speter   these unique rtl objects.  On machines where the frame-pointer and
11318334Speter   arg-pointer are the same register, they use the same unique object.
11418334Speter
11518334Speter   After register allocation, other rtl objects which used to be pseudo-regs
11618334Speter   may be clobbered to refer to the frame-pointer register.
11718334Speter   But references that were originally to the frame-pointer can be
11818334Speter   distinguished from the others because they contain frame_pointer_rtx.
11918334Speter
12018334Speter   When to use frame_pointer_rtx and hard_frame_pointer_rtx is a little
12118334Speter   tricky: until register elimination has taken place hard_frame_pointer_rtx
12290075Sobrien   should be used if it is being set, and frame_pointer_rtx otherwise.  After
12318334Speter   register elimination hard_frame_pointer_rtx should always be used.
12418334Speter   On machines where the two registers are same (most) then these are the
12518334Speter   same.
12618334Speter
12718334Speter   In an inline procedure, the stack and frame pointer rtxs may not be
12818334Speter   used for anything else.  */
12918334Speterrtx static_chain_rtx;		/* (REG:Pmode STATIC_CHAIN_REGNUM) */
13018334Speterrtx static_chain_incoming_rtx;	/* (REG:Pmode STATIC_CHAIN_INCOMING_REGNUM) */
13118334Speterrtx pic_offset_table_rtx;	/* (REG:Pmode PIC_OFFSET_TABLE_REGNUM) */
13218334Speter
13350397Sobrien/* This is used to implement __builtin_return_address for some machines.
13450397Sobrien   See for instance the MIPS port.  */
13550397Sobrienrtx return_address_pointer_rtx;	/* (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM) */
13618334Speter
13718334Speter/* We make one copy of (const_int C) where C is in
13818334Speter   [- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT]
13918334Speter   to save space during the compilation and simplify comparisons of
14018334Speter   integers.  */
14118334Speter
14290075Sobrienrtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
14318334Speter
14490075Sobrien/* A hash table storing CONST_INTs whose absolute value is greater
14590075Sobrien   than MAX_SAVED_CONST_INT.  */
14618334Speter
147117404Skanstatic GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
148117404Skan     htab_t const_int_htab;
14918334Speter
15090075Sobrien/* A hash table storing memory attribute structures.  */
151117404Skanstatic GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
152117404Skan     htab_t mem_attrs_htab;
15318334Speter
154132727Skan/* A hash table storing register attribute structures.  */
155132727Skanstatic GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs)))
156132727Skan     htab_t reg_attrs_htab;
157132727Skan
158117404Skan/* A hash table storing all CONST_DOUBLEs.  */
159117404Skanstatic GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
160117404Skan     htab_t const_double_htab;
16118334Speter
16290075Sobrien#define first_insn (cfun->emit->x_first_insn)
16390075Sobrien#define last_insn (cfun->emit->x_last_insn)
16490075Sobrien#define cur_insn_uid (cfun->emit->x_cur_insn_uid)
165132727Skan#define last_location (cfun->emit->x_last_location)
16690075Sobrien#define first_label_num (cfun->emit->x_first_label_num)
16718334Speter
168132727Skanstatic rtx make_call_insn_raw (rtx);
169132727Skanstatic rtx find_line_note (rtx);
170132727Skanstatic rtx change_address_1 (rtx, enum machine_mode, rtx, int);
171132727Skanstatic void unshare_all_decls (tree);
172132727Skanstatic void reset_used_decls (tree);
173132727Skanstatic void mark_label_nuses (rtx);
174132727Skanstatic hashval_t const_int_htab_hash (const void *);
175132727Skanstatic int const_int_htab_eq (const void *, const void *);
176132727Skanstatic hashval_t const_double_htab_hash (const void *);
177132727Skanstatic int const_double_htab_eq (const void *, const void *);
178132727Skanstatic rtx lookup_const_double (rtx);
179132727Skanstatic hashval_t mem_attrs_htab_hash (const void *);
180132727Skanstatic int mem_attrs_htab_eq (const void *, const void *);
181132727Skanstatic mem_attrs *get_mem_attrs (HOST_WIDE_INT, tree, rtx, rtx, unsigned int,
182132727Skan				 enum machine_mode);
183132727Skanstatic hashval_t reg_attrs_htab_hash (const void *);
184132727Skanstatic int reg_attrs_htab_eq (const void *, const void *);
185132727Skanstatic reg_attrs *get_reg_attrs (tree, int);
186132727Skanstatic tree component_ref_for_mem_expr (tree);
187169699Skanstatic rtx gen_const_vector (enum machine_mode, int);
188132727Skanstatic void copy_rtx_if_shared_1 (rtx *orig);
18950397Sobrien
19090075Sobrien/* Probability of the conditional branch currently proceeded by try_split.
19190075Sobrien   Set to -1 otherwise.  */
19290075Sobrienint split_branch_probability = -1;
19390075Sobrien
19490075Sobrien/* Returns a hash code for X (which is a really a CONST_INT).  */
19518334Speter
19690075Sobrienstatic hashval_t
197132727Skanconst_int_htab_hash (const void *x)
19890075Sobrien{
199132727Skan  return (hashval_t) INTVAL ((rtx) x);
20090075Sobrien}
20118334Speter
202117404Skan/* Returns nonzero if the value represented by X (which is really a
20390075Sobrien   CONST_INT) is the same as that given by Y (which is really a
20490075Sobrien   HOST_WIDE_INT *).  */
20518334Speter
20690075Sobrienstatic int
207132727Skanconst_int_htab_eq (const void *x, const void *y)
20890075Sobrien{
209117404Skan  return (INTVAL ((rtx) x) == *((const HOST_WIDE_INT *) y));
21090075Sobrien}
21118334Speter
212117404Skan/* Returns a hash code for X (which is really a CONST_DOUBLE).  */
213117404Skanstatic hashval_t
214132727Skanconst_double_htab_hash (const void *x)
215117404Skan{
216117404Skan  rtx value = (rtx) x;
217117404Skan  hashval_t h;
218117404Skan
219117404Skan  if (GET_MODE (value) == VOIDmode)
220117404Skan    h = CONST_DOUBLE_LOW (value) ^ CONST_DOUBLE_HIGH (value);
221117404Skan  else
222132727Skan    {
223132727Skan      h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
224132727Skan      /* MODE is used in the comparison, so it should be in the hash.  */
225132727Skan      h ^= GET_MODE (value);
226132727Skan    }
227117404Skan  return h;
228117404Skan}
229117404Skan
230117404Skan/* Returns nonzero if the value represented by X (really a ...)
231117404Skan   is the same as that represented by Y (really a ...) */
232117404Skanstatic int
233132727Skanconst_double_htab_eq (const void *x, const void *y)
234117404Skan{
235117404Skan  rtx a = (rtx)x, b = (rtx)y;
236117404Skan
237117404Skan  if (GET_MODE (a) != GET_MODE (b))
238117404Skan    return 0;
239117404Skan  if (GET_MODE (a) == VOIDmode)
240117404Skan    return (CONST_DOUBLE_LOW (a) == CONST_DOUBLE_LOW (b)
241117404Skan	    && CONST_DOUBLE_HIGH (a) == CONST_DOUBLE_HIGH (b));
242117404Skan  else
243117404Skan    return real_identical (CONST_DOUBLE_REAL_VALUE (a),
244117404Skan			   CONST_DOUBLE_REAL_VALUE (b));
245117404Skan}
246117404Skan
24790075Sobrien/* Returns a hash code for X (which is a really a mem_attrs *).  */
24818334Speter
24990075Sobrienstatic hashval_t
250132727Skanmem_attrs_htab_hash (const void *x)
25190075Sobrien{
25290075Sobrien  mem_attrs *p = (mem_attrs *) x;
25318334Speter
25490075Sobrien  return (p->alias ^ (p->align * 1000)
25590075Sobrien	  ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
25690075Sobrien	  ^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
257169699Skan	  ^ (size_t) iterative_hash_expr (p->expr, 0));
25890075Sobrien}
25918334Speter
260117404Skan/* Returns nonzero if the value represented by X (which is really a
26190075Sobrien   mem_attrs *) is the same as that given by Y (which is also really a
26290075Sobrien   mem_attrs *).  */
26318334Speter
26490075Sobrienstatic int
265132727Skanmem_attrs_htab_eq (const void *x, const void *y)
26690075Sobrien{
26790075Sobrien  mem_attrs *p = (mem_attrs *) x;
26890075Sobrien  mem_attrs *q = (mem_attrs *) y;
26918334Speter
270169699Skan  return (p->alias == q->alias && p->offset == q->offset
271169699Skan	  && p->size == q->size && p->align == q->align
272169699Skan	  && (p->expr == q->expr
273169699Skan	      || (p->expr != NULL_TREE && q->expr != NULL_TREE
274169699Skan		  && operand_equal_p (p->expr, q->expr, 0))));
27590075Sobrien}
27618334Speter
27790075Sobrien/* Allocate a new mem_attrs structure and insert it into the hash table if
27890075Sobrien   one identical to it is not already in the table.  We are doing this for
27990075Sobrien   MEM of mode MODE.  */
28090075Sobrien
28190075Sobrienstatic mem_attrs *
282132727Skanget_mem_attrs (HOST_WIDE_INT alias, tree expr, rtx offset, rtx size,
283132727Skan	       unsigned int align, enum machine_mode mode)
28490075Sobrien{
28590075Sobrien  mem_attrs attrs;
28690075Sobrien  void **slot;
28790075Sobrien
288132727Skan  /* If everything is the default, we can just return zero.
289132727Skan     This must match what the corresponding MEM_* macros return when the
290132727Skan     field is not present.  */
29190075Sobrien  if (alias == 0 && expr == 0 && offset == 0
29290075Sobrien      && (size == 0
29390075Sobrien	  || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
294132727Skan      && (STRICT_ALIGNMENT && mode != BLKmode
295132727Skan	  ? align == GET_MODE_ALIGNMENT (mode) : align == BITS_PER_UNIT))
29690075Sobrien    return 0;
29790075Sobrien
29890075Sobrien  attrs.alias = alias;
29990075Sobrien  attrs.expr = expr;
30090075Sobrien  attrs.offset = offset;
30190075Sobrien  attrs.size = size;
30290075Sobrien  attrs.align = align;
30390075Sobrien
30490075Sobrien  slot = htab_find_slot (mem_attrs_htab, &attrs, INSERT);
30590075Sobrien  if (*slot == 0)
30690075Sobrien    {
30790075Sobrien      *slot = ggc_alloc (sizeof (mem_attrs));
30890075Sobrien      memcpy (*slot, &attrs, sizeof (mem_attrs));
30990075Sobrien    }
31090075Sobrien
31190075Sobrien  return *slot;
31290075Sobrien}
31390075Sobrien
314132727Skan/* Returns a hash code for X (which is a really a reg_attrs *).  */
315132727Skan
316132727Skanstatic hashval_t
317132727Skanreg_attrs_htab_hash (const void *x)
318132727Skan{
319132727Skan  reg_attrs *p = (reg_attrs *) x;
320132727Skan
321132727Skan  return ((p->offset * 1000) ^ (long) p->decl);
322132727Skan}
323132727Skan
324132727Skan/* Returns nonzero if the value represented by X (which is really a
325132727Skan   reg_attrs *) is the same as that given by Y (which is also really a
326132727Skan   reg_attrs *).  */
327132727Skan
328132727Skanstatic int
329132727Skanreg_attrs_htab_eq (const void *x, const void *y)
330132727Skan{
331132727Skan  reg_attrs *p = (reg_attrs *) x;
332132727Skan  reg_attrs *q = (reg_attrs *) y;
333132727Skan
334132727Skan  return (p->decl == q->decl && p->offset == q->offset);
335132727Skan}
336132727Skan/* Allocate a new reg_attrs structure and insert it into the hash table if
337132727Skan   one identical to it is not already in the table.  We are doing this for
338132727Skan   MEM of mode MODE.  */
339132727Skan
340132727Skanstatic reg_attrs *
341132727Skanget_reg_attrs (tree decl, int offset)
342132727Skan{
343132727Skan  reg_attrs attrs;
344132727Skan  void **slot;
345132727Skan
346132727Skan  /* If everything is the default, we can just return zero.  */
347132727Skan  if (decl == 0 && offset == 0)
348132727Skan    return 0;
349132727Skan
350132727Skan  attrs.decl = decl;
351132727Skan  attrs.offset = offset;
352132727Skan
353132727Skan  slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
354132727Skan  if (*slot == 0)
355132727Skan    {
356132727Skan      *slot = ggc_alloc (sizeof (reg_attrs));
357132727Skan      memcpy (*slot, &attrs, sizeof (reg_attrs));
358132727Skan    }
359132727Skan
360132727Skan  return *slot;
361132727Skan}
362132727Skan
36390075Sobrien/* Generate a new REG rtx.  Make sure ORIGINAL_REGNO is set properly, and
36490075Sobrien   don't attempt to share with the various global pieces of rtl (such as
36590075Sobrien   frame_pointer_rtx).  */
36690075Sobrien
36750397Sobrienrtx
368132727Skangen_raw_REG (enum machine_mode mode, int regno)
36990075Sobrien{
37090075Sobrien  rtx x = gen_rtx_raw_REG (mode, regno);
37190075Sobrien  ORIGINAL_REGNO (x) = regno;
37290075Sobrien  return x;
37390075Sobrien}
37490075Sobrien
37590075Sobrien/* There are some RTL codes that require special attention; the generation
37690075Sobrien   functions do the raw handling.  If you add to this list, modify
37790075Sobrien   special_rtx in gengenrtl.c as well.  */
37890075Sobrien
37990075Sobrienrtx
380132727Skangen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
38150397Sobrien{
38290075Sobrien  void **slot;
38390075Sobrien
38450397Sobrien  if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
38590075Sobrien    return const_int_rtx[arg + MAX_SAVED_CONST_INT];
38618334Speter
38750397Sobrien#if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1
38850397Sobrien  if (const_true_rtx && arg == STORE_FLAG_VALUE)
38950397Sobrien    return const_true_rtx;
39050397Sobrien#endif
39150397Sobrien
39290075Sobrien  /* Look up the CONST_INT in the hash table.  */
39390075Sobrien  slot = htab_find_slot_with_hash (const_int_htab, &arg,
39490075Sobrien				   (hashval_t) arg, INSERT);
39590075Sobrien  if (*slot == 0)
39690075Sobrien    *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);
39790075Sobrien
39890075Sobrien  return (rtx) *slot;
39950397Sobrien}
40050397Sobrien
401102793Skanrtx
402132727Skangen_int_mode (HOST_WIDE_INT c, enum machine_mode mode)
403102793Skan{
404102793Skan  return GEN_INT (trunc_int_for_mode (c, mode));
405102793Skan}
406102793Skan
407117404Skan/* CONST_DOUBLEs might be created from pairs of integers, or from
408117404Skan   REAL_VALUE_TYPEs.  Also, their length is known only at run time,
409117404Skan   so we cannot use gen_rtx_raw_CONST_DOUBLE.  */
41090075Sobrien
411117404Skan/* Determine whether REAL, a CONST_DOUBLE, already exists in the
412117404Skan   hash table.  If so, return its counterpart; otherwise add it
413117404Skan   to the hash table and return it.  */
414117404Skanstatic rtx
415132727Skanlookup_const_double (rtx real)
416117404Skan{
417117404Skan  void **slot = htab_find_slot (const_double_htab, real, INSERT);
418117404Skan  if (*slot == 0)
419117404Skan    *slot = real;
420117404Skan
421117404Skan  return (rtx) *slot;
422117404Skan}
423117404Skan
424117404Skan/* Return a CONST_DOUBLE rtx for a floating-point value specified by
425117404Skan   VALUE in mode MODE.  */
42650397Sobrienrtx
427132727Skanconst_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode)
42852284Sobrien{
429117404Skan  rtx real = rtx_alloc (CONST_DOUBLE);
430117404Skan  PUT_MODE (real, mode);
43152284Sobrien
432169699Skan  real->u.rv = value;
43352284Sobrien
434117404Skan  return lookup_const_double (real);
435117404Skan}
43652284Sobrien
437117404Skan/* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair
438117404Skan   of ints: I0 is the low-order word and I1 is the high-order word.
439117404Skan   Do not use this routine for non-integer modes; convert to
440117404Skan   REAL_VALUE_TYPE and use CONST_DOUBLE_FROM_REAL_VALUE.  */
441117404Skan
442117404Skanrtx
443132727Skanimmed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, enum machine_mode mode)
444117404Skan{
445117404Skan  rtx value;
446117404Skan  unsigned int i;
447117404Skan
448169699Skan  /* There are the following cases (note that there are no modes with
449169699Skan     HOST_BITS_PER_WIDE_INT < GET_MODE_BITSIZE (mode) < 2 * HOST_BITS_PER_WIDE_INT):
450169699Skan
451169699Skan     1) If GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT, then we use
452169699Skan	gen_int_mode.
453169699Skan     2) GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT, but the value of
454169699Skan	the integer fits into HOST_WIDE_INT anyway (i.e., i1 consists only
455169699Skan	from copies of the sign bit, and sign of i0 and i1 are the same),  then
456169699Skan	we return a CONST_INT for i0.
457169699Skan     3) Otherwise, we create a CONST_DOUBLE for i0 and i1.  */
458117404Skan  if (mode != VOIDmode)
459117404Skan    {
460169699Skan      gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
461169699Skan		  || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
462169699Skan		  /* We can get a 0 for an error mark.  */
463169699Skan		  || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
464169699Skan		  || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT);
465117404Skan
466169699Skan      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
467169699Skan	return gen_int_mode (i0, mode);
468117404Skan
469169699Skan      gcc_assert (GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT);
470117404Skan    }
471117404Skan
472117404Skan  /* If this integer fits in one word, return a CONST_INT.  */
473117404Skan  if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
474117404Skan    return GEN_INT (i0);
475117404Skan
476117404Skan  /* We use VOIDmode for integers.  */
477117404Skan  value = rtx_alloc (CONST_DOUBLE);
478117404Skan  PUT_MODE (value, VOIDmode);
479117404Skan
480117404Skan  CONST_DOUBLE_LOW (value) = i0;
481117404Skan  CONST_DOUBLE_HIGH (value) = i1;
482117404Skan
483117404Skan  for (i = 2; i < (sizeof CONST_DOUBLE_FORMAT - 1); i++)
484117404Skan    XWINT (value, i) = 0;
485117404Skan
486117404Skan  return lookup_const_double (value);
48752284Sobrien}
48852284Sobrien
48952284Sobrienrtx
490132727Skangen_rtx_REG (enum machine_mode mode, unsigned int regno)
49150397Sobrien{
49250397Sobrien  /* In case the MD file explicitly references the frame pointer, have
49350397Sobrien     all such references point to the same frame pointer.  This is
49450397Sobrien     used during frame pointer elimination to distinguish the explicit
49550397Sobrien     references to these registers from pseudos that happened to be
49650397Sobrien     assigned to them.
49750397Sobrien
49850397Sobrien     If we have eliminated the frame pointer or arg pointer, we will
49950397Sobrien     be using it as a normal register, for example as a spill
50050397Sobrien     register.  In such cases, we might be accessing it in a mode that
50150397Sobrien     is not Pmode and therefore cannot use the pre-allocated rtx.
50250397Sobrien
50350397Sobrien     Also don't do this when we are making new REGs in reload, since
50450397Sobrien     we don't want to get confused with the real pointers.  */
50550397Sobrien
50650397Sobrien  if (mode == Pmode && !reload_in_progress)
50750397Sobrien    {
508117404Skan      if (regno == FRAME_POINTER_REGNUM
509117404Skan	  && (!reload_completed || frame_pointer_needed))
51050397Sobrien	return frame_pointer_rtx;
51150397Sobrien#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
512117404Skan      if (regno == HARD_FRAME_POINTER_REGNUM
513117404Skan	  && (!reload_completed || frame_pointer_needed))
51450397Sobrien	return hard_frame_pointer_rtx;
51550397Sobrien#endif
51650397Sobrien#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
51750397Sobrien      if (regno == ARG_POINTER_REGNUM)
51850397Sobrien	return arg_pointer_rtx;
51950397Sobrien#endif
52050397Sobrien#ifdef RETURN_ADDRESS_POINTER_REGNUM
52150397Sobrien      if (regno == RETURN_ADDRESS_POINTER_REGNUM)
52250397Sobrien	return return_address_pointer_rtx;
52350397Sobrien#endif
524132727Skan      if (regno == (unsigned) PIC_OFFSET_TABLE_REGNUM
52590075Sobrien	  && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
526117404Skan	return pic_offset_table_rtx;
52750397Sobrien      if (regno == STACK_POINTER_REGNUM)
52850397Sobrien	return stack_pointer_rtx;
52950397Sobrien    }
53050397Sobrien
531117404Skan#if 0
532117404Skan  /* If the per-function register table has been set up, try to re-use
533117404Skan     an existing entry in that table to avoid useless generation of RTL.
534117404Skan
535117404Skan     This code is disabled for now until we can fix the various backends
536117404Skan     which depend on having non-shared hard registers in some cases.   Long
537117404Skan     term we want to re-enable this code as it can significantly cut down
538117404Skan     on the amount of useless RTL that gets generated.
539117404Skan
540117404Skan     We'll also need to fix some code that runs after reload that wants to
541117404Skan     set ORIGINAL_REGNO.  */
542117404Skan
543117404Skan  if (cfun
544117404Skan      && cfun->emit
545117404Skan      && regno_reg_rtx
546117404Skan      && regno < FIRST_PSEUDO_REGISTER
547117404Skan      && reg_raw_mode[regno] == mode)
548117404Skan    return regno_reg_rtx[regno];
549117404Skan#endif
550117404Skan
55190075Sobrien  return gen_raw_REG (mode, regno);
55250397Sobrien}
55350397Sobrien
55450397Sobrienrtx
555132727Skangen_rtx_MEM (enum machine_mode mode, rtx addr)
55650397Sobrien{
55750397Sobrien  rtx rt = gen_rtx_raw_MEM (mode, addr);
55850397Sobrien
55950397Sobrien  /* This field is not cleared by the mere allocation of the rtx, so
56050397Sobrien     we clear it here.  */
56190075Sobrien  MEM_ATTRS (rt) = 0;
56250397Sobrien
56350397Sobrien  return rt;
56450397Sobrien}
56550397Sobrien
566169699Skan/* Generate a memory referring to non-trapping constant memory.  */
567169699Skan
56890075Sobrienrtx
569169699Skangen_const_mem (enum machine_mode mode, rtx addr)
57090075Sobrien{
571169699Skan  rtx mem = gen_rtx_MEM (mode, addr);
572169699Skan  MEM_READONLY_P (mem) = 1;
573169699Skan  MEM_NOTRAP_P (mem) = 1;
574169699Skan  return mem;
57590075Sobrien}
57690075Sobrien
577169699Skan/* Generate a MEM referring to fixed portions of the frame, e.g., register
578169699Skan   save areas.  */
57990075Sobrien
58090075Sobrienrtx
581169699Skangen_frame_mem (enum machine_mode mode, rtx addr)
58290075Sobrien{
583169699Skan  rtx mem = gen_rtx_MEM (mode, addr);
584169699Skan  MEM_NOTRAP_P (mem) = 1;
585169699Skan  set_mem_alias_set (mem, get_frame_alias_set ());
586169699Skan  return mem;
58790075Sobrien}
58818334Speter
589169699Skan/* Generate a MEM referring to a temporary use of the stack, not part
590169699Skan    of the fixed stack frame.  For example, something which is pushed
591169699Skan    by a target splitter.  */
59218334Speterrtx
593169699Skangen_tmp_stack_mem (enum machine_mode mode, rtx addr)
59418334Speter{
595169699Skan  rtx mem = gen_rtx_MEM (mode, addr);
596169699Skan  MEM_NOTRAP_P (mem) = 1;
597169699Skan  if (!current_function_calls_alloca)
598169699Skan    set_mem_alias_set (mem, get_frame_alias_set ());
599169699Skan  return mem;
600169699Skan}
60118334Speter
602169699Skan/* We want to create (subreg:OMODE (obj:IMODE) OFFSET).  Return true if
603169699Skan   this construct would be valid, and false otherwise.  */
60418334Speter
605169699Skanbool
606169699Skanvalidate_subreg (enum machine_mode omode, enum machine_mode imode,
607169699Skan		 rtx reg, unsigned int offset)
608169699Skan{
609169699Skan  unsigned int isize = GET_MODE_SIZE (imode);
610169699Skan  unsigned int osize = GET_MODE_SIZE (omode);
61152284Sobrien
612169699Skan  /* All subregs must be aligned.  */
613169699Skan  if (offset % osize != 0)
614169699Skan    return false;
61590075Sobrien
616169699Skan  /* The subreg offset cannot be outside the inner object.  */
617169699Skan  if (offset >= isize)
618169699Skan    return false;
61952284Sobrien
620169699Skan  /* ??? This should not be here.  Temporarily continue to allow word_mode
621169699Skan     subregs of anything.  The most common offender is (subreg:SI (reg:DF)).
622169699Skan     Generally, backends are doing something sketchy but it'll take time to
623169699Skan     fix them all.  */
624169699Skan  if (omode == word_mode)
625169699Skan    ;
626169699Skan  /* ??? Similarly, e.g. with (subreg:DF (reg:TI)).  Though store_bit_field
627169699Skan     is the culprit here, and not the backends.  */
628169699Skan  else if (osize >= UNITS_PER_WORD && isize >= osize)
629169699Skan    ;
630169699Skan  /* Allow component subregs of complex and vector.  Though given the below
631169699Skan     extraction rules, it's not always clear what that means.  */
632169699Skan  else if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
633169699Skan	   && GET_MODE_INNER (imode) == omode)
634169699Skan    ;
635169699Skan  /* ??? x86 sse code makes heavy use of *paradoxical* vector subregs,
636169699Skan     i.e. (subreg:V4SF (reg:SF) 0).  This surely isn't the cleanest way to
637169699Skan     represent this.  It's questionable if this ought to be represented at
638169699Skan     all -- why can't this all be hidden in post-reload splitters that make
639169699Skan     arbitrarily mode changes to the registers themselves.  */
640169699Skan  else if (VECTOR_MODE_P (omode) && GET_MODE_INNER (omode) == imode)
641169699Skan    ;
642169699Skan  /* Subregs involving floating point modes are not allowed to
643169699Skan     change size.  Therefore (subreg:DI (reg:DF) 0) is fine, but
644169699Skan     (subreg:SI (reg:DF) 0) isn't.  */
645169699Skan  else if (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))
646169699Skan    {
647169699Skan      if (isize != osize)
648169699Skan	return false;
649169699Skan    }
65052284Sobrien
651169699Skan  /* Paradoxical subregs must have offset zero.  */
652169699Skan  if (osize > isize)
653169699Skan    return offset == 0;
65452284Sobrien
655169699Skan  /* This is a normal subreg.  Verify that the offset is representable.  */
65618334Speter
657169699Skan  /* For hard registers, we already have most of these rules collected in
658169699Skan     subreg_offset_representable_p.  */
659169699Skan  if (reg && REG_P (reg) && HARD_REGISTER_P (reg))
660169699Skan    {
661169699Skan      unsigned int regno = REGNO (reg);
66218334Speter
663169699Skan#ifdef CANNOT_CHANGE_MODE_CLASS
664169699Skan      if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
665169699Skan	  && GET_MODE_INNER (imode) == omode)
666169699Skan	;
667169699Skan      else if (REG_CANNOT_CHANGE_MODE_P (regno, imode, omode))
668169699Skan	return false;
669169699Skan#endif
67018334Speter
671169699Skan      return subreg_offset_representable_p (regno, imode, offset, omode);
672169699Skan    }
67318334Speter
674169699Skan  /* For pseudo registers, we want most of the same checks.  Namely:
675169699Skan     If the register no larger than a word, the subreg must be lowpart.
676169699Skan     If the register is larger than a word, the subreg must be the lowpart
677169699Skan     of a subword.  A subreg does *not* perform arbitrary bit extraction.
678169699Skan     Given that we've already checked mode/offset alignment, we only have
679169699Skan     to check subword subregs here.  */
680169699Skan  if (osize < UNITS_PER_WORD)
681169699Skan    {
682169699Skan      enum machine_mode wmode = isize > UNITS_PER_WORD ? word_mode : imode;
683169699Skan      unsigned int low_off = subreg_lowpart_offset (omode, wmode);
684169699Skan      if (offset % UNITS_PER_WORD != low_off)
685169699Skan	return false;
686169699Skan    }
687169699Skan  return true;
688169699Skan}
68918334Speter
690169699Skanrtx
691169699Skangen_rtx_SUBREG (enum machine_mode mode, rtx reg, int offset)
692169699Skan{
693169699Skan  gcc_assert (validate_subreg (mode, GET_MODE (reg), reg, offset));
694169699Skan  return gen_rtx_raw_SUBREG (mode, reg, offset);
695169699Skan}
69618334Speter
697169699Skan/* Generate a SUBREG representing the least-significant part of REG if MODE
698169699Skan   is smaller than mode of REG, otherwise paradoxical SUBREG.  */
69918334Speter
700169699Skanrtx
701169699Skangen_lowpart_SUBREG (enum machine_mode mode, rtx reg)
702169699Skan{
703169699Skan  enum machine_mode inmode;
70450397Sobrien
705169699Skan  inmode = GET_MODE (reg);
706169699Skan  if (inmode == VOIDmode)
707169699Skan    inmode = mode;
708169699Skan  return gen_rtx_SUBREG (mode, reg,
709169699Skan			 subreg_lowpart_offset (mode, inmode));
71018334Speter}
711169699Skan
71218334Speter/* gen_rtvec (n, [rt1, ..., rtn])
71318334Speter**
71418334Speter**	    This routine creates an rtvec and stores within it the
71518334Speter**	pointers to rtx's which are its arguments.
71618334Speter*/
71718334Speter
71818334Speter/*VARARGS1*/
71918334Speterrtvec
720132727Skangen_rtvec (int n, ...)
72118334Speter{
72290075Sobrien  int i, save_n;
72318334Speter  rtx *vector;
724132727Skan  va_list p;
72518334Speter
726132727Skan  va_start (p, n);
72718334Speter
72818334Speter  if (n == 0)
72918334Speter    return NULL_RTVEC;		/* Don't allocate an empty rtvec...	*/
73018334Speter
731132727Skan  vector = alloca (n * sizeof (rtx));
73218334Speter
73318334Speter  for (i = 0; i < n; i++)
73418334Speter    vector[i] = va_arg (p, rtx);
73518334Speter
73690075Sobrien  /* The definition of VA_* in K&R C causes `n' to go out of scope.  */
73790075Sobrien  save_n = n;
738132727Skan  va_end (p);
73990075Sobrien
74090075Sobrien  return gen_rtvec_v (save_n, vector);
74118334Speter}
74218334Speter
74318334Speterrtvec
744132727Skangen_rtvec_v (int n, rtx *argp)
74518334Speter{
74690075Sobrien  int i;
74790075Sobrien  rtvec rt_val;
74818334Speter
74918334Speter  if (n == 0)
75018334Speter    return NULL_RTVEC;		/* Don't allocate an empty rtvec...	*/
75118334Speter
75218334Speter  rt_val = rtvec_alloc (n);	/* Allocate an rtvec...			*/
75318334Speter
75418334Speter  for (i = 0; i < n; i++)
75590075Sobrien    rt_val->elem[i] = *argp++;
75618334Speter
75718334Speter  return rt_val;
75818334Speter}
75918334Speter
76018334Speter/* Generate a REG rtx for a new pseudo register of mode MODE.
76118334Speter   This pseudo is assigned the next sequential register number.  */
76218334Speter
76318334Speterrtx
764132727Skangen_reg_rtx (enum machine_mode mode)
76518334Speter{
76690075Sobrien  struct function *f = cfun;
76790075Sobrien  rtx val;
76818334Speter
76952284Sobrien  /* Don't let anything called after initial flow analysis create new
77052284Sobrien     registers.  */
771169699Skan  gcc_assert (!no_new_pseudos);
77218334Speter
77390075Sobrien  if (generating_concat_p
77490075Sobrien      && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
77590075Sobrien	  || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT))
77618334Speter    {
77718334Speter      /* For complex modes, don't make a single pseudo.
77818334Speter	 Instead, make a CONCAT of two pseudos.
77918334Speter	 This allows noncontiguous allocation of the real and imaginary parts,
78018334Speter	 which makes much better code.  Besides, allocating DCmode
78118334Speter	 pseudos overstrains reload on some machines like the 386.  */
78218334Speter      rtx realpart, imagpart;
783117404Skan      enum machine_mode partmode = GET_MODE_INNER (mode);
78418334Speter
78518334Speter      realpart = gen_reg_rtx (partmode);
78618334Speter      imagpart = gen_reg_rtx (partmode);
78750397Sobrien      return gen_rtx_CONCAT (mode, realpart, imagpart);
78818334Speter    }
78918334Speter
790132727Skan  /* Make sure regno_pointer_align, and regno_reg_rtx are large
79118334Speter     enough to have an element for this pseudo reg number.  */
79218334Speter
79390075Sobrien  if (reg_rtx_no == f->emit->regno_pointer_align_length)
79418334Speter    {
79590075Sobrien      int old_size = f->emit->regno_pointer_align_length;
79690075Sobrien      char *new;
79718334Speter      rtx *new1;
79818334Speter
799117404Skan      new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
80090075Sobrien      memset (new + old_size, 0, old_size);
80190075Sobrien      f->emit->regno_pointer_align = (unsigned char *) new;
80250397Sobrien
803132727Skan      new1 = ggc_realloc (f->emit->x_regno_reg_rtx,
804132727Skan			  old_size * 2 * sizeof (rtx));
80590075Sobrien      memset (new1 + old_size, 0, old_size * sizeof (rtx));
80618334Speter      regno_reg_rtx = new1;
80718334Speter
80890075Sobrien      f->emit->regno_pointer_align_length = old_size * 2;
80918334Speter    }
81018334Speter
81190075Sobrien  val = gen_raw_REG (mode, reg_rtx_no);
81218334Speter  regno_reg_rtx[reg_rtx_no++] = val;
81318334Speter  return val;
81418334Speter}
81518334Speter
816169699Skan/* Generate a register with same attributes as REG, but offsetted by OFFSET.
817169699Skan   Do the big endian correction if needed.  */
818132727Skan
819132727Skanrtx
820132727Skangen_rtx_REG_offset (rtx reg, enum machine_mode mode, unsigned int regno, int offset)
821132727Skan{
822132727Skan  rtx new = gen_rtx_REG (mode, regno);
823169699Skan  tree decl;
824169699Skan  HOST_WIDE_INT var_size;
825169699Skan
826169699Skan  /* PR middle-end/14084
827169699Skan     The problem appears when a variable is stored in a larger register
828169699Skan     and later it is used in the original mode or some mode in between
829169699Skan     or some part of variable is accessed.
830169699Skan
831169699Skan     On little endian machines there is no problem because
832169699Skan     the REG_OFFSET of the start of the variable is the same when
833169699Skan     accessed in any mode (it is 0).
834169699Skan
835169699Skan     However, this is not true on big endian machines.
836169699Skan     The offset of the start of the variable is different when accessed
837169699Skan     in different modes.
838169699Skan     When we are taking a part of the REG we have to change the OFFSET
839169699Skan     from offset WRT size of mode of REG to offset WRT size of variable.
840169699Skan
841169699Skan     If we would not do the big endian correction the resulting REG_OFFSET
842169699Skan     would be larger than the size of the DECL.
843169699Skan
844169699Skan     Examples of correction, for BYTES_BIG_ENDIAN WORDS_BIG_ENDIAN machine:
845169699Skan
846169699Skan     REG.mode  MODE  DECL size  old offset  new offset  description
847169699Skan     DI        SI    4          4           0           int32 in SImode
848169699Skan     DI        SI    1          4           0           char in SImode
849169699Skan     DI        QI    1          7           0           char in QImode
850169699Skan     DI        QI    4          5           1           1st element in QImode
851169699Skan                                                        of char[4]
852169699Skan     DI        HI    4          6           2           1st element in HImode
853169699Skan                                                        of int16[2]
854169699Skan
855169699Skan     If the size of DECL is equal or greater than the size of REG
856169699Skan     we can't do this correction because the register holds the
857169699Skan     whole variable or a part of the variable and thus the REG_OFFSET
858169699Skan     is already correct.  */
859169699Skan
860169699Skan  decl = REG_EXPR (reg);
861169699Skan  if ((BYTES_BIG_ENDIAN || WORDS_BIG_ENDIAN)
862169699Skan      && decl != NULL
863169699Skan      && offset > 0
864169699Skan      && GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode)
865169699Skan      && ((var_size = int_size_in_bytes (TREE_TYPE (decl))) > 0
866169699Skan	  && var_size < GET_MODE_SIZE (GET_MODE (reg))))
867169699Skan    {
868169699Skan      int offset_le;
869169699Skan
870169699Skan      /* Convert machine endian to little endian WRT size of mode of REG.  */
871169699Skan      if (WORDS_BIG_ENDIAN)
872169699Skan	offset_le = ((GET_MODE_SIZE (GET_MODE (reg)) - 1 - offset)
873169699Skan		     / UNITS_PER_WORD) * UNITS_PER_WORD;
874169699Skan      else
875169699Skan	offset_le = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
876169699Skan
877169699Skan      if (BYTES_BIG_ENDIAN)
878169699Skan	offset_le += ((GET_MODE_SIZE (GET_MODE (reg)) - 1 - offset)
879169699Skan		      % UNITS_PER_WORD);
880169699Skan      else
881169699Skan	offset_le += offset % UNITS_PER_WORD;
882169699Skan
883169699Skan      if (offset_le >= var_size)
884169699Skan	{
885169699Skan	  /* MODE is wider than the variable so the new reg will cover
886169699Skan	     the whole variable so the resulting OFFSET should be 0.  */
887169699Skan	  offset = 0;
888169699Skan	}
889169699Skan      else
890169699Skan	{
891169699Skan	  /* Convert little endian to machine endian WRT size of variable.  */
892169699Skan	  if (WORDS_BIG_ENDIAN)
893169699Skan	    offset = ((var_size - 1 - offset_le)
894169699Skan		      / UNITS_PER_WORD) * UNITS_PER_WORD;
895169699Skan	  else
896169699Skan	    offset = (offset_le / UNITS_PER_WORD) * UNITS_PER_WORD;
897169699Skan
898169699Skan	  if (BYTES_BIG_ENDIAN)
899169699Skan	    offset += ((var_size - 1 - offset_le)
900169699Skan		       % UNITS_PER_WORD);
901169699Skan	  else
902169699Skan	    offset += offset_le % UNITS_PER_WORD;
903169699Skan	}
904169699Skan    }
905169699Skan
906132727Skan  REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg),
907132727Skan				   REG_OFFSET (reg) + offset);
908132727Skan  return new;
909132727Skan}
910132727Skan
911132727Skan/* Set the decl for MEM to DECL.  */
912132727Skan
913132727Skanvoid
914132727Skanset_reg_attrs_from_mem (rtx reg, rtx mem)
915132727Skan{
916132727Skan  if (MEM_OFFSET (mem) && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
917132727Skan    REG_ATTRS (reg)
918132727Skan      = get_reg_attrs (MEM_EXPR (mem), INTVAL (MEM_OFFSET (mem)));
919132727Skan}
920132727Skan
921132727Skan/* Set the register attributes for registers contained in PARM_RTX.
922132727Skan   Use needed values from memory attributes of MEM.  */
923132727Skan
924132727Skanvoid
925132727Skanset_reg_attrs_for_parm (rtx parm_rtx, rtx mem)
926132727Skan{
927169699Skan  if (REG_P (parm_rtx))
928132727Skan    set_reg_attrs_from_mem (parm_rtx, mem);
929132727Skan  else if (GET_CODE (parm_rtx) == PARALLEL)
930132727Skan    {
931132727Skan      /* Check for a NULL entry in the first slot, used to indicate that the
932132727Skan	 parameter goes both on the stack and in registers.  */
933132727Skan      int i = XEXP (XVECEXP (parm_rtx, 0, 0), 0) ? 0 : 1;
934132727Skan      for (; i < XVECLEN (parm_rtx, 0); i++)
935132727Skan	{
936132727Skan	  rtx x = XVECEXP (parm_rtx, 0, i);
937169699Skan	  if (REG_P (XEXP (x, 0)))
938132727Skan	    REG_ATTRS (XEXP (x, 0))
939132727Skan	      = get_reg_attrs (MEM_EXPR (mem),
940132727Skan			       INTVAL (XEXP (x, 1)));
941132727Skan	}
942132727Skan    }
943132727Skan}
944132727Skan
945132727Skan/* Assign the RTX X to declaration T.  */
946132727Skanvoid
947132727Skanset_decl_rtl (tree t, rtx x)
948132727Skan{
949169699Skan  DECL_WRTL_CHECK (t)->decl_with_rtl.rtl = x;
950132727Skan
951132727Skan  if (!x)
952132727Skan    return;
953132727Skan  /* For register, we maintain the reverse information too.  */
954169699Skan  if (REG_P (x))
955132727Skan    REG_ATTRS (x) = get_reg_attrs (t, 0);
956132727Skan  else if (GET_CODE (x) == SUBREG)
957132727Skan    REG_ATTRS (SUBREG_REG (x))
958132727Skan      = get_reg_attrs (t, -SUBREG_BYTE (x));
959132727Skan  if (GET_CODE (x) == CONCAT)
960132727Skan    {
961132727Skan      if (REG_P (XEXP (x, 0)))
962132727Skan        REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
963132727Skan      if (REG_P (XEXP (x, 1)))
964132727Skan	REG_ATTRS (XEXP (x, 1))
965132727Skan	  = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
966132727Skan    }
967132727Skan  if (GET_CODE (x) == PARALLEL)
968132727Skan    {
969132727Skan      int i;
970132727Skan      for (i = 0; i < XVECLEN (x, 0); i++)
971132727Skan	{
972132727Skan	  rtx y = XVECEXP (x, 0, i);
973132727Skan	  if (REG_P (XEXP (y, 0)))
974132727Skan	    REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
975132727Skan	}
976132727Skan    }
977132727Skan}
978132727Skan
979169699Skan/* Assign the RTX X to parameter declaration T.  */
980169699Skanvoid
981169699Skanset_decl_incoming_rtl (tree t, rtx x)
982169699Skan{
983169699Skan  DECL_INCOMING_RTL (t) = x;
984169699Skan
985169699Skan  if (!x)
986169699Skan    return;
987169699Skan  /* For register, we maintain the reverse information too.  */
988169699Skan  if (REG_P (x))
989169699Skan    REG_ATTRS (x) = get_reg_attrs (t, 0);
990169699Skan  else if (GET_CODE (x) == SUBREG)
991169699Skan    REG_ATTRS (SUBREG_REG (x))
992169699Skan      = get_reg_attrs (t, -SUBREG_BYTE (x));
993169699Skan  if (GET_CODE (x) == CONCAT)
994169699Skan    {
995169699Skan      if (REG_P (XEXP (x, 0)))
996169699Skan        REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
997169699Skan      if (REG_P (XEXP (x, 1)))
998169699Skan	REG_ATTRS (XEXP (x, 1))
999169699Skan	  = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
1000169699Skan    }
1001169699Skan  if (GET_CODE (x) == PARALLEL)
1002169699Skan    {
1003169699Skan      int i, start;
1004169699Skan
1005169699Skan      /* Check for a NULL entry, used to indicate that the parameter goes
1006169699Skan	 both on the stack and in registers.  */
1007169699Skan      if (XEXP (XVECEXP (x, 0, 0), 0))
1008169699Skan	start = 0;
1009169699Skan      else
1010169699Skan	start = 1;
1011169699Skan
1012169699Skan      for (i = start; i < XVECLEN (x, 0); i++)
1013169699Skan	{
1014169699Skan	  rtx y = XVECEXP (x, 0, i);
1015169699Skan	  if (REG_P (XEXP (y, 0)))
1016169699Skan	    REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
1017169699Skan	}
1018169699Skan    }
1019169699Skan}
1020169699Skan
102150397Sobrien/* Identify REG (which may be a CONCAT) as a user register.  */
102218334Speter
102318334Spetervoid
1024132727Skanmark_user_reg (rtx reg)
102518334Speter{
102650397Sobrien  if (GET_CODE (reg) == CONCAT)
102750397Sobrien    {
102850397Sobrien      REG_USERVAR_P (XEXP (reg, 0)) = 1;
102950397Sobrien      REG_USERVAR_P (XEXP (reg, 1)) = 1;
103050397Sobrien    }
103150397Sobrien  else
1032169699Skan    {
1033169699Skan      gcc_assert (REG_P (reg));
1034169699Skan      REG_USERVAR_P (reg) = 1;
1035169699Skan    }
103650397Sobrien}
103750397Sobrien
103850397Sobrien/* Identify REG as a probable pointer register and show its alignment
103950397Sobrien   as ALIGN, if nonzero.  */
104050397Sobrien
104150397Sobrienvoid
1042132727Skanmark_reg_pointer (rtx reg, int align)
104350397Sobrien{
104490075Sobrien  if (! REG_POINTER (reg))
104552284Sobrien    {
104690075Sobrien      REG_POINTER (reg) = 1;
104750397Sobrien
104852284Sobrien      if (align)
104952284Sobrien	REGNO_POINTER_ALIGN (REGNO (reg)) = align;
105052284Sobrien    }
105152284Sobrien  else if (align && align < REGNO_POINTER_ALIGN (REGNO (reg)))
1052132727Skan    /* We can no-longer be sure just how aligned this pointer is.  */
105350397Sobrien    REGNO_POINTER_ALIGN (REGNO (reg)) = align;
105418334Speter}
105518334Speter
105618334Speter/* Return 1 plus largest pseudo reg number used in the current function.  */
105718334Speter
105818334Speterint
1059132727Skanmax_reg_num (void)
106018334Speter{
106118334Speter  return reg_rtx_no;
106218334Speter}
106318334Speter
106418334Speter/* Return 1 + the largest label number used so far in the current function.  */
106518334Speter
106618334Speterint
1067132727Skanmax_label_num (void)
106818334Speter{
106918334Speter  return label_num;
107018334Speter}
107118334Speter
107218334Speter/* Return first label number used in this function (if any were used).  */
107318334Speter
107418334Speterint
1075132727Skanget_first_label_num (void)
107618334Speter{
107718334Speter  return first_label_num;
107818334Speter}
107990075Sobrien
1080169699Skan/* If the rtx for label was created during the expansion of a nested
1081169699Skan   function, then first_label_num won't include this label number.
1082169699Skan   Fix this now so that array indicies work later.  */
108390075Sobrien
1084169699Skanvoid
1085169699Skanmaybe_set_first_label_num (rtx x)
1086169699Skan{
1087169699Skan  if (CODE_LABEL_NUMBER (x) < first_label_num)
1088169699Skan    first_label_num = CODE_LABEL_NUMBER (x);
108990075Sobrien}
1090169699Skan
109118334Speter/* Return a value representing some low-order bits of X, where the number
109218334Speter   of low-order bits is given by MODE.  Note that no conversion is done
109390075Sobrien   between floating-point and fixed-point values, rather, the bit
109418334Speter   representation is returned.
109518334Speter
109618334Speter   This function handles the cases in common between gen_lowpart, below,
109718334Speter   and two variants in cse.c and combine.c.  These are the cases that can
109818334Speter   be safely handled at all points in the compilation.
109918334Speter
110018334Speter   If this is not a case we can handle, return 0.  */
110118334Speter
110218334Speterrtx
1103132727Skangen_lowpart_common (enum machine_mode mode, rtx x)
110418334Speter{
110590075Sobrien  int msize = GET_MODE_SIZE (mode);
1106132727Skan  int xsize;
110790075Sobrien  int offset = 0;
1108132727Skan  enum machine_mode innermode;
110918334Speter
1110132727Skan  /* Unfortunately, this routine doesn't take a parameter for the mode of X,
1111132727Skan     so we have to make one up.  Yuk.  */
1112132727Skan  innermode = GET_MODE (x);
1113169699Skan  if (GET_CODE (x) == CONST_INT
1114169699Skan      && msize * BITS_PER_UNIT <= HOST_BITS_PER_WIDE_INT)
1115132727Skan    innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
1116132727Skan  else if (innermode == VOIDmode)
1117132727Skan    innermode = mode_for_size (HOST_BITS_PER_WIDE_INT * 2, MODE_INT, 0);
1118132727Skan
1119132727Skan  xsize = GET_MODE_SIZE (innermode);
1120132727Skan
1121169699Skan  gcc_assert (innermode != VOIDmode && innermode != BLKmode);
1122132727Skan
1123132727Skan  if (innermode == mode)
112418334Speter    return x;
112518334Speter
112618334Speter  /* MODE must occupy no more words than the mode of X.  */
1127132727Skan  if ((msize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD
1128132727Skan      > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
112918334Speter    return 0;
113018334Speter
113199396Sobrien  /* Don't allow generating paradoxical FLOAT_MODE subregs.  */
1132169699Skan  if (SCALAR_FLOAT_MODE_P (mode) && msize > xsize)
113399396Sobrien    return 0;
113499396Sobrien
1135132727Skan  offset = subreg_lowpart_offset (mode, innermode);
113618334Speter
113718334Speter  if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
113818334Speter      && (GET_MODE_CLASS (mode) == MODE_INT
113918334Speter	  || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT))
114018334Speter    {
114118334Speter      /* If we are getting the low-order part of something that has been
114218334Speter	 sign- or zero-extended, we can either just use the object being
114318334Speter	 extended or make a narrower extension.  If we want an even smaller
114418334Speter	 piece than the size of the object being extended, call ourselves
114518334Speter	 recursively.
114618334Speter
114718334Speter	 This case is used mostly by combine and cse.  */
114818334Speter
114918334Speter      if (GET_MODE (XEXP (x, 0)) == mode)
115018334Speter	return XEXP (x, 0);
1151132727Skan      else if (msize < GET_MODE_SIZE (GET_MODE (XEXP (x, 0))))
115218334Speter	return gen_lowpart_common (mode, XEXP (x, 0));
1153132727Skan      else if (msize < xsize)
115450397Sobrien	return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
115518334Speter    }
1156169699Skan  else if (GET_CODE (x) == SUBREG || REG_P (x)
1157132727Skan	   || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR
1158132727Skan	   || GET_CODE (x) == CONST_DOUBLE || GET_CODE (x) == CONST_INT)
1159132727Skan    return simplify_gen_subreg (mode, x, innermode, offset);
116018334Speter
1161132727Skan  /* Otherwise, we can't do this.  */
1162132727Skan  return 0;
1163132727Skan}
1164132727Skan
116518334Speterrtx
1166132727Skangen_highpart (enum machine_mode mode, rtx x)
116718334Speter{
116890075Sobrien  unsigned int msize = GET_MODE_SIZE (mode);
116990075Sobrien  rtx result;
117090075Sobrien
117118334Speter  /* This case loses if X is a subreg.  To catch bugs early,
117218334Speter     complain if an invalid MODE is used even in other cases.  */
1173169699Skan  gcc_assert (msize <= UNITS_PER_WORD
1174169699Skan	      || msize == (unsigned int) GET_MODE_UNIT_SIZE (GET_MODE (x)));
117518334Speter
117690075Sobrien  result = simplify_gen_subreg (mode, x, GET_MODE (x),
117790075Sobrien				subreg_highpart_offset (mode, GET_MODE (x)));
1178169699Skan  gcc_assert (result);
1179169699Skan
118090075Sobrien  /* simplify_gen_subreg is not guaranteed to return a valid operand for
118190075Sobrien     the target if we have a MEM.  gen_highpart must return a valid operand,
118290075Sobrien     emitting code if necessary to do so.  */
1183169699Skan  if (MEM_P (result))
1184169699Skan    {
1185169699Skan      result = validize_mem (result);
1186169699Skan      gcc_assert (result);
1187169699Skan    }
1188169699Skan
118990075Sobrien  return result;
119090075Sobrien}
119190075Sobrien
1192132727Skan/* Like gen_highpart, but accept mode of EXP operand in case EXP can
119390075Sobrien   be VOIDmode constant.  */
119490075Sobrienrtx
1195132727Skangen_highpart_mode (enum machine_mode outermode, enum machine_mode innermode, rtx exp)
119690075Sobrien{
119790075Sobrien  if (GET_MODE (exp) != VOIDmode)
119818334Speter    {
1199169699Skan      gcc_assert (GET_MODE (exp) == innermode);
120090075Sobrien      return gen_highpart (outermode, exp);
120118334Speter    }
120290075Sobrien  return simplify_gen_subreg (outermode, exp, innermode,
120390075Sobrien			      subreg_highpart_offset (outermode, innermode));
120490075Sobrien}
1205117404Skan
120690075Sobrien/* Return offset in bytes to get OUTERMODE low part
120790075Sobrien   of the value in mode INNERMODE stored in memory in target format.  */
120818334Speter
120990075Sobrienunsigned int
1210132727Skansubreg_lowpart_offset (enum machine_mode outermode, enum machine_mode innermode)
121190075Sobrien{
121290075Sobrien  unsigned int offset = 0;
121390075Sobrien  int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
121450397Sobrien
121590075Sobrien  if (difference > 0)
121690075Sobrien    {
121750397Sobrien      if (WORDS_BIG_ENDIAN)
121890075Sobrien	offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
121990075Sobrien      if (BYTES_BIG_ENDIAN)
122090075Sobrien	offset += difference % UNITS_PER_WORD;
122190075Sobrien    }
122218334Speter
122390075Sobrien  return offset;
122490075Sobrien}
122590075Sobrien
122690075Sobrien/* Return offset in bytes to get OUTERMODE high part
122790075Sobrien   of the value in mode INNERMODE stored in memory in target format.  */
122890075Sobrienunsigned int
1229132727Skansubreg_highpart_offset (enum machine_mode outermode, enum machine_mode innermode)
123090075Sobrien{
123190075Sobrien  unsigned int offset = 0;
123290075Sobrien  int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
123390075Sobrien
1234169699Skan  gcc_assert (GET_MODE_SIZE (innermode) >= GET_MODE_SIZE (outermode));
123590075Sobrien
123690075Sobrien  if (difference > 0)
123790075Sobrien    {
123890075Sobrien      if (! WORDS_BIG_ENDIAN)
123990075Sobrien	offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
124090075Sobrien      if (! BYTES_BIG_ENDIAN)
124190075Sobrien	offset += difference % UNITS_PER_WORD;
124218334Speter    }
124390075Sobrien
124490075Sobrien  return offset;
124518334Speter}
124618334Speter
124718334Speter/* Return 1 iff X, assumed to be a SUBREG,
124818334Speter   refers to the least significant part of its containing reg.
124918334Speter   If X is not a SUBREG, always return 1 (it is its own low part!).  */
125018334Speter
125118334Speterint
1252132727Skansubreg_lowpart_p (rtx x)
125318334Speter{
125418334Speter  if (GET_CODE (x) != SUBREG)
125518334Speter    return 1;
125650397Sobrien  else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
125750397Sobrien    return 0;
125818334Speter
125990075Sobrien  return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
126090075Sobrien	  == SUBREG_BYTE (x));
126118334Speter}
126218334Speter
126390075Sobrien/* Return subword OFFSET of operand OP.
126490075Sobrien   The word number, OFFSET, is interpreted as the word number starting
126590075Sobrien   at the low-order address.  OFFSET 0 is the low-order word if not
126690075Sobrien   WORDS_BIG_ENDIAN, otherwise it is the high-order word.
126750397Sobrien
126890075Sobrien   If we cannot extract the required word, we return zero.  Otherwise,
126990075Sobrien   an rtx corresponding to the requested word will be returned.
127050397Sobrien
127190075Sobrien   VALIDATE_ADDRESS is nonzero if the address should be validated.  Before
127290075Sobrien   reload has completed, a valid address will always be returned.  After
127390075Sobrien   reload, if a valid address cannot be returned, we return zero.
127490075Sobrien
127590075Sobrien   If VALIDATE_ADDRESS is zero, we simply form the required address; validating
127690075Sobrien   it is the responsibility of the caller.
127790075Sobrien
127890075Sobrien   MODE is the mode of OP in case it is a CONST_INT.
127990075Sobrien
128090075Sobrien   ??? This is still rather broken for some cases.  The problem for the
128190075Sobrien   moment is that all callers of this thing provide no 'goal mode' to
128290075Sobrien   tell us to work with.  This exists because all callers were written
128390075Sobrien   in a word based SUBREG world.
128490075Sobrien   Now use of this function can be deprecated by simplify_subreg in most
128590075Sobrien   cases.
128690075Sobrien */
128790075Sobrien
128890075Sobrienrtx
1289132727Skanoperand_subword (rtx op, unsigned int offset, int validate_address, enum machine_mode mode)
129090075Sobrien{
129190075Sobrien  if (mode == VOIDmode)
129290075Sobrien    mode = GET_MODE (op);
129390075Sobrien
1294169699Skan  gcc_assert (mode != VOIDmode);
129590075Sobrien
129690075Sobrien  /* If OP is narrower than a word, fail.  */
129790075Sobrien  if (mode != BLKmode
129890075Sobrien      && (GET_MODE_SIZE (mode) < UNITS_PER_WORD))
129990075Sobrien    return 0;
130090075Sobrien
130190075Sobrien  /* If we want a word outside OP, return zero.  */
130290075Sobrien  if (mode != BLKmode
130390075Sobrien      && (offset + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))
130490075Sobrien    return const0_rtx;
130590075Sobrien
130690075Sobrien  /* Form a new MEM at the requested address.  */
1307169699Skan  if (MEM_P (op))
130890075Sobrien    {
130990075Sobrien      rtx new = adjust_address_nv (op, word_mode, offset * UNITS_PER_WORD);
131090075Sobrien
131190075Sobrien      if (! validate_address)
131290075Sobrien	return new;
131390075Sobrien
131490075Sobrien      else if (reload_completed)
131590075Sobrien	{
131690075Sobrien	  if (! strict_memory_address_p (word_mode, XEXP (new, 0)))
131790075Sobrien	    return 0;
131890075Sobrien	}
131990075Sobrien      else
132090075Sobrien	return replace_equiv_address (new, XEXP (new, 0));
132190075Sobrien    }
132290075Sobrien
132390075Sobrien  /* Rest can be handled by simplify_subreg.  */
132490075Sobrien  return simplify_gen_subreg (word_mode, op, mode, (offset * UNITS_PER_WORD));
132518334Speter}
132618334Speter
1327169699Skan/* Similar to `operand_subword', but never return 0.  If we can't
1328169699Skan   extract the required subword, put OP into a register and try again.
1329169699Skan   The second attempt must succeed.  We always validate the address in
1330169699Skan   this case.
133118334Speter
133218334Speter   MODE is the mode of OP, in case it is CONST_INT.  */
133318334Speter
133418334Speterrtx
1335132727Skanoperand_subword_force (rtx op, unsigned int offset, enum machine_mode mode)
133618334Speter{
133790075Sobrien  rtx result = operand_subword (op, offset, 1, mode);
133818334Speter
133918334Speter  if (result)
134018334Speter    return result;
134118334Speter
134218334Speter  if (mode != BLKmode && mode != VOIDmode)
134350397Sobrien    {
134450397Sobrien      /* If this is a register which can not be accessed by words, copy it
134550397Sobrien	 to a pseudo register.  */
1346169699Skan      if (REG_P (op))
134750397Sobrien	op = copy_to_reg (op);
134850397Sobrien      else
134950397Sobrien	op = force_reg (mode, op);
135050397Sobrien    }
135118334Speter
135290075Sobrien  result = operand_subword (op, offset, 1, mode);
1353169699Skan  gcc_assert (result);
135418334Speter
135518334Speter  return result;
135618334Speter}
135718334Speter
135890075Sobrien/* Within a MEM_EXPR, we care about either (1) a component ref of a decl,
135990075Sobrien   or (2) a component ref of something variable.  Represent the later with
136090075Sobrien   a NULL expression.  */
136118334Speter
136290075Sobrienstatic tree
1363132727Skancomponent_ref_for_mem_expr (tree ref)
136490075Sobrien{
136590075Sobrien  tree inner = TREE_OPERAND (ref, 0);
136690075Sobrien
136790075Sobrien  if (TREE_CODE (inner) == COMPONENT_REF)
136890075Sobrien    inner = component_ref_for_mem_expr (inner);
136990075Sobrien  else
137090075Sobrien    {
137190075Sobrien      /* Now remove any conversions: they don't change what the underlying
1372169699Skan	 object is.  Likewise for SAVE_EXPR.  */
137390075Sobrien      while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR
137490075Sobrien	     || TREE_CODE (inner) == NON_LVALUE_EXPR
137590075Sobrien	     || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1376169699Skan	     || TREE_CODE (inner) == SAVE_EXPR)
1377169699Skan	inner = TREE_OPERAND (inner, 0);
137890075Sobrien
137990075Sobrien      if (! DECL_P (inner))
138090075Sobrien	inner = NULL_TREE;
138190075Sobrien    }
138290075Sobrien
138390075Sobrien  if (inner == TREE_OPERAND (ref, 0))
138490075Sobrien    return ref;
138590075Sobrien  else
1386169699Skan    return build3 (COMPONENT_REF, TREE_TYPE (ref), inner,
1387169699Skan		   TREE_OPERAND (ref, 1), NULL_TREE);
138890075Sobrien}
138990075Sobrien
1390132727Skan/* Returns 1 if both MEM_EXPR can be considered equal
1391132727Skan   and 0 otherwise.  */
1392132727Skan
1393132727Skanint
1394132727Skanmem_expr_equal_p (tree expr1, tree expr2)
1395132727Skan{
1396132727Skan  if (expr1 == expr2)
1397132727Skan    return 1;
1398132727Skan
1399132727Skan  if (! expr1 || ! expr2)
1400132727Skan    return 0;
1401132727Skan
1402132727Skan  if (TREE_CODE (expr1) != TREE_CODE (expr2))
1403132727Skan    return 0;
1404132727Skan
1405132727Skan  if (TREE_CODE (expr1) == COMPONENT_REF)
1406132727Skan    return
1407132727Skan      mem_expr_equal_p (TREE_OPERAND (expr1, 0),
1408132727Skan			TREE_OPERAND (expr2, 0))
1409132727Skan      && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */
1410132727Skan			   TREE_OPERAND (expr2, 1));
1411132727Skan
1412169699Skan  if (INDIRECT_REF_P (expr1))
1413132727Skan    return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
1414132727Skan			     TREE_OPERAND (expr2, 0));
1415169699Skan
1416169699Skan  /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already
1417169699Skan	      have been resolved here.  */
1418169699Skan  gcc_assert (DECL_P (expr1));
1419132727Skan
1420132727Skan  /* Decls with different pointers can't be equal.  */
1421169699Skan  return 0;
1422132727Skan}
1423132727Skan
142490075Sobrien/* Given REF, a MEM, and T, either the type of X or the expression
142590075Sobrien   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
1426110621Skan   if we are making a new object of this type.  BITPOS is nonzero if
1427110621Skan   there is an offset outstanding on T that will be applied later.  */
142890075Sobrien
142990075Sobrienvoid
1430132727Skanset_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
1431132727Skan				 HOST_WIDE_INT bitpos)
143290075Sobrien{
143390075Sobrien  HOST_WIDE_INT alias = MEM_ALIAS_SET (ref);
143490075Sobrien  tree expr = MEM_EXPR (ref);
143590075Sobrien  rtx offset = MEM_OFFSET (ref);
143690075Sobrien  rtx size = MEM_SIZE (ref);
143790075Sobrien  unsigned int align = MEM_ALIGN (ref);
1438110621Skan  HOST_WIDE_INT apply_bitpos = 0;
143990075Sobrien  tree type;
144090075Sobrien
144190075Sobrien  /* It can happen that type_for_mode was given a mode for which there
144290075Sobrien     is no language-level type.  In which case it returns NULL, which
144390075Sobrien     we can see here.  */
144490075Sobrien  if (t == NULL_TREE)
144590075Sobrien    return;
144690075Sobrien
144790075Sobrien  type = TYPE_P (t) ? t : TREE_TYPE (t);
1448132727Skan  if (type == error_mark_node)
1449132727Skan    return;
145090075Sobrien
145190075Sobrien  /* If we have already set DECL_RTL = ref, get_alias_set will get the
145290075Sobrien     wrong answer, as it assumes that DECL_RTL already has the right alias
145390075Sobrien     info.  Callers should not set DECL_RTL until after the call to
145490075Sobrien     set_mem_attributes.  */
1455169699Skan  gcc_assert (!DECL_P (t) || ref != DECL_RTL_IF_SET (t));
145690075Sobrien
145790075Sobrien  /* Get the alias set from the expression or type (perhaps using a
145890075Sobrien     front-end routine) and use it.  */
145990075Sobrien  alias = get_alias_set (t);
146090075Sobrien
1461169699Skan  MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
146290075Sobrien  MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type);
1463169699Skan  MEM_POINTER (ref) = POINTER_TYPE_P (type);
146490075Sobrien
146590075Sobrien  /* If we are making an object of this type, or if this is a DECL, we know
146690075Sobrien     that it is a scalar if the type is not an aggregate.  */
146790075Sobrien  if ((objectp || DECL_P (t)) && ! AGGREGATE_TYPE_P (type))
146890075Sobrien    MEM_SCALAR_P (ref) = 1;
146990075Sobrien
147090075Sobrien  /* We can set the alignment from the type if we are making an object,
147190075Sobrien     this is an INDIRECT_REF, or if TYPE_ALIGN_OK.  */
1472169699Skan  if (objectp || TREE_CODE (t) == INDIRECT_REF
1473169699Skan      || TREE_CODE (t) == ALIGN_INDIRECT_REF
1474169699Skan      || TYPE_ALIGN_OK (type))
147590075Sobrien    align = MAX (align, TYPE_ALIGN (type));
1476169699Skan  else
1477169699Skan    if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
1478169699Skan      {
1479169699Skan	if (integer_zerop (TREE_OPERAND (t, 1)))
1480169699Skan	  /* We don't know anything about the alignment.  */
1481169699Skan	  align = BITS_PER_UNIT;
1482169699Skan	else
1483169699Skan	  align = tree_low_cst (TREE_OPERAND (t, 1), 1);
1484169699Skan      }
148590075Sobrien
148690075Sobrien  /* If the size is known, we can set that.  */
148790075Sobrien  if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
148890075Sobrien    size = GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1));
148990075Sobrien
149090075Sobrien  /* If T is not a type, we may be able to deduce some more information about
149190075Sobrien     the expression.  */
149290075Sobrien  if (! TYPE_P (t))
149390075Sobrien    {
1494169699Skan      tree base;
1495169699Skan
149690075Sobrien      if (TREE_THIS_VOLATILE (t))
149790075Sobrien	MEM_VOLATILE_P (ref) = 1;
149890075Sobrien
149990075Sobrien      /* Now remove any conversions: they don't change what the underlying
150090075Sobrien	 object is.  Likewise for SAVE_EXPR.  */
150190075Sobrien      while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR
150290075Sobrien	     || TREE_CODE (t) == NON_LVALUE_EXPR
150390075Sobrien	     || TREE_CODE (t) == VIEW_CONVERT_EXPR
150490075Sobrien	     || TREE_CODE (t) == SAVE_EXPR)
150590075Sobrien	t = TREE_OPERAND (t, 0);
150690075Sobrien
1507169699Skan      /* We may look through structure-like accesses for the purposes of
1508169699Skan	 examining TREE_THIS_NOTRAP, but not array-like accesses.  */
1509169699Skan      base = t;
1510169699Skan      while (TREE_CODE (base) == COMPONENT_REF
1511169699Skan	     || TREE_CODE (base) == REALPART_EXPR
1512169699Skan	     || TREE_CODE (base) == IMAGPART_EXPR
1513169699Skan	     || TREE_CODE (base) == BIT_FIELD_REF)
1514169699Skan	base = TREE_OPERAND (base, 0);
1515169699Skan
1516169699Skan      if (DECL_P (base))
1517169699Skan	{
1518169699Skan	  if (CODE_CONTAINS_STRUCT (TREE_CODE (base), TS_DECL_WITH_VIS))
1519169699Skan	    MEM_NOTRAP_P (ref) = !DECL_WEAK (base);
1520169699Skan	  else
1521169699Skan	    MEM_NOTRAP_P (ref) = 1;
1522169699Skan	}
1523169699Skan      else
1524169699Skan	MEM_NOTRAP_P (ref) = TREE_THIS_NOTRAP (base);
1525169699Skan
1526169699Skan      base = get_base_address (base);
1527169699Skan      if (base && DECL_P (base)
1528169699Skan	  && TREE_READONLY (base)
1529169699Skan	  && (TREE_STATIC (base) || DECL_EXTERNAL (base)))
1530169699Skan	{
1531169699Skan	  tree base_type = TREE_TYPE (base);
1532169699Skan	  gcc_assert (!(base_type && TYPE_NEEDS_CONSTRUCTING (base_type))
1533169699Skan		      || DECL_ARTIFICIAL (base));
1534169699Skan	  MEM_READONLY_P (ref) = 1;
1535169699Skan	}
1536169699Skan
1537169699Skan      /* If this expression uses it's parent's alias set, mark it such
1538169699Skan	 that we won't change it.  */
1539169699Skan      if (component_uses_parent_alias_set (t))
154090075Sobrien	MEM_KEEP_ALIAS_SET_P (ref) = 1;
154190075Sobrien
154290075Sobrien      /* If this is a decl, set the attributes of the MEM from it.  */
154390075Sobrien      if (DECL_P (t))
154490075Sobrien	{
154590075Sobrien	  expr = t;
154690075Sobrien	  offset = const0_rtx;
1547110621Skan	  apply_bitpos = bitpos;
154890075Sobrien	  size = (DECL_SIZE_UNIT (t)
154990075Sobrien		  && host_integerp (DECL_SIZE_UNIT (t), 1)
155090075Sobrien		  ? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0);
1551117404Skan	  align = DECL_ALIGN (t);
155290075Sobrien	}
155390075Sobrien
155490075Sobrien      /* If this is a constant, we know the alignment.  */
1555169699Skan      else if (CONSTANT_CLASS_P (t))
155690075Sobrien	{
155790075Sobrien	  align = TYPE_ALIGN (type);
155890075Sobrien#ifdef CONSTANT_ALIGNMENT
155990075Sobrien	  align = CONSTANT_ALIGNMENT (t, align);
156090075Sobrien#endif
156190075Sobrien	}
156290075Sobrien
156390075Sobrien      /* If this is a field reference and not a bit-field, record it.  */
156490075Sobrien      /* ??? There is some information that can be gleened from bit-fields,
156590075Sobrien	 such as the word offset in the structure that might be modified.
156690075Sobrien	 But skip it for now.  */
156790075Sobrien      else if (TREE_CODE (t) == COMPONENT_REF
156890075Sobrien	       && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
156990075Sobrien	{
157090075Sobrien	  expr = component_ref_for_mem_expr (t);
157190075Sobrien	  offset = const0_rtx;
1572110621Skan	  apply_bitpos = bitpos;
157390075Sobrien	  /* ??? Any reason the field size would be different than
157490075Sobrien	     the size we got from the type?  */
157590075Sobrien	}
157690075Sobrien
157790075Sobrien      /* If this is an array reference, look for an outer field reference.  */
157890075Sobrien      else if (TREE_CODE (t) == ARRAY_REF)
157990075Sobrien	{
158090075Sobrien	  tree off_tree = size_zero_node;
1581117404Skan	  /* We can't modify t, because we use it at the end of the
1582117404Skan	     function.  */
1583117404Skan	  tree t2 = t;
158490075Sobrien
158590075Sobrien	  do
158690075Sobrien	    {
1587117404Skan	      tree index = TREE_OPERAND (t2, 1);
1588169699Skan	      tree low_bound = array_ref_low_bound (t2);
1589169699Skan	      tree unit_size = array_ref_element_size (t2);
1590110621Skan
1591110621Skan	      /* We assume all arrays have sizes that are a multiple of a byte.
1592110621Skan		 First subtract the lower bound, if any, in the type of the
1593169699Skan		 index, then convert to sizetype and multiply by the size of
1594169699Skan		 the array element.  */
1595169699Skan	      if (! integer_zerop (low_bound))
1596169699Skan		index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
1597169699Skan				     index, low_bound);
1598110621Skan
1599169699Skan	      off_tree = size_binop (PLUS_EXPR,
1600169699Skan				     size_binop (MULT_EXPR,
1601169699Skan						 fold_convert (sizetype,
1602169699Skan							       index),
1603169699Skan						 unit_size),
1604169699Skan				     off_tree);
1605117404Skan	      t2 = TREE_OPERAND (t2, 0);
160690075Sobrien	    }
1607117404Skan	  while (TREE_CODE (t2) == ARRAY_REF);
160890075Sobrien
1609117404Skan	  if (DECL_P (t2))
161090075Sobrien	    {
1611117404Skan	      expr = t2;
1612110621Skan	      offset = NULL;
1613110621Skan	      if (host_integerp (off_tree, 1))
1614110621Skan		{
1615110621Skan		  HOST_WIDE_INT ioff = tree_low_cst (off_tree, 1);
1616110621Skan		  HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT;
1617117404Skan		  align = DECL_ALIGN (t2);
1618132727Skan		  if (aoff && (unsigned HOST_WIDE_INT) aoff < align)
1619110621Skan	            align = aoff;
1620110621Skan		  offset = GEN_INT (ioff);
1621110621Skan		  apply_bitpos = bitpos;
1622110621Skan		}
1623110621Skan	    }
1624117404Skan	  else if (TREE_CODE (t2) == COMPONENT_REF)
1625110621Skan	    {
1626117404Skan	      expr = component_ref_for_mem_expr (t2);
162790075Sobrien	      if (host_integerp (off_tree, 1))
1628110621Skan		{
1629110621Skan		  offset = GEN_INT (tree_low_cst (off_tree, 1));
1630110621Skan		  apply_bitpos = bitpos;
1631110621Skan		}
163290075Sobrien	      /* ??? Any reason the field size would be different than
163390075Sobrien		 the size we got from the type?  */
163490075Sobrien	    }
1635110621Skan	  else if (flag_argument_noalias > 1
1636169699Skan		   && (INDIRECT_REF_P (t2))
1637117404Skan		   && TREE_CODE (TREE_OPERAND (t2, 0)) == PARM_DECL)
1638110621Skan	    {
1639117404Skan	      expr = t2;
1640110621Skan	      offset = NULL;
1641110621Skan	    }
164290075Sobrien	}
1643110621Skan
1644110621Skan      /* If this is a Fortran indirect argument reference, record the
1645110621Skan	 parameter decl.  */
1646110621Skan      else if (flag_argument_noalias > 1
1647169699Skan	       && (INDIRECT_REF_P (t))
1648110621Skan	       && TREE_CODE (TREE_OPERAND (t, 0)) == PARM_DECL)
1649110621Skan	{
1650110621Skan	  expr = t;
1651110621Skan	  offset = NULL;
1652110621Skan	}
165390075Sobrien    }
165490075Sobrien
1655132727Skan  /* If we modified OFFSET based on T, then subtract the outstanding
1656110621Skan     bit position offset.  Similarly, increase the size of the accessed
1657110621Skan     object to contain the negative offset.  */
1658110621Skan  if (apply_bitpos)
1659110621Skan    {
1660110621Skan      offset = plus_constant (offset, -(apply_bitpos / BITS_PER_UNIT));
1661110621Skan      if (size)
1662110621Skan	size = plus_constant (size, apply_bitpos / BITS_PER_UNIT);
1663110621Skan    }
1664110621Skan
1665169699Skan  if (TREE_CODE (t) == ALIGN_INDIRECT_REF)
1666169699Skan    {
1667169699Skan      /* Force EXPR and OFFSE to NULL, since we don't know exactly what
1668169699Skan	 we're overlapping.  */
1669169699Skan      offset = NULL;
1670169699Skan      expr = NULL;
1671169699Skan    }
1672169699Skan
167390075Sobrien  /* Now set the attributes we computed above.  */
167490075Sobrien  MEM_ATTRS (ref)
167590075Sobrien    = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref));
167690075Sobrien
167790075Sobrien  /* If this is already known to be a scalar or aggregate, we are done.  */
167890075Sobrien  if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
167990075Sobrien    return;
168090075Sobrien
168190075Sobrien  /* If it is a reference into an aggregate, this is part of an aggregate.
168290075Sobrien     Otherwise we don't know.  */
168390075Sobrien  else if (TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF
168490075Sobrien	   || TREE_CODE (t) == ARRAY_RANGE_REF
168590075Sobrien	   || TREE_CODE (t) == BIT_FIELD_REF)
168690075Sobrien    MEM_IN_STRUCT_P (ref) = 1;
168790075Sobrien}
168890075Sobrien
1689110621Skanvoid
1690132727Skanset_mem_attributes (rtx ref, tree t, int objectp)
1691110621Skan{
1692110621Skan  set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
1693110621Skan}
1694110621Skan
1695132727Skan/* Set the decl for MEM to DECL.  */
1696132727Skan
1697132727Skanvoid
1698132727Skanset_mem_attrs_from_reg (rtx mem, rtx reg)
1699132727Skan{
1700132727Skan  MEM_ATTRS (mem)
1701132727Skan    = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg),
1702132727Skan		     GEN_INT (REG_OFFSET (reg)),
1703132727Skan		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
1704132727Skan}
1705132727Skan
170690075Sobrien/* Set the alias set of MEM to SET.  */
170790075Sobrien
170890075Sobrienvoid
1709132727Skanset_mem_alias_set (rtx mem, HOST_WIDE_INT set)
171090075Sobrien{
1711117404Skan#ifdef ENABLE_CHECKING
171290075Sobrien  /* If the new and old alias sets don't conflict, something is wrong.  */
1713169699Skan  gcc_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
171490075Sobrien#endif
171590075Sobrien
171690075Sobrien  MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
171790075Sobrien				   MEM_SIZE (mem), MEM_ALIGN (mem),
171890075Sobrien				   GET_MODE (mem));
171990075Sobrien}
172090075Sobrien
172190075Sobrien/* Set the alignment of MEM to ALIGN bits.  */
172290075Sobrien
172390075Sobrienvoid
1724132727Skanset_mem_align (rtx mem, unsigned int align)
172590075Sobrien{
172690075Sobrien  MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
172790075Sobrien				   MEM_OFFSET (mem), MEM_SIZE (mem), align,
172890075Sobrien				   GET_MODE (mem));
172990075Sobrien}
173090075Sobrien
173190075Sobrien/* Set the expr for MEM to EXPR.  */
173290075Sobrien
173390075Sobrienvoid
1734132727Skanset_mem_expr (rtx mem, tree expr)
173590075Sobrien{
173690075Sobrien  MEM_ATTRS (mem)
173790075Sobrien    = get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
173890075Sobrien		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
173990075Sobrien}
174090075Sobrien
174190075Sobrien/* Set the offset of MEM to OFFSET.  */
174290075Sobrien
174390075Sobrienvoid
1744132727Skanset_mem_offset (rtx mem, rtx offset)
174590075Sobrien{
174690075Sobrien  MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
174790075Sobrien				   offset, MEM_SIZE (mem), MEM_ALIGN (mem),
174890075Sobrien				   GET_MODE (mem));
174990075Sobrien}
1750103453Skan
1751103453Skan/* Set the size of MEM to SIZE.  */
1752103453Skan
1753103453Skanvoid
1754132727Skanset_mem_size (rtx mem, rtx size)
1755103453Skan{
1756103453Skan  MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
1757103453Skan				   MEM_OFFSET (mem), size, MEM_ALIGN (mem),
1758103453Skan				   GET_MODE (mem));
1759103453Skan}
176090075Sobrien
176190075Sobrien/* Return a memory reference like MEMREF, but with its mode changed to MODE
176290075Sobrien   and its address changed to ADDR.  (VOIDmode means don't change the mode.
176390075Sobrien   NULL for ADDR means don't change the address.)  VALIDATE is nonzero if the
176490075Sobrien   returned memory location is required to be valid.  The memory
176590075Sobrien   attributes are not changed.  */
176690075Sobrien
176790075Sobrienstatic rtx
1768132727Skanchange_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
176918334Speter{
177018334Speter  rtx new;
177118334Speter
1772169699Skan  gcc_assert (MEM_P (memref));
177318334Speter  if (mode == VOIDmode)
177418334Speter    mode = GET_MODE (memref);
177518334Speter  if (addr == 0)
177618334Speter    addr = XEXP (memref, 0);
1777132727Skan  if (mode == GET_MODE (memref) && addr == XEXP (memref, 0)
1778132727Skan      && (!validate || memory_address_p (mode, addr)))
1779132727Skan    return memref;
178018334Speter
178190075Sobrien  if (validate)
178218334Speter    {
178390075Sobrien      if (reload_in_progress || reload_completed)
1784169699Skan	gcc_assert (memory_address_p (mode, addr));
178590075Sobrien      else
178690075Sobrien	addr = memory_address (mode, addr);
178718334Speter    }
178890075Sobrien
178950397Sobrien  if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
179050397Sobrien    return memref;
179150397Sobrien
179250397Sobrien  new = gen_rtx_MEM (mode, addr);
179352284Sobrien  MEM_COPY_ATTRIBUTES (new, memref);
179418334Speter  return new;
179518334Speter}
179690075Sobrien
179790075Sobrien/* Like change_address_1 with VALIDATE nonzero, but we are not saying in what
179890075Sobrien   way we are changing MEMREF, so we only preserve the alias set.  */
179990075Sobrien
180090075Sobrienrtx
1801132727Skanchange_address (rtx memref, enum machine_mode mode, rtx addr)
180290075Sobrien{
1803132727Skan  rtx new = change_address_1 (memref, mode, addr, 1), size;
180490075Sobrien  enum machine_mode mmode = GET_MODE (new);
1805132727Skan  unsigned int align;
180690075Sobrien
1807132727Skan  size = mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode));
1808132727Skan  align = mmode == BLKmode ? BITS_PER_UNIT : GET_MODE_ALIGNMENT (mmode);
1809132727Skan
1810132727Skan  /* If there are no changes, just return the original memory reference.  */
1811132727Skan  if (new == memref)
1812132727Skan    {
1813132727Skan      if (MEM_ATTRS (memref) == 0
1814132727Skan	  || (MEM_EXPR (memref) == NULL
1815132727Skan	      && MEM_OFFSET (memref) == NULL
1816132727Skan	      && MEM_SIZE (memref) == size
1817132727Skan	      && MEM_ALIGN (memref) == align))
1818132727Skan	return new;
1819132727Skan
1820132727Skan      new = gen_rtx_MEM (mmode, XEXP (memref, 0));
1821132727Skan      MEM_COPY_ATTRIBUTES (new, memref);
1822132727Skan    }
1823132727Skan
182490075Sobrien  MEM_ATTRS (new)
1825132727Skan    = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
182690075Sobrien
182790075Sobrien  return new;
182890075Sobrien}
182990075Sobrien
183090075Sobrien/* Return a memory reference like MEMREF, but with its mode changed
183190075Sobrien   to MODE and its address offset by OFFSET bytes.  If VALIDATE is
183290075Sobrien   nonzero, the memory address is forced to be valid.
183390075Sobrien   If ADJUST is zero, OFFSET is only used to update MEM_ATTRS
183490075Sobrien   and caller is responsible for adjusting MEMREF base register.  */
183590075Sobrien
183690075Sobrienrtx
1837132727Skanadjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
1838132727Skan		  int validate, int adjust)
183990075Sobrien{
184090075Sobrien  rtx addr = XEXP (memref, 0);
184190075Sobrien  rtx new;
184290075Sobrien  rtx memoffset = MEM_OFFSET (memref);
184390075Sobrien  rtx size = 0;
184490075Sobrien  unsigned int memalign = MEM_ALIGN (memref);
184590075Sobrien
1846132727Skan  /* If there are no changes, just return the original memory reference.  */
1847132727Skan  if (mode == GET_MODE (memref) && !offset
1848132727Skan      && (!validate || memory_address_p (mode, addr)))
1849132727Skan    return memref;
1850132727Skan
185190075Sobrien  /* ??? Prefer to create garbage instead of creating shared rtl.
1852117404Skan     This may happen even if offset is nonzero -- consider
185390075Sobrien     (plus (plus reg reg) const_int) -- so do this always.  */
185490075Sobrien  addr = copy_rtx (addr);
185590075Sobrien
185690075Sobrien  if (adjust)
185790075Sobrien    {
185890075Sobrien      /* If MEMREF is a LO_SUM and the offset is within the alignment of the
185990075Sobrien	 object, we can merge it into the LO_SUM.  */
186090075Sobrien      if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM
186190075Sobrien	  && offset >= 0
186290075Sobrien	  && (unsigned HOST_WIDE_INT) offset
186390075Sobrien	      < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
186490075Sobrien	addr = gen_rtx_LO_SUM (Pmode, XEXP (addr, 0),
186590075Sobrien			       plus_constant (XEXP (addr, 1), offset));
186690075Sobrien      else
186790075Sobrien	addr = plus_constant (addr, offset);
186890075Sobrien    }
186990075Sobrien
187090075Sobrien  new = change_address_1 (memref, mode, addr, validate);
187190075Sobrien
187290075Sobrien  /* Compute the new values of the memory attributes due to this adjustment.
187390075Sobrien     We add the offsets and update the alignment.  */
187490075Sobrien  if (memoffset)
187590075Sobrien    memoffset = GEN_INT (offset + INTVAL (memoffset));
187690075Sobrien
187790075Sobrien  /* Compute the new alignment by taking the MIN of the alignment and the
187890075Sobrien     lowest-order set bit in OFFSET, but don't change the alignment if OFFSET
187990075Sobrien     if zero.  */
188090075Sobrien  if (offset != 0)
188196263Sobrien    memalign
188296263Sobrien      = MIN (memalign,
188396263Sobrien	     (unsigned HOST_WIDE_INT) (offset & -offset) * BITS_PER_UNIT);
188490075Sobrien
188590075Sobrien  /* We can compute the size in a number of ways.  */
188690075Sobrien  if (GET_MODE (new) != BLKmode)
188790075Sobrien    size = GEN_INT (GET_MODE_SIZE (GET_MODE (new)));
188890075Sobrien  else if (MEM_SIZE (memref))
188990075Sobrien    size = plus_constant (MEM_SIZE (memref), -offset);
189090075Sobrien
189190075Sobrien  MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
189290075Sobrien				   memoffset, size, memalign, GET_MODE (new));
189390075Sobrien
189490075Sobrien  /* At some point, we should validate that this offset is within the object,
189590075Sobrien     if all the appropriate values are known.  */
189690075Sobrien  return new;
189790075Sobrien}
189890075Sobrien
189990075Sobrien/* Return a memory reference like MEMREF, but with its mode changed
190090075Sobrien   to MODE and its address changed to ADDR, which is assumed to be
190190075Sobrien   MEMREF offseted by OFFSET bytes.  If VALIDATE is
190290075Sobrien   nonzero, the memory address is forced to be valid.  */
190390075Sobrien
190490075Sobrienrtx
1905132727Skanadjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
1906132727Skan			     HOST_WIDE_INT offset, int validate)
190790075Sobrien{
190890075Sobrien  memref = change_address_1 (memref, VOIDmode, addr, validate);
190990075Sobrien  return adjust_address_1 (memref, mode, offset, validate, 0);
191090075Sobrien}
191190075Sobrien
191290075Sobrien/* Return a memory reference like MEMREF, but whose address is changed by
191390075Sobrien   adding OFFSET, an RTX, to it.  POW2 is the highest power of two factor
191490075Sobrien   known to be in OFFSET (possibly 1).  */
191590075Sobrien
191690075Sobrienrtx
1917132727Skanoffset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
191890075Sobrien{
191996263Sobrien  rtx new, addr = XEXP (memref, 0);
192090075Sobrien
192196263Sobrien  new = simplify_gen_binary (PLUS, Pmode, addr, offset);
192296263Sobrien
1923117404Skan  /* At this point we don't know _why_ the address is invalid.  It
1924132727Skan     could have secondary memory references, multiplies or anything.
192596263Sobrien
192696263Sobrien     However, if we did go and rearrange things, we can wind up not
192796263Sobrien     being able to recognize the magic around pic_offset_table_rtx.
192896263Sobrien     This stuff is fragile, and is yet another example of why it is
192996263Sobrien     bad to expose PIC machinery too early.  */
193096263Sobrien  if (! memory_address_p (GET_MODE (memref), new)
193196263Sobrien      && GET_CODE (addr) == PLUS
193296263Sobrien      && XEXP (addr, 0) == pic_offset_table_rtx)
193396263Sobrien    {
193496263Sobrien      addr = force_reg (GET_MODE (addr), addr);
193596263Sobrien      new = simplify_gen_binary (PLUS, Pmode, addr, offset);
193696263Sobrien    }
193796263Sobrien
193896263Sobrien  update_temp_slot_address (XEXP (memref, 0), new);
193996263Sobrien  new = change_address_1 (memref, VOIDmode, new, 1);
194096263Sobrien
1941132727Skan  /* If there are no changes, just return the original memory reference.  */
1942132727Skan  if (new == memref)
1943132727Skan    return new;
1944132727Skan
194590075Sobrien  /* Update the alignment to reflect the offset.  Reset the offset, which
194690075Sobrien     we don't know.  */
194790075Sobrien  MEM_ATTRS (new)
194890075Sobrien    = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
1949132727Skan		     MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
195090075Sobrien		     GET_MODE (new));
195190075Sobrien  return new;
195290075Sobrien}
1953117404Skan
195490075Sobrien/* Return a memory reference like MEMREF, but with its address changed to
195590075Sobrien   ADDR.  The caller is asserting that the actual piece of memory pointed
195690075Sobrien   to is the same, just the form of the address is being changed, such as
195790075Sobrien   by putting something into a register.  */
195890075Sobrien
195990075Sobrienrtx
1960132727Skanreplace_equiv_address (rtx memref, rtx addr)
196190075Sobrien{
196290075Sobrien  /* change_address_1 copies the memory attribute structure without change
196390075Sobrien     and that's exactly what we want here.  */
196490075Sobrien  update_temp_slot_address (XEXP (memref, 0), addr);
196590075Sobrien  return change_address_1 (memref, VOIDmode, addr, 1);
196690075Sobrien}
196790075Sobrien
196890075Sobrien/* Likewise, but the reference is not required to be valid.  */
196990075Sobrien
197090075Sobrienrtx
1971132727Skanreplace_equiv_address_nv (rtx memref, rtx addr)
197290075Sobrien{
197390075Sobrien  return change_address_1 (memref, VOIDmode, addr, 0);
197490075Sobrien}
197590075Sobrien
197690075Sobrien/* Return a memory reference like MEMREF, but with its mode widened to
197790075Sobrien   MODE and offset by OFFSET.  This would be used by targets that e.g.
197890075Sobrien   cannot issue QImode memory operations and have to use SImode memory
197990075Sobrien   operations plus masking logic.  */
198090075Sobrien
198190075Sobrienrtx
1982132727Skanwiden_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
198390075Sobrien{
198490075Sobrien  rtx new = adjust_address_1 (memref, mode, offset, 1, 1);
198590075Sobrien  tree expr = MEM_EXPR (new);
198690075Sobrien  rtx memoffset = MEM_OFFSET (new);
198790075Sobrien  unsigned int size = GET_MODE_SIZE (mode);
198890075Sobrien
1989132727Skan  /* If there are no changes, just return the original memory reference.  */
1990132727Skan  if (new == memref)
1991132727Skan    return new;
1992132727Skan
199390075Sobrien  /* If we don't know what offset we were at within the expression, then
199490075Sobrien     we can't know if we've overstepped the bounds.  */
199596263Sobrien  if (! memoffset)
199690075Sobrien    expr = NULL_TREE;
199790075Sobrien
199890075Sobrien  while (expr)
199990075Sobrien    {
200090075Sobrien      if (TREE_CODE (expr) == COMPONENT_REF)
200190075Sobrien	{
200290075Sobrien	  tree field = TREE_OPERAND (expr, 1);
2003169699Skan	  tree offset = component_ref_field_offset (expr);
200490075Sobrien
200590075Sobrien	  if (! DECL_SIZE_UNIT (field))
200690075Sobrien	    {
200790075Sobrien	      expr = NULL_TREE;
200890075Sobrien	      break;
200990075Sobrien	    }
201090075Sobrien
201190075Sobrien	  /* Is the field at least as large as the access?  If so, ok,
201290075Sobrien	     otherwise strip back to the containing structure.  */
201390075Sobrien	  if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST
201490075Sobrien	      && compare_tree_int (DECL_SIZE_UNIT (field), size) >= 0
201590075Sobrien	      && INTVAL (memoffset) >= 0)
201690075Sobrien	    break;
201790075Sobrien
2018169699Skan	  if (! host_integerp (offset, 1))
201990075Sobrien	    {
202090075Sobrien	      expr = NULL_TREE;
202190075Sobrien	      break;
202290075Sobrien	    }
202390075Sobrien
202490075Sobrien	  expr = TREE_OPERAND (expr, 0);
2025169699Skan	  memoffset
2026169699Skan	    = (GEN_INT (INTVAL (memoffset)
2027169699Skan			+ tree_low_cst (offset, 1)
2028169699Skan			+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
2029169699Skan			   / BITS_PER_UNIT)));
203090075Sobrien	}
203190075Sobrien      /* Similarly for the decl.  */
203290075Sobrien      else if (DECL_P (expr)
203390075Sobrien	       && DECL_SIZE_UNIT (expr)
2034102793Skan	       && TREE_CODE (DECL_SIZE_UNIT (expr)) == INTEGER_CST
203590075Sobrien	       && compare_tree_int (DECL_SIZE_UNIT (expr), size) >= 0
203690075Sobrien	       && (! memoffset || INTVAL (memoffset) >= 0))
203790075Sobrien	break;
203890075Sobrien      else
203990075Sobrien	{
204090075Sobrien	  /* The widened memory access overflows the expression, which means
204190075Sobrien	     that it could alias another expression.  Zap it.  */
204290075Sobrien	  expr = NULL_TREE;
204390075Sobrien	  break;
204490075Sobrien	}
204590075Sobrien    }
204690075Sobrien
204790075Sobrien  if (! expr)
204890075Sobrien    memoffset = NULL_RTX;
204990075Sobrien
205090075Sobrien  /* The widened memory may alias other stuff, so zap the alias set.  */
205190075Sobrien  /* ??? Maybe use get_alias_set on any remaining expression.  */
205290075Sobrien
205390075Sobrien  MEM_ATTRS (new) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
205490075Sobrien				   MEM_ALIGN (new), mode);
205590075Sobrien
205690075Sobrien  return new;
205790075Sobrien}
205818334Speter
205918334Speter/* Return a newly created CODE_LABEL rtx with a unique label number.  */
206018334Speter
206118334Speterrtx
2062132727Skangen_label_rtx (void)
206318334Speter{
2064117404Skan  return gen_rtx_CODE_LABEL (VOIDmode, 0, NULL_RTX, NULL_RTX,
2065260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
2066260918Spfg			     NULL, label_num++, NULL, 0);
2067260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
206818334Speter}
206918334Speter
207018334Speter/* For procedure integration.  */
207118334Speter
207218334Speter/* Install new pointers to the first and last insns in the chain.
207350397Sobrien   Also, set cur_insn_uid to one higher than the last in use.
207418334Speter   Used for an inline-procedure after copying the insn chain.  */
207518334Speter
207618334Spetervoid
2077132727Skanset_new_first_and_last_insn (rtx first, rtx last)
207818334Speter{
207950397Sobrien  rtx insn;
208050397Sobrien
208118334Speter  first_insn = first;
208218334Speter  last_insn = last;
208350397Sobrien  cur_insn_uid = 0;
208450397Sobrien
208550397Sobrien  for (insn = first; insn; insn = NEXT_INSN (insn))
208650397Sobrien    cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
208750397Sobrien
208850397Sobrien  cur_insn_uid++;
208918334Speter}
209090075Sobrien
209190075Sobrien/* Go through all the RTL insn bodies and copy any invalid shared
209272562Sobrien   structure.  This routine should only be called once.  */
209318334Speter
2094169699Skanstatic void
2095169699Skanunshare_all_rtl_1 (tree fndecl, rtx insn)
209618334Speter{
209772562Sobrien  tree decl;
209818334Speter
209972562Sobrien  /* Make sure that virtual parameters are not shared.  */
210072562Sobrien  for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
210190075Sobrien    SET_DECL_RTL (decl, copy_rtx_if_shared (DECL_RTL (decl)));
210272562Sobrien
210372562Sobrien  /* Make sure that virtual stack slots are not shared.  */
210472562Sobrien  unshare_all_decls (DECL_INITIAL (fndecl));
210572562Sobrien
210672562Sobrien  /* Unshare just about everything else.  */
2107132727Skan  unshare_all_rtl_in_chain (insn);
210890075Sobrien
210918334Speter  /* Make sure the addresses of stack slots found outside the insn chain
211018334Speter     (such as, in DECL_RTL of a variable) are not shared
211118334Speter     with the insn chain.
211218334Speter
211318334Speter     This special care is necessary when the stack slot MEM does not
211418334Speter     actually appear in the insn chain.  If it does appear, its address
211518334Speter     is unshared from all else at that point.  */
211672562Sobrien  stack_slot_list = copy_rtx_if_shared (stack_slot_list);
211772562Sobrien}
211818334Speter
211990075Sobrien/* Go through all the RTL insn bodies and copy any invalid shared
212072562Sobrien   structure, again.  This is a fairly expensive thing to do so it
212172562Sobrien   should be done sparingly.  */
212272562Sobrien
212372562Sobrienvoid
2124132727Skanunshare_all_rtl_again (rtx insn)
212572562Sobrien{
212672562Sobrien  rtx p;
212790075Sobrien  tree decl;
212890075Sobrien
212972562Sobrien  for (p = insn; p; p = NEXT_INSN (p))
213090075Sobrien    if (INSN_P (p))
213172562Sobrien      {
213272562Sobrien	reset_used_flags (PATTERN (p));
213372562Sobrien	reset_used_flags (REG_NOTES (p));
213472562Sobrien	reset_used_flags (LOG_LINKS (p));
213572562Sobrien      }
213690075Sobrien
213790075Sobrien  /* Make sure that virtual stack slots are not shared.  */
213890075Sobrien  reset_used_decls (DECL_INITIAL (cfun->decl));
213990075Sobrien
214090075Sobrien  /* Make sure that virtual parameters are not shared.  */
214190075Sobrien  for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = TREE_CHAIN (decl))
214290075Sobrien    reset_used_flags (DECL_RTL (decl));
214390075Sobrien
214490075Sobrien  reset_used_flags (stack_slot_list);
214590075Sobrien
2146169699Skan  unshare_all_rtl_1 (cfun->decl, insn);
214718334Speter}
214818334Speter
2149169699Skanunsigned int
2150169699Skanunshare_all_rtl (void)
2151169699Skan{
2152169699Skan  unshare_all_rtl_1 (current_function_decl, get_insns ());
2153169699Skan  return 0;
2154169699Skan}
2155169699Skan
2156169699Skanstruct tree_opt_pass pass_unshare_all_rtl =
2157169699Skan{
2158169699Skan  "unshare",                            /* name */
2159169699Skan  NULL,                                 /* gate */
2160169699Skan  unshare_all_rtl,                      /* execute */
2161169699Skan  NULL,                                 /* sub */
2162169699Skan  NULL,                                 /* next */
2163169699Skan  0,                                    /* static_pass_number */
2164169699Skan  0,                                    /* tv_id */
2165169699Skan  0,                                    /* properties_required */
2166169699Skan  0,                                    /* properties_provided */
2167169699Skan  0,                                    /* properties_destroyed */
2168169699Skan  0,                                    /* todo_flags_start */
2169169699Skan  TODO_dump_func,                       /* todo_flags_finish */
2170169699Skan  0                                     /* letter */
2171169699Skan};
2172169699Skan
2173169699Skan
2174132727Skan/* Check that ORIG is not marked when it should not be and mark ORIG as in use,
2175132727Skan   Recursively does the same for subexpressions.  */
2176132727Skan
2177132727Skanstatic void
2178132727Skanverify_rtx_sharing (rtx orig, rtx insn)
2179132727Skan{
2180132727Skan  rtx x = orig;
2181132727Skan  int i;
2182132727Skan  enum rtx_code code;
2183132727Skan  const char *format_ptr;
2184132727Skan
2185132727Skan  if (x == 0)
2186132727Skan    return;
2187132727Skan
2188132727Skan  code = GET_CODE (x);
2189132727Skan
2190132727Skan  /* These types may be freely shared.  */
2191132727Skan
2192132727Skan  switch (code)
2193132727Skan    {
2194132727Skan    case REG:
2195132727Skan    case CONST_INT:
2196132727Skan    case CONST_DOUBLE:
2197132727Skan    case CONST_VECTOR:
2198132727Skan    case SYMBOL_REF:
2199132727Skan    case LABEL_REF:
2200132727Skan    case CODE_LABEL:
2201132727Skan    case PC:
2202132727Skan    case CC0:
2203132727Skan    case SCRATCH:
2204169699Skan      return;
2205132727Skan      /* SCRATCH must be shared because they represent distinct values.  */
2206169699Skan    case CLOBBER:
2207169699Skan      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
2208169699Skan	return;
2209169699Skan      break;
2210132727Skan
2211132727Skan    case CONST:
2212132727Skan      /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
2213132727Skan	 a LABEL_REF, it isn't sharable.  */
2214132727Skan      if (GET_CODE (XEXP (x, 0)) == PLUS
2215132727Skan	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
2216132727Skan	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2217132727Skan	return;
2218132727Skan      break;
2219132727Skan
2220132727Skan    case MEM:
2221132727Skan      /* A MEM is allowed to be shared if its address is constant.  */
2222132727Skan      if (CONSTANT_ADDRESS_P (XEXP (x, 0))
2223132727Skan	  || reload_completed || reload_in_progress)
2224132727Skan	return;
2225132727Skan
2226132727Skan      break;
2227132727Skan
2228132727Skan    default:
2229132727Skan      break;
2230132727Skan    }
2231132727Skan
2232132727Skan  /* This rtx may not be shared.  If it has already been seen,
2233132727Skan     replace it with a copy of itself.  */
2234169699Skan#ifdef ENABLE_CHECKING
2235132727Skan  if (RTX_FLAG (x, used))
2236132727Skan    {
2237169699Skan      error ("invalid rtl sharing found in the insn");
2238132727Skan      debug_rtx (insn);
2239169699Skan      error ("shared rtx");
2240132727Skan      debug_rtx (x);
2241169699Skan      internal_error ("internal consistency failure");
2242132727Skan    }
2243169699Skan#endif
2244169699Skan  gcc_assert (!RTX_FLAG (x, used));
2245169699Skan
2246132727Skan  RTX_FLAG (x, used) = 1;
2247132727Skan
2248132727Skan  /* Now scan the subexpressions recursively.  */
2249132727Skan
2250132727Skan  format_ptr = GET_RTX_FORMAT (code);
2251132727Skan
2252132727Skan  for (i = 0; i < GET_RTX_LENGTH (code); i++)
2253132727Skan    {
2254132727Skan      switch (*format_ptr++)
2255132727Skan	{
2256132727Skan	case 'e':
2257132727Skan	  verify_rtx_sharing (XEXP (x, i), insn);
2258132727Skan	  break;
2259132727Skan
2260132727Skan	case 'E':
2261132727Skan	  if (XVEC (x, i) != NULL)
2262132727Skan	    {
2263132727Skan	      int j;
2264132727Skan	      int len = XVECLEN (x, i);
2265132727Skan
2266132727Skan	      for (j = 0; j < len; j++)
2267132727Skan		{
2268169699Skan		  /* We allow sharing of ASM_OPERANDS inside single
2269169699Skan		     instruction.  */
2270132727Skan		  if (j && GET_CODE (XVECEXP (x, i, j)) == SET
2271169699Skan		      && (GET_CODE (SET_SRC (XVECEXP (x, i, j)))
2272169699Skan			  == ASM_OPERANDS))
2273132727Skan		    verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
2274132727Skan		  else
2275132727Skan		    verify_rtx_sharing (XVECEXP (x, i, j), insn);
2276132727Skan		}
2277132727Skan	    }
2278132727Skan	  break;
2279132727Skan	}
2280132727Skan    }
2281132727Skan  return;
2282132727Skan}
2283132727Skan
2284132727Skan/* Go through all the RTL insn bodies and check that there is no unexpected
2285132727Skan   sharing in between the subexpressions.  */
2286132727Skan
2287132727Skanvoid
2288132727Skanverify_rtl_sharing (void)
2289132727Skan{
2290132727Skan  rtx p;
2291132727Skan
2292132727Skan  for (p = get_insns (); p; p = NEXT_INSN (p))
2293132727Skan    if (INSN_P (p))
2294132727Skan      {
2295132727Skan	reset_used_flags (PATTERN (p));
2296132727Skan	reset_used_flags (REG_NOTES (p));
2297132727Skan	reset_used_flags (LOG_LINKS (p));
2298132727Skan      }
2299132727Skan
2300132727Skan  for (p = get_insns (); p; p = NEXT_INSN (p))
2301132727Skan    if (INSN_P (p))
2302132727Skan      {
2303132727Skan	verify_rtx_sharing (PATTERN (p), p);
2304132727Skan	verify_rtx_sharing (REG_NOTES (p), p);
2305132727Skan	verify_rtx_sharing (LOG_LINKS (p), p);
2306132727Skan      }
2307132727Skan}
2308132727Skan
230972562Sobrien/* Go through all the RTL insn bodies and copy any invalid shared structure.
231072562Sobrien   Assumes the mark bits are cleared at entry.  */
231172562Sobrien
2312132727Skanvoid
2313132727Skanunshare_all_rtl_in_chain (rtx insn)
231472562Sobrien{
231572562Sobrien  for (; insn; insn = NEXT_INSN (insn))
231690075Sobrien    if (INSN_P (insn))
231772562Sobrien      {
231872562Sobrien	PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
231972562Sobrien	REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
232072562Sobrien	LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
232172562Sobrien      }
232272562Sobrien}
232372562Sobrien
232472562Sobrien/* Go through all virtual stack slots of a function and copy any
232572562Sobrien   shared structure.  */
232672562Sobrienstatic void
2327132727Skanunshare_all_decls (tree blk)
232872562Sobrien{
232972562Sobrien  tree t;
233072562Sobrien
233172562Sobrien  /* Copy shared decls.  */
233272562Sobrien  for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
233390075Sobrien    if (DECL_RTL_SET_P (t))
233490075Sobrien      SET_DECL_RTL (t, copy_rtx_if_shared (DECL_RTL (t)));
233572562Sobrien
233672562Sobrien  /* Now process sub-blocks.  */
233772562Sobrien  for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
233872562Sobrien    unshare_all_decls (t);
233972562Sobrien}
234072562Sobrien
234172562Sobrien/* Go through all virtual stack slots of a function and mark them as
234290075Sobrien   not shared.  */
234372562Sobrienstatic void
2344132727Skanreset_used_decls (tree blk)
234572562Sobrien{
234672562Sobrien  tree t;
234772562Sobrien
234872562Sobrien  /* Mark decls.  */
234972562Sobrien  for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
235090075Sobrien    if (DECL_RTL_SET_P (t))
235190075Sobrien      reset_used_flags (DECL_RTL (t));
235272562Sobrien
235372562Sobrien  /* Now process sub-blocks.  */
235472562Sobrien  for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
235572562Sobrien    reset_used_decls (t);
235672562Sobrien}
235772562Sobrien
235818334Speter/* Mark ORIG as in use, and return a copy of it if it was already in use.
2359132727Skan   Recursively does the same for subexpressions.  Uses
2360132727Skan   copy_rtx_if_shared_1 to reduce stack space.  */
236118334Speter
236218334Speterrtx
2363132727Skancopy_rtx_if_shared (rtx orig)
236418334Speter{
2365132727Skan  copy_rtx_if_shared_1 (&orig);
2366132727Skan  return orig;
2367132727Skan}
2368132727Skan
2369132727Skan/* Mark *ORIG1 as in use, and set it to a copy of it if it was already in
2370132727Skan   use.  Recursively does the same for subexpressions.  */
2371132727Skan
2372132727Skanstatic void
2373132727Skancopy_rtx_if_shared_1 (rtx *orig1)
2374132727Skan{
2375132727Skan  rtx x;
237690075Sobrien  int i;
237790075Sobrien  enum rtx_code code;
2378132727Skan  rtx *last_ptr;
237990075Sobrien  const char *format_ptr;
238018334Speter  int copied = 0;
2381132727Skan  int length;
238218334Speter
2383132727Skan  /* Repeat is used to turn tail-recursion into iteration.  */
2384132727Skanrepeat:
2385132727Skan  x = *orig1;
2386132727Skan
238718334Speter  if (x == 0)
2388132727Skan    return;
238918334Speter
239018334Speter  code = GET_CODE (x);
239118334Speter
239218334Speter  /* These types may be freely shared.  */
239318334Speter
239418334Speter  switch (code)
239518334Speter    {
239618334Speter    case REG:
239718334Speter    case CONST_INT:
239818334Speter    case CONST_DOUBLE:
239996263Sobrien    case CONST_VECTOR:
240018334Speter    case SYMBOL_REF:
2401132727Skan    case LABEL_REF:
240218334Speter    case CODE_LABEL:
240318334Speter    case PC:
240418334Speter    case CC0:
240518334Speter    case SCRATCH:
240650397Sobrien      /* SCRATCH must be shared because they represent distinct values.  */
2407132727Skan      return;
2408169699Skan    case CLOBBER:
2409169699Skan      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
2410169699Skan	return;
2411169699Skan      break;
241218334Speter
241318334Speter    case CONST:
241418334Speter      /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
241518334Speter	 a LABEL_REF, it isn't sharable.  */
241618334Speter      if (GET_CODE (XEXP (x, 0)) == PLUS
241718334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
241818334Speter	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2419132727Skan	return;
242018334Speter      break;
242118334Speter
242218334Speter    case INSN:
242318334Speter    case JUMP_INSN:
242418334Speter    case CALL_INSN:
242518334Speter    case NOTE:
242618334Speter    case BARRIER:
242718334Speter      /* The chain of insns is not being copied.  */
2428132727Skan      return;
242918334Speter
243050397Sobrien    default:
243150397Sobrien      break;
243218334Speter    }
243318334Speter
243418334Speter  /* This rtx may not be shared.  If it has already been seen,
243518334Speter     replace it with a copy of itself.  */
243618334Speter
2437117404Skan  if (RTX_FLAG (x, used))
243818334Speter    {
2439169699Skan      x = shallow_copy_rtx (x);
244018334Speter      copied = 1;
244118334Speter    }
2442117404Skan  RTX_FLAG (x, used) = 1;
244318334Speter
244418334Speter  /* Now scan the subexpressions recursively.
244518334Speter     We can store any replaced subexpressions directly into X
244618334Speter     since we know X is not shared!  Any vectors in X
244718334Speter     must be copied if X was copied.  */
244818334Speter
244918334Speter  format_ptr = GET_RTX_FORMAT (code);
2450132727Skan  length = GET_RTX_LENGTH (code);
2451132727Skan  last_ptr = NULL;
2452132727Skan
2453132727Skan  for (i = 0; i < length; i++)
245418334Speter    {
245518334Speter      switch (*format_ptr++)
245618334Speter	{
245718334Speter	case 'e':
2458132727Skan          if (last_ptr)
2459132727Skan            copy_rtx_if_shared_1 (last_ptr);
2460132727Skan	  last_ptr = &XEXP (x, i);
246118334Speter	  break;
246218334Speter
246318334Speter	case 'E':
246418334Speter	  if (XVEC (x, i) != NULL)
246518334Speter	    {
246690075Sobrien	      int j;
246718334Speter	      int len = XVECLEN (x, i);
2468132727Skan
2469132727Skan              /* Copy the vector iff I copied the rtx and the length
2470132727Skan		 is nonzero.  */
247118334Speter	      if (copied && len > 0)
247290075Sobrien		XVEC (x, i) = gen_rtvec_v (len, XVEC (x, i)->elem);
2473132727Skan
2474132727Skan              /* Call recursively on all inside the vector.  */
247518334Speter	      for (j = 0; j < len; j++)
2476132727Skan                {
2477132727Skan		  if (last_ptr)
2478132727Skan		    copy_rtx_if_shared_1 (last_ptr);
2479132727Skan                  last_ptr = &XVECEXP (x, i, j);
2480132727Skan                }
248118334Speter	    }
248218334Speter	  break;
248318334Speter	}
248418334Speter    }
2485132727Skan  *orig1 = x;
2486132727Skan  if (last_ptr)
2487132727Skan    {
2488132727Skan      orig1 = last_ptr;
2489132727Skan      goto repeat;
2490132727Skan    }
2491132727Skan  return;
249218334Speter}
249318334Speter
249418334Speter/* Clear all the USED bits in X to allow copy_rtx_if_shared to be used
249518334Speter   to look for shared sub-parts.  */
249618334Speter
249718334Spetervoid
2498132727Skanreset_used_flags (rtx x)
249918334Speter{
250090075Sobrien  int i, j;
250190075Sobrien  enum rtx_code code;
250290075Sobrien  const char *format_ptr;
2503132727Skan  int length;
250418334Speter
2505132727Skan  /* Repeat is used to turn tail-recursion into iteration.  */
2506132727Skanrepeat:
250718334Speter  if (x == 0)
250818334Speter    return;
250918334Speter
251018334Speter  code = GET_CODE (x);
251118334Speter
251218334Speter  /* These types may be freely shared so we needn't do any resetting
251318334Speter     for them.  */
251418334Speter
251518334Speter  switch (code)
251618334Speter    {
251718334Speter    case REG:
251818334Speter    case CONST_INT:
251918334Speter    case CONST_DOUBLE:
252096263Sobrien    case CONST_VECTOR:
252118334Speter    case SYMBOL_REF:
252218334Speter    case CODE_LABEL:
252318334Speter    case PC:
252418334Speter    case CC0:
252518334Speter      return;
252618334Speter
252718334Speter    case INSN:
252818334Speter    case JUMP_INSN:
252918334Speter    case CALL_INSN:
253018334Speter    case NOTE:
253118334Speter    case LABEL_REF:
253218334Speter    case BARRIER:
253318334Speter      /* The chain of insns is not being copied.  */
253418334Speter      return;
253590075Sobrien
253650397Sobrien    default:
253750397Sobrien      break;
253818334Speter    }
253918334Speter
2540117404Skan  RTX_FLAG (x, used) = 0;
254118334Speter
254218334Speter  format_ptr = GET_RTX_FORMAT (code);
2543132727Skan  length = GET_RTX_LENGTH (code);
2544132727Skan
2545132727Skan  for (i = 0; i < length; i++)
254618334Speter    {
254718334Speter      switch (*format_ptr++)
254818334Speter	{
254918334Speter	case 'e':
2550132727Skan          if (i == length-1)
2551132727Skan            {
2552132727Skan              x = XEXP (x, i);
2553132727Skan	      goto repeat;
2554132727Skan            }
255518334Speter	  reset_used_flags (XEXP (x, i));
255618334Speter	  break;
255718334Speter
255818334Speter	case 'E':
255918334Speter	  for (j = 0; j < XVECLEN (x, i); j++)
256018334Speter	    reset_used_flags (XVECEXP (x, i, j));
256118334Speter	  break;
256218334Speter	}
256318334Speter    }
256418334Speter}
2565132727Skan
2566132727Skan/* Set all the USED bits in X to allow copy_rtx_if_shared to be used
2567132727Skan   to look for shared sub-parts.  */
2568132727Skan
2569132727Skanvoid
2570132727Skanset_used_flags (rtx x)
2571132727Skan{
2572132727Skan  int i, j;
2573132727Skan  enum rtx_code code;
2574132727Skan  const char *format_ptr;
2575132727Skan
2576132727Skan  if (x == 0)
2577132727Skan    return;
2578132727Skan
2579132727Skan  code = GET_CODE (x);
2580132727Skan
2581132727Skan  /* These types may be freely shared so we needn't do any resetting
2582132727Skan     for them.  */
2583132727Skan
2584132727Skan  switch (code)
2585132727Skan    {
2586132727Skan    case REG:
2587132727Skan    case CONST_INT:
2588132727Skan    case CONST_DOUBLE:
2589132727Skan    case CONST_VECTOR:
2590132727Skan    case SYMBOL_REF:
2591132727Skan    case CODE_LABEL:
2592132727Skan    case PC:
2593132727Skan    case CC0:
2594132727Skan      return;
2595132727Skan
2596132727Skan    case INSN:
2597132727Skan    case JUMP_INSN:
2598132727Skan    case CALL_INSN:
2599132727Skan    case NOTE:
2600132727Skan    case LABEL_REF:
2601132727Skan    case BARRIER:
2602132727Skan      /* The chain of insns is not being copied.  */
2603132727Skan      return;
2604132727Skan
2605132727Skan    default:
2606132727Skan      break;
2607132727Skan    }
2608132727Skan
2609132727Skan  RTX_FLAG (x, used) = 1;
2610132727Skan
2611132727Skan  format_ptr = GET_RTX_FORMAT (code);
2612132727Skan  for (i = 0; i < GET_RTX_LENGTH (code); i++)
2613132727Skan    {
2614132727Skan      switch (*format_ptr++)
2615132727Skan	{
2616132727Skan	case 'e':
2617132727Skan	  set_used_flags (XEXP (x, i));
2618132727Skan	  break;
2619132727Skan
2620132727Skan	case 'E':
2621132727Skan	  for (j = 0; j < XVECLEN (x, i); j++)
2622132727Skan	    set_used_flags (XVECEXP (x, i, j));
2623132727Skan	  break;
2624132727Skan	}
2625132727Skan    }
2626132727Skan}
262718334Speter
262818334Speter/* Copy X if necessary so that it won't be altered by changes in OTHER.
262918334Speter   Return X or the rtx for the pseudo reg the value of X was copied into.
263018334Speter   OTHER must be valid as a SET_DEST.  */
263118334Speter
263218334Speterrtx
2633132727Skanmake_safe_from (rtx x, rtx other)
263418334Speter{
263518334Speter  while (1)
263618334Speter    switch (GET_CODE (other))
263718334Speter      {
263818334Speter      case SUBREG:
263918334Speter	other = SUBREG_REG (other);
264018334Speter	break;
264118334Speter      case STRICT_LOW_PART:
264218334Speter      case SIGN_EXTEND:
264318334Speter      case ZERO_EXTEND:
264418334Speter	other = XEXP (other, 0);
264518334Speter	break;
264618334Speter      default:
264718334Speter	goto done;
264818334Speter      }
264918334Speter done:
2650169699Skan  if ((MEM_P (other)
265118334Speter       && ! CONSTANT_P (x)
2652169699Skan       && !REG_P (x)
265318334Speter       && GET_CODE (x) != SUBREG)
2654169699Skan      || (REG_P (other)
265518334Speter	  && (REGNO (other) < FIRST_PSEUDO_REGISTER
265618334Speter	      || reg_mentioned_p (other, x))))
265718334Speter    {
265818334Speter      rtx temp = gen_reg_rtx (GET_MODE (x));
265918334Speter      emit_move_insn (temp, x);
266018334Speter      return temp;
266118334Speter    }
266218334Speter  return x;
266318334Speter}
266418334Speter
266518334Speter/* Emission of insns (adding them to the doubly-linked list).  */
266618334Speter
266718334Speter/* Return the first insn of the current sequence or current function.  */
266818334Speter
266918334Speterrtx
2670132727Skanget_insns (void)
267118334Speter{
267218334Speter  return first_insn;
267318334Speter}
267418334Speter
2675117404Skan/* Specify a new insn as the first in the chain.  */
2676117404Skan
2677117404Skanvoid
2678132727Skanset_first_insn (rtx insn)
2679117404Skan{
2680169699Skan  gcc_assert (!PREV_INSN (insn));
2681117404Skan  first_insn = insn;
2682117404Skan}
2683117404Skan
268418334Speter/* Return the last insn emitted in current sequence or current function.  */
268518334Speter
268618334Speterrtx
2687132727Skanget_last_insn (void)
268818334Speter{
268918334Speter  return last_insn;
269018334Speter}
269118334Speter
269218334Speter/* Specify a new insn as the last in the chain.  */
269318334Speter
269418334Spetervoid
2695132727Skanset_last_insn (rtx insn)
269618334Speter{
2697169699Skan  gcc_assert (!NEXT_INSN (insn));
269818334Speter  last_insn = insn;
269918334Speter}
270018334Speter
270118334Speter/* Return the last insn emitted, even if it is in a sequence now pushed.  */
270218334Speter
270318334Speterrtx
2704132727Skanget_last_insn_anywhere (void)
270518334Speter{
270618334Speter  struct sequence_stack *stack;
270718334Speter  if (last_insn)
270818334Speter    return last_insn;
270990075Sobrien  for (stack = seq_stack; stack; stack = stack->next)
271018334Speter    if (stack->last != 0)
271118334Speter      return stack->last;
271218334Speter  return 0;
271318334Speter}
271418334Speter
2715117404Skan/* Return the first nonnote insn emitted in current sequence or current
2716117404Skan   function.  This routine looks inside SEQUENCEs.  */
2717117404Skan
2718117404Skanrtx
2719132727Skanget_first_nonnote_insn (void)
2720117404Skan{
2721117404Skan  rtx insn = first_insn;
2722117404Skan
2723146906Skan  if (insn)
2724117404Skan    {
2725146906Skan      if (NOTE_P (insn))
2726146906Skan	for (insn = next_insn (insn);
2727146906Skan	     insn && NOTE_P (insn);
2728146906Skan	     insn = next_insn (insn))
2729146906Skan	  continue;
2730146906Skan      else
2731146906Skan	{
2732169699Skan	  if (NONJUMP_INSN_P (insn)
2733146906Skan	      && GET_CODE (PATTERN (insn)) == SEQUENCE)
2734146906Skan	    insn = XVECEXP (PATTERN (insn), 0, 0);
2735146906Skan	}
2736117404Skan    }
2737117404Skan
2738117404Skan  return insn;
2739117404Skan}
2740117404Skan
2741117404Skan/* Return the last nonnote insn emitted in current sequence or current
2742117404Skan   function.  This routine looks inside SEQUENCEs.  */
2743117404Skan
2744117404Skanrtx
2745132727Skanget_last_nonnote_insn (void)
2746117404Skan{
2747117404Skan  rtx insn = last_insn;
2748117404Skan
2749146906Skan  if (insn)
2750117404Skan    {
2751146906Skan      if (NOTE_P (insn))
2752146906Skan	for (insn = previous_insn (insn);
2753146906Skan	     insn && NOTE_P (insn);
2754146906Skan	     insn = previous_insn (insn))
2755146906Skan	  continue;
2756146906Skan      else
2757146906Skan	{
2758169699Skan	  if (NONJUMP_INSN_P (insn)
2759146906Skan	      && GET_CODE (PATTERN (insn)) == SEQUENCE)
2760146906Skan	    insn = XVECEXP (PATTERN (insn), 0,
2761146906Skan			    XVECLEN (PATTERN (insn), 0) - 1);
2762146906Skan	}
2763117404Skan    }
2764117404Skan
2765117404Skan  return insn;
2766117404Skan}
2767117404Skan
276818334Speter/* Return a number larger than any instruction's uid in this function.  */
276918334Speter
277018334Speterint
2771132727Skanget_max_uid (void)
277218334Speter{
277318334Speter  return cur_insn_uid;
277418334Speter}
277590075Sobrien
277690075Sobrien/* Renumber instructions so that no instruction UIDs are wasted.  */
277790075Sobrien
277890075Sobrienvoid
2779169699Skanrenumber_insns (void)
278090075Sobrien{
278190075Sobrien  rtx insn;
278290075Sobrien
278390075Sobrien  /* If we're not supposed to renumber instructions, don't.  */
278490075Sobrien  if (!flag_renumber_insns)
278590075Sobrien    return;
278690075Sobrien
278790075Sobrien  /* If there aren't that many instructions, then it's not really
278890075Sobrien     worth renumbering them.  */
278990075Sobrien  if (flag_renumber_insns == 1 && get_max_uid () < 25000)
279090075Sobrien    return;
279190075Sobrien
279290075Sobrien  cur_insn_uid = 1;
279390075Sobrien
279490075Sobrien  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
279590075Sobrien    {
2796169699Skan      if (dump_file)
2797169699Skan	fprintf (dump_file, "Renumbering insn %d to %d\n",
279890075Sobrien		 INSN_UID (insn), cur_insn_uid);
279990075Sobrien      INSN_UID (insn) = cur_insn_uid++;
280090075Sobrien    }
280190075Sobrien}
280218334Speter
280318334Speter/* Return the next insn.  If it is a SEQUENCE, return the first insn
280418334Speter   of the sequence.  */
280518334Speter
280618334Speterrtx
2807132727Skannext_insn (rtx insn)
280818334Speter{
280918334Speter  if (insn)
281018334Speter    {
281118334Speter      insn = NEXT_INSN (insn);
2812169699Skan      if (insn && NONJUMP_INSN_P (insn)
281318334Speter	  && GET_CODE (PATTERN (insn)) == SEQUENCE)
281418334Speter	insn = XVECEXP (PATTERN (insn), 0, 0);
281518334Speter    }
281618334Speter
281718334Speter  return insn;
281818334Speter}
281918334Speter
282018334Speter/* Return the previous insn.  If it is a SEQUENCE, return the last insn
282118334Speter   of the sequence.  */
282218334Speter
282318334Speterrtx
2824132727Skanprevious_insn (rtx insn)
282518334Speter{
282618334Speter  if (insn)
282718334Speter    {
282818334Speter      insn = PREV_INSN (insn);
2829169699Skan      if (insn && NONJUMP_INSN_P (insn)
283018334Speter	  && GET_CODE (PATTERN (insn)) == SEQUENCE)
283118334Speter	insn = XVECEXP (PATTERN (insn), 0, XVECLEN (PATTERN (insn), 0) - 1);
283218334Speter    }
283318334Speter
283418334Speter  return insn;
283518334Speter}
283618334Speter
283718334Speter/* Return the next insn after INSN that is not a NOTE.  This routine does not
283818334Speter   look inside SEQUENCEs.  */
283918334Speter
284018334Speterrtx
2841132727Skannext_nonnote_insn (rtx insn)
284218334Speter{
284318334Speter  while (insn)
284418334Speter    {
284518334Speter      insn = NEXT_INSN (insn);
2846169699Skan      if (insn == 0 || !NOTE_P (insn))
284718334Speter	break;
284818334Speter    }
284918334Speter
285018334Speter  return insn;
285118334Speter}
285218334Speter
285318334Speter/* Return the previous insn before INSN that is not a NOTE.  This routine does
285418334Speter   not look inside SEQUENCEs.  */
285518334Speter
285618334Speterrtx
2857132727Skanprev_nonnote_insn (rtx insn)
285818334Speter{
285918334Speter  while (insn)
286018334Speter    {
286118334Speter      insn = PREV_INSN (insn);
2862169699Skan      if (insn == 0 || !NOTE_P (insn))
286318334Speter	break;
286418334Speter    }
286518334Speter
286618334Speter  return insn;
286718334Speter}
286818334Speter
286918334Speter/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
287018334Speter   or 0, if there is none.  This routine does not look inside
287150397Sobrien   SEQUENCEs.  */
287218334Speter
287318334Speterrtx
2874132727Skannext_real_insn (rtx insn)
287518334Speter{
287618334Speter  while (insn)
287718334Speter    {
287818334Speter      insn = NEXT_INSN (insn);
2879169699Skan      if (insn == 0 || INSN_P (insn))
288018334Speter	break;
288118334Speter    }
288218334Speter
288318334Speter  return insn;
288418334Speter}
288518334Speter
288618334Speter/* Return the last INSN, CALL_INSN or JUMP_INSN before INSN;
288718334Speter   or 0, if there is none.  This routine does not look inside
288818334Speter   SEQUENCEs.  */
288918334Speter
289018334Speterrtx
2891132727Skanprev_real_insn (rtx insn)
289218334Speter{
289318334Speter  while (insn)
289418334Speter    {
289518334Speter      insn = PREV_INSN (insn);
2896169699Skan      if (insn == 0 || INSN_P (insn))
289718334Speter	break;
289818334Speter    }
289918334Speter
290018334Speter  return insn;
290118334Speter}
290218334Speter
2903132727Skan/* Return the last CALL_INSN in the current list, or 0 if there is none.
2904132727Skan   This routine does not look inside SEQUENCEs.  */
2905132727Skan
2906132727Skanrtx
2907132727Skanlast_call_insn (void)
2908132727Skan{
2909132727Skan  rtx insn;
2910132727Skan
2911132727Skan  for (insn = get_last_insn ();
2912169699Skan       insn && !CALL_P (insn);
2913132727Skan       insn = PREV_INSN (insn))
2914132727Skan    ;
2915132727Skan
2916132727Skan  return insn;
2917132727Skan}
2918132727Skan
291918334Speter/* Find the next insn after INSN that really does something.  This routine
292018334Speter   does not look inside SEQUENCEs.  Until reload has completed, this is the
292118334Speter   same as next_real_insn.  */
292218334Speter
292390075Sobrienint
2924132727Skanactive_insn_p (rtx insn)
292590075Sobrien{
2926169699Skan  return (CALL_P (insn) || JUMP_P (insn)
2927169699Skan	  || (NONJUMP_INSN_P (insn)
292890075Sobrien	      && (! reload_completed
292990075Sobrien		  || (GET_CODE (PATTERN (insn)) != USE
293090075Sobrien		      && GET_CODE (PATTERN (insn)) != CLOBBER))));
293190075Sobrien}
293290075Sobrien
293318334Speterrtx
2934132727Skannext_active_insn (rtx insn)
293518334Speter{
293618334Speter  while (insn)
293718334Speter    {
293818334Speter      insn = NEXT_INSN (insn);
293990075Sobrien      if (insn == 0 || active_insn_p (insn))
294018334Speter	break;
294118334Speter    }
294218334Speter
294318334Speter  return insn;
294418334Speter}
294518334Speter
294618334Speter/* Find the last insn before INSN that really does something.  This routine
294718334Speter   does not look inside SEQUENCEs.  Until reload has completed, this is the
294818334Speter   same as prev_real_insn.  */
294918334Speter
295018334Speterrtx
2951132727Skanprev_active_insn (rtx insn)
295218334Speter{
295318334Speter  while (insn)
295418334Speter    {
295518334Speter      insn = PREV_INSN (insn);
295690075Sobrien      if (insn == 0 || active_insn_p (insn))
295718334Speter	break;
295818334Speter    }
295918334Speter
296018334Speter  return insn;
296118334Speter}
296218334Speter
296318334Speter/* Return the next CODE_LABEL after the insn INSN, or 0 if there is none.  */
296418334Speter
296518334Speterrtx
2966132727Skannext_label (rtx insn)
296718334Speter{
296818334Speter  while (insn)
296918334Speter    {
297018334Speter      insn = NEXT_INSN (insn);
2971169699Skan      if (insn == 0 || LABEL_P (insn))
297218334Speter	break;
297318334Speter    }
297418334Speter
297518334Speter  return insn;
297618334Speter}
297718334Speter
297818334Speter/* Return the last CODE_LABEL before the insn INSN, or 0 if there is none.  */
297918334Speter
298018334Speterrtx
2981132727Skanprev_label (rtx insn)
298218334Speter{
298318334Speter  while (insn)
298418334Speter    {
298518334Speter      insn = PREV_INSN (insn);
2986169699Skan      if (insn == 0 || LABEL_P (insn))
298718334Speter	break;
298818334Speter    }
298918334Speter
299018334Speter  return insn;
299118334Speter}
2992169699Skan
2993169699Skan/* Return the last label to mark the same position as LABEL.  Return null
2994169699Skan   if LABEL itself is null.  */
2995169699Skan
2996169699Skanrtx
2997169699Skanskip_consecutive_labels (rtx label)
2998169699Skan{
2999169699Skan  rtx insn;
3000169699Skan
3001169699Skan  for (insn = label; insn != 0 && !INSN_P (insn); insn = NEXT_INSN (insn))
3002169699Skan    if (LABEL_P (insn))
3003169699Skan      label = insn;
3004169699Skan
3005169699Skan  return label;
3006169699Skan}
300718334Speter
300818334Speter#ifdef HAVE_cc0
300918334Speter/* INSN uses CC0 and is being moved into a delay slot.  Set up REG_CC_SETTER
301018334Speter   and REG_CC_USER notes so we can find it.  */
301118334Speter
301218334Spetervoid
3013132727Skanlink_cc0_insns (rtx insn)
301418334Speter{
301518334Speter  rtx user = next_nonnote_insn (insn);
301618334Speter
3017169699Skan  if (NONJUMP_INSN_P (user) && GET_CODE (PATTERN (user)) == SEQUENCE)
301818334Speter    user = XVECEXP (PATTERN (user), 0, 0);
301918334Speter
302090075Sobrien  REG_NOTES (user) = gen_rtx_INSN_LIST (REG_CC_SETTER, insn,
302190075Sobrien					REG_NOTES (user));
302250397Sobrien  REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_CC_USER, user, REG_NOTES (insn));
302318334Speter}
302418334Speter
302518334Speter/* Return the next insn that uses CC0 after INSN, which is assumed to
302618334Speter   set it.  This is the inverse of prev_cc0_setter (i.e., prev_cc0_setter
302718334Speter   applied to the result of this function should yield INSN).
302818334Speter
302918334Speter   Normally, this is simply the next insn.  However, if a REG_CC_USER note
303018334Speter   is present, it contains the insn that uses CC0.
303118334Speter
303218334Speter   Return 0 if we can't find the insn.  */
303318334Speter
303418334Speterrtx
3035132727Skannext_cc0_user (rtx insn)
303618334Speter{
303718334Speter  rtx note = find_reg_note (insn, REG_CC_USER, NULL_RTX);
303818334Speter
303918334Speter  if (note)
304018334Speter    return XEXP (note, 0);
304118334Speter
304218334Speter  insn = next_nonnote_insn (insn);
3043169699Skan  if (insn && NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
304418334Speter    insn = XVECEXP (PATTERN (insn), 0, 0);
304518334Speter
304690075Sobrien  if (insn && INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
304718334Speter    return insn;
304818334Speter
304918334Speter  return 0;
305018334Speter}
305118334Speter
305218334Speter/* Find the insn that set CC0 for INSN.  Unless INSN has a REG_CC_SETTER
305318334Speter   note, it is the previous insn.  */
305418334Speter
305518334Speterrtx
3056132727Skanprev_cc0_setter (rtx insn)
305718334Speter{
305818334Speter  rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
305918334Speter
306018334Speter  if (note)
306118334Speter    return XEXP (note, 0);
306218334Speter
306318334Speter  insn = prev_nonnote_insn (insn);
3064169699Skan  gcc_assert (sets_cc0_p (PATTERN (insn)));
306518334Speter
306618334Speter  return insn;
306718334Speter}
306818334Speter#endif
306990075Sobrien
307090075Sobrien/* Increment the label uses for all labels present in rtx.  */
307190075Sobrien
307290075Sobrienstatic void
3073132727Skanmark_label_nuses (rtx x)
307490075Sobrien{
307590075Sobrien  enum rtx_code code;
307690075Sobrien  int i, j;
307790075Sobrien  const char *fmt;
307890075Sobrien
307990075Sobrien  code = GET_CODE (x);
3080132727Skan  if (code == LABEL_REF && LABEL_P (XEXP (x, 0)))
308190075Sobrien    LABEL_NUSES (XEXP (x, 0))++;
308290075Sobrien
308390075Sobrien  fmt = GET_RTX_FORMAT (code);
308490075Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
308590075Sobrien    {
308690075Sobrien      if (fmt[i] == 'e')
3087117404Skan	mark_label_nuses (XEXP (x, i));
308890075Sobrien      else if (fmt[i] == 'E')
3089117404Skan	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
309090075Sobrien	  mark_label_nuses (XVECEXP (x, i, j));
309190075Sobrien    }
309290075Sobrien}
309390075Sobrien
309418334Speter
309518334Speter/* Try splitting insns that can be split for better scheduling.
309618334Speter   PAT is the pattern which might split.
309718334Speter   TRIAL is the insn providing PAT.
3098117404Skan   LAST is nonzero if we should return the last insn of the sequence produced.
309918334Speter
310018334Speter   If this routine succeeds in splitting, it returns the first or last
310118334Speter   replacement insn depending on the value of LAST.  Otherwise, it
310218334Speter   returns TRIAL.  If the insn to be returned can be split, it will be.  */
310318334Speter
310418334Speterrtx
3105132727Skantry_split (rtx pat, rtx trial, int last)
310618334Speter{
310718334Speter  rtx before = PREV_INSN (trial);
310818334Speter  rtx after = NEXT_INSN (trial);
310918334Speter  int has_barrier = 0;
311018334Speter  rtx tem;
311190075Sobrien  rtx note, seq;
311290075Sobrien  int probability;
3113117404Skan  rtx insn_last, insn;
3114117404Skan  int njumps = 0;
311518334Speter
311690075Sobrien  if (any_condjump_p (trial)
311790075Sobrien      && (note = find_reg_note (trial, REG_BR_PROB, 0)))
311890075Sobrien    split_branch_probability = INTVAL (XEXP (note, 0));
311990075Sobrien  probability = split_branch_probability;
312090075Sobrien
312190075Sobrien  seq = split_insns (pat, trial);
312290075Sobrien
312390075Sobrien  split_branch_probability = -1;
312490075Sobrien
312518334Speter  /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER.
312618334Speter     We may need to handle this specially.  */
3127169699Skan  if (after && BARRIER_P (after))
312818334Speter    {
312918334Speter      has_barrier = 1;
313018334Speter      after = NEXT_INSN (after);
313118334Speter    }
313218334Speter
3133117404Skan  if (!seq)
3134117404Skan    return trial;
3135117404Skan
3136117404Skan  /* Avoid infinite loop if any insn of the result matches
3137117404Skan     the original pattern.  */
3138117404Skan  insn_last = seq;
3139117404Skan  while (1)
314018334Speter    {
3141117404Skan      if (INSN_P (insn_last)
3142117404Skan	  && rtx_equal_p (PATTERN (insn_last), pat))
3143117404Skan	return trial;
3144117404Skan      if (!NEXT_INSN (insn_last))
3145117404Skan	break;
3146117404Skan      insn_last = NEXT_INSN (insn_last);
3147117404Skan    }
3148117404Skan
3149117404Skan  /* Mark labels.  */
3150117404Skan  for (insn = insn_last; insn ; insn = PREV_INSN (insn))
3151117404Skan    {
3152169699Skan      if (JUMP_P (insn))
315318334Speter	{
3154117404Skan	  mark_jump_label (PATTERN (insn), insn, 0);
3155117404Skan	  njumps++;
3156117404Skan	  if (probability != -1
3157117404Skan	      && any_condjump_p (insn)
3158117404Skan	      && !find_reg_note (insn, REG_BR_PROB, 0))
3159117404Skan	    {
3160117404Skan	      /* We can preserve the REG_BR_PROB notes only if exactly
3161117404Skan		 one jump is created, otherwise the machine description
3162117404Skan		 is responsible for this step using
3163117404Skan		 split_branch_probability variable.  */
3164169699Skan	      gcc_assert (njumps == 1);
3165117404Skan	      REG_NOTES (insn)
3166117404Skan		= gen_rtx_EXPR_LIST (REG_BR_PROB,
3167117404Skan				     GEN_INT (probability),
3168117404Skan				     REG_NOTES (insn));
3169117404Skan	    }
3170117404Skan	}
3171117404Skan    }
317270635Sobrien
3173117404Skan  /* If we are splitting a CALL_INSN, look for the CALL_INSN
3174117404Skan     in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it.  */
3175169699Skan  if (CALL_P (trial))
3176117404Skan    {
3177117404Skan      for (insn = insn_last; insn ; insn = PREV_INSN (insn))
3178169699Skan	if (CALL_P (insn))
3179117404Skan	  {
3180132727Skan	    rtx *p = &CALL_INSN_FUNCTION_USAGE (insn);
3181132727Skan	    while (*p)
3182132727Skan	      p = &XEXP (*p, 1);
3183132727Skan	    *p = CALL_INSN_FUNCTION_USAGE (trial);
3184117404Skan	    SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
3185117404Skan	  }
3186117404Skan    }
318770635Sobrien
3188117404Skan  /* Copy notes, particularly those related to the CFG.  */
3189117404Skan  for (note = REG_NOTES (trial); note; note = XEXP (note, 1))
3190117404Skan    {
3191117404Skan      switch (REG_NOTE_KIND (note))
3192117404Skan	{
3193117404Skan	case REG_EH_REGION:
3194117404Skan	  insn = insn_last;
3195117404Skan	  while (insn != NULL_RTX)
3196117404Skan	    {
3197169699Skan	      if (CALL_P (insn)
3198169699Skan		  || (flag_non_call_exceptions && INSN_P (insn)
3199117404Skan		      && may_trap_p (PATTERN (insn))))
3200117404Skan		REG_NOTES (insn)
3201117404Skan		  = gen_rtx_EXPR_LIST (REG_EH_REGION,
3202117404Skan				       XEXP (note, 0),
3203117404Skan				       REG_NOTES (insn));
3204117404Skan	      insn = PREV_INSN (insn);
3205117404Skan	    }
3206117404Skan	  break;
320718334Speter
3208117404Skan	case REG_NORETURN:
3209117404Skan	case REG_SETJMP:
3210117404Skan	  insn = insn_last;
3211117404Skan	  while (insn != NULL_RTX)
3212117404Skan	    {
3213169699Skan	      if (CALL_P (insn))
3214117404Skan		REG_NOTES (insn)
3215222207Sbenl		  = gen_rtx_EXPR_LIST (GET_MODE (note),
3216117404Skan				       XEXP (note, 0),
3217117404Skan				       REG_NOTES (insn));
3218117404Skan	      insn = PREV_INSN (insn);
3219117404Skan	    }
3220117404Skan	  break;
322190075Sobrien
3222117404Skan	case REG_NON_LOCAL_GOTO:
3223117404Skan	  insn = insn_last;
3224117404Skan	  while (insn != NULL_RTX)
322590075Sobrien	    {
3226169699Skan	      if (JUMP_P (insn))
3227117404Skan		REG_NOTES (insn)
3228222207Sbenl		  = gen_rtx_EXPR_LIST (GET_MODE (note),
3229117404Skan				       XEXP (note, 0),
3230117404Skan				       REG_NOTES (insn));
3231117404Skan	      insn = PREV_INSN (insn);
3232117404Skan	    }
3233117404Skan	  break;
323418334Speter
3235117404Skan	default:
3236117404Skan	  break;
3237117404Skan	}
3238117404Skan    }
323990075Sobrien
3240117404Skan  /* If there are LABELS inside the split insns increment the
3241117404Skan     usage count so we don't delete the label.  */
3242169699Skan  if (NONJUMP_INSN_P (trial))
3243117404Skan    {
3244117404Skan      insn = insn_last;
3245117404Skan      while (insn != NULL_RTX)
3246117404Skan	{
3247169699Skan	  if (NONJUMP_INSN_P (insn))
3248117404Skan	    mark_label_nuses (PATTERN (insn));
324990075Sobrien
3250117404Skan	  insn = PREV_INSN (insn);
3251117404Skan	}
3252117404Skan    }
325318334Speter
3254132727Skan  tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));
325518334Speter
3256117404Skan  delete_insn (trial);
3257117404Skan  if (has_barrier)
3258117404Skan    emit_barrier_after (tem);
325990075Sobrien
3260117404Skan  /* Recursively call try_split for each new insn created; by the
3261117404Skan     time control returns here that insn will be fully split, so
3262117404Skan     set LAST and continue from the insn after the one returned.
3263117404Skan     We can't use next_active_insn here since AFTER may be a note.
3264117404Skan     Ignore deleted insns, which can be occur if not optimizing.  */
3265117404Skan  for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
3266117404Skan    if (! INSN_DELETED_P (tem) && INSN_P (tem))
3267117404Skan      tem = try_split (PATTERN (tem), tem, 1);
326818334Speter
3269117404Skan  /* Return either the first or the last insn, depending on which was
3270117404Skan     requested.  */
3271117404Skan  return last
3272117404Skan    ? (after ? PREV_INSN (after) : last_insn)
3273117404Skan    : NEXT_INSN (before);
327418334Speter}
327518334Speter
327618334Speter/* Make and return an INSN rtx, initializing all its slots.
327718334Speter   Store PATTERN in the pattern slots.  */
327818334Speter
327918334Speterrtx
3280132727Skanmake_insn_raw (rtx pattern)
328118334Speter{
328290075Sobrien  rtx insn;
328318334Speter
328490075Sobrien  insn = rtx_alloc (INSN);
328550397Sobrien
328618334Speter  INSN_UID (insn) = cur_insn_uid++;
328718334Speter  PATTERN (insn) = pattern;
328818334Speter  INSN_CODE (insn) = -1;
328918334Speter  LOG_LINKS (insn) = NULL;
329018334Speter  REG_NOTES (insn) = NULL;
3291132727Skan  INSN_LOCATOR (insn) = 0;
3292117404Skan  BLOCK_FOR_INSN (insn) = NULL;
329318334Speter
329490075Sobrien#ifdef ENABLE_RTL_CHECKING
329590075Sobrien  if (insn
329690075Sobrien      && INSN_P (insn)
329790075Sobrien      && (returnjump_p (insn)
329890075Sobrien	  || (GET_CODE (insn) == SET
329990075Sobrien	      && SET_DEST (insn) == pc_rtx)))
330090075Sobrien    {
3301169699Skan      warning (0, "ICE: emit_insn used where emit_jump_insn needed:\n");
330290075Sobrien      debug_rtx (insn);
330390075Sobrien    }
330490075Sobrien#endif
330590075Sobrien
330618334Speter  return insn;
330718334Speter}
330818334Speter
3309117404Skan/* Like `make_insn_raw' but make a JUMP_INSN instead of an insn.  */
331018334Speter
3311169699Skanrtx
3312132727Skanmake_jump_insn_raw (rtx pattern)
331318334Speter{
331490075Sobrien  rtx insn;
331518334Speter
331618334Speter  insn = rtx_alloc (JUMP_INSN);
331718334Speter  INSN_UID (insn) = cur_insn_uid++;
331818334Speter
331918334Speter  PATTERN (insn) = pattern;
332018334Speter  INSN_CODE (insn) = -1;
332118334Speter  LOG_LINKS (insn) = NULL;
332218334Speter  REG_NOTES (insn) = NULL;
332318334Speter  JUMP_LABEL (insn) = NULL;
3324132727Skan  INSN_LOCATOR (insn) = 0;
3325117404Skan  BLOCK_FOR_INSN (insn) = NULL;
332618334Speter
332718334Speter  return insn;
332818334Speter}
332918334Speter
3330117404Skan/* Like `make_insn_raw' but make a CALL_INSN instead of an insn.  */
333118334Speter
333218334Speterstatic rtx
3333132727Skanmake_call_insn_raw (rtx pattern)
333418334Speter{
333590075Sobrien  rtx insn;
333618334Speter
333718334Speter  insn = rtx_alloc (CALL_INSN);
333818334Speter  INSN_UID (insn) = cur_insn_uid++;
333918334Speter
334018334Speter  PATTERN (insn) = pattern;
334118334Speter  INSN_CODE (insn) = -1;
334218334Speter  LOG_LINKS (insn) = NULL;
334318334Speter  REG_NOTES (insn) = NULL;
334418334Speter  CALL_INSN_FUNCTION_USAGE (insn) = NULL;
3345132727Skan  INSN_LOCATOR (insn) = 0;
3346117404Skan  BLOCK_FOR_INSN (insn) = NULL;
334718334Speter
334818334Speter  return insn;
334918334Speter}
335018334Speter
335118334Speter/* Add INSN to the end of the doubly-linked list.
335218334Speter   INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE.  */
335318334Speter
335418334Spetervoid
3355132727Skanadd_insn (rtx insn)
335618334Speter{
335718334Speter  PREV_INSN (insn) = last_insn;
335818334Speter  NEXT_INSN (insn) = 0;
335918334Speter
336018334Speter  if (NULL != last_insn)
336118334Speter    NEXT_INSN (last_insn) = insn;
336218334Speter
336318334Speter  if (NULL == first_insn)
336418334Speter    first_insn = insn;
336518334Speter
336618334Speter  last_insn = insn;
336718334Speter}
336818334Speter
336918334Speter/* Add INSN into the doubly-linked list after insn AFTER.  This and
337018334Speter   the next should be the only functions called to insert an insn once
337118334Speter   delay slots have been filled since only they know how to update a
337218334Speter   SEQUENCE.  */
337318334Speter
337418334Spetervoid
3375132727Skanadd_insn_after (rtx insn, rtx after)
337618334Speter{
337718334Speter  rtx next = NEXT_INSN (after);
337890075Sobrien  basic_block bb;
337918334Speter
3380169699Skan  gcc_assert (!optimize || !INSN_DELETED_P (after));
338118334Speter
338218334Speter  NEXT_INSN (insn) = next;
338318334Speter  PREV_INSN (insn) = after;
338418334Speter
338518334Speter  if (next)
338618334Speter    {
338718334Speter      PREV_INSN (next) = insn;
3388169699Skan      if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
338918334Speter	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;
339018334Speter    }
339118334Speter  else if (last_insn == after)
339218334Speter    last_insn = insn;
339318334Speter  else
339418334Speter    {
339590075Sobrien      struct sequence_stack *stack = seq_stack;
339618334Speter      /* Scan all pending sequences too.  */
339718334Speter      for (; stack; stack = stack->next)
339818334Speter	if (after == stack->last)
339918334Speter	  {
340018334Speter	    stack->last = insn;
340118334Speter	    break;
340218334Speter	  }
340318334Speter
3404169699Skan      gcc_assert (stack);
340518334Speter    }
340618334Speter
3407169699Skan  if (!BARRIER_P (after)
3408169699Skan      && !BARRIER_P (insn)
340990075Sobrien      && (bb = BLOCK_FOR_INSN (after)))
341090075Sobrien    {
341190075Sobrien      set_block_for_insn (insn, bb);
3412117404Skan      if (INSN_P (insn))
3413117404Skan	bb->flags |= BB_DIRTY;
341490075Sobrien      /* Should not happen as first in the BB is always
341590075Sobrien	 either NOTE or LABEL.  */
3416132727Skan      if (BB_END (bb) == after
341790075Sobrien	  /* Avoid clobbering of structure when creating new BB.  */
3418169699Skan	  && !BARRIER_P (insn)
3419169699Skan	  && (!NOTE_P (insn)
342090075Sobrien	      || NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
3421132727Skan	BB_END (bb) = insn;
342290075Sobrien    }
342390075Sobrien
342418334Speter  NEXT_INSN (after) = insn;
3425169699Skan  if (NONJUMP_INSN_P (after) && GET_CODE (PATTERN (after)) == SEQUENCE)
342618334Speter    {
342718334Speter      rtx sequence = PATTERN (after);
342818334Speter      NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
342918334Speter    }
343018334Speter}
343118334Speter
343218334Speter/* Add INSN into the doubly-linked list before insn BEFORE.  This and
343318334Speter   the previous should be the only functions called to insert an insn once
343418334Speter   delay slots have been filled since only they know how to update a
343518334Speter   SEQUENCE.  */
343618334Speter
343718334Spetervoid
3438132727Skanadd_insn_before (rtx insn, rtx before)
343918334Speter{
344018334Speter  rtx prev = PREV_INSN (before);
344190075Sobrien  basic_block bb;
344218334Speter
3443169699Skan  gcc_assert (!optimize || !INSN_DELETED_P (before));
344418334Speter
344518334Speter  PREV_INSN (insn) = prev;
344618334Speter  NEXT_INSN (insn) = before;
344718334Speter
344818334Speter  if (prev)
344918334Speter    {
345018334Speter      NEXT_INSN (prev) = insn;
3451169699Skan      if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
345218334Speter	{
345318334Speter	  rtx sequence = PATTERN (prev);
345418334Speter	  NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
345518334Speter	}
345618334Speter    }
345718334Speter  else if (first_insn == before)
345818334Speter    first_insn = insn;
345918334Speter  else
346018334Speter    {
346190075Sobrien      struct sequence_stack *stack = seq_stack;
346218334Speter      /* Scan all pending sequences too.  */
346318334Speter      for (; stack; stack = stack->next)
346418334Speter	if (before == stack->first)
346518334Speter	  {
346618334Speter	    stack->first = insn;
346718334Speter	    break;
346818334Speter	  }
346918334Speter
3470169699Skan      gcc_assert (stack);
347118334Speter    }
347218334Speter
3473169699Skan  if (!BARRIER_P (before)
3474169699Skan      && !BARRIER_P (insn)
347590075Sobrien      && (bb = BLOCK_FOR_INSN (before)))
347690075Sobrien    {
347790075Sobrien      set_block_for_insn (insn, bb);
3478117404Skan      if (INSN_P (insn))
3479117404Skan	bb->flags |= BB_DIRTY;
3480169699Skan      /* Should not happen as first in the BB is always either NOTE or
3481169699Skan	 LABEL.  */
3482169699Skan      gcc_assert (BB_HEAD (bb) != insn
3483169699Skan		  /* Avoid clobbering of structure when creating new BB.  */
3484169699Skan		  || BARRIER_P (insn)
3485169699Skan		  || (NOTE_P (insn)
3486169699Skan		      && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK));
348790075Sobrien    }
348890075Sobrien
348918334Speter  PREV_INSN (before) = insn;
3490169699Skan  if (NONJUMP_INSN_P (before) && GET_CODE (PATTERN (before)) == SEQUENCE)
349118334Speter    PREV_INSN (XVECEXP (PATTERN (before), 0, 0)) = insn;
349218334Speter}
349318334Speter
349452284Sobrien/* Remove an insn from its doubly-linked list.  This function knows how
349552284Sobrien   to handle sequences.  */
349652284Sobrienvoid
3497132727Skanremove_insn (rtx insn)
349852284Sobrien{
349952284Sobrien  rtx next = NEXT_INSN (insn);
350052284Sobrien  rtx prev = PREV_INSN (insn);
350190075Sobrien  basic_block bb;
350290075Sobrien
350352284Sobrien  if (prev)
350452284Sobrien    {
350552284Sobrien      NEXT_INSN (prev) = next;
3506169699Skan      if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
350752284Sobrien	{
350852284Sobrien	  rtx sequence = PATTERN (prev);
350952284Sobrien	  NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next;
351052284Sobrien	}
351152284Sobrien    }
351252284Sobrien  else if (first_insn == insn)
351352284Sobrien    first_insn = next;
351452284Sobrien  else
351552284Sobrien    {
351690075Sobrien      struct sequence_stack *stack = seq_stack;
351752284Sobrien      /* Scan all pending sequences too.  */
351852284Sobrien      for (; stack; stack = stack->next)
351952284Sobrien	if (insn == stack->first)
352052284Sobrien	  {
352152284Sobrien	    stack->first = next;
352252284Sobrien	    break;
352352284Sobrien	  }
352452284Sobrien
3525169699Skan      gcc_assert (stack);
352652284Sobrien    }
352752284Sobrien
352852284Sobrien  if (next)
352952284Sobrien    {
353052284Sobrien      PREV_INSN (next) = prev;
3531169699Skan      if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
353252284Sobrien	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
353352284Sobrien    }
353452284Sobrien  else if (last_insn == insn)
353552284Sobrien    last_insn = prev;
353652284Sobrien  else
353752284Sobrien    {
353890075Sobrien      struct sequence_stack *stack = seq_stack;
353952284Sobrien      /* Scan all pending sequences too.  */
354052284Sobrien      for (; stack; stack = stack->next)
354152284Sobrien	if (insn == stack->last)
354252284Sobrien	  {
354352284Sobrien	    stack->last = prev;
354452284Sobrien	    break;
354552284Sobrien	  }
354652284Sobrien
3547169699Skan      gcc_assert (stack);
354852284Sobrien    }
3549169699Skan  if (!BARRIER_P (insn)
355090075Sobrien      && (bb = BLOCK_FOR_INSN (insn)))
355190075Sobrien    {
3552117404Skan      if (INSN_P (insn))
3553117404Skan	bb->flags |= BB_DIRTY;
3554132727Skan      if (BB_HEAD (bb) == insn)
355590075Sobrien	{
355696263Sobrien	  /* Never ever delete the basic block note without deleting whole
355796263Sobrien	     basic block.  */
3558169699Skan	  gcc_assert (!NOTE_P (insn));
3559132727Skan	  BB_HEAD (bb) = next;
356090075Sobrien	}
3561132727Skan      if (BB_END (bb) == insn)
3562132727Skan	BB_END (bb) = prev;
356390075Sobrien    }
356452284Sobrien}
356552284Sobrien
3566132727Skan/* Append CALL_FUSAGE to the CALL_INSN_FUNCTION_USAGE for CALL_INSN.  */
3567132727Skan
3568132727Skanvoid
3569132727Skanadd_function_usage_to (rtx call_insn, rtx call_fusage)
3570132727Skan{
3571169699Skan  gcc_assert (call_insn && CALL_P (call_insn));
3572132727Skan
3573132727Skan  /* Put the register usage information on the CALL.  If there is already
3574132727Skan     some usage information, put ours at the end.  */
3575132727Skan  if (CALL_INSN_FUNCTION_USAGE (call_insn))
3576132727Skan    {
3577132727Skan      rtx link;
3578132727Skan
3579132727Skan      for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
3580132727Skan	   link = XEXP (link, 1))
3581132727Skan	;
3582132727Skan
3583132727Skan      XEXP (link, 1) = call_fusage;
3584132727Skan    }
3585132727Skan  else
3586132727Skan    CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
3587132727Skan}
3588132727Skan
358918334Speter/* Delete all insns made since FROM.
359018334Speter   FROM becomes the new last instruction.  */
359118334Speter
359218334Spetervoid
3593132727Skandelete_insns_since (rtx from)
359418334Speter{
359518334Speter  if (from == 0)
359618334Speter    first_insn = 0;
359718334Speter  else
359818334Speter    NEXT_INSN (from) = 0;
359918334Speter  last_insn = from;
360018334Speter}
360118334Speter
360218334Speter/* This function is deprecated, please use sequences instead.
360318334Speter
360418334Speter   Move a consecutive bunch of insns to a different place in the chain.
360518334Speter   The insns to be moved are those between FROM and TO.
360618334Speter   They are moved to a new position after the insn AFTER.
360718334Speter   AFTER must not be FROM or TO or any insn in between.
360818334Speter
360918334Speter   This function does not know about SEQUENCEs and hence should not be
361018334Speter   called after delay-slot filling has been done.  */
361118334Speter
361218334Spetervoid
3613132727Skanreorder_insns_nobb (rtx from, rtx to, rtx after)
361418334Speter{
361518334Speter  /* Splice this bunch out of where it is now.  */
361618334Speter  if (PREV_INSN (from))
361718334Speter    NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);
361818334Speter  if (NEXT_INSN (to))
361918334Speter    PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);
362018334Speter  if (last_insn == to)
362118334Speter    last_insn = PREV_INSN (from);
362218334Speter  if (first_insn == from)
362318334Speter    first_insn = NEXT_INSN (to);
362418334Speter
362518334Speter  /* Make the new neighbors point to it and it to them.  */
362618334Speter  if (NEXT_INSN (after))
362718334Speter    PREV_INSN (NEXT_INSN (after)) = to;
362818334Speter
362918334Speter  NEXT_INSN (to) = NEXT_INSN (after);
363018334Speter  PREV_INSN (from) = after;
363118334Speter  NEXT_INSN (after) = from;
363218334Speter  if (after == last_insn)
363318334Speter    last_insn = to;
363418334Speter}
363518334Speter
363690075Sobrien/* Same as function above, but take care to update BB boundaries.  */
363790075Sobrienvoid
3638132727Skanreorder_insns (rtx from, rtx to, rtx after)
363990075Sobrien{
364090075Sobrien  rtx prev = PREV_INSN (from);
364190075Sobrien  basic_block bb, bb2;
364290075Sobrien
364390075Sobrien  reorder_insns_nobb (from, to, after);
364490075Sobrien
3645169699Skan  if (!BARRIER_P (after)
364690075Sobrien      && (bb = BLOCK_FOR_INSN (after)))
364790075Sobrien    {
364890075Sobrien      rtx x;
3649117404Skan      bb->flags |= BB_DIRTY;
3650117404Skan
3651169699Skan      if (!BARRIER_P (from)
365290075Sobrien	  && (bb2 = BLOCK_FOR_INSN (from)))
365390075Sobrien	{
3654132727Skan	  if (BB_END (bb2) == to)
3655132727Skan	    BB_END (bb2) = prev;
3656117404Skan	  bb2->flags |= BB_DIRTY;
365790075Sobrien	}
365890075Sobrien
3659132727Skan      if (BB_END (bb) == after)
3660132727Skan	BB_END (bb) = to;
366190075Sobrien
366290075Sobrien      for (x = from; x != NEXT_INSN (to); x = NEXT_INSN (x))
3663169699Skan	if (!BARRIER_P (x))
3664169699Skan	  set_block_for_insn (x, bb);
366590075Sobrien    }
366690075Sobrien}
366790075Sobrien
366818334Speter/* Return the line note insn preceding INSN.  */
366918334Speter
367018334Speterstatic rtx
3671132727Skanfind_line_note (rtx insn)
367218334Speter{
367318334Speter  if (no_line_numbers)
367418334Speter    return 0;
367518334Speter
367618334Speter  for (; insn; insn = PREV_INSN (insn))
3677169699Skan    if (NOTE_P (insn)
3678117404Skan	&& NOTE_LINE_NUMBER (insn) >= 0)
367918334Speter      break;
368018334Speter
368118334Speter  return insn;
368218334Speter}
368318334Speter
368418334Speter
3685117404Skan/* Emit insn(s) of given code and pattern
3686117404Skan   at a specified place within the doubly-linked list.
368718334Speter
3688117404Skan   All of the emit_foo global entry points accept an object
3689117404Skan   X which is either an insn list or a PATTERN of a single
3690117404Skan   instruction.
369118334Speter
3692117404Skan   There are thus a few canonical ways to generate code and
3693117404Skan   emit it at a specific place in the instruction stream.  For
3694117404Skan   example, consider the instruction named SPOT and the fact that
3695117404Skan   we would like to emit some instructions before SPOT.  We might
3696117404Skan   do it like this:
3697117404Skan
3698117404Skan	start_sequence ();
3699117404Skan	... emit the new instructions ...
3700117404Skan	insns_head = get_insns ();
3701117404Skan	end_sequence ();
3702117404Skan
3703117404Skan	emit_insn_before (insns_head, SPOT);
3704117404Skan
3705117404Skan   It used to be common to generate SEQUENCE rtl instead, but that
3706117404Skan   is a relic of the past which no longer occurs.  The reason is that
3707117404Skan   SEQUENCE rtl results in much fragmented RTL memory since the SEQUENCE
3708117404Skan   generated would almost certainly die right after it was created.  */
3709117404Skan
3710117404Skan/* Make X be output before the instruction BEFORE.  */
3711117404Skan
371218334Speterrtx
3713132727Skanemit_insn_before_noloc (rtx x, rtx before)
371418334Speter{
3715117404Skan  rtx last = before;
3716117404Skan  rtx insn;
371718334Speter
3718169699Skan  gcc_assert (before);
3719117404Skan
3720117404Skan  if (x == NULL_RTX)
3721117404Skan    return last;
3722117404Skan
3723117404Skan  switch (GET_CODE (x))
372418334Speter    {
3725117404Skan    case INSN:
3726117404Skan    case JUMP_INSN:
3727117404Skan    case CALL_INSN:
3728117404Skan    case CODE_LABEL:
3729117404Skan    case BARRIER:
3730117404Skan    case NOTE:
3731117404Skan      insn = x;
3732117404Skan      while (insn)
373318334Speter	{
3734117404Skan	  rtx next = NEXT_INSN (insn);
373518334Speter	  add_insn_before (insn, before);
3736117404Skan	  last = insn;
3737117404Skan	  insn = next;
373818334Speter	}
3739117404Skan      break;
3740117404Skan
3741117404Skan#ifdef ENABLE_RTL_CHECKING
3742117404Skan    case SEQUENCE:
3743169699Skan      gcc_unreachable ();
3744117404Skan      break;
3745117404Skan#endif
3746117404Skan
3747117404Skan    default:
3748117404Skan      last = make_insn_raw (x);
3749117404Skan      add_insn_before (last, before);
3750117404Skan      break;
375118334Speter    }
375218334Speter
3753117404Skan  return last;
375418334Speter}
375518334Speter
3756117404Skan/* Make an instruction with body X and code JUMP_INSN
375718334Speter   and output it before the instruction BEFORE.  */
375818334Speter
375918334Speterrtx
3760132727Skanemit_jump_insn_before_noloc (rtx x, rtx before)
376118334Speter{
3762117404Skan  rtx insn, last = NULL_RTX;
376318334Speter
3764169699Skan  gcc_assert (before);
3765117404Skan
3766117404Skan  switch (GET_CODE (x))
376718334Speter    {
3768117404Skan    case INSN:
3769117404Skan    case JUMP_INSN:
3770117404Skan    case CALL_INSN:
3771117404Skan    case CODE_LABEL:
3772117404Skan    case BARRIER:
3773117404Skan    case NOTE:
3774117404Skan      insn = x;
3775117404Skan      while (insn)
3776117404Skan	{
3777117404Skan	  rtx next = NEXT_INSN (insn);
3778117404Skan	  add_insn_before (insn, before);
3779117404Skan	  last = insn;
3780117404Skan	  insn = next;
3781117404Skan	}
3782117404Skan      break;
3783117404Skan
3784117404Skan#ifdef ENABLE_RTL_CHECKING
3785117404Skan    case SEQUENCE:
3786169699Skan      gcc_unreachable ();
3787117404Skan      break;
3788117404Skan#endif
3789117404Skan
3790117404Skan    default:
3791117404Skan      last = make_jump_insn_raw (x);
3792117404Skan      add_insn_before (last, before);
3793117404Skan      break;
379418334Speter    }
379518334Speter
3796117404Skan  return last;
379718334Speter}
379818334Speter
3799117404Skan/* Make an instruction with body X and code CALL_INSN
380018334Speter   and output it before the instruction BEFORE.  */
380118334Speter
380218334Speterrtx
3803132727Skanemit_call_insn_before_noloc (rtx x, rtx before)
380418334Speter{
3805117404Skan  rtx last = NULL_RTX, insn;
380618334Speter
3807169699Skan  gcc_assert (before);
3808117404Skan
3809117404Skan  switch (GET_CODE (x))
381018334Speter    {
3811117404Skan    case INSN:
3812117404Skan    case JUMP_INSN:
3813117404Skan    case CALL_INSN:
3814117404Skan    case CODE_LABEL:
3815117404Skan    case BARRIER:
3816117404Skan    case NOTE:
3817117404Skan      insn = x;
3818117404Skan      while (insn)
3819117404Skan	{
3820117404Skan	  rtx next = NEXT_INSN (insn);
3821117404Skan	  add_insn_before (insn, before);
3822117404Skan	  last = insn;
3823117404Skan	  insn = next;
3824117404Skan	}
3825117404Skan      break;
3826117404Skan
3827117404Skan#ifdef ENABLE_RTL_CHECKING
3828117404Skan    case SEQUENCE:
3829169699Skan      gcc_unreachable ();
3830117404Skan      break;
3831117404Skan#endif
3832117404Skan
3833117404Skan    default:
3834117404Skan      last = make_call_insn_raw (x);
3835117404Skan      add_insn_before (last, before);
3836117404Skan      break;
383718334Speter    }
383818334Speter
3839117404Skan  return last;
384018334Speter}
384118334Speter
384218334Speter/* Make an insn of code BARRIER
384352284Sobrien   and output it before the insn BEFORE.  */
384418334Speter
384518334Speterrtx
3846132727Skanemit_barrier_before (rtx before)
384718334Speter{
384890075Sobrien  rtx insn = rtx_alloc (BARRIER);
384918334Speter
385018334Speter  INSN_UID (insn) = cur_insn_uid++;
385118334Speter
385218334Speter  add_insn_before (insn, before);
385318334Speter  return insn;
385418334Speter}
385518334Speter
385652284Sobrien/* Emit the label LABEL before the insn BEFORE.  */
385752284Sobrien
385852284Sobrienrtx
3859132727Skanemit_label_before (rtx label, rtx before)
386052284Sobrien{
386152284Sobrien  /* This can be called twice for the same label as a result of the
386252284Sobrien     confusion that follows a syntax error!  So make it harmless.  */
386352284Sobrien  if (INSN_UID (label) == 0)
386452284Sobrien    {
386552284Sobrien      INSN_UID (label) = cur_insn_uid++;
386652284Sobrien      add_insn_before (label, before);
386752284Sobrien    }
386852284Sobrien
386952284Sobrien  return label;
387052284Sobrien}
387152284Sobrien
387218334Speter/* Emit a note of subtype SUBTYPE before the insn BEFORE.  */
387318334Speter
387418334Speterrtx
3875132727Skanemit_note_before (int subtype, rtx before)
387618334Speter{
387790075Sobrien  rtx note = rtx_alloc (NOTE);
387818334Speter  INSN_UID (note) = cur_insn_uid++;
3879169699Skan#ifndef USE_MAPPED_LOCATION
388018334Speter  NOTE_SOURCE_FILE (note) = 0;
3881169699Skan#endif
388218334Speter  NOTE_LINE_NUMBER (note) = subtype;
3883117404Skan  BLOCK_FOR_INSN (note) = NULL;
388418334Speter
388518334Speter  add_insn_before (note, before);
388618334Speter  return note;
388718334Speter}
388818334Speter
3889117404Skan/* Helper for emit_insn_after, handles lists of instructions
3890117404Skan   efficiently.  */
389118334Speter
3892132727Skanstatic rtx emit_insn_after_1 (rtx, rtx);
3893117404Skan
3894117404Skanstatic rtx
3895132727Skanemit_insn_after_1 (rtx first, rtx after)
389618334Speter{
3897117404Skan  rtx last;
3898117404Skan  rtx after_after;
3899117404Skan  basic_block bb;
390018334Speter
3901169699Skan  if (!BARRIER_P (after)
3902117404Skan      && (bb = BLOCK_FOR_INSN (after)))
390318334Speter    {
3904117404Skan      bb->flags |= BB_DIRTY;
3905117404Skan      for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
3906169699Skan	if (!BARRIER_P (last))
3907117404Skan	  set_block_for_insn (last, bb);
3908169699Skan      if (!BARRIER_P (last))
3909117404Skan	set_block_for_insn (last, bb);
3910132727Skan      if (BB_END (bb) == after)
3911132727Skan	BB_END (bb) = last;
391218334Speter    }
391318334Speter  else
3914117404Skan    for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
3915117404Skan      continue;
3916117404Skan
3917117404Skan  after_after = NEXT_INSN (after);
3918117404Skan
3919117404Skan  NEXT_INSN (after) = first;
3920117404Skan  PREV_INSN (first) = after;
3921117404Skan  NEXT_INSN (last) = after_after;
3922117404Skan  if (after_after)
3923117404Skan    PREV_INSN (after_after) = last;
3924117404Skan
3925117404Skan  if (after == last_insn)
3926117404Skan    last_insn = last;
3927117404Skan  return last;
3928117404Skan}
3929117404Skan
3930117404Skan/* Make X be output after the insn AFTER.  */
3931117404Skan
3932117404Skanrtx
3933132727Skanemit_insn_after_noloc (rtx x, rtx after)
3934117404Skan{
3935117404Skan  rtx last = after;
3936117404Skan
3937169699Skan  gcc_assert (after);
3938117404Skan
3939117404Skan  if (x == NULL_RTX)
3940117404Skan    return last;
3941117404Skan
3942117404Skan  switch (GET_CODE (x))
394318334Speter    {
3944117404Skan    case INSN:
3945117404Skan    case JUMP_INSN:
3946117404Skan    case CALL_INSN:
3947117404Skan    case CODE_LABEL:
3948117404Skan    case BARRIER:
3949117404Skan    case NOTE:
3950117404Skan      last = emit_insn_after_1 (x, after);
3951117404Skan      break;
3952117404Skan
3953117404Skan#ifdef ENABLE_RTL_CHECKING
3954117404Skan    case SEQUENCE:
3955169699Skan      gcc_unreachable ();
3956117404Skan      break;
3957117404Skan#endif
3958117404Skan
3959117404Skan    default:
3960117404Skan      last = make_insn_raw (x);
3961117404Skan      add_insn_after (last, after);
3962117404Skan      break;
396318334Speter    }
396418334Speter
3965117404Skan  return last;
396618334Speter}
396718334Speter
396818334Speter/* Similar to emit_insn_after, except that line notes are to be inserted so
396918334Speter   as to act as if this insn were at FROM.  */
397018334Speter
397118334Spetervoid
3972132727Skanemit_insn_after_with_line_notes (rtx x, rtx after, rtx from)
397318334Speter{
397418334Speter  rtx from_line = find_line_note (from);
397518334Speter  rtx after_line = find_line_note (after);
3976117404Skan  rtx insn = emit_insn_after (x, after);
397718334Speter
397818334Speter  if (from_line)
3979132727Skan    emit_note_copy_after (from_line, after);
398018334Speter
398118334Speter  if (after_line)
3982132727Skan    emit_note_copy_after (after_line, insn);
398318334Speter}
398418334Speter
3985117404Skan/* Make an insn of code JUMP_INSN with body X
398618334Speter   and output it after the insn AFTER.  */
398718334Speter
398818334Speterrtx
3989132727Skanemit_jump_insn_after_noloc (rtx x, rtx after)
399018334Speter{
3991117404Skan  rtx last;
399218334Speter
3993169699Skan  gcc_assert (after);
3994117404Skan
3995117404Skan  switch (GET_CODE (x))
399618334Speter    {
3997117404Skan    case INSN:
3998117404Skan    case JUMP_INSN:
3999117404Skan    case CALL_INSN:
4000117404Skan    case CODE_LABEL:
4001117404Skan    case BARRIER:
4002117404Skan    case NOTE:
4003117404Skan      last = emit_insn_after_1 (x, after);
4004117404Skan      break;
4005117404Skan
4006117404Skan#ifdef ENABLE_RTL_CHECKING
4007117404Skan    case SEQUENCE:
4008169699Skan      gcc_unreachable ();
4009117404Skan      break;
4010117404Skan#endif
4011117404Skan
4012117404Skan    default:
4013117404Skan      last = make_jump_insn_raw (x);
4014117404Skan      add_insn_after (last, after);
4015117404Skan      break;
401618334Speter    }
401718334Speter
4018117404Skan  return last;
401918334Speter}
402018334Speter
4021117404Skan/* Make an instruction with body X and code CALL_INSN
4022117404Skan   and output it after the instruction AFTER.  */
4023117404Skan
4024117404Skanrtx
4025132727Skanemit_call_insn_after_noloc (rtx x, rtx after)
4026117404Skan{
4027117404Skan  rtx last;
4028117404Skan
4029169699Skan  gcc_assert (after);
4030117404Skan
4031117404Skan  switch (GET_CODE (x))
4032117404Skan    {
4033117404Skan    case INSN:
4034117404Skan    case JUMP_INSN:
4035117404Skan    case CALL_INSN:
4036117404Skan    case CODE_LABEL:
4037117404Skan    case BARRIER:
4038117404Skan    case NOTE:
4039117404Skan      last = emit_insn_after_1 (x, after);
4040117404Skan      break;
4041117404Skan
4042117404Skan#ifdef ENABLE_RTL_CHECKING
4043117404Skan    case SEQUENCE:
4044169699Skan      gcc_unreachable ();
4045117404Skan      break;
4046117404Skan#endif
4047117404Skan
4048117404Skan    default:
4049117404Skan      last = make_call_insn_raw (x);
4050117404Skan      add_insn_after (last, after);
4051117404Skan      break;
4052117404Skan    }
4053117404Skan
4054117404Skan  return last;
4055117404Skan}
4056117404Skan
405718334Speter/* Make an insn of code BARRIER
405818334Speter   and output it after the insn AFTER.  */
405918334Speter
406018334Speterrtx
4061132727Skanemit_barrier_after (rtx after)
406218334Speter{
406390075Sobrien  rtx insn = rtx_alloc (BARRIER);
406418334Speter
406518334Speter  INSN_UID (insn) = cur_insn_uid++;
406618334Speter
406718334Speter  add_insn_after (insn, after);
406818334Speter  return insn;
406918334Speter}
407018334Speter
407118334Speter/* Emit the label LABEL after the insn AFTER.  */
407218334Speter
407318334Speterrtx
4074132727Skanemit_label_after (rtx label, rtx after)
407518334Speter{
407618334Speter  /* This can be called twice for the same label
407718334Speter     as a result of the confusion that follows a syntax error!
407818334Speter     So make it harmless.  */
407918334Speter  if (INSN_UID (label) == 0)
408018334Speter    {
408118334Speter      INSN_UID (label) = cur_insn_uid++;
408218334Speter      add_insn_after (label, after);
408318334Speter    }
408418334Speter
408518334Speter  return label;
408618334Speter}
408718334Speter
408818334Speter/* Emit a note of subtype SUBTYPE after the insn AFTER.  */
408918334Speter
409018334Speterrtx
4091132727Skanemit_note_after (int subtype, rtx after)
409218334Speter{
409390075Sobrien  rtx note = rtx_alloc (NOTE);
409418334Speter  INSN_UID (note) = cur_insn_uid++;
4095169699Skan#ifndef USE_MAPPED_LOCATION
409618334Speter  NOTE_SOURCE_FILE (note) = 0;
4097169699Skan#endif
409818334Speter  NOTE_LINE_NUMBER (note) = subtype;
4099117404Skan  BLOCK_FOR_INSN (note) = NULL;
410018334Speter  add_insn_after (note, after);
410118334Speter  return note;
410218334Speter}
410318334Speter
4104132727Skan/* Emit a copy of note ORIG after the insn AFTER.  */
410518334Speter
410618334Speterrtx
4107132727Skanemit_note_copy_after (rtx orig, rtx after)
410818334Speter{
410990075Sobrien  rtx note;
411018334Speter
4111132727Skan  if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
411218334Speter    {
411318334Speter      cur_insn_uid++;
411418334Speter      return 0;
411518334Speter    }
411618334Speter
4117117404Skan  note = rtx_alloc (NOTE);
411818334Speter  INSN_UID (note) = cur_insn_uid++;
4119132727Skan  NOTE_LINE_NUMBER (note) = NOTE_LINE_NUMBER (orig);
4120132727Skan  NOTE_DATA (note) = NOTE_DATA (orig);
4121117404Skan  BLOCK_FOR_INSN (note) = NULL;
412218334Speter  add_insn_after (note, after);
412318334Speter  return note;
412418334Speter}
412518334Speter
4126132727Skan/* Like emit_insn_after_noloc, but set INSN_LOCATOR according to SCOPE.  */
4127117404Skanrtx
4128132727Skanemit_insn_after_setloc (rtx pattern, rtx after, int loc)
4129117404Skan{
4130132727Skan  rtx last = emit_insn_after_noloc (pattern, after);
413118334Speter
4132132727Skan  if (pattern == NULL_RTX || !loc)
4133132727Skan    return last;
4134132727Skan
4135117404Skan  after = NEXT_INSN (after);
4136117404Skan  while (1)
4137117404Skan    {
4138132727Skan      if (active_insn_p (after) && !INSN_LOCATOR (after))
4139132727Skan	INSN_LOCATOR (after) = loc;
4140117404Skan      if (after == last)
4141117404Skan	break;
4142117404Skan      after = NEXT_INSN (after);
4143117404Skan    }
4144117404Skan  return last;
4145117404Skan}
414618334Speter
4147132727Skan/* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
414818334Speterrtx
4149132727Skanemit_insn_after (rtx pattern, rtx after)
415018334Speter{
4151132727Skan  if (INSN_P (after))
4152132727Skan    return emit_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
4153132727Skan  else
4154132727Skan    return emit_insn_after_noloc (pattern, after);
4155132727Skan}
415618334Speter
4157132727Skan/* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to SCOPE.  */
4158132727Skanrtx
4159132727Skanemit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
4160132727Skan{
4161132727Skan  rtx last = emit_jump_insn_after_noloc (pattern, after);
4162132727Skan
4163132727Skan  if (pattern == NULL_RTX || !loc)
4164132727Skan    return last;
4165132727Skan
4166117404Skan  after = NEXT_INSN (after);
4167117404Skan  while (1)
416818334Speter    {
4169132727Skan      if (active_insn_p (after) && !INSN_LOCATOR (after))
4170132727Skan	INSN_LOCATOR (after) = loc;
4171117404Skan      if (after == last)
4172117404Skan	break;
4173117404Skan      after = NEXT_INSN (after);
417418334Speter    }
4175117404Skan  return last;
417618334Speter}
417718334Speter
4178132727Skan/* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
417918334Speterrtx
4180132727Skanemit_jump_insn_after (rtx pattern, rtx after)
418118334Speter{
4182132727Skan  if (INSN_P (after))
4183132727Skan    return emit_jump_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
4184132727Skan  else
4185132727Skan    return emit_jump_insn_after_noloc (pattern, after);
4186132727Skan}
418718334Speter
4188132727Skan/* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to SCOPE.  */
4189132727Skanrtx
4190132727Skanemit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
4191132727Skan{
4192132727Skan  rtx last = emit_call_insn_after_noloc (pattern, after);
4193132727Skan
4194132727Skan  if (pattern == NULL_RTX || !loc)
4195132727Skan    return last;
4196132727Skan
4197117404Skan  after = NEXT_INSN (after);
4198117404Skan  while (1)
419918334Speter    {
4200132727Skan      if (active_insn_p (after) && !INSN_LOCATOR (after))
4201132727Skan	INSN_LOCATOR (after) = loc;
4202117404Skan      if (after == last)
4203117404Skan	break;
4204117404Skan      after = NEXT_INSN (after);
420518334Speter    }
420618334Speter  return last;
420718334Speter}
420818334Speter
4209132727Skan/* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
421018334Speterrtx
4211132727Skanemit_call_insn_after (rtx pattern, rtx after)
421218334Speter{
4213132727Skan  if (INSN_P (after))
4214132727Skan    return emit_call_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
4215132727Skan  else
4216132727Skan    return emit_call_insn_after_noloc (pattern, after);
4217132727Skan}
4218132727Skan
4219132727Skan/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to SCOPE.  */
4220132727Skanrtx
4221132727Skanemit_insn_before_setloc (rtx pattern, rtx before, int loc)
4222132727Skan{
4223117404Skan  rtx first = PREV_INSN (before);
4224132727Skan  rtx last = emit_insn_before_noloc (pattern, before);
422518334Speter
4226132727Skan  if (pattern == NULL_RTX || !loc)
4227132727Skan    return last;
4228132727Skan
4229117404Skan  first = NEXT_INSN (first);
4230117404Skan  while (1)
423118334Speter    {
4232132727Skan      if (active_insn_p (first) && !INSN_LOCATOR (first))
4233132727Skan	INSN_LOCATOR (first) = loc;
4234117404Skan      if (first == last)
4235117404Skan	break;
4236117404Skan      first = NEXT_INSN (first);
423718334Speter    }
423818334Speter  return last;
423918334Speter}
4240132727Skan
4241132727Skan/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
4242132727Skanrtx
4243132727Skanemit_insn_before (rtx pattern, rtx before)
4244132727Skan{
4245132727Skan  if (INSN_P (before))
4246132727Skan    return emit_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
4247132727Skan  else
4248132727Skan    return emit_insn_before_noloc (pattern, before);
4249132727Skan}
4250132727Skan
4251132727Skan/* like emit_insn_before_noloc, but set insn_locator according to scope.  */
4252132727Skanrtx
4253132727Skanemit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
4254132727Skan{
4255132727Skan  rtx first = PREV_INSN (before);
4256132727Skan  rtx last = emit_jump_insn_before_noloc (pattern, before);
4257132727Skan
4258132727Skan  if (pattern == NULL_RTX)
4259132727Skan    return last;
4260132727Skan
4261132727Skan  first = NEXT_INSN (first);
4262132727Skan  while (1)
4263132727Skan    {
4264132727Skan      if (active_insn_p (first) && !INSN_LOCATOR (first))
4265132727Skan	INSN_LOCATOR (first) = loc;
4266132727Skan      if (first == last)
4267132727Skan	break;
4268132727Skan      first = NEXT_INSN (first);
4269132727Skan    }
4270132727Skan  return last;
4271132727Skan}
4272132727Skan
4273132727Skan/* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
4274132727Skanrtx
4275132727Skanemit_jump_insn_before (rtx pattern, rtx before)
4276132727Skan{
4277132727Skan  if (INSN_P (before))
4278132727Skan    return emit_jump_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
4279132727Skan  else
4280132727Skan    return emit_jump_insn_before_noloc (pattern, before);
4281132727Skan}
4282132727Skan
4283132727Skan/* like emit_insn_before_noloc, but set insn_locator according to scope.  */
4284132727Skanrtx
4285132727Skanemit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
4286132727Skan{
4287132727Skan  rtx first = PREV_INSN (before);
4288132727Skan  rtx last = emit_call_insn_before_noloc (pattern, before);
4289132727Skan
4290132727Skan  if (pattern == NULL_RTX)
4291132727Skan    return last;
4292132727Skan
4293132727Skan  first = NEXT_INSN (first);
4294132727Skan  while (1)
4295132727Skan    {
4296132727Skan      if (active_insn_p (first) && !INSN_LOCATOR (first))
4297132727Skan	INSN_LOCATOR (first) = loc;
4298132727Skan      if (first == last)
4299132727Skan	break;
4300132727Skan      first = NEXT_INSN (first);
4301132727Skan    }
4302132727Skan  return last;
4303132727Skan}
4304132727Skan
4305132727Skan/* like emit_call_insn_before_noloc,
4306132727Skan   but set insn_locator according to before.  */
4307132727Skanrtx
4308132727Skanemit_call_insn_before (rtx pattern, rtx before)
4309132727Skan{
4310132727Skan  if (INSN_P (before))
4311132727Skan    return emit_call_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
4312132727Skan  else
4313132727Skan    return emit_call_insn_before_noloc (pattern, before);
4314132727Skan}
4315117404Skan
4316117404Skan/* Take X and emit it at the end of the doubly-linked
4317117404Skan   INSN list.
431818334Speter
4319117404Skan   Returns the last insn emitted.  */
432018334Speter
432118334Speterrtx
4322132727Skanemit_insn (rtx x)
432318334Speter{
4324117404Skan  rtx last = last_insn;
4325117404Skan  rtx insn;
432618334Speter
4327117404Skan  if (x == NULL_RTX)
4328117404Skan    return last;
432918334Speter
4330117404Skan  switch (GET_CODE (x))
433190075Sobrien    {
4332117404Skan    case INSN:
4333117404Skan    case JUMP_INSN:
4334117404Skan    case CALL_INSN:
4335117404Skan    case CODE_LABEL:
4336117404Skan    case BARRIER:
4337117404Skan    case NOTE:
4338117404Skan      insn = x;
4339117404Skan      while (insn)
4340117404Skan	{
4341117404Skan	  rtx next = NEXT_INSN (insn);
4342117404Skan	  add_insn (insn);
4343117404Skan	  last = insn;
4344117404Skan	  insn = next;
4345117404Skan	}
4346117404Skan      break;
434718334Speter
4348117404Skan#ifdef ENABLE_RTL_CHECKING
4349117404Skan    case SEQUENCE:
4350169699Skan      gcc_unreachable ();
4351117404Skan      break;
4352117404Skan#endif
435318334Speter
4354117404Skan    default:
4355117404Skan      last = make_insn_raw (x);
4356117404Skan      add_insn (last);
4357117404Skan      break;
4358117404Skan    }
435918334Speter
436018334Speter  return last;
436118334Speter}
436218334Speter
4363117404Skan/* Make an insn of code JUMP_INSN with pattern X
436418334Speter   and add it to the end of the doubly-linked list.  */
436518334Speter
436618334Speterrtx
4367132727Skanemit_jump_insn (rtx x)
436818334Speter{
4369117404Skan  rtx last = NULL_RTX, insn;
4370117404Skan
4371117404Skan  switch (GET_CODE (x))
437218334Speter    {
4373117404Skan    case INSN:
4374117404Skan    case JUMP_INSN:
4375117404Skan    case CALL_INSN:
4376117404Skan    case CODE_LABEL:
4377117404Skan    case BARRIER:
4378117404Skan    case NOTE:
4379117404Skan      insn = x;
4380117404Skan      while (insn)
4381117404Skan	{
4382117404Skan	  rtx next = NEXT_INSN (insn);
4383117404Skan	  add_insn (insn);
4384117404Skan	  last = insn;
4385117404Skan	  insn = next;
4386117404Skan	}
4387117404Skan      break;
4388117404Skan
4389117404Skan#ifdef ENABLE_RTL_CHECKING
4390117404Skan    case SEQUENCE:
4391169699Skan      gcc_unreachable ();
4392117404Skan      break;
4393117404Skan#endif
4394117404Skan
4395117404Skan    default:
4396117404Skan      last = make_jump_insn_raw (x);
4397117404Skan      add_insn (last);
4398117404Skan      break;
439918334Speter    }
4400117404Skan
4401117404Skan  return last;
440218334Speter}
440318334Speter
4404117404Skan/* Make an insn of code CALL_INSN with pattern X
440518334Speter   and add it to the end of the doubly-linked list.  */
440618334Speter
440718334Speterrtx
4408132727Skanemit_call_insn (rtx x)
440918334Speter{
4410117404Skan  rtx insn;
4411117404Skan
4412117404Skan  switch (GET_CODE (x))
441318334Speter    {
4414117404Skan    case INSN:
4415117404Skan    case JUMP_INSN:
4416117404Skan    case CALL_INSN:
4417117404Skan    case CODE_LABEL:
4418117404Skan    case BARRIER:
4419117404Skan    case NOTE:
4420117404Skan      insn = emit_insn (x);
4421117404Skan      break;
4422117404Skan
4423117404Skan#ifdef ENABLE_RTL_CHECKING
4424117404Skan    case SEQUENCE:
4425169699Skan      gcc_unreachable ();
4426117404Skan      break;
4427117404Skan#endif
4428117404Skan
4429117404Skan    default:
4430117404Skan      insn = make_call_insn_raw (x);
443118334Speter      add_insn (insn);
4432117404Skan      break;
443318334Speter    }
4434117404Skan
4435117404Skan  return insn;
443618334Speter}
443718334Speter
443818334Speter/* Add the label LABEL to the end of the doubly-linked list.  */
443918334Speter
444018334Speterrtx
4441132727Skanemit_label (rtx label)
444218334Speter{
444318334Speter  /* This can be called twice for the same label
444418334Speter     as a result of the confusion that follows a syntax error!
444518334Speter     So make it harmless.  */
444618334Speter  if (INSN_UID (label) == 0)
444718334Speter    {
444818334Speter      INSN_UID (label) = cur_insn_uid++;
444918334Speter      add_insn (label);
445018334Speter    }
445118334Speter  return label;
445218334Speter}
445318334Speter
445418334Speter/* Make an insn of code BARRIER
445518334Speter   and add it to the end of the doubly-linked list.  */
445618334Speter
445718334Speterrtx
4458132727Skanemit_barrier (void)
445918334Speter{
446090075Sobrien  rtx barrier = rtx_alloc (BARRIER);
446118334Speter  INSN_UID (barrier) = cur_insn_uid++;
446218334Speter  add_insn (barrier);
446318334Speter  return barrier;
446418334Speter}
446518334Speter
4466132727Skan/* Make line numbering NOTE insn for LOCATION add it to the end
4467132727Skan   of the doubly-linked list, but only if line-numbers are desired for
4468132727Skan   debugging info and it doesn't match the previous one.  */
446918334Speter
447018334Speterrtx
4471132727Skanemit_line_note (location_t location)
447218334Speter{
4473132727Skan  rtx note;
4474132727Skan
4475169699Skan#ifdef USE_MAPPED_LOCATION
4476169699Skan  if (location == last_location)
4477169699Skan    return NULL_RTX;
4478169699Skan#else
4479132727Skan  if (location.file && last_location.file
4480132727Skan      && !strcmp (location.file, last_location.file)
4481132727Skan      && location.line == last_location.line)
4482132727Skan    return NULL_RTX;
4483169699Skan#endif
4484132727Skan  last_location = location;
4485132727Skan
448618334Speter  if (no_line_numbers)
4487132727Skan    {
4488132727Skan      cur_insn_uid++;
4489132727Skan      return NULL_RTX;
4490132727Skan    }
449118334Speter
4492169699Skan#ifdef USE_MAPPED_LOCATION
4493169699Skan  note = emit_note ((int) location);
4494169699Skan#else
4495132727Skan  note = emit_note (location.line);
4496132727Skan  NOTE_SOURCE_FILE (note) = location.file;
4497169699Skan#endif
4498132727Skan
4499132727Skan  return note;
450018334Speter}
450118334Speter
4502132727Skan/* Emit a copy of note ORIG.  */
450318334Speter
450418334Speterrtx
4505132727Skanemit_note_copy (rtx orig)
450618334Speter{
450790075Sobrien  rtx note;
4508132727Skan
4509132727Skan  if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
451018334Speter    {
451118334Speter      cur_insn_uid++;
4512132727Skan      return NULL_RTX;
451318334Speter    }
4514132727Skan
451518334Speter  note = rtx_alloc (NOTE);
4516132727Skan
451718334Speter  INSN_UID (note) = cur_insn_uid++;
4518132727Skan  NOTE_DATA (note) = NOTE_DATA (orig);
4519132727Skan  NOTE_LINE_NUMBER (note) = NOTE_LINE_NUMBER (orig);
4520117404Skan  BLOCK_FOR_INSN (note) = NULL;
452118334Speter  add_insn (note);
4522132727Skan
452318334Speter  return note;
452418334Speter}
452518334Speter
4526132727Skan/* Make an insn of code NOTE or type NOTE_NO
4527132727Skan   and add it to the end of the doubly-linked list.  */
452818334Speter
452918334Speterrtx
4530132727Skanemit_note (int note_no)
453118334Speter{
4532132727Skan  rtx note;
4533132727Skan
4534132727Skan  note = rtx_alloc (NOTE);
4535132727Skan  INSN_UID (note) = cur_insn_uid++;
4536132727Skan  NOTE_LINE_NUMBER (note) = note_no;
4537132727Skan  memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
4538132727Skan  BLOCK_FOR_INSN (note) = NULL;
4539132727Skan  add_insn (note);
4540132727Skan  return note;
454118334Speter}
454218334Speter
454318334Speter/* Cause next statement to emit a line note even if the line number
4544132727Skan   has not changed.  */
454518334Speter
454618334Spetervoid
4547132727Skanforce_next_line_note (void)
454818334Speter{
4549169699Skan#ifdef USE_MAPPED_LOCATION
4550169699Skan  last_location = -1;
4551169699Skan#else
4552132727Skan  last_location.line = -1;
4553169699Skan#endif
455418334Speter}
455552284Sobrien
455652284Sobrien/* Place a note of KIND on insn INSN with DATUM as the datum. If a
455790075Sobrien   note of this type already exists, remove it first.  */
455852284Sobrien
455990075Sobrienrtx
4560132727Skanset_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
456152284Sobrien{
456252284Sobrien  rtx note = find_reg_note (insn, kind, NULL_RTX);
456352284Sobrien
456490075Sobrien  switch (kind)
456590075Sobrien    {
456690075Sobrien    case REG_EQUAL:
456790075Sobrien    case REG_EQUIV:
456890075Sobrien      /* Don't add REG_EQUAL/REG_EQUIV notes if the insn
456990075Sobrien	 has multiple sets (some callers assume single_set
457090075Sobrien	 means the insn only has one set, when in fact it
457190075Sobrien	 means the insn only has one * useful * set).  */
457290075Sobrien      if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
457390075Sobrien	{
4574169699Skan	  gcc_assert (!note);
457590075Sobrien	  return NULL_RTX;
457690075Sobrien	}
457752284Sobrien
457890075Sobrien      /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
457990075Sobrien	 It serves no useful purpose and breaks eliminate_regs.  */
458090075Sobrien      if (GET_CODE (datum) == ASM_OPERANDS)
458190075Sobrien	return NULL_RTX;
458290075Sobrien      break;
458390075Sobrien
458490075Sobrien    default:
458590075Sobrien      break;
458690075Sobrien    }
458790075Sobrien
458890075Sobrien  if (note)
458990075Sobrien    {
459090075Sobrien      XEXP (note, 0) = datum;
459190075Sobrien      return note;
459290075Sobrien    }
459390075Sobrien
4594222207Sbenl  REG_NOTES (insn) = gen_rtx_EXPR_LIST ((enum machine_mode) kind, datum,
4595222207Sbenl					REG_NOTES (insn));
459690075Sobrien  return REG_NOTES (insn);
459752284Sobrien}
459818334Speter
459918334Speter/* Return an indication of which type of insn should have X as a body.
460018334Speter   The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN.  */
460118334Speter
4602169699Skanstatic enum rtx_code
4603132727Skanclassify_insn (rtx x)
460418334Speter{
4605169699Skan  if (LABEL_P (x))
460618334Speter    return CODE_LABEL;
460718334Speter  if (GET_CODE (x) == CALL)
460818334Speter    return CALL_INSN;
460918334Speter  if (GET_CODE (x) == RETURN)
461018334Speter    return JUMP_INSN;
461118334Speter  if (GET_CODE (x) == SET)
461218334Speter    {
461318334Speter      if (SET_DEST (x) == pc_rtx)
461418334Speter	return JUMP_INSN;
461518334Speter      else if (GET_CODE (SET_SRC (x)) == CALL)
461618334Speter	return CALL_INSN;
461718334Speter      else
461818334Speter	return INSN;
461918334Speter    }
462018334Speter  if (GET_CODE (x) == PARALLEL)
462118334Speter    {
462290075Sobrien      int j;
462318334Speter      for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
462418334Speter	if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
462518334Speter	  return CALL_INSN;
462618334Speter	else if (GET_CODE (XVECEXP (x, 0, j)) == SET
462718334Speter		 && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx)
462818334Speter	  return JUMP_INSN;
462918334Speter	else if (GET_CODE (XVECEXP (x, 0, j)) == SET
463018334Speter		 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
463118334Speter	  return CALL_INSN;
463218334Speter    }
463318334Speter  return INSN;
463418334Speter}
463518334Speter
463618334Speter/* Emit the rtl pattern X as an appropriate kind of insn.
463718334Speter   If X is a label, it is simply added into the insn chain.  */
463818334Speter
463918334Speterrtx
4640132727Skanemit (rtx x)
464118334Speter{
464218334Speter  enum rtx_code code = classify_insn (x);
464318334Speter
4644169699Skan  switch (code)
464518334Speter    {
4646169699Skan    case CODE_LABEL:
4647169699Skan      return emit_label (x);
4648169699Skan    case INSN:
4649169699Skan      return emit_insn (x);
4650169699Skan    case  JUMP_INSN:
4651169699Skan      {
4652169699Skan	rtx insn = emit_jump_insn (x);
4653169699Skan	if (any_uncondjump_p (insn) || GET_CODE (x) == RETURN)
4654169699Skan	  return emit_barrier ();
4655169699Skan	return insn;
4656169699Skan      }
4657169699Skan    case CALL_INSN:
4658169699Skan      return emit_call_insn (x);
4659169699Skan    default:
4660169699Skan      gcc_unreachable ();
466118334Speter    }
466218334Speter}
466318334Speter
4664117404Skan/* Space for free sequence stack entries.  */
4665169699Skanstatic GTY ((deletable)) struct sequence_stack *free_sequence_stack;
4666117404Skan
4667169699Skan/* Begin emitting insns to a sequence.  If this sequence will contain
4668169699Skan   something that might cause the compiler to pop arguments to function
4669169699Skan   calls (because those pops have previously been deferred; see
4670169699Skan   INHIBIT_DEFER_POP for more details), use do_pending_stack_adjust
4671169699Skan   before calling this function.  That will ensure that the deferred
4672169699Skan   pops are not accidentally emitted in the middle of this sequence.  */
467318334Speter
467418334Spetervoid
4675132727Skanstart_sequence (void)
467618334Speter{
467718334Speter  struct sequence_stack *tem;
467818334Speter
4679117404Skan  if (free_sequence_stack != NULL)
4680117404Skan    {
4681117404Skan      tem = free_sequence_stack;
4682117404Skan      free_sequence_stack = tem->next;
4683117404Skan    }
4684117404Skan  else
4685132727Skan    tem = ggc_alloc (sizeof (struct sequence_stack));
468618334Speter
468790075Sobrien  tem->next = seq_stack;
468818334Speter  tem->first = first_insn;
468918334Speter  tem->last = last_insn;
469018334Speter
469190075Sobrien  seq_stack = tem;
469218334Speter
469318334Speter  first_insn = 0;
469418334Speter  last_insn = 0;
469518334Speter}
469618334Speter
469752284Sobrien/* Set up the insn chain starting with FIRST as the current sequence,
469852284Sobrien   saving the previously current one.  See the documentation for
469952284Sobrien   start_sequence for more information about how to use this function.  */
470018334Speter
470118334Spetervoid
4702132727Skanpush_to_sequence (rtx first)
470318334Speter{
470418334Speter  rtx last;
470518334Speter
470618334Speter  start_sequence ();
470718334Speter
470818334Speter  for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last));
470918334Speter
471018334Speter  first_insn = first;
471118334Speter  last_insn = last;
471218334Speter}
471318334Speter
471418334Speter/* Set up the outer-level insn chain
471518334Speter   as the current sequence, saving the previously current one.  */
471618334Speter
471718334Spetervoid
4718132727Skanpush_topmost_sequence (void)
471918334Speter{
472050397Sobrien  struct sequence_stack *stack, *top = NULL;
472118334Speter
472218334Speter  start_sequence ();
472318334Speter
472490075Sobrien  for (stack = seq_stack; stack; stack = stack->next)
472518334Speter    top = stack;
472618334Speter
472718334Speter  first_insn = top->first;
472818334Speter  last_insn = top->last;
472918334Speter}
473018334Speter
473118334Speter/* After emitting to the outer-level insn chain, update the outer-level
473218334Speter   insn chain, and restore the previous saved state.  */
473318334Speter
473418334Spetervoid
4735132727Skanpop_topmost_sequence (void)
473618334Speter{
473750397Sobrien  struct sequence_stack *stack, *top = NULL;
473818334Speter
473990075Sobrien  for (stack = seq_stack; stack; stack = stack->next)
474018334Speter    top = stack;
474118334Speter
474218334Speter  top->first = first_insn;
474318334Speter  top->last = last_insn;
474418334Speter
474518334Speter  end_sequence ();
474618334Speter}
474718334Speter
474818334Speter/* After emitting to a sequence, restore previous saved state.
474918334Speter
475052284Sobrien   To get the contents of the sequence just made, you must call
4751117404Skan   `get_insns' *before* calling here.
475218334Speter
475352284Sobrien   If the compiler might have deferred popping arguments while
475452284Sobrien   generating this sequence, and this sequence will not be immediately
475552284Sobrien   inserted into the instruction stream, use do_pending_stack_adjust
4756117404Skan   before calling get_insns.  That will ensure that the deferred
475752284Sobrien   pops are inserted into this sequence, and not into some random
475852284Sobrien   location in the instruction stream.  See INHIBIT_DEFER_POP for more
475952284Sobrien   information about deferred popping of arguments.  */
476052284Sobrien
476118334Spetervoid
4762132727Skanend_sequence (void)
476318334Speter{
476490075Sobrien  struct sequence_stack *tem = seq_stack;
476518334Speter
476618334Speter  first_insn = tem->first;
476718334Speter  last_insn = tem->last;
476890075Sobrien  seq_stack = tem->next;
476918334Speter
4770117404Skan  memset (tem, 0, sizeof (*tem));
4771117404Skan  tem->next = free_sequence_stack;
4772117404Skan  free_sequence_stack = tem;
477318334Speter}
477418334Speter
477518334Speter/* Return 1 if currently emitting into a sequence.  */
477618334Speter
477718334Speterint
4778132727Skanin_sequence_p (void)
477918334Speter{
478090075Sobrien  return seq_stack != 0;
478118334Speter}
478218334Speter
478352284Sobrien/* Put the various virtual registers into REGNO_REG_RTX.  */
478452284Sobrien
4785169699Skanstatic void
4786132727Skaninit_virtual_regs (struct emit_status *es)
478752284Sobrien{
478890075Sobrien  rtx *ptr = es->x_regno_reg_rtx;
478990075Sobrien  ptr[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
479090075Sobrien  ptr[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
479190075Sobrien  ptr[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
479290075Sobrien  ptr[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
479390075Sobrien  ptr[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
479452284Sobrien}
479552284Sobrien
479690075Sobrien
479790075Sobrien/* Used by copy_insn_1 to avoid copying SCRATCHes more than once.  */
479890075Sobrienstatic rtx copy_insn_scratch_in[MAX_RECOG_OPERANDS];
479990075Sobrienstatic rtx copy_insn_scratch_out[MAX_RECOG_OPERANDS];
480090075Sobrienstatic int copy_insn_n_scratches;
480190075Sobrien
480290075Sobrien/* When an insn is being copied by copy_insn_1, this is nonzero if we have
480390075Sobrien   copied an ASM_OPERANDS.
480490075Sobrien   In that case, it is the original input-operand vector.  */
480590075Sobrienstatic rtvec orig_asm_operands_vector;
480690075Sobrien
480790075Sobrien/* When an insn is being copied by copy_insn_1, this is nonzero if we have
480890075Sobrien   copied an ASM_OPERANDS.
480990075Sobrien   In that case, it is the copied input-operand vector.  */
481090075Sobrienstatic rtvec copy_asm_operands_vector;
481190075Sobrien
481290075Sobrien/* Likewise for the constraints vector.  */
481390075Sobrienstatic rtvec orig_asm_constraints_vector;
481490075Sobrienstatic rtvec copy_asm_constraints_vector;
481590075Sobrien
481690075Sobrien/* Recursively create a new copy of an rtx for copy_insn.
481790075Sobrien   This function differs from copy_rtx in that it handles SCRATCHes and
481890075Sobrien   ASM_OPERANDs properly.
481990075Sobrien   Normally, this function is not used directly; use copy_insn as front end.
482090075Sobrien   However, you could first copy an insn pattern with copy_insn and then use
482190075Sobrien   this function afterwards to properly copy any REG_NOTEs containing
482290075Sobrien   SCRATCHes.  */
482390075Sobrien
482490075Sobrienrtx
4825132727Skancopy_insn_1 (rtx orig)
482690075Sobrien{
482790075Sobrien  rtx copy;
482890075Sobrien  int i, j;
482990075Sobrien  RTX_CODE code;
483090075Sobrien  const char *format_ptr;
483190075Sobrien
483290075Sobrien  code = GET_CODE (orig);
483390075Sobrien
483490075Sobrien  switch (code)
483590075Sobrien    {
483690075Sobrien    case REG:
483790075Sobrien    case CONST_INT:
483890075Sobrien    case CONST_DOUBLE:
483996263Sobrien    case CONST_VECTOR:
484090075Sobrien    case SYMBOL_REF:
484190075Sobrien    case CODE_LABEL:
484290075Sobrien    case PC:
484390075Sobrien    case CC0:
484490075Sobrien      return orig;
4845169699Skan    case CLOBBER:
4846169699Skan      if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
4847169699Skan	return orig;
4848169699Skan      break;
484990075Sobrien
485090075Sobrien    case SCRATCH:
485190075Sobrien      for (i = 0; i < copy_insn_n_scratches; i++)
485290075Sobrien	if (copy_insn_scratch_in[i] == orig)
485390075Sobrien	  return copy_insn_scratch_out[i];
485490075Sobrien      break;
485590075Sobrien
485690075Sobrien    case CONST:
485790075Sobrien      /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
485890075Sobrien	 a LABEL_REF, it isn't sharable.  */
485990075Sobrien      if (GET_CODE (XEXP (orig, 0)) == PLUS
486090075Sobrien	  && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
486190075Sobrien	  && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
486290075Sobrien	return orig;
486390075Sobrien      break;
486490075Sobrien
486590075Sobrien      /* A MEM with a constant address is not sharable.  The problem is that
486690075Sobrien	 the constant address may need to be reloaded.  If the mem is shared,
486790075Sobrien	 then reloading one copy of this mem will cause all copies to appear
486890075Sobrien	 to have been reloaded.  */
486990075Sobrien
487090075Sobrien    default:
487190075Sobrien      break;
487290075Sobrien    }
487390075Sobrien
4874169699Skan  /* Copy the various flags, fields, and other information.  We assume
4875169699Skan     that all fields need copying, and then clear the fields that should
487690075Sobrien     not be copied.  That is the sensible default behavior, and forces
487790075Sobrien     us to explicitly document why we are *not* copying a flag.  */
4878169699Skan  copy = shallow_copy_rtx (orig);
487990075Sobrien
488090075Sobrien  /* We do not copy the USED flag, which is used as a mark bit during
488190075Sobrien     walks over the RTL.  */
4882117404Skan  RTX_FLAG (copy, used) = 0;
488390075Sobrien
488490075Sobrien  /* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs.  */
4885169699Skan  if (INSN_P (orig))
488690075Sobrien    {
4887117404Skan      RTX_FLAG (copy, jump) = 0;
4888117404Skan      RTX_FLAG (copy, call) = 0;
4889117404Skan      RTX_FLAG (copy, frame_related) = 0;
489090075Sobrien    }
489190075Sobrien
489290075Sobrien  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
489390075Sobrien
489490075Sobrien  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4895169699Skan    switch (*format_ptr++)
4896169699Skan      {
4897169699Skan      case 'e':
4898169699Skan	if (XEXP (orig, i) != NULL)
4899169699Skan	  XEXP (copy, i) = copy_insn_1 (XEXP (orig, i));
4900169699Skan	break;
490190075Sobrien
4902169699Skan      case 'E':
4903169699Skan      case 'V':
4904169699Skan	if (XVEC (orig, i) == orig_asm_constraints_vector)
4905169699Skan	  XVEC (copy, i) = copy_asm_constraints_vector;
4906169699Skan	else if (XVEC (orig, i) == orig_asm_operands_vector)
4907169699Skan	  XVEC (copy, i) = copy_asm_operands_vector;
4908169699Skan	else if (XVEC (orig, i) != NULL)
4909169699Skan	  {
4910169699Skan	    XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4911169699Skan	    for (j = 0; j < XVECLEN (copy, i); j++)
4912169699Skan	      XVECEXP (copy, i, j) = copy_insn_1 (XVECEXP (orig, i, j));
4913169699Skan	  }
4914169699Skan	break;
491590075Sobrien
4916169699Skan      case 't':
4917169699Skan      case 'w':
4918169699Skan      case 'i':
4919169699Skan      case 's':
4920169699Skan      case 'S':
4921169699Skan      case 'u':
4922169699Skan      case '0':
4923169699Skan	/* These are left unchanged.  */
4924169699Skan	break;
492590075Sobrien
4926169699Skan      default:
4927169699Skan	gcc_unreachable ();
4928169699Skan      }
492990075Sobrien
493090075Sobrien  if (code == SCRATCH)
493190075Sobrien    {
493290075Sobrien      i = copy_insn_n_scratches++;
4933169699Skan      gcc_assert (i < MAX_RECOG_OPERANDS);
493490075Sobrien      copy_insn_scratch_in[i] = orig;
493590075Sobrien      copy_insn_scratch_out[i] = copy;
493690075Sobrien    }
493790075Sobrien  else if (code == ASM_OPERANDS)
493890075Sobrien    {
493990075Sobrien      orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
494090075Sobrien      copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
494190075Sobrien      orig_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (orig);
494290075Sobrien      copy_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
494390075Sobrien    }
494490075Sobrien
494590075Sobrien  return copy;
494690075Sobrien}
494790075Sobrien
494890075Sobrien/* Create a new copy of an rtx.
494990075Sobrien   This function differs from copy_rtx in that it handles SCRATCHes and
495090075Sobrien   ASM_OPERANDs properly.
495190075Sobrien   INSN doesn't really have to be a full INSN; it could be just the
495290075Sobrien   pattern.  */
495390075Sobrienrtx
4954132727Skancopy_insn (rtx insn)
495590075Sobrien{
495690075Sobrien  copy_insn_n_scratches = 0;
495790075Sobrien  orig_asm_operands_vector = 0;
495890075Sobrien  orig_asm_constraints_vector = 0;
495990075Sobrien  copy_asm_operands_vector = 0;
496090075Sobrien  copy_asm_constraints_vector = 0;
496190075Sobrien  return copy_insn_1 (insn);
496290075Sobrien}
496390075Sobrien
496418334Speter/* Initialize data structures and variables in this file
496518334Speter   before generating rtl for each function.  */
496618334Speter
496718334Spetervoid
4968132727Skaninit_emit (void)
496918334Speter{
497090075Sobrien  struct function *f = cfun;
497118334Speter
4972132727Skan  f->emit = ggc_alloc (sizeof (struct emit_status));
497318334Speter  first_insn = NULL;
497418334Speter  last_insn = NULL;
497518334Speter  cur_insn_uid = 1;
497618334Speter  reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
4977169699Skan  last_location = UNKNOWN_LOCATION;
497818334Speter  first_label_num = label_num;
497990075Sobrien  seq_stack = NULL;
498018334Speter
498118334Speter  /* Init the tables that describe all the pseudo regs.  */
498218334Speter
498390075Sobrien  f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
498418334Speter
498590075Sobrien  f->emit->regno_pointer_align
4986132727Skan    = ggc_alloc_cleared (f->emit->regno_pointer_align_length
4987132727Skan			 * sizeof (unsigned char));
498818334Speter
498990075Sobrien  regno_reg_rtx
4990132727Skan    = ggc_alloc (f->emit->regno_pointer_align_length * sizeof (rtx));
499150397Sobrien
4992117404Skan  /* Put copies of all the hard registers into regno_reg_rtx.  */
4993117404Skan  memcpy (regno_reg_rtx,
4994117404Skan	  static_regno_reg_rtx,
4995117404Skan	  FIRST_PSEUDO_REGISTER * sizeof (rtx));
4996117404Skan
499718334Speter  /* Put copies of all the virtual register rtx into regno_reg_rtx.  */
499890075Sobrien  init_virtual_regs (f->emit);
499918334Speter
500018334Speter  /* Indicate that the virtual registers and stack locations are
500118334Speter     all pointers.  */
500290075Sobrien  REG_POINTER (stack_pointer_rtx) = 1;
500390075Sobrien  REG_POINTER (frame_pointer_rtx) = 1;
500490075Sobrien  REG_POINTER (hard_frame_pointer_rtx) = 1;
500590075Sobrien  REG_POINTER (arg_pointer_rtx) = 1;
500618334Speter
500790075Sobrien  REG_POINTER (virtual_incoming_args_rtx) = 1;
500890075Sobrien  REG_POINTER (virtual_stack_vars_rtx) = 1;
500990075Sobrien  REG_POINTER (virtual_stack_dynamic_rtx) = 1;
501090075Sobrien  REG_POINTER (virtual_outgoing_args_rtx) = 1;
501190075Sobrien  REG_POINTER (virtual_cfa_rtx) = 1;
501218334Speter
501350397Sobrien#ifdef STACK_BOUNDARY
501490075Sobrien  REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
501590075Sobrien  REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
501690075Sobrien  REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
501790075Sobrien  REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
501850397Sobrien
501990075Sobrien  REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
502090075Sobrien  REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
502190075Sobrien  REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
502290075Sobrien  REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
502390075Sobrien  REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
502450397Sobrien#endif
502550397Sobrien
502618334Speter#ifdef INIT_EXPANDERS
502718334Speter  INIT_EXPANDERS;
502818334Speter#endif
502918334Speter}
503018334Speter
5031169699Skan/* Generate a vector constant for mode MODE and constant value CONSTANT.  */
503296263Sobrien
503396263Sobrienstatic rtx
5034169699Skangen_const_vector (enum machine_mode mode, int constant)
503596263Sobrien{
503696263Sobrien  rtx tem;
503796263Sobrien  rtvec v;
503896263Sobrien  int units, i;
503996263Sobrien  enum machine_mode inner;
504096263Sobrien
504196263Sobrien  units = GET_MODE_NUNITS (mode);
504296263Sobrien  inner = GET_MODE_INNER (mode);
504396263Sobrien
5044169699Skan  gcc_assert (!DECIMAL_FLOAT_MODE_P (inner));
5045169699Skan
504696263Sobrien  v = rtvec_alloc (units);
504796263Sobrien
5048169699Skan  /* We need to call this function after we set the scalar const_tiny_rtx
5049169699Skan     entries.  */
5050169699Skan  gcc_assert (const_tiny_rtx[constant][(int) inner]);
505196263Sobrien
505296263Sobrien  for (i = 0; i < units; ++i)
5053169699Skan    RTVEC_ELT (v, i) = const_tiny_rtx[constant][(int) inner];
505496263Sobrien
5055117404Skan  tem = gen_rtx_raw_CONST_VECTOR (mode, v);
505696263Sobrien  return tem;
505796263Sobrien}
505896263Sobrien
5059117404Skan/* Generate a vector like gen_rtx_raw_CONST_VEC, but use the zero vector when
5060169699Skan   all elements are zero, and the one vector when all elements are one.  */
5061117404Skanrtx
5062132727Skangen_rtx_CONST_VECTOR (enum machine_mode mode, rtvec v)
5063117404Skan{
5064169699Skan  enum machine_mode inner = GET_MODE_INNER (mode);
5065169699Skan  int nunits = GET_MODE_NUNITS (mode);
5066169699Skan  rtx x;
5067117404Skan  int i;
5068117404Skan
5069169699Skan  /* Check to see if all of the elements have the same value.  */
5070169699Skan  x = RTVEC_ELT (v, nunits - 1);
5071169699Skan  for (i = nunits - 2; i >= 0; i--)
5072169699Skan    if (RTVEC_ELT (v, i) != x)
5073169699Skan      break;
5074169699Skan
5075169699Skan  /* If the values are all the same, check to see if we can use one of the
5076169699Skan     standard constant vectors.  */
5077169699Skan  if (i == -1)
5078169699Skan    {
5079169699Skan      if (x == CONST0_RTX (inner))
5080169699Skan	return CONST0_RTX (mode);
5081169699Skan      else if (x == CONST1_RTX (inner))
5082169699Skan	return CONST1_RTX (mode);
5083169699Skan    }
5084169699Skan
5085169699Skan  return gen_rtx_raw_CONST_VECTOR (mode, v);
5086117404Skan}
5087117404Skan
508818334Speter/* Create some permanent unique rtl objects shared between all functions.
508918334Speter   LINE_NUMBERS is nonzero if line numbers are to be generated.  */
509018334Speter
509118334Spetervoid
5092132727Skaninit_emit_once (int line_numbers)
509318334Speter{
509418334Speter  int i;
509518334Speter  enum machine_mode mode;
509650397Sobrien  enum machine_mode double_mode;
509718334Speter
5098132727Skan  /* We need reg_raw_mode, so initialize the modes now.  */
5099132727Skan  init_reg_modes_once ();
5100132727Skan
5101117404Skan  /* Initialize the CONST_INT, CONST_DOUBLE, and memory attribute hash
5102117404Skan     tables.  */
5103132727Skan  const_int_htab = htab_create_ggc (37, const_int_htab_hash,
5104132727Skan				    const_int_htab_eq, NULL);
510590075Sobrien
5106132727Skan  const_double_htab = htab_create_ggc (37, const_double_htab_hash,
5107132727Skan				       const_double_htab_eq, NULL);
5108117404Skan
5109132727Skan  mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash,
5110132727Skan				    mem_attrs_htab_eq, NULL);
5111132727Skan  reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash,
5112132727Skan				    reg_attrs_htab_eq, NULL);
511390075Sobrien
511418334Speter  no_line_numbers = ! line_numbers;
511518334Speter
511618334Speter  /* Compute the word and byte modes.  */
511718334Speter
511818334Speter  byte_mode = VOIDmode;
511918334Speter  word_mode = VOIDmode;
512050397Sobrien  double_mode = VOIDmode;
512118334Speter
5122169699Skan  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
5123169699Skan       mode != VOIDmode;
512418334Speter       mode = GET_MODE_WIDER_MODE (mode))
512518334Speter    {
512618334Speter      if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
512718334Speter	  && byte_mode == VOIDmode)
512818334Speter	byte_mode = mode;
512918334Speter
513018334Speter      if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD
513118334Speter	  && word_mode == VOIDmode)
513218334Speter	word_mode = mode;
513318334Speter    }
513418334Speter
5135169699Skan  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
5136169699Skan       mode != VOIDmode;
513750397Sobrien       mode = GET_MODE_WIDER_MODE (mode))
513850397Sobrien    {
513950397Sobrien      if (GET_MODE_BITSIZE (mode) == DOUBLE_TYPE_SIZE
514050397Sobrien	  && double_mode == VOIDmode)
514150397Sobrien	double_mode = mode;
514250397Sobrien    }
514350397Sobrien
514418334Speter  ptr_mode = mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0);
514518334Speter
514690075Sobrien  /* Assign register numbers to the globally defined register rtx.
514790075Sobrien     This must be done at runtime because the register number field
514890075Sobrien     is in a union and some compilers can't initialize unions.  */
514990075Sobrien
5150169699Skan  pc_rtx = gen_rtx_PC (VOIDmode);
5151169699Skan  cc0_rtx = gen_rtx_CC0 (VOIDmode);
515290075Sobrien  stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
515390075Sobrien  frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
515490075Sobrien  if (hard_frame_pointer_rtx == 0)
515590075Sobrien    hard_frame_pointer_rtx = gen_raw_REG (Pmode,
515690075Sobrien					  HARD_FRAME_POINTER_REGNUM);
515790075Sobrien  if (arg_pointer_rtx == 0)
515890075Sobrien    arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM);
515990075Sobrien  virtual_incoming_args_rtx =
516090075Sobrien    gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM);
516190075Sobrien  virtual_stack_vars_rtx =
516290075Sobrien    gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM);
516390075Sobrien  virtual_stack_dynamic_rtx =
516490075Sobrien    gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM);
516590075Sobrien  virtual_outgoing_args_rtx =
516690075Sobrien    gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
516790075Sobrien  virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
516890075Sobrien
5169117404Skan  /* Initialize RTL for commonly used hard registers.  These are
5170117404Skan     copied into regno_reg_rtx as we begin to compile each function.  */
5171117404Skan  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5172117404Skan    static_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
517390075Sobrien
517490075Sobrien#ifdef INIT_EXPANDERS
517590075Sobrien  /* This is to initialize {init|mark|free}_machine_status before the first
517690075Sobrien     call to push_function_context_to.  This is needed by the Chill front
517790075Sobrien     end which calls push_function_context_to before the first call to
517890075Sobrien     init_function_start.  */
517990075Sobrien  INIT_EXPANDERS;
518090075Sobrien#endif
518190075Sobrien
518218334Speter  /* Create the unique rtx's for certain rtx codes and operand values.  */
518318334Speter
5184169699Skan  /* Don't use gen_rtx_CONST_INT here since gen_rtx_CONST_INT in this case
518590075Sobrien     tries to use these variables.  */
518618334Speter  for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
518790075Sobrien    const_int_rtx[i + MAX_SAVED_CONST_INT] =
5188102793Skan      gen_rtx_raw_CONST_INT (VOIDmode, (HOST_WIDE_INT) i);
518918334Speter
519050397Sobrien  if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT
519150397Sobrien      && STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT)
519290075Sobrien    const_true_rtx = const_int_rtx[STORE_FLAG_VALUE + MAX_SAVED_CONST_INT];
519350397Sobrien  else
519450397Sobrien    const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
519518334Speter
5196117404Skan  REAL_VALUE_FROM_INT (dconst0,   0,  0, double_mode);
5197117404Skan  REAL_VALUE_FROM_INT (dconst1,   1,  0, double_mode);
5198117404Skan  REAL_VALUE_FROM_INT (dconst2,   2,  0, double_mode);
5199132727Skan  REAL_VALUE_FROM_INT (dconst3,   3,  0, double_mode);
5200132727Skan  REAL_VALUE_FROM_INT (dconst10, 10,  0, double_mode);
5201117404Skan  REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);
5202132727Skan  REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode);
520318334Speter
5204132727Skan  dconsthalf = dconst1;
5205169699Skan  SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);
5206132727Skan
5207132727Skan  real_arithmetic (&dconstthird, RDIV_EXPR, &dconst1, &dconst3);
5208132727Skan
5209132727Skan  /* Initialize mathematical constants for constant folding builtins.
5210132727Skan     These constants need to be given to at least 160 bits precision.  */
5211132727Skan  real_from_string (&dconstpi,
5212132727Skan    "3.1415926535897932384626433832795028841971693993751058209749445923078");
5213132727Skan  real_from_string (&dconste,
5214132727Skan    "2.7182818284590452353602874713526624977572470936999595749669676277241");
5215132727Skan
5216132727Skan  for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++)
521718334Speter    {
5218117404Skan      REAL_VALUE_TYPE *r =
5219117404Skan	(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
5220117404Skan
5221169699Skan      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
5222169699Skan	   mode != VOIDmode;
522318334Speter	   mode = GET_MODE_WIDER_MODE (mode))
5224117404Skan	const_tiny_rtx[i][(int) mode] =
5225117404Skan	  CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
522618334Speter
5227169699Skan      for (mode = GET_CLASS_NARROWEST_MODE (MODE_DECIMAL_FLOAT);
5228169699Skan	   mode != VOIDmode;
5229169699Skan	   mode = GET_MODE_WIDER_MODE (mode))
5230169699Skan	const_tiny_rtx[i][(int) mode] =
5231169699Skan	  CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
5232169699Skan
523318334Speter      const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);
523418334Speter
5235169699Skan      for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
5236169699Skan	   mode != VOIDmode;
523718334Speter	   mode = GET_MODE_WIDER_MODE (mode))
523818334Speter	const_tiny_rtx[i][(int) mode] = GEN_INT (i);
523918334Speter
524018334Speter      for (mode = GET_CLASS_NARROWEST_MODE (MODE_PARTIAL_INT);
524118334Speter	   mode != VOIDmode;
524218334Speter	   mode = GET_MODE_WIDER_MODE (mode))
524318334Speter	const_tiny_rtx[i][(int) mode] = GEN_INT (i);
524418334Speter    }
524518334Speter
524696263Sobrien  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
524796263Sobrien       mode != VOIDmode;
524896263Sobrien       mode = GET_MODE_WIDER_MODE (mode))
5249169699Skan    {
5250169699Skan      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5251169699Skan      const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
5252169699Skan    }
525396263Sobrien
525496263Sobrien  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
525596263Sobrien       mode != VOIDmode;
525696263Sobrien       mode = GET_MODE_WIDER_MODE (mode))
5257169699Skan    {
5258169699Skan      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
5259169699Skan      const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
5260169699Skan    }
526196263Sobrien
526290075Sobrien  for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
526390075Sobrien    if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)
526490075Sobrien      const_tiny_rtx[0][i] = const0_rtx;
526518334Speter
526690075Sobrien  const_tiny_rtx[0][(int) BImode] = const0_rtx;
526790075Sobrien  if (STORE_FLAG_VALUE == 1)
526890075Sobrien    const_tiny_rtx[1][(int) BImode] = const1_rtx;
526918334Speter
527050397Sobrien#ifdef RETURN_ADDRESS_POINTER_REGNUM
527150397Sobrien  return_address_pointer_rtx
527290075Sobrien    = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
527350397Sobrien#endif
527450397Sobrien
527518334Speter#ifdef STATIC_CHAIN_REGNUM
527650397Sobrien  static_chain_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
527718334Speter
527818334Speter#ifdef STATIC_CHAIN_INCOMING_REGNUM
527918334Speter  if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)
528090075Sobrien    static_chain_incoming_rtx
528190075Sobrien      = gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM);
528218334Speter  else
528318334Speter#endif
528418334Speter    static_chain_incoming_rtx = static_chain_rtx;
528518334Speter#endif
528618334Speter
528718334Speter#ifdef STATIC_CHAIN
528818334Speter  static_chain_rtx = STATIC_CHAIN;
528918334Speter
529018334Speter#ifdef STATIC_CHAIN_INCOMING
529118334Speter  static_chain_incoming_rtx = STATIC_CHAIN_INCOMING;
529218334Speter#else
529318334Speter  static_chain_incoming_rtx = static_chain_rtx;
529418334Speter#endif
529518334Speter#endif
529618334Speter
5297132727Skan  if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
529890075Sobrien    pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
529918334Speter}
530050397Sobrien
5301117404Skan/* Produce exact duplicate of insn INSN after AFTER.
5302117404Skan   Care updating of libcall regions if present.  */
5303117404Skan
5304117404Skanrtx
5305132727Skanemit_copy_of_insn_after (rtx insn, rtx after)
5306117404Skan{
5307117404Skan  rtx new;
5308117404Skan  rtx note1, note2, link;
5309117404Skan
5310117404Skan  switch (GET_CODE (insn))
5311117404Skan    {
5312117404Skan    case INSN:
5313117404Skan      new = emit_insn_after (copy_insn (PATTERN (insn)), after);
5314117404Skan      break;
5315117404Skan
5316117404Skan    case JUMP_INSN:
5317117404Skan      new = emit_jump_insn_after (copy_insn (PATTERN (insn)), after);
5318117404Skan      break;
5319117404Skan
5320117404Skan    case CALL_INSN:
5321117404Skan      new = emit_call_insn_after (copy_insn (PATTERN (insn)), after);
5322117404Skan      if (CALL_INSN_FUNCTION_USAGE (insn))
5323117404Skan	CALL_INSN_FUNCTION_USAGE (new)
5324117404Skan	  = copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
5325117404Skan      SIBLING_CALL_P (new) = SIBLING_CALL_P (insn);
5326117404Skan      CONST_OR_PURE_CALL_P (new) = CONST_OR_PURE_CALL_P (insn);
5327117404Skan      break;
5328117404Skan
5329117404Skan    default:
5330169699Skan      gcc_unreachable ();
5331117404Skan    }
5332117404Skan
5333117404Skan  /* Update LABEL_NUSES.  */
5334117404Skan  mark_jump_label (PATTERN (new), new, 0);
5335117404Skan
5336132727Skan  INSN_LOCATOR (new) = INSN_LOCATOR (insn);
5337117404Skan
5338169699Skan  /* If the old insn is frame related, then so is the new one.  This is
5339169699Skan     primarily needed for IA-64 unwind info which marks epilogue insns,
5340169699Skan     which may be duplicated by the basic block reordering code.  */
5341169699Skan  RTX_FRAME_RELATED_P (new) = RTX_FRAME_RELATED_P (insn);
5342169699Skan
5343117404Skan  /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
5344117404Skan     make them.  */
5345117404Skan  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
5346117404Skan    if (REG_NOTE_KIND (link) != REG_LABEL)
5347117404Skan      {
5348117404Skan	if (GET_CODE (link) == EXPR_LIST)
5349117404Skan	  REG_NOTES (new)
5350222207Sbenl	    = copy_insn_1 (gen_rtx_EXPR_LIST (GET_MODE (link),
5351117404Skan					      XEXP (link, 0),
5352117404Skan					      REG_NOTES (new)));
5353117404Skan	else
5354117404Skan	  REG_NOTES (new)
5355222207Sbenl	    = copy_insn_1 (gen_rtx_INSN_LIST (GET_MODE (link),
5356117404Skan					      XEXP (link, 0),
5357117404Skan					      REG_NOTES (new)));
5358117404Skan      }
5359117404Skan
5360117404Skan  /* Fix the libcall sequences.  */
5361117404Skan  if ((note1 = find_reg_note (new, REG_RETVAL, NULL_RTX)) != NULL)
5362117404Skan    {
5363117404Skan      rtx p = new;
5364117404Skan      while ((note2 = find_reg_note (p, REG_LIBCALL, NULL_RTX)) == NULL)
5365117404Skan	p = PREV_INSN (p);
5366117404Skan      XEXP (note1, 0) = p;
5367117404Skan      XEXP (note2, 0) = new;
5368117404Skan    }
5369132727Skan  INSN_CODE (new) = INSN_CODE (insn);
5370117404Skan  return new;
5371117404Skan}
5372117404Skan
5373169699Skanstatic GTY((deletable)) rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
5374169699Skanrtx
5375169699Skangen_hard_reg_clobber (enum machine_mode mode, unsigned int regno)
5376169699Skan{
5377169699Skan  if (hard_reg_clobbers[mode][regno])
5378169699Skan    return hard_reg_clobbers[mode][regno];
5379169699Skan  else
5380169699Skan    return (hard_reg_clobbers[mode][regno] =
5381169699Skan	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
5382169699Skan}
5383169699Skan
5384117404Skan#include "gt-emit-rtl.h"
5385