• Main Page
  • Modules
  • Data Types
  • Files

osprey-gcc/gcc/expr.c

Go to the documentation of this file.
00001 /* Convert tree expression to rtl instructions, for GNU compiler.
00002    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
00004 
00005 This file is part of GCC.
00006 
00007 GCC is free software; you can redistribute it and/or modify it under
00008 the terms of the GNU General Public License as published by the Free
00009 Software Foundation; either version 2, or (at your option) any later
00010 version.
00011 
00012 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
00013 WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GCC; see the file COPYING.  If not, write to the Free
00019 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
00020 02111-1307, USA.  */
00021 
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "machmode.h"
00027 #include "real.h"
00028 #include "rtl.h"
00029 #include "tree.h"
00030 #include "flags.h"
00031 #include "regs.h"
00032 #include "hard-reg-set.h"
00033 #include "except.h"
00034 #include "function.h"
00035 #include "insn-config.h"
00036 #include "insn-attr.h"
00037 /* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
00038 #include "expr.h"
00039 #include "optabs.h"
00040 #include "libfuncs.h"
00041 #include "recog.h"
00042 #include "reload.h"
00043 #include "output.h"
00044 #include "typeclass.h"
00045 #include "toplev.h"
00046 #include "ggc.h"
00047 #include "langhooks.h"
00048 #include "intl.h"
00049 #include "tm_p.h"
00050 #include "tree-iterator.h"
00051 #include "tree-pass.h"
00052 #include "tree-flow.h"
00053 #include "target.h"
00054 #include "timevar.h"
00055 
00056 /* Decide whether a function's arguments should be processed
00057    from first to last or from last to first.
00058 
00059    They should if the stack and args grow in opposite directions, but
00060    only if we have push insns.  */
00061 
00062 #ifdef PUSH_ROUNDING
00063 
00064 #ifndef PUSH_ARGS_REVERSED
00065 #if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
00066 #define PUSH_ARGS_REVERSED  /* If it's last to first.  */
00067 #endif
00068 #endif
00069 
00070 #endif
00071 
00072 #ifndef STACK_PUSH_CODE
00073 #ifdef STACK_GROWS_DOWNWARD
00074 #define STACK_PUSH_CODE PRE_DEC
00075 #else
00076 #define STACK_PUSH_CODE PRE_INC
00077 #endif
00078 #endif
00079 
00080 
00081 /* If this is nonzero, we do not bother generating VOLATILE
00082    around volatile memory references, and we are willing to
00083    output indirect addresses.  If cse is to follow, we reject
00084    indirect addresses so a useful potential cse is generated;
00085    if it is used only once, instruction combination will produce
00086    the same indirect address eventually.  */
00087 int cse_not_expected;
00088 
00089 /* This structure is used by move_by_pieces to describe the move to
00090    be performed.  */
00091 struct move_by_pieces
00092 {
00093   rtx to;
00094   rtx to_addr;
00095   int autinc_to;
00096   int explicit_inc_to;
00097   rtx from;
00098   rtx from_addr;
00099   int autinc_from;
00100   int explicit_inc_from;
00101   unsigned HOST_WIDE_INT len;
00102   HOST_WIDE_INT offset;
00103   int reverse;
00104 };
00105 
00106 /* This structure is used by store_by_pieces to describe the clear to
00107    be performed.  */
00108 
00109 struct store_by_pieces
00110 {
00111   rtx to;
00112   rtx to_addr;
00113   int autinc_to;
00114   int explicit_inc_to;
00115   unsigned HOST_WIDE_INT len;
00116   HOST_WIDE_INT offset;
00117   rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode);
00118   void *constfundata;
00119   int reverse;
00120 };
00121 
00122 static unsigned HOST_WIDE_INT move_by_pieces_ninsns (unsigned HOST_WIDE_INT,
00123                  unsigned int,
00124                  unsigned int);
00125 static void move_by_pieces_1 (rtx (*) (rtx, ...), enum machine_mode,
00126             struct move_by_pieces *);
00127 static bool block_move_libcall_safe_for_call_parm (void);
00128 static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned);
00129 static rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool);
00130 static tree emit_block_move_libcall_fn (int);
00131 static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned);
00132 static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, enum machine_mode);
00133 static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
00134 static void store_by_pieces_1 (struct store_by_pieces *, unsigned int);
00135 static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
00136              struct store_by_pieces *);
00137 static bool clear_storage_via_clrmem (rtx, rtx, unsigned);
00138 static rtx clear_storage_via_libcall (rtx, rtx, bool);
00139 static tree clear_storage_libcall_fn (int);
00140 static rtx compress_float_constant (rtx, rtx);
00141 static rtx get_subtarget (rtx);
00142 static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
00143              HOST_WIDE_INT, enum machine_mode,
00144              tree, tree, int, int);
00145 static void store_constructor (tree, rtx, int, HOST_WIDE_INT);
00146 static rtx store_field (rtx, HOST_WIDE_INT, HOST_WIDE_INT, enum machine_mode,
00147       tree, tree, int);
00148 
00149 static unsigned HOST_WIDE_INT highest_pow2_factor (tree);
00150 static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (tree, tree);
00151 
00152 static int is_aligning_offset (tree, tree);
00153 static void expand_operands (tree, tree, rtx, rtx*, rtx*,
00154            enum expand_modifier);
00155 static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
00156 static rtx do_store_flag (tree, rtx, enum machine_mode, int);
00157 #ifdef PUSH_ROUNDING
00158 static void emit_single_push_insn (enum machine_mode, rtx, tree);
00159 #endif
00160 static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
00161 static rtx const_vector_from_tree (tree);
00162 static void write_complex_part (rtx, rtx, bool);
00163 
00164 /* Record for each mode whether we can move a register directly to or
00165    from an object of that mode in memory.  If we can't, we won't try
00166    to use that mode directly when accessing a field of that mode.  */
00167 
00168 static char direct_load[NUM_MACHINE_MODES];
00169 static char direct_store[NUM_MACHINE_MODES];
00170 
00171 /* Record for each mode whether we can float-extend from memory.  */
00172 
00173 static bool float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
00174 
00175 /* This macro is used to determine whether move_by_pieces should be called
00176    to perform a structure copy.  */
00177 #ifndef MOVE_BY_PIECES_P
00178 #define MOVE_BY_PIECES_P(SIZE, ALIGN) \
00179   (move_by_pieces_ninsns (SIZE, ALIGN, MOVE_MAX_PIECES + 1) \
00180    < (unsigned int) MOVE_RATIO)
00181 #endif
00182 
00183 /* This macro is used to determine whether clear_by_pieces should be
00184    called to clear storage.  */
00185 #ifndef CLEAR_BY_PIECES_P
00186 #define CLEAR_BY_PIECES_P(SIZE, ALIGN) \
00187   (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
00188    < (unsigned int) CLEAR_RATIO)
00189 #endif
00190 
00191 /* This macro is used to determine whether store_by_pieces should be
00192    called to "memset" storage with byte values other than zero, or
00193    to "memcpy" storage when the source is a constant string.  */
00194 #ifndef STORE_BY_PIECES_P
00195 #define STORE_BY_PIECES_P(SIZE, ALIGN) \
00196   (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
00197    < (unsigned int) MOVE_RATIO)
00198 #endif
00199 
00200 /* This array records the insn_code of insns to perform block moves.  */
00201 enum insn_code movmem_optab[NUM_MACHINE_MODES];
00202 
00203 /* This array records the insn_code of insns to perform block clears.  */
00204 enum insn_code clrmem_optab[NUM_MACHINE_MODES];
00205 
00206 /* These arrays record the insn_code of two different kinds of insns
00207    to perform block compares.  */
00208 enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
00209 enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
00210 
00211 /* SLOW_UNALIGNED_ACCESS is nonzero if unaligned accesses are very slow.  */
00212 
00213 #ifndef SLOW_UNALIGNED_ACCESS
00214 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
00215 #endif
00216 
00217 /* This is run once per compilation to set up which modes can be used
00218    directly in memory and to initialize the block move optab.  */
00219 
00220 void
00221 init_expr_once (void)
00222 {
00223   rtx insn, pat;
00224   enum machine_mode mode;
00225   int num_clobbers;
00226   rtx mem, mem1;
00227   rtx reg;
00228 
00229   /* Try indexing by frame ptr and try by stack ptr.
00230      It is known that on the Convex the stack ptr isn't a valid index.
00231      With luck, one or the other is valid on any machine.  */
00232   mem = gen_rtx_MEM (VOIDmode, stack_pointer_rtx);
00233   mem1 = gen_rtx_MEM (VOIDmode, frame_pointer_rtx);
00234 
00235   /* A scratch register we can modify in-place below to avoid
00236      useless RTL allocations.  */
00237   reg = gen_rtx_REG (VOIDmode, -1);
00238 
00239   insn = rtx_alloc (INSN);
00240   pat = gen_rtx_SET (0, NULL_RTX, NULL_RTX);
00241   PATTERN (insn) = pat;
00242 
00243   for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
00244        mode = (enum machine_mode) ((int) mode + 1))
00245     {
00246       int regno;
00247 
00248       direct_load[(int) mode] = direct_store[(int) mode] = 0;
00249       PUT_MODE (mem, mode);
00250       PUT_MODE (mem1, mode);
00251       PUT_MODE (reg, mode);
00252 
00253       /* See if there is some register that can be used in this mode and
00254    directly loaded or stored from memory.  */
00255 
00256       if (mode != VOIDmode && mode != BLKmode)
00257   for (regno = 0; regno < FIRST_PSEUDO_REGISTER
00258        && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
00259        regno++)
00260     {
00261       if (! HARD_REGNO_MODE_OK (regno, mode))
00262         continue;
00263 
00264       REGNO (reg) = regno;
00265 
00266       SET_SRC (pat) = mem;
00267       SET_DEST (pat) = reg;
00268       if (recog (pat, insn, &num_clobbers) >= 0)
00269         direct_load[(int) mode] = 1;
00270 
00271       SET_SRC (pat) = mem1;
00272       SET_DEST (pat) = reg;
00273       if (recog (pat, insn, &num_clobbers) >= 0)
00274         direct_load[(int) mode] = 1;
00275 
00276       SET_SRC (pat) = reg;
00277       SET_DEST (pat) = mem;
00278       if (recog (pat, insn, &num_clobbers) >= 0)
00279         direct_store[(int) mode] = 1;
00280 
00281       SET_SRC (pat) = reg;
00282       SET_DEST (pat) = mem1;
00283       if (recog (pat, insn, &num_clobbers) >= 0)
00284         direct_store[(int) mode] = 1;
00285     }
00286     }
00287 
00288   mem = gen_rtx_MEM (VOIDmode, gen_rtx_raw_REG (Pmode, 10000));
00289 
00290   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
00291        mode = GET_MODE_WIDER_MODE (mode))
00292     {
00293       enum machine_mode srcmode;
00294       for (srcmode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); srcmode != mode;
00295      srcmode = GET_MODE_WIDER_MODE (srcmode))
00296   {
00297     enum insn_code ic;
00298 
00299     ic = can_extend_p (mode, srcmode, 0);
00300     if (ic == CODE_FOR_nothing)
00301       continue;
00302 
00303     PUT_MODE (mem, srcmode);
00304 
00305     if ((*insn_data[ic].operand[1].predicate) (mem, srcmode))
00306       float_extend_from_mem[mode][srcmode] = true;
00307   }
00308     }
00309 }
00310 
00311 /* This is run at the start of compiling a function.  */
00312 
00313 void
00314 init_expr (void)
00315 {
00316   cfun->expr = ggc_alloc_cleared (sizeof (struct expr_status));
00317 }
00318 
00319 /* Copy data from FROM to TO, where the machine modes are not the same.
00320    Both modes may be integer, or both may be floating.
00321    UNSIGNEDP should be nonzero if FROM is an unsigned type.
00322    This causes zero-extension instead of sign-extension.  */
00323 
00324 void
00325 convert_move (rtx to, rtx from, int unsignedp)
00326 {
00327   enum machine_mode to_mode = GET_MODE (to);
00328   enum machine_mode from_mode = GET_MODE (from);
00329   int to_real = GET_MODE_CLASS (to_mode) == MODE_FLOAT;
00330   int from_real = GET_MODE_CLASS (from_mode) == MODE_FLOAT;
00331   enum insn_code code;
00332   rtx libcall;
00333 
00334   /* rtx code for making an equivalent value.  */
00335   enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
00336             : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
00337 
00338 
00339   gcc_assert (to_real == from_real);
00340 
00341   /* If the source and destination are already the same, then there's
00342      nothing to do.  */
00343   if (to == from)
00344     return;
00345 
00346   /* If FROM is a SUBREG that indicates that we have already done at least
00347      the required extension, strip it.  We don't handle such SUBREGs as
00348      TO here.  */
00349 
00350   if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from)
00351       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (from)))
00352     >= GET_MODE_SIZE (to_mode))
00353       && SUBREG_PROMOTED_UNSIGNED_P (from) == unsignedp)
00354     from = gen_lowpart (to_mode, from), from_mode = to_mode;
00355 
00356   gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
00357 
00358   if (to_mode == from_mode
00359       || (from_mode == VOIDmode && CONSTANT_P (from)))
00360     {
00361       emit_move_insn (to, from);
00362       return;
00363     }
00364 
00365   if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
00366     {
00367       gcc_assert (GET_MODE_BITSIZE (from_mode) == GET_MODE_BITSIZE (to_mode));
00368 
00369       if (VECTOR_MODE_P (to_mode))
00370   from = simplify_gen_subreg (to_mode, from, GET_MODE (from), 0);
00371       else
00372   to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
00373 
00374       emit_move_insn (to, from);
00375       return;
00376     }
00377 
00378   if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
00379     {
00380       convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
00381       convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
00382       return;
00383     }
00384 
00385   if (to_real)
00386     {
00387       rtx value, insns;
00388       convert_optab tab;
00389 
00390       gcc_assert (GET_MODE_PRECISION (from_mode)
00391       != GET_MODE_PRECISION (to_mode));
00392       
00393       if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
00394   tab = sext_optab;
00395       else
00396   tab = trunc_optab;
00397 
00398       /* Try converting directly if the insn is supported.  */
00399 
00400       code = tab->handlers[to_mode][from_mode].insn_code;
00401       if (code != CODE_FOR_nothing)
00402   {
00403     emit_unop_insn (code, to, from,
00404         tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
00405     return;
00406   }
00407 
00408       /* Otherwise use a libcall.  */
00409       libcall = tab->handlers[to_mode][from_mode].libfunc;
00410 
00411       /* Is this conversion implemented yet?  */
00412       gcc_assert (libcall);
00413 
00414       start_sequence ();
00415       value = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, to_mode,
00416                1, from, from_mode);
00417       insns = get_insns ();
00418       end_sequence ();
00419       emit_libcall_block (insns, to, value,
00420         tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
00421                        from)
00422         : gen_rtx_FLOAT_EXTEND (to_mode, from));
00423       return;
00424     }
00425 
00426   /* Handle pointer conversion.  */     /* SPEE 900220.  */
00427   /* Targets are expected to provide conversion insns between PxImode and
00428      xImode for all MODE_PARTIAL_INT modes they use, but no others.  */
00429   if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
00430     {
00431       enum machine_mode full_mode
00432   = smallest_mode_for_size (GET_MODE_BITSIZE (to_mode), MODE_INT);
00433 
00434       gcc_assert (trunc_optab->handlers[to_mode][full_mode].insn_code
00435       != CODE_FOR_nothing);
00436 
00437       if (full_mode != from_mode)
00438   from = convert_to_mode (full_mode, from, unsignedp);
00439       emit_unop_insn (trunc_optab->handlers[to_mode][full_mode].insn_code,
00440           to, from, UNKNOWN);
00441       return;
00442     }
00443   if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
00444     {
00445       enum machine_mode full_mode
00446   = smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT);
00447 
00448       gcc_assert (sext_optab->handlers[full_mode][from_mode].insn_code
00449       != CODE_FOR_nothing);
00450 
00451       emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
00452           to, from, UNKNOWN);
00453       if (to_mode == full_mode)
00454   return;
00455 
00456       /* else proceed to integer conversions below.  */
00457       from_mode = full_mode;
00458     }
00459 
00460   /* Now both modes are integers.  */
00461 
00462   /* Handle expanding beyond a word.  */
00463   if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode)
00464       && GET_MODE_BITSIZE (to_mode) > BITS_PER_WORD)
00465     {
00466       rtx insns;
00467       rtx lowpart;
00468       rtx fill_value;
00469       rtx lowfrom;
00470       int i;
00471       enum machine_mode lowpart_mode;
00472       int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
00473 
00474       /* Try converting directly if the insn is supported.  */
00475       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
00476     != CODE_FOR_nothing)
00477   {
00478     /* If FROM is a SUBREG, put it into a register.  Do this
00479        so that we always generate the same set of insns for
00480        better cse'ing; if an intermediate assignment occurred,
00481        we won't be doing the operation directly on the SUBREG.  */
00482     if (optimize > 0 && GET_CODE (from) == SUBREG)
00483       from = force_reg (from_mode, from);
00484     emit_unop_insn (code, to, from, equiv_code);
00485     return;
00486   }
00487       /* Next, try converting via full word.  */
00488       else if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD
00489          && ((code = can_extend_p (to_mode, word_mode, unsignedp))
00490        != CODE_FOR_nothing))
00491   {
00492     if (REG_P (to))
00493       {
00494         if (reg_overlap_mentioned_p (to, from))
00495     from = force_reg (from_mode, from);
00496         emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
00497       }
00498     convert_move (gen_lowpart (word_mode, to), from, unsignedp);
00499     emit_unop_insn (code, to,
00500         gen_lowpart (word_mode, to), equiv_code);
00501     return;
00502   }
00503 
00504       /* No special multiword conversion insn; do it by hand.  */
00505       start_sequence ();
00506 
00507       /* Since we will turn this into a no conflict block, we must ensure
00508    that the source does not overlap the target.  */
00509 
00510       if (reg_overlap_mentioned_p (to, from))
00511   from = force_reg (from_mode, from);
00512 
00513       /* Get a copy of FROM widened to a word, if necessary.  */
00514       if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD)
00515   lowpart_mode = word_mode;
00516       else
00517   lowpart_mode = from_mode;
00518 
00519       lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
00520 
00521       lowpart = gen_lowpart (lowpart_mode, to);
00522       emit_move_insn (lowpart, lowfrom);
00523 
00524       /* Compute the value to put in each remaining word.  */
00525       if (unsignedp)
00526   fill_value = const0_rtx;
00527       else
00528   {
00529 #ifdef HAVE_slt
00530     if (HAVE_slt
00531         && insn_data[(int) CODE_FOR_slt].operand[0].mode == word_mode
00532         && STORE_FLAG_VALUE == -1)
00533       {
00534         emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,
00535            lowpart_mode, 0);
00536         fill_value = gen_reg_rtx (word_mode);
00537         emit_insn (gen_slt (fill_value));
00538       }
00539     else
00540 #endif
00541       {
00542         fill_value
00543     = expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom,
00544         size_int (GET_MODE_BITSIZE (lowpart_mode) - 1),
00545         NULL_RTX, 0);
00546         fill_value = convert_to_mode (word_mode, fill_value, 1);
00547       }
00548   }
00549 
00550       /* Fill the remaining words.  */
00551       for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
00552   {
00553     int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
00554     rtx subword = operand_subword (to, index, 1, to_mode);
00555 
00556     gcc_assert (subword);
00557 
00558     if (fill_value != subword)
00559       emit_move_insn (subword, fill_value);
00560   }
00561 
00562       insns = get_insns ();
00563       end_sequence ();
00564 
00565       emit_no_conflict_block (insns, to, from, NULL_RTX,
00566             gen_rtx_fmt_e (equiv_code, to_mode, copy_rtx (from)));
00567       return;
00568     }
00569 
00570   /* Truncating multi-word to a word or less.  */
00571   if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD
00572       && GET_MODE_BITSIZE (to_mode) <= BITS_PER_WORD)
00573     {
00574       if (!((MEM_P (from)
00575        && ! MEM_VOLATILE_P (from)
00576        && direct_load[(int) to_mode]
00577        && ! mode_dependent_address_p (XEXP (from, 0)))
00578       || REG_P (from)
00579       || GET_CODE (from) == SUBREG))
00580   from = force_reg (from_mode, from);
00581       convert_move (to, gen_lowpart (word_mode, from), 0);
00582       return;
00583     }
00584 
00585   /* Now follow all the conversions between integers
00586      no more than a word long.  */
00587 
00588   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
00589   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
00590       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
00591         GET_MODE_BITSIZE (from_mode)))
00592     {
00593       if (!((MEM_P (from)
00594        && ! MEM_VOLATILE_P (from)
00595        && direct_load[(int) to_mode]
00596        && ! mode_dependent_address_p (XEXP (from, 0)))
00597       || REG_P (from)
00598       || GET_CODE (from) == SUBREG))
00599   from = force_reg (from_mode, from);
00600       if (REG_P (from) && REGNO (from) < FIRST_PSEUDO_REGISTER
00601     && ! HARD_REGNO_MODE_OK (REGNO (from), to_mode))
00602   from = copy_to_reg (from);
00603       emit_move_insn (to, gen_lowpart (to_mode, from));
00604       return;
00605     }
00606 
00607   /* Handle extension.  */
00608   if (GET_MODE_BITSIZE (to_mode) > GET_MODE_BITSIZE (from_mode))
00609     {
00610       /* Convert directly if that works.  */
00611       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
00612     != CODE_FOR_nothing)
00613   {
00614     if (flag_force_mem)
00615       from = force_not_mem (from);
00616 
00617     emit_unop_insn (code, to, from, equiv_code);
00618     return;
00619   }
00620       else
00621   {
00622     enum machine_mode intermediate;
00623     rtx tmp;
00624     tree shift_amount;
00625 
00626     /* Search for a mode to convert via.  */
00627     for (intermediate = from_mode; intermediate != VOIDmode;
00628          intermediate = GET_MODE_WIDER_MODE (intermediate))
00629       if (((can_extend_p (to_mode, intermediate, unsignedp)
00630       != CODE_FOR_nothing)
00631      || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
00632          && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
00633                  GET_MODE_BITSIZE (intermediate))))
00634     && (can_extend_p (intermediate, from_mode, unsignedp)
00635         != CODE_FOR_nothing))
00636         {
00637     convert_move (to, convert_to_mode (intermediate, from,
00638                unsignedp), unsignedp);
00639     return;
00640         }
00641 
00642     /* No suitable intermediate mode.
00643        Generate what we need with shifts.  */
00644     shift_amount = build_int_cst (NULL_TREE,
00645           GET_MODE_BITSIZE (to_mode)
00646           - GET_MODE_BITSIZE (from_mode));
00647     from = gen_lowpart (to_mode, force_reg (from_mode, from));
00648     tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
00649             to, unsignedp);
00650     tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
00651             to, unsignedp);
00652     if (tmp != to)
00653       emit_move_insn (to, tmp);
00654     return;
00655   }
00656     }
00657 
00658   /* Support special truncate insns for certain modes.  */
00659   if (trunc_optab->handlers[to_mode][from_mode].insn_code != CODE_FOR_nothing)
00660     {
00661       emit_unop_insn (trunc_optab->handlers[to_mode][from_mode].insn_code,
00662           to, from, UNKNOWN);
00663       return;
00664     }
00665 
00666   /* Handle truncation of volatile memrefs, and so on;
00667      the things that couldn't be truncated directly,
00668      and for which there was no special instruction.
00669 
00670      ??? Code above formerly short-circuited this, for most integer
00671      mode pairs, with a force_reg in from_mode followed by a recursive
00672      call to this routine.  Appears always to have been wrong.  */
00673   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))
00674     {
00675       rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
00676       emit_move_insn (to, temp);
00677       return;
00678     }
00679 
00680   /* Mode combination is not recognized.  */
00681   gcc_unreachable ();
00682 }
00683 
00684 /* Return an rtx for a value that would result
00685    from converting X to mode MODE.
00686    Both X and MODE may be floating, or both integer.
00687    UNSIGNEDP is nonzero if X is an unsigned value.
00688    This can be done by referring to a part of X in place
00689    or by copying to a new temporary with conversion.  */
00690 
00691 rtx
00692 convert_to_mode (enum machine_mode mode, rtx x, int unsignedp)
00693 {
00694   return convert_modes (mode, VOIDmode, x, unsignedp);
00695 }
00696 
00697 /* Return an rtx for a value that would result
00698    from converting X from mode OLDMODE to mode MODE.
00699    Both modes may be floating, or both integer.
00700    UNSIGNEDP is nonzero if X is an unsigned value.
00701 
00702    This can be done by referring to a part of X in place
00703    or by copying to a new temporary with conversion.
00704 
00705    You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.  */
00706 
00707 rtx
00708 convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int unsignedp)
00709 {
00710   rtx temp;
00711 
00712   /* If FROM is a SUBREG that indicates that we have already done at least
00713      the required extension, strip it.  */
00714 
00715   if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
00716       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode)
00717       && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp)
00718     x = gen_lowpart (mode, x);
00719 
00720   if (GET_MODE (x) != VOIDmode)
00721     oldmode = GET_MODE (x);
00722 
00723   if (mode == oldmode)
00724     return x;
00725 
00726   /* There is one case that we must handle specially: If we are converting
00727      a CONST_INT into a mode whose size is twice HOST_BITS_PER_WIDE_INT and
00728      we are to interpret the constant as unsigned, gen_lowpart will do
00729      the wrong if the constant appears negative.  What we want to do is
00730      make the high-order word of the constant zero, not all ones.  */
00731 
00732   if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
00733       && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
00734       && GET_CODE (x) == CONST_INT && INTVAL (x) < 0)
00735     {
00736       HOST_WIDE_INT val = INTVAL (x);
00737 
00738       if (oldmode != VOIDmode
00739     && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode))
00740   {
00741     int width = GET_MODE_BITSIZE (oldmode);
00742 
00743     /* We need to zero extend VAL.  */
00744     val &= ((HOST_WIDE_INT) 1 << width) - 1;
00745   }
00746 
00747       return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
00748     }
00749 
00750   /* We can do this with a gen_lowpart if both desired and current modes
00751      are integer, and this is either a constant integer, a register, or a
00752      non-volatile MEM.  Except for the constant case where MODE is no
00753      wider than HOST_BITS_PER_WIDE_INT, we must be narrowing the operand.  */
00754 
00755   if ((GET_CODE (x) == CONST_INT
00756        && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
00757       || (GET_MODE_CLASS (mode) == MODE_INT
00758     && GET_MODE_CLASS (oldmode) == MODE_INT
00759     && (GET_CODE (x) == CONST_DOUBLE
00760         || (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (oldmode)
00761       && ((MEM_P (x) && ! MEM_VOLATILE_P (x)
00762            && direct_load[(int) mode])
00763           || (REG_P (x)
00764         && (! HARD_REGISTER_P (x)
00765             || HARD_REGNO_MODE_OK (REGNO (x), mode))
00766         && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
00767                 GET_MODE_BITSIZE (GET_MODE (x)))))))))
00768     {
00769       /* ?? If we don't know OLDMODE, we have to assume here that
00770    X does not need sign- or zero-extension.   This may not be
00771    the case, but it's the best we can do.  */
00772       if (GET_CODE (x) == CONST_INT && oldmode != VOIDmode
00773     && GET_MODE_SIZE (mode) > GET_MODE_SIZE (oldmode))
00774   {
00775     HOST_WIDE_INT val = INTVAL (x);
00776     int width = GET_MODE_BITSIZE (oldmode);
00777 
00778     /* We must sign or zero-extend in this case.  Start by
00779        zero-extending, then sign extend if we need to.  */
00780     val &= ((HOST_WIDE_INT) 1 << width) - 1;
00781     if (! unsignedp
00782         && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
00783       val |= (HOST_WIDE_INT) (-1) << width;
00784 
00785     return gen_int_mode (val, mode);
00786   }
00787 
00788       return gen_lowpart (mode, x);
00789     }
00790 
00791   /* Converting from integer constant into mode is always equivalent to an
00792      subreg operation.  */
00793   if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode)
00794     {
00795       gcc_assert (GET_MODE_BITSIZE (mode) == GET_MODE_BITSIZE (oldmode));
00796       return simplify_gen_subreg (mode, x, oldmode, 0);
00797     }
00798 
00799   temp = gen_reg_rtx (mode);
00800   convert_move (temp, x, unsignedp);
00801   return temp;
00802 }
00803 
00804 /* STORE_MAX_PIECES is the number of bytes at a time that we can
00805    store efficiently.  Due to internal GCC limitations, this is
00806    MOVE_MAX_PIECES limited by the number of bytes GCC can represent
00807    for an immediate constant.  */
00808 
00809 #define STORE_MAX_PIECES  MIN (MOVE_MAX_PIECES, 2 * sizeof (HOST_WIDE_INT))
00810 
00811 /* Determine whether the LEN bytes can be moved by using several move
00812    instructions.  Return nonzero if a call to move_by_pieces should
00813    succeed.  */
00814 
00815 int
00816 can_move_by_pieces (unsigned HOST_WIDE_INT len,
00817         unsigned int align ATTRIBUTE_UNUSED)
00818 {
00819   return MOVE_BY_PIECES_P (len, align);
00820 }
00821 
00822 /* Generate several move instructions to copy LEN bytes from block FROM to
00823    block TO.  (These are MEM rtx's with BLKmode).
00824 
00825    If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
00826    used to push FROM to the stack.
00827 
00828    ALIGN is maximum stack alignment we can assume.
00829 
00830    If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
00831    mempcpy, and if ENDP is 2 return memory the end minus one byte ala
00832    stpcpy.  */
00833 
00834 rtx
00835 move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
00836     unsigned int align, int endp)
00837 {
00838   struct move_by_pieces data;
00839   rtx to_addr, from_addr = XEXP (from, 0);
00840   unsigned int max_size = MOVE_MAX_PIECES + 1;
00841   enum machine_mode mode = VOIDmode, tmode;
00842   enum insn_code icode;
00843 
00844   align = MIN (to ? MEM_ALIGN (to) : align, MEM_ALIGN (from));
00845 
00846   data.offset = 0;
00847   data.from_addr = from_addr;
00848   if (to)
00849     {
00850       to_addr = XEXP (to, 0);
00851       data.to = to;
00852       data.autinc_to
00853   = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
00854      || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
00855       data.reverse
00856   = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
00857     }
00858   else
00859     {
00860       to_addr = NULL_RTX;
00861       data.to = NULL_RTX;
00862       data.autinc_to = 1;
00863 #ifdef STACK_GROWS_DOWNWARD
00864       data.reverse = 1;
00865 #else
00866       data.reverse = 0;
00867 #endif
00868     }
00869   data.to_addr = to_addr;
00870   data.from = from;
00871   data.autinc_from
00872     = (GET_CODE (from_addr) == PRE_INC || GET_CODE (from_addr) == PRE_DEC
00873        || GET_CODE (from_addr) == POST_INC
00874        || GET_CODE (from_addr) == POST_DEC);
00875 
00876   data.explicit_inc_from = 0;
00877   data.explicit_inc_to = 0;
00878   if (data.reverse) data.offset = len;
00879   data.len = len;
00880 
00881   /* If copying requires more than two move insns,
00882      copy addresses to registers (to make displacements shorter)
00883      and use post-increment if available.  */
00884   if (!(data.autinc_from && data.autinc_to)
00885       && move_by_pieces_ninsns (len, align, max_size) > 2)
00886     {
00887       /* Find the mode of the largest move...  */
00888       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
00889      tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
00890   if (GET_MODE_SIZE (tmode) < max_size)
00891     mode = tmode;
00892 
00893       if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
00894   {
00895     data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
00896     data.autinc_from = 1;
00897     data.explicit_inc_from = -1;
00898   }
00899       if (USE_LOAD_POST_INCREMENT (mode) && ! data.autinc_from)
00900   {
00901     data.from_addr = copy_addr_to_reg (from_addr);
00902     data.autinc_from = 1;
00903     data.explicit_inc_from = 1;
00904   }
00905       if (!data.autinc_from && CONSTANT_P (from_addr))
00906   data.from_addr = copy_addr_to_reg (from_addr);
00907       if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
00908   {
00909     data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
00910     data.autinc_to = 1;
00911     data.explicit_inc_to = -1;
00912   }
00913       if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
00914   {
00915     data.to_addr = copy_addr_to_reg (to_addr);
00916     data.autinc_to = 1;
00917     data.explicit_inc_to = 1;
00918   }
00919       if (!data.autinc_to && CONSTANT_P (to_addr))
00920   data.to_addr = copy_addr_to_reg (to_addr);
00921     }
00922 
00923   tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
00924   if (align >= GET_MODE_ALIGNMENT (tmode))
00925     align = GET_MODE_ALIGNMENT (tmode);
00926   else
00927     {
00928       enum machine_mode xmode;
00929 
00930       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
00931      tmode != VOIDmode;
00932      xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
00933   if (GET_MODE_SIZE (tmode) > MOVE_MAX_PIECES
00934       || SLOW_UNALIGNED_ACCESS (tmode, align))
00935     break;
00936 
00937       align = MAX (align, GET_MODE_ALIGNMENT (xmode));
00938     }
00939 
00940   /* First move what we can in the largest integer mode, then go to
00941      successively smaller modes.  */
00942 
00943   while (max_size > 1)
00944     {
00945       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
00946      tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
00947   if (GET_MODE_SIZE (tmode) < max_size)
00948     mode = tmode;
00949 
00950       if (mode == VOIDmode)
00951   break;
00952 
00953       icode = mov_optab->handlers[(int) mode].insn_code;
00954       if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
00955   move_by_pieces_1 (GEN_FCN (icode), mode, &data);
00956 
00957       max_size = GET_MODE_SIZE (mode);
00958     }
00959 
00960   /* The code above should have handled everything.  */
00961   gcc_assert (!data.len);
00962 
00963   if (endp)
00964     {
00965       rtx to1;
00966 
00967       gcc_assert (!data.reverse);
00968       if (data.autinc_to)
00969   {
00970     if (endp == 2)
00971       {
00972         if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
00973     emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
00974         else
00975     data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
00976                 -1));
00977       }
00978     to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
00979              data.offset);
00980   }
00981       else
00982   {
00983     if (endp == 2)
00984       --data.offset;
00985     to1 = adjust_address (data.to, QImode, data.offset);
00986   }
00987       return to1;
00988     }
00989   else
00990     return data.to;
00991 }
00992 
00993 /* Return number of insns required to move L bytes by pieces.
00994    ALIGN (in bits) is maximum alignment we can assume.  */
00995 
00996 static unsigned HOST_WIDE_INT
00997 move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
00998            unsigned int max_size)
00999 {
01000   unsigned HOST_WIDE_INT n_insns = 0;
01001   enum machine_mode tmode;
01002 
01003   tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
01004   if (align >= GET_MODE_ALIGNMENT (tmode))
01005     align = GET_MODE_ALIGNMENT (tmode);
01006   else
01007     {
01008       enum machine_mode tmode, xmode;
01009 
01010       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
01011      tmode != VOIDmode;
01012      xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
01013   if (GET_MODE_SIZE (tmode) > MOVE_MAX_PIECES
01014       || SLOW_UNALIGNED_ACCESS (tmode, align))
01015     break;
01016 
01017       align = MAX (align, GET_MODE_ALIGNMENT (xmode));
01018     }
01019 
01020   while (max_size > 1)
01021     {
01022       enum machine_mode mode = VOIDmode;
01023       enum insn_code icode;
01024 
01025       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
01026      tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
01027   if (GET_MODE_SIZE (tmode) < max_size)
01028     mode = tmode;
01029 
01030       if (mode == VOIDmode)
01031   break;
01032 
01033       icode = mov_optab->handlers[(int) mode].insn_code;
01034       if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
01035   n_insns += l / GET_MODE_SIZE (mode), l %= GET_MODE_SIZE (mode);
01036 
01037       max_size = GET_MODE_SIZE (mode);
01038     }
01039 
01040   gcc_assert (!l);
01041   return n_insns;
01042 }
01043 
01044 /* Subroutine of move_by_pieces.  Move as many bytes as appropriate
01045    with move instructions for mode MODE.  GENFUN is the gen_... function
01046    to make a move insn for that mode.  DATA has all the other info.  */
01047 
01048 static void
01049 move_by_pieces_1 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
01050       struct move_by_pieces *data)
01051 {
01052   unsigned int size = GET_MODE_SIZE (mode);
01053   rtx to1 = NULL_RTX, from1;
01054 
01055   while (data->len >= size)
01056     {
01057       if (data->reverse)
01058   data->offset -= size;
01059 
01060       if (data->to)
01061   {
01062     if (data->autinc_to)
01063       to1 = adjust_automodify_address (data->to, mode, data->to_addr,
01064                data->offset);
01065     else
01066       to1 = adjust_address (data->to, mode, data->offset);
01067   }
01068 
01069       if (data->autinc_from)
01070   from1 = adjust_automodify_address (data->from, mode, data->from_addr,
01071              data->offset);
01072       else
01073   from1 = adjust_address (data->from, mode, data->offset);
01074 
01075       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
01076   emit_insn (gen_add2_insn (data->to_addr,
01077           GEN_INT (-(HOST_WIDE_INT)size)));
01078       if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
01079   emit_insn (gen_add2_insn (data->from_addr,
01080           GEN_INT (-(HOST_WIDE_INT)size)));
01081 
01082       if (data->to)
01083   emit_insn ((*genfun) (to1, from1));
01084       else
01085   {
01086 #ifdef PUSH_ROUNDING
01087     emit_single_push_insn (mode, from1, NULL);
01088 #else
01089     gcc_unreachable ();
01090 #endif
01091   }
01092 
01093       if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
01094   emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
01095       if (HAVE_POST_INCREMENT && data->explicit_inc_from > 0)
01096   emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size)));
01097 
01098       if (! data->reverse)
01099   data->offset += size;
01100 
01101       data->len -= size;
01102     }
01103 }
01104 
01105 /* Emit code to move a block Y to a block X.  This may be done with
01106    string-move instructions, with multiple scalar move instructions,
01107    or with a library call.
01108 
01109    Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
01110    SIZE is an rtx that says how long they are.
01111    ALIGN is the maximum alignment we can assume they have.
01112    METHOD describes what kind of copy this is, and what mechanisms may be used.
01113 
01114    Return the address of the new block, if memcpy is called and returns it,
01115    0 otherwise.  */
01116 
01117 rtx
01118 emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
01119 {
01120   bool may_use_call;
01121   rtx retval = 0;
01122   unsigned int align;
01123 
01124   switch (method)
01125     {
01126     case BLOCK_OP_NORMAL:
01127     case BLOCK_OP_TAILCALL:
01128       may_use_call = true;
01129       break;
01130 
01131     case BLOCK_OP_CALL_PARM:
01132       may_use_call = block_move_libcall_safe_for_call_parm ();
01133 
01134       /* Make inhibit_defer_pop nonzero around the library call
01135    to force it to pop the arguments right away.  */
01136       NO_DEFER_POP;
01137       break;
01138 
01139     case BLOCK_OP_NO_LIBCALL:
01140       may_use_call = false;
01141       break;
01142 
01143     default:
01144       gcc_unreachable ();
01145     }
01146 
01147   align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
01148 
01149   gcc_assert (MEM_P (x));
01150   gcc_assert (MEM_P (y));
01151   gcc_assert (size);
01152 
01153   /* Make sure we've got BLKmode addresses; store_one_arg can decide that
01154      block copy is more efficient for other large modes, e.g. DCmode.  */
01155   x = adjust_address (x, BLKmode, 0);
01156   y = adjust_address (y, BLKmode, 0);
01157 
01158   /* Set MEM_SIZE as appropriate for this block copy.  The main place this
01159      can be incorrect is coming from __builtin_memcpy.  */
01160   if (GET_CODE (size) == CONST_INT)
01161     {
01162       if (INTVAL (size) == 0)
01163   return 0;
01164 
01165       x = shallow_copy_rtx (x);
01166       y = shallow_copy_rtx (y);
01167       set_mem_size (x, size);
01168       set_mem_size (y, size);
01169     }
01170 
01171   if (GET_CODE (size) == CONST_INT && MOVE_BY_PIECES_P (INTVAL (size), align))
01172     move_by_pieces (x, y, INTVAL (size), align, 0);
01173   else if (emit_block_move_via_movmem (x, y, size, align))
01174     ;
01175   else if (may_use_call)
01176     retval = emit_block_move_via_libcall (x, y, size,
01177             method == BLOCK_OP_TAILCALL);
01178   else
01179     emit_block_move_via_loop (x, y, size, align);
01180 
01181   if (method == BLOCK_OP_CALL_PARM)
01182     OK_DEFER_POP;
01183 
01184   return retval;
01185 }
01186 
01187 /* A subroutine of emit_block_move.  Returns true if calling the
01188    block move libcall will not clobber any parameters which may have
01189    already been placed on the stack.  */
01190 
01191 static bool
01192 block_move_libcall_safe_for_call_parm (void)
01193 {
01194   /* If arguments are pushed on the stack, then they're safe.  */
01195   if (PUSH_ARGS)
01196     return true;
01197 
01198   /* If registers go on the stack anyway, any argument is sure to clobber
01199      an outgoing argument.  */
01200 #if defined (REG_PARM_STACK_SPACE) && defined (OUTGOING_REG_PARM_STACK_SPACE)
01201   {
01202     tree fn = emit_block_move_libcall_fn (false);
01203     (void) fn;
01204     if (REG_PARM_STACK_SPACE (fn) != 0)
01205       return false;
01206   }
01207 #endif
01208 
01209   /* If any argument goes in memory, then it might clobber an outgoing
01210      argument.  */
01211   {
01212     CUMULATIVE_ARGS args_so_far;
01213     tree fn, arg;
01214 
01215     fn = emit_block_move_libcall_fn (false);
01216     INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0, 3);
01217 
01218     arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
01219     for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
01220       {
01221   enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
01222   rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
01223   if (!tmp || !REG_P (tmp))
01224     return false;
01225   if (targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL, 1))
01226     return false;
01227   FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
01228       }
01229   }
01230   return true;
01231 }
01232 
01233 /* A subroutine of emit_block_move.  Expand a movmem pattern;
01234    return true if successful.  */
01235 
01236 static bool
01237 emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align)
01238 {
01239   rtx opalign = GEN_INT (align / BITS_PER_UNIT);
01240   int save_volatile_ok = volatile_ok;
01241   enum machine_mode mode;
01242 
01243   /* Since this is a move insn, we don't care about volatility.  */
01244   volatile_ok = 1;
01245 
01246   /* Try the most limited insn first, because there's no point
01247      including more than one in the machine description unless
01248      the more limited one has some advantage.  */
01249 
01250   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
01251        mode = GET_MODE_WIDER_MODE (mode))
01252     {
01253       enum insn_code code = movmem_optab[(int) mode];
01254       insn_operand_predicate_fn pred;
01255 
01256       if (code != CODE_FOR_nothing
01257     /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
01258        here because if SIZE is less than the mode mask, as it is
01259        returned by the macro, it will definitely be less than the
01260        actual mode mask.  */
01261     && ((GET_CODE (size) == CONST_INT
01262          && ((unsigned HOST_WIDE_INT) INTVAL (size)
01263        <= (GET_MODE_MASK (mode) >> 1)))
01264         || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
01265     && ((pred = insn_data[(int) code].operand[0].predicate) == 0
01266         || (*pred) (x, BLKmode))
01267     && ((pred = insn_data[(int) code].operand[1].predicate) == 0
01268         || (*pred) (y, BLKmode))
01269     && ((pred = insn_data[(int) code].operand[3].predicate) == 0
01270         || (*pred) (opalign, VOIDmode)))
01271   {
01272     rtx op2;
01273     rtx last = get_last_insn ();
01274     rtx pat;
01275 
01276     op2 = convert_to_mode (mode, size, 1);
01277     pred = insn_data[(int) code].operand[2].predicate;
01278     if (pred != 0 && ! (*pred) (op2, mode))
01279       op2 = copy_to_mode_reg (mode, op2);
01280 
01281     /* ??? When called via emit_block_move_for_call, it'd be
01282        nice if there were some way to inform the backend, so
01283        that it doesn't fail the expansion because it thinks
01284        emitting the libcall would be more efficient.  */
01285 
01286     pat = GEN_FCN ((int) code) (x, y, op2, opalign);
01287     if (pat)
01288       {
01289         emit_insn (pat);
01290         volatile_ok = save_volatile_ok;
01291         return true;
01292       }
01293     else
01294       delete_insns_since (last);
01295   }
01296     }
01297 
01298   volatile_ok = save_volatile_ok;
01299   return false;
01300 }
01301 
01302 /* A subroutine of emit_block_move.  Expand a call to memcpy.
01303    Return the return value from memcpy, 0 otherwise.  */
01304 
01305 static rtx
01306 emit_block_move_via_libcall (rtx dst, rtx src, rtx size, bool tailcall)
01307 {
01308   rtx dst_addr, src_addr;
01309   tree call_expr, arg_list, fn, src_tree, dst_tree, size_tree;
01310   enum machine_mode size_mode;
01311   rtx retval;
01312 
01313   /* Emit code to copy the addresses of DST and SRC and SIZE into new
01314      pseudos.  We can then place those new pseudos into a VAR_DECL and
01315      use them later.  */
01316 
01317   dst_addr = copy_to_mode_reg (Pmode, XEXP (dst, 0));
01318   src_addr = copy_to_mode_reg (Pmode, XEXP (src, 0));
01319 
01320   dst_addr = convert_memory_address (ptr_mode, dst_addr);
01321   src_addr = convert_memory_address (ptr_mode, src_addr);
01322 
01323   dst_tree = make_tree (ptr_type_node, dst_addr);
01324   src_tree = make_tree (ptr_type_node, src_addr);
01325 
01326   size_mode = TYPE_MODE (sizetype);
01327 
01328   size = convert_to_mode (size_mode, size, 1);
01329   size = copy_to_mode_reg (size_mode, size);
01330 
01331   /* It is incorrect to use the libcall calling conventions to call
01332      memcpy in this context.  This could be a user call to memcpy and
01333      the user may wish to examine the return value from memcpy.  For
01334      targets where libcalls and normal calls have different conventions
01335      for returning pointers, we could end up generating incorrect code.  */
01336 
01337   size_tree = make_tree (sizetype, size);
01338 
01339   fn = emit_block_move_libcall_fn (true);
01340   arg_list = tree_cons (NULL_TREE, size_tree, NULL_TREE);
01341   arg_list = tree_cons (NULL_TREE, src_tree, arg_list);
01342   arg_list = tree_cons (NULL_TREE, dst_tree, arg_list);
01343 
01344   /* Now we have to build up the CALL_EXPR itself.  */
01345   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
01346   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
01347           call_expr, arg_list, NULL_TREE);
01348   CALL_EXPR_TAILCALL (call_expr) = tailcall;
01349 
01350   retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
01351 
01352   return retval;
01353 }
01354 
01355 /* A subroutine of emit_block_move_via_libcall.  Create the tree node
01356    for the function we use for block copies.  The first time FOR_CALL
01357    is true, we call assemble_external.  */
01358 
01359 static GTY(()) tree block_move_fn;
01360 
01361 void
01362 init_block_move_fn (const char *asmspec)
01363 {
01364   if (!block_move_fn)
01365     {
01366       tree args, fn;
01367 
01368       fn = get_identifier ("memcpy");
01369       args = build_function_type_list (ptr_type_node, ptr_type_node,
01370                const_ptr_type_node, sizetype,
01371                NULL_TREE);
01372 
01373       fn = build_decl (FUNCTION_DECL, fn, args);
01374       DECL_EXTERNAL (fn) = 1;
01375       TREE_PUBLIC (fn) = 1;
01376       DECL_ARTIFICIAL (fn) = 1;
01377       TREE_NOTHROW (fn) = 1;
01378 
01379       block_move_fn = fn;
01380     }
01381 
01382   if (asmspec)
01383     set_user_assembler_name (block_move_fn, asmspec);
01384 }
01385 
01386 static tree
01387 emit_block_move_libcall_fn (int for_call)
01388 {
01389   static bool emitted_extern;
01390 
01391   if (!block_move_fn)
01392     init_block_move_fn (NULL);
01393 
01394   if (for_call && !emitted_extern)
01395     {
01396       emitted_extern = true;
01397       make_decl_rtl (block_move_fn);
01398       assemble_external (block_move_fn);
01399     }
01400 
01401   return block_move_fn;
01402 }
01403 
01404 /* A subroutine of emit_block_move.  Copy the data via an explicit
01405    loop.  This is used only when libcalls are forbidden.  */
01406 /* ??? It'd be nice to copy in hunks larger than QImode.  */
01407 
01408 static void
01409 emit_block_move_via_loop (rtx x, rtx y, rtx size,
01410         unsigned int align ATTRIBUTE_UNUSED)
01411 {
01412   rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
01413   enum machine_mode iter_mode;
01414 
01415   iter_mode = GET_MODE (size);
01416   if (iter_mode == VOIDmode)
01417     iter_mode = word_mode;
01418 
01419   top_label = gen_label_rtx ();
01420   cmp_label = gen_label_rtx ();
01421   iter = gen_reg_rtx (iter_mode);
01422 
01423   emit_move_insn (iter, const0_rtx);
01424 
01425   x_addr = force_operand (XEXP (x, 0), NULL_RTX);
01426   y_addr = force_operand (XEXP (y, 0), NULL_RTX);
01427   do_pending_stack_adjust ();
01428 
01429   emit_jump (cmp_label);
01430   emit_label (top_label);
01431 
01432   tmp = convert_modes (Pmode, iter_mode, iter, true);
01433   x_addr = gen_rtx_PLUS (Pmode, x_addr, tmp);
01434   y_addr = gen_rtx_PLUS (Pmode, y_addr, tmp);
01435   x = change_address (x, QImode, x_addr);
01436   y = change_address (y, QImode, y_addr);
01437 
01438   emit_move_insn (x, y);
01439 
01440   tmp = expand_simple_binop (iter_mode, PLUS, iter, const1_rtx, iter,
01441            true, OPTAB_LIB_WIDEN);
01442   if (tmp != iter)
01443     emit_move_insn (iter, tmp);
01444 
01445   emit_label (cmp_label);
01446 
01447   emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
01448          true, top_label);
01449 }
01450 
01451 /* Copy all or part of a value X into registers starting at REGNO.
01452    The number of registers to be filled is NREGS.  */
01453 
01454 void
01455 move_block_to_reg (int regno, rtx x, int nregs, enum machine_mode mode)
01456 {
01457   int i;
01458 #ifdef HAVE_load_multiple
01459   rtx pat;
01460   rtx last;
01461 #endif
01462 
01463   if (nregs == 0)
01464     return;
01465 
01466   if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
01467     x = validize_mem (force_const_mem (mode, x));
01468 
01469   /* See if the machine can do this with a load multiple insn.  */
01470 #ifdef HAVE_load_multiple
01471   if (HAVE_load_multiple)
01472     {
01473       last = get_last_insn ();
01474       pat = gen_load_multiple (gen_rtx_REG (word_mode, regno), x,
01475              GEN_INT (nregs));
01476       if (pat)
01477   {
01478     emit_insn (pat);
01479     return;
01480   }
01481       else
01482   delete_insns_since (last);
01483     }
01484 #endif
01485 
01486   for (i = 0; i < nregs; i++)
01487     emit_move_insn (gen_rtx_REG (word_mode, regno + i),
01488         operand_subword_force (x, i, mode));
01489 }
01490 
01491 /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
01492    The number of registers to be filled is NREGS.  */
01493 
01494 void
01495 move_block_from_reg (int regno, rtx x, int nregs)
01496 {
01497   int i;
01498 
01499   if (nregs == 0)
01500     return;
01501 
01502   /* See if the machine can do this with a store multiple insn.  */
01503 #ifdef HAVE_store_multiple
01504   if (HAVE_store_multiple)
01505     {
01506       rtx last = get_last_insn ();
01507       rtx pat = gen_store_multiple (x, gen_rtx_REG (word_mode, regno),
01508             GEN_INT (nregs));
01509       if (pat)
01510   {
01511     emit_insn (pat);
01512     return;
01513   }
01514       else
01515   delete_insns_since (last);
01516     }
01517 #endif
01518 
01519   for (i = 0; i < nregs; i++)
01520     {
01521       rtx tem = operand_subword (x, i, 1, BLKmode);
01522 
01523       gcc_assert (tem);
01524 
01525       emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
01526     }
01527 }
01528 
01529 /* Generate a PARALLEL rtx for a new non-consecutive group of registers from
01530    ORIG, where ORIG is a non-consecutive group of registers represented by
01531    a PARALLEL.  The clone is identical to the original except in that the
01532    original set of registers is replaced by a new set of pseudo registers.
01533    The new set has the same modes as the original set.  */
01534 
01535 rtx
01536 gen_group_rtx (rtx orig)
01537 {
01538   int i, length;
01539   rtx *tmps;
01540 
01541   gcc_assert (GET_CODE (orig) == PARALLEL);
01542 
01543   length = XVECLEN (orig, 0);
01544   tmps = alloca (sizeof (rtx) * length);
01545 
01546   /* Skip a NULL entry in first slot.  */
01547   i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
01548 
01549   if (i)
01550     tmps[0] = 0;
01551 
01552   for (; i < length; i++)
01553     {
01554       enum machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
01555       rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
01556 
01557       tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
01558     }
01559 
01560   return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
01561 }
01562 
01563 /* A subroutine of emit_group_load.  Arguments as for emit_group_load,
01564    except that values are placed in TMPS[i], and must later be moved
01565    into corresponding XEXP (XVECEXP (DST, 0, i), 0) element.  */
01566 
01567 static void
01568 emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
01569 {
01570   rtx src;
01571   int start, i;
01572   enum machine_mode m = GET_MODE (orig_src);
01573 
01574   gcc_assert (GET_CODE (dst) == PARALLEL);
01575 
01576   if (m != VOIDmode
01577       && !SCALAR_INT_MODE_P (m)
01578       && !MEM_P (orig_src)
01579       && GET_CODE (orig_src) != CONCAT)
01580     {
01581       enum machine_mode imode = int_mode_for_mode (GET_MODE (orig_src));
01582       if (imode == BLKmode)
01583   src = assign_stack_temp (GET_MODE (orig_src), ssize, 0);
01584       else
01585   src = gen_reg_rtx (imode);
01586       if (imode != BLKmode)
01587   src = gen_lowpart (GET_MODE (orig_src), src);
01588       emit_move_insn (src, orig_src);
01589       /* ...and back again.  */
01590       if (imode != BLKmode)
01591   src = gen_lowpart (imode, src);
01592       emit_group_load_1 (tmps, dst, src, type, ssize);
01593       return;
01594     }
01595 
01596   /* Check for a NULL entry, used to indicate that the parameter goes
01597      both on the stack and in registers.  */
01598   if (XEXP (XVECEXP (dst, 0, 0), 0))
01599     start = 0;
01600   else
01601     start = 1;
01602 
01603   /* Process the pieces.  */
01604   for (i = start; i < XVECLEN (dst, 0); i++)
01605     {
01606       enum machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
01607       HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (dst, 0, i), 1));
01608       unsigned int bytelen = GET_MODE_SIZE (mode);
01609       int shift = 0;
01610 
01611       /* Handle trailing fragments that run over the size of the struct.  */
01612       if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
01613   {
01614     /* Arrange to shift the fragment to where it belongs.
01615        extract_bit_field loads to the lsb of the reg.  */
01616     if (
01617 #ifdef BLOCK_REG_PADDING
01618         BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
01619         == (BYTES_BIG_ENDIAN ? upward : downward)
01620 #else
01621         BYTES_BIG_ENDIAN
01622 #endif
01623         )
01624       shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
01625     bytelen = ssize - bytepos;
01626     gcc_assert (bytelen > 0);
01627   }
01628 
01629       /* If we won't be loading directly from memory, protect the real source
01630    from strange tricks we might play; but make sure that the source can
01631    be loaded directly into the destination.  */
01632       src = orig_src;
01633       if (!MEM_P (orig_src)
01634     && (!CONSTANT_P (orig_src)
01635         || (GET_MODE (orig_src) != mode
01636       && GET_MODE (orig_src) != VOIDmode)))
01637   {
01638     if (GET_MODE (orig_src) == VOIDmode)
01639       src = gen_reg_rtx (mode);
01640     else
01641       src = gen_reg_rtx (GET_MODE (orig_src));
01642 
01643     emit_move_insn (src, orig_src);
01644   }
01645 
01646       /* Optimize the access just a bit.  */
01647       if (MEM_P (src)
01648     && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (src))
01649         || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
01650     && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
01651     && bytelen == GET_MODE_SIZE (mode))
01652   {
01653     tmps[i] = gen_reg_rtx (mode);
01654     emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
01655   }
01656       else if (COMPLEX_MODE_P (mode)
01657          && GET_MODE (src) == mode
01658          && bytelen == GET_MODE_SIZE (mode))
01659   /* Let emit_move_complex do the bulk of the work.  */
01660   tmps[i] = src;
01661       else if (GET_CODE (src) == CONCAT)
01662   {
01663     unsigned int slen = GET_MODE_SIZE (GET_MODE (src));
01664     unsigned int slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
01665 
01666     if ((bytepos == 0 && bytelen == slen0)
01667         || (bytepos != 0 && bytepos + bytelen <= slen))
01668       {
01669         /* The following assumes that the concatenated objects all
01670      have the same size.  In this case, a simple calculation
01671      can be used to determine the object and the bit field
01672      to be extracted.  */
01673         tmps[i] = XEXP (src, bytepos / slen0);
01674         if (! CONSTANT_P (tmps[i])
01675       && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode))
01676     tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
01677                (bytepos % slen0) * BITS_PER_UNIT,
01678                1, NULL_RTX, mode, mode);
01679       }
01680     else
01681       {
01682         rtx mem;
01683 
01684         gcc_assert (!bytepos);
01685         mem = assign_stack_temp (GET_MODE (src), slen, 0);
01686         emit_move_insn (mem, src);
01687         tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
01688              0, 1, NULL_RTX, mode, mode);
01689       }
01690   }
01691       /* FIXME: A SIMD parallel will eventually lead to a subreg of a
01692    SIMD register, which is currently broken.  While we get GCC
01693    to emit proper RTL for these cases, let's dump to memory.  */
01694       else if (VECTOR_MODE_P (GET_MODE (dst))
01695          && REG_P (src))
01696   {
01697     int slen = GET_MODE_SIZE (GET_MODE (src));
01698     rtx mem;
01699 
01700     mem = assign_stack_temp (GET_MODE (src), slen, 0);
01701     emit_move_insn (mem, src);
01702     tmps[i] = adjust_address (mem, mode, (int) bytepos);
01703   }
01704       else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
01705                && XVECLEN (dst, 0) > 1)
01706         tmps[i] = simplify_gen_subreg (mode, src, GET_MODE(dst), bytepos);
01707       else if (CONSTANT_P (src)
01708          || (REG_P (src) && GET_MODE (src) == mode))
01709   tmps[i] = src;
01710       else
01711   tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
01712              bytepos * BITS_PER_UNIT, 1, NULL_RTX,
01713              mode, mode);
01714 
01715       if (shift)
01716   tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
01717         build_int_cst (NULL_TREE, shift), tmps[i], 0);
01718     }
01719 }
01720 
01721 /* Emit code to move a block SRC of type TYPE to a block DST,
01722    where DST is non-consecutive registers represented by a PARALLEL.
01723    SSIZE represents the total size of block ORIG_SRC in bytes, or -1
01724    if not known.  */
01725 
01726 void
01727 emit_group_load (rtx dst, rtx src, tree type, int ssize)
01728 {
01729   rtx *tmps;
01730   int i;
01731 
01732   tmps = alloca (sizeof (rtx) * XVECLEN (dst, 0));
01733   emit_group_load_1 (tmps, dst, src, type, ssize);
01734 
01735   /* Copy the extracted pieces into the proper (probable) hard regs.  */
01736   for (i = 0; i < XVECLEN (dst, 0); i++)
01737     {
01738       rtx d = XEXP (XVECEXP (dst, 0, i), 0);
01739       if (d == NULL)
01740   continue;
01741       emit_move_insn (d, tmps[i]);
01742     }
01743 }
01744 
01745 /* Similar, but load SRC into new pseudos in a format that looks like
01746    PARALLEL.  This can later be fed to emit_group_move to get things
01747    in the right place.  */
01748 
01749 rtx
01750 emit_group_load_into_temps (rtx parallel, rtx src, tree type, int ssize)
01751 {
01752   rtvec vec;
01753   int i;
01754 
01755   vec = rtvec_alloc (XVECLEN (parallel, 0));
01756   emit_group_load_1 (&RTVEC_ELT (vec, 0), parallel, src, type, ssize);
01757 
01758   /* Convert the vector to look just like the original PARALLEL, except
01759      with the computed values.  */
01760   for (i = 0; i < XVECLEN (parallel, 0); i++)
01761     {
01762       rtx e = XVECEXP (parallel, 0, i);
01763       rtx d = XEXP (e, 0);
01764 
01765       if (d)
01766   {
01767     d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i));
01768     e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1));
01769   }
01770       RTVEC_ELT (vec, i) = e;
01771     }
01772 
01773   return gen_rtx_PARALLEL (GET_MODE (parallel), vec);
01774 }
01775 
01776 /* Emit code to move a block SRC to block DST, where SRC and DST are
01777    non-consecutive groups of registers, each represented by a PARALLEL.  */
01778 
01779 void
01780 emit_group_move (rtx dst, rtx src)
01781 {
01782   int i;
01783 
01784   gcc_assert (GET_CODE (src) == PARALLEL
01785         && GET_CODE (dst) == PARALLEL
01786         && XVECLEN (src, 0) == XVECLEN (dst, 0));
01787 
01788   /* Skip first entry if NULL.  */
01789   for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
01790     emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
01791         XEXP (XVECEXP (src, 0, i), 0));
01792 }
01793 
01794 /* Move a group of registers represented by a PARALLEL into pseudos.  */
01795 
01796 rtx
01797 emit_group_move_into_temps (rtx src)
01798 {
01799   rtvec vec = rtvec_alloc (XVECLEN (src, 0));
01800   int i;
01801 
01802   for (i = 0; i < XVECLEN (src, 0); i++)
01803     {
01804       rtx e = XVECEXP (src, 0, i);
01805       rtx d = XEXP (e, 0);
01806 
01807       if (d)
01808   e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1));
01809       RTVEC_ELT (vec, i) = e;
01810     }
01811 
01812   return gen_rtx_PARALLEL (GET_MODE (src), vec);
01813 }
01814 
01815 /* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
01816    where SRC is non-consecutive registers represented by a PARALLEL.
01817    SSIZE represents the total size of block ORIG_DST, or -1 if not
01818    known.  */
01819 
01820 void
01821 emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
01822 {
01823   rtx *tmps, dst;
01824   int start, i;
01825   enum machine_mode m = GET_MODE (orig_dst);
01826 
01827   gcc_assert (GET_CODE (src) == PARALLEL);
01828 
01829   if (!SCALAR_INT_MODE_P (m)
01830       && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT)
01831     {
01832       enum machine_mode imode = int_mode_for_mode (GET_MODE (orig_dst));
01833       if (imode == BLKmode)
01834         dst = assign_stack_temp (GET_MODE (orig_dst), ssize, 0);
01835       else
01836         dst = gen_reg_rtx (imode);
01837       emit_group_store (dst, src, type, ssize);
01838       if (imode != BLKmode)
01839         dst = gen_lowpart (GET_MODE (orig_dst), dst);
01840       emit_move_insn (orig_dst, dst);
01841       return;
01842     }
01843 
01844   /* Check for a NULL entry, used to indicate that the parameter goes
01845      both on the stack and in registers.  */
01846   if (XEXP (XVECEXP (src, 0, 0), 0))
01847     start = 0;
01848   else
01849     start = 1;
01850 
01851   tmps = alloca (sizeof (rtx) * XVECLEN (src, 0));
01852 
01853   /* Copy the (probable) hard regs into pseudos.  */
01854   for (i = start; i < XVECLEN (src, 0); i++)
01855     {
01856       rtx reg = XEXP (XVECEXP (src, 0, i), 0);
01857       tmps[i] = gen_reg_rtx (GET_MODE (reg));
01858       emit_move_insn (tmps[i], reg);
01859     }
01860 
01861   /* If we won't be storing directly into memory, protect the real destination
01862      from strange tricks we might play.  */
01863   dst = orig_dst;
01864   if (GET_CODE (dst) == PARALLEL)
01865     {
01866       rtx temp;
01867 
01868       /* We can get a PARALLEL dst if there is a conditional expression in
01869    a return statement.  In that case, the dst and src are the same,
01870    so no action is necessary.  */
01871       if (rtx_equal_p (dst, src))
01872   return;
01873 
01874       /* It is unclear if we can ever reach here, but we may as well handle
01875    it.  Allocate a temporary, and split this into a store/load to/from
01876    the temporary.  */
01877 
01878       temp = assign_stack_temp (GET_MODE (dst), ssize, 0);
01879       emit_group_store (temp, src, type, ssize);
01880       emit_group_load (dst, temp, type, ssize);
01881       return;
01882     }
01883   else if (!MEM_P (dst) && GET_CODE (dst) != CONCAT)
01884     {
01885       dst = gen_reg_rtx (GET_MODE (orig_dst));
01886       /* Make life a bit easier for combine.  */
01887       emit_move_insn (dst, CONST0_RTX (GET_MODE (orig_dst)));
01888     }
01889 
01890   /* Process the pieces.  */
01891   for (i = start; i < XVECLEN (src, 0); i++)
01892     {
01893       HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1));
01894       enum machine_mode mode = GET_MODE (tmps[i]);
01895       unsigned int bytelen = GET_MODE_SIZE (mode);
01896       rtx dest = dst;
01897 
01898       /* Handle trailing fragments that run over the size of the struct.  */
01899       if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
01900   {
01901     /* store_bit_field always takes its value from the lsb.
01902        Move the fragment to the lsb if it's not already there.  */
01903     if (
01904 #ifdef BLOCK_REG_PADDING
01905         BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
01906         == (BYTES_BIG_ENDIAN ? upward : downward)
01907 #else
01908         BYTES_BIG_ENDIAN
01909 #endif
01910         )
01911       {
01912         int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
01913         tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
01914               build_int_cst (NULL_TREE, shift),
01915               tmps[i], 0);
01916       }
01917     bytelen = ssize - bytepos;
01918   }
01919 
01920       if (GET_CODE (dst) == CONCAT)
01921   {
01922     if (bytepos + bytelen <= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))))
01923       dest = XEXP (dst, 0);
01924     else if (bytepos >= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))))
01925       {
01926         bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
01927         dest = XEXP (dst, 1);
01928       }
01929     else
01930       {
01931         gcc_assert (bytepos == 0 && XVECLEN (src, 0));
01932         dest = assign_stack_temp (GET_MODE (dest),
01933                 GET_MODE_SIZE (GET_MODE (dest)), 0);
01934         emit_move_insn (adjust_address (dest, GET_MODE (tmps[i]), bytepos),
01935             tmps[i]);
01936         dst = dest;
01937         break;
01938       }
01939   }
01940 
01941       /* Optimize the access just a bit.  */
01942       if (MEM_P (dest)
01943     && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
01944         || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
01945     && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
01946     && bytelen == GET_MODE_SIZE (mode))
01947   emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
01948       else
01949   store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
01950        mode, tmps[i]);
01951     }
01952 
01953   /* Copy from the pseudo into the (probable) hard reg.  */
01954   if (orig_dst != dst)
01955     emit_move_insn (orig_dst, dst);
01956 }
01957 
01958 /* Generate code to copy a BLKmode object of TYPE out of a
01959    set of registers starting with SRCREG into TGTBLK.  If TGTBLK
01960    is null, a stack temporary is created.  TGTBLK is returned.
01961 
01962    The purpose of this routine is to handle functions that return
01963    BLKmode structures in registers.  Some machines (the PA for example)
01964    want to return all small structures in registers regardless of the
01965    structure's alignment.  */
01966 
01967 rtx
01968 copy_blkmode_from_reg (rtx tgtblk, rtx srcreg, tree type)
01969 {
01970   unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
01971   rtx src = NULL, dst = NULL;
01972   unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
01973   unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
01974 
01975   if (tgtblk == 0)
01976     {
01977       tgtblk = assign_temp (build_qualified_type (type,
01978               (TYPE_QUALS (type)
01979                | TYPE_QUAL_CONST)),
01980           0, 1, 1);
01981       preserve_temp_slots (tgtblk);
01982     }
01983 
01984   /* This code assumes srcreg is at least a full word.  If it isn't, copy it
01985      into a new pseudo which is a full word.  */
01986 
01987   if (GET_MODE (srcreg) != BLKmode
01988       && GET_MODE_SIZE (GET_MODE (srcreg)) < UNITS_PER_WORD)
01989     srcreg = convert_to_mode (word_mode, srcreg, TYPE_UNSIGNED (type));
01990 
01991   /* If the structure doesn't take up a whole number of words, see whether
01992      SRCREG is padded on the left or on the right.  If it's on the left,
01993      set PADDING_CORRECTION to the number of bits to skip.
01994 
01995      In most ABIs, the structure will be returned at the least end of
01996      the register, which translates to right padding on little-endian
01997      targets and left padding on big-endian targets.  The opposite
01998      holds if the structure is returned at the most significant
01999      end of the register.  */
02000   if (bytes % UNITS_PER_WORD != 0
02001       && (targetm.calls.return_in_msb (type)
02002     ? !BYTES_BIG_ENDIAN
02003     : BYTES_BIG_ENDIAN))
02004     padding_correction
02005       = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
02006 
02007   /* Copy the structure BITSIZE bites at a time.
02008 
02009      We could probably emit more efficient code for machines which do not use
02010      strict alignment, but it doesn't seem worth the effort at the current
02011      time.  */
02012   for (bitpos = 0, xbitpos = padding_correction;
02013        bitpos < bytes * BITS_PER_UNIT;
02014        bitpos += bitsize, xbitpos += bitsize)
02015     {
02016       /* We need a new source operand each time xbitpos is on a
02017    word boundary and when xbitpos == padding_correction
02018    (the first time through).  */
02019       if (xbitpos % BITS_PER_WORD == 0
02020     || xbitpos == padding_correction)
02021   src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD,
02022              GET_MODE (srcreg));
02023 
02024       /* We need a new destination operand each time bitpos is on
02025    a word boundary.  */
02026       if (bitpos % BITS_PER_WORD == 0)
02027   dst = operand_subword (tgtblk, bitpos / BITS_PER_WORD, 1, BLKmode);
02028 
02029       /* Use xbitpos for the source extraction (right justified) and
02030    xbitpos for the destination store (left justified).  */
02031       store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, word_mode,
02032            extract_bit_field (src, bitsize,
02033             xbitpos % BITS_PER_WORD, 1,
02034             NULL_RTX, word_mode, word_mode));
02035     }
02036 
02037   return tgtblk;
02038 }
02039 
02040 /* Add a USE expression for REG to the (possibly empty) list pointed
02041    to by CALL_FUSAGE.  REG must denote a hard register.  */
02042 
02043 void
02044 use_reg (rtx *call_fusage, rtx reg)
02045 {
02046   gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
02047   
02048   *call_fusage
02049     = gen_rtx_EXPR_LIST (VOIDmode,
02050        gen_rtx_USE (VOIDmode, reg), *call_fusage);
02051 }
02052 
02053 /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
02054    starting at REGNO.  All of these registers must be hard registers.  */
02055 
02056 void
02057 use_regs (rtx *call_fusage, int regno, int nregs)
02058 {
02059   int i;
02060 
02061   gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
02062 
02063   for (i = 0; i < nregs; i++)
02064     use_reg (call_fusage, regno_reg_rtx[regno + i]);
02065 }
02066 
02067 /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
02068    PARALLEL REGS.  This is for calls that pass values in multiple
02069    non-contiguous locations.  The Irix 6 ABI has examples of this.  */
02070 
02071 void
02072 use_group_regs (rtx *call_fusage, rtx regs)
02073 {
02074   int i;
02075 
02076   for (i = 0; i < XVECLEN (regs, 0); i++)
02077     {
02078       rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
02079 
02080       /* A NULL entry means the parameter goes both on the stack and in
02081    registers.  This can also be a MEM for targets that pass values
02082    partially on the stack and partially in registers.  */
02083       if (reg != 0 && REG_P (reg))
02084   use_reg (call_fusage, reg);
02085     }
02086 }
02087 
02088 
02089 /* Determine whether the LEN bytes generated by CONSTFUN can be
02090    stored to memory using several move instructions.  CONSTFUNDATA is
02091    a pointer which will be passed as argument in every CONSTFUN call.
02092    ALIGN is maximum alignment we can assume.  Return nonzero if a
02093    call to store_by_pieces should succeed.  */
02094 
02095 int
02096 can_store_by_pieces (unsigned HOST_WIDE_INT len,
02097          rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
02098          void *constfundata, unsigned int align)
02099 {
02100   unsigned HOST_WIDE_INT l;
02101   unsigned int max_size;
02102   HOST_WIDE_INT offset = 0;
02103   enum machine_mode mode, tmode;
02104   enum insn_code icode;
02105   int reverse;
02106   rtx cst;
02107 
02108   if (len == 0)
02109     return 1;
02110 
02111   if (! STORE_BY_PIECES_P (len, align))
02112     return 0;
02113 
02114   tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
02115   if (align >= GET_MODE_ALIGNMENT (tmode))
02116     align = GET_MODE_ALIGNMENT (tmode);
02117   else
02118     {
02119       enum machine_mode xmode;
02120 
02121       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
02122      tmode != VOIDmode;
02123      xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
02124   if (GET_MODE_SIZE (tmode) > STORE_MAX_PIECES
02125       || SLOW_UNALIGNED_ACCESS (tmode, align))
02126     break;
02127 
02128       align = MAX (align, GET_MODE_ALIGNMENT (xmode));
02129     }
02130 
02131   /* We would first store what we can in the largest integer mode, then go to
02132      successively smaller modes.  */
02133 
02134   for (reverse = 0;
02135        reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
02136        reverse++)
02137     {
02138       l = len;
02139       mode = VOIDmode;
02140       max_size = STORE_MAX_PIECES + 1;
02141       while (max_size > 1)
02142   {
02143     for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
02144          tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
02145       if (GET_MODE_SIZE (tmode) < max_size)
02146         mode = tmode;
02147 
02148     if (mode == VOIDmode)
02149       break;
02150 
02151     icode = mov_optab->handlers[(int) mode].insn_code;
02152     if (icode != CODE_FOR_nothing
02153         && align >= GET_MODE_ALIGNMENT (mode))
02154       {
02155         unsigned int size = GET_MODE_SIZE (mode);
02156 
02157         while (l >= size)
02158     {
02159       if (reverse)
02160         offset -= size;
02161 
02162       cst = (*constfun) (constfundata, offset, mode);
02163       if (!LEGITIMATE_CONSTANT_P (cst))
02164         return 0;
02165 
02166       if (!reverse)
02167         offset += size;
02168 
02169       l -= size;
02170     }
02171       }
02172 
02173     max_size = GET_MODE_SIZE (mode);
02174   }
02175 
02176       /* The code above should have handled everything.  */
02177       gcc_assert (!l);
02178     }
02179 
02180   return 1;
02181 }
02182 
02183 /* Generate several move instructions to store LEN bytes generated by
02184    CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
02185    pointer which will be passed as argument in every CONSTFUN call.
02186    ALIGN is maximum alignment we can assume.
02187    If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
02188    mempcpy, and if ENDP is 2 return memory the end minus one byte ala
02189    stpcpy.  */
02190 
02191 rtx
02192 store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
02193      rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
02194      void *constfundata, unsigned int align, int endp)
02195 {
02196   struct store_by_pieces data;
02197 
02198   if (len == 0)
02199     {
02200       gcc_assert (endp != 2);
02201       return to;
02202     }
02203 
02204   gcc_assert (STORE_BY_PIECES_P (len, align));
02205   data.constfun = constfun;
02206   data.constfundata = constfundata;
02207   data.len = len;
02208   data.to = to;
02209   store_by_pieces_1 (&data, align);
02210   if (endp)
02211     {
02212       rtx to1;
02213 
02214       gcc_assert (!data.reverse);
02215       if (data.autinc_to)
02216   {
02217     if (endp == 2)
02218       {
02219         if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
02220     emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
02221         else
02222     data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
02223                 -1));
02224       }
02225     to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
02226              data.offset);
02227   }
02228       else
02229   {
02230     if (endp == 2)
02231       --data.offset;
02232     to1 = adjust_address (data.to, QImode, data.offset);
02233   }
02234       return to1;
02235     }
02236   else
02237     return data.to;
02238 }
02239 
02240 /* Generate several move instructions to clear LEN bytes of block TO.  (A MEM
02241    rtx with BLKmode).  ALIGN is maximum alignment we can assume.  */
02242 
02243 static void
02244 clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
02245 {
02246   struct store_by_pieces data;
02247 
02248   if (len == 0)
02249     return;
02250 
02251   data.constfun = clear_by_pieces_1;
02252   data.constfundata = NULL;
02253   data.len = len;
02254   data.to = to;
02255   store_by_pieces_1 (&data, align);
02256 }
02257 
02258 /* Callback routine for clear_by_pieces.
02259    Return const0_rtx unconditionally.  */
02260 
02261 static rtx
02262 clear_by_pieces_1 (void *data ATTRIBUTE_UNUSED,
02263        HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
02264        enum machine_mode mode ATTRIBUTE_UNUSED)
02265 {
02266   return const0_rtx;
02267 }
02268 
02269 /* Subroutine of clear_by_pieces and store_by_pieces.
02270    Generate several move instructions to store LEN bytes of block TO.  (A MEM
02271    rtx with BLKmode).  ALIGN is maximum alignment we can assume.  */
02272 
02273 static void
02274 store_by_pieces_1 (struct store_by_pieces *data ATTRIBUTE_UNUSED,
02275        unsigned int align ATTRIBUTE_UNUSED)
02276 {
02277   rtx to_addr = XEXP (data->to, 0);
02278   unsigned int max_size = STORE_MAX_PIECES + 1;
02279   enum machine_mode mode = VOIDmode, tmode;
02280   enum insn_code icode;
02281 
02282   data->offset = 0;
02283   data->to_addr = to_addr;
02284   data->autinc_to
02285     = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
02286        || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
02287 
02288   data->explicit_inc_to = 0;
02289   data->reverse
02290     = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
02291   if (data->reverse)
02292     data->offset = data->len;
02293 
02294   /* If storing requires more than two move insns,
02295      copy addresses to registers (to make displacements shorter)
02296      and use post-increment if available.  */
02297   if (!data->autinc_to
02298       && move_by_pieces_ninsns (data->len, align, max_size) > 2)
02299     {
02300       /* Determine the main mode we'll be using.  */
02301       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
02302      tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
02303   if (GET_MODE_SIZE (tmode) < max_size)
02304     mode = tmode;
02305 
02306       if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
02307   {
02308     data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len));
02309     data->autinc_to = 1;
02310     data->explicit_inc_to = -1;
02311   }
02312 
02313       if (USE_STORE_POST_INCREMENT (mode) && ! data->reverse
02314     && ! data->autinc_to)
02315   {
02316     data->to_addr = copy_addr_to_reg (to_addr);
02317     data->autinc_to = 1;
02318     data->explicit_inc_to = 1;
02319   }
02320 
02321       if ( !data->autinc_to && CONSTANT_P (to_addr))
02322   data->to_addr = copy_addr_to_reg (to_addr);
02323     }
02324 
02325   tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
02326   if (align >= GET_MODE_ALIGNMENT (tmode))
02327     align = GET_MODE_ALIGNMENT (tmode);
02328   else
02329     {
02330       enum machine_mode xmode;
02331 
02332       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
02333      tmode != VOIDmode;
02334      xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
02335   if (GET_MODE_SIZE (tmode) > STORE_MAX_PIECES
02336       || SLOW_UNALIGNED_ACCESS (tmode, align))
02337     break;
02338 
02339       align = MAX (align, GET_MODE_ALIGNMENT (xmode));
02340     }
02341 
02342   /* First store what we can in the largest integer mode, then go to
02343      successively smaller modes.  */
02344 
02345   while (max_size > 1)
02346     {
02347       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
02348      tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
02349   if (GET_MODE_SIZE (tmode) < max_size)
02350     mode = tmode;
02351 
02352       if (mode == VOIDmode)
02353   break;
02354 
02355       icode = mov_optab->handlers[(int) mode].insn_code;
02356       if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
02357   store_by_pieces_2 (GEN_FCN (icode), mode, data);
02358 
02359       max_size = GET_MODE_SIZE (mode);
02360     }
02361 
02362   /* The code above should have handled everything.  */
02363   gcc_assert (!data->len);
02364 }
02365 
02366 /* Subroutine of store_by_pieces_1.  Store as many bytes as appropriate
02367    with move instructions for mode MODE.  GENFUN is the gen_... function
02368    to make a move insn for that mode.  DATA has all the other info.  */
02369 
02370 static void
02371 store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
02372        struct store_by_pieces *data)
02373 {
02374   unsigned int size = GET_MODE_SIZE (mode);
02375   rtx to1, cst;
02376 
02377   while (data->len >= size)
02378     {
02379       if (data->reverse)
02380   data->offset -= size;
02381 
02382       if (data->autinc_to)
02383   to1 = adjust_automodify_address (data->to, mode, data->to_addr,
02384            data->offset);
02385       else
02386   to1 = adjust_address (data->to, mode, data->offset);
02387 
02388       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
02389   emit_insn (gen_add2_insn (data->to_addr,
02390           GEN_INT (-(HOST_WIDE_INT) size)));
02391 
02392       cst = (*data->constfun) (data->constfundata, data->offset, mode);
02393       emit_insn ((*genfun) (to1, cst));
02394 
02395       if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
02396   emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
02397 
02398       if (! data->reverse)
02399   data->offset += size;
02400 
02401       data->len -= size;
02402     }
02403 }
02404 
02405 /* Write zeros through the storage of OBJECT.  If OBJECT has BLKmode, SIZE is
02406    its length in bytes.  */
02407 
02408 rtx
02409 clear_storage (rtx object, rtx size, enum block_op_methods method)
02410 {
02411   enum machine_mode mode = GET_MODE (object);
02412   unsigned int align;
02413 
02414   gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
02415 
02416   /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
02417      just move a zero.  Otherwise, do this a piece at a time.  */
02418   if (mode != BLKmode
02419       && GET_CODE (size) == CONST_INT
02420       && INTVAL (size) == (HOST_WIDE_INT) GET_MODE_SIZE (mode))
02421     {
02422       rtx zero = CONST0_RTX (mode);
02423       if (zero != NULL)
02424   {
02425     emit_move_insn (object, zero);
02426     return NULL;
02427   }
02428 
02429       if (COMPLEX_MODE_P (mode))
02430   {
02431     zero = CONST0_RTX (GET_MODE_INNER (mode));
02432     if (zero != NULL)
02433       {
02434         write_complex_part (object, zero, 0);
02435         write_complex_part (object, zero, 1);
02436         return NULL;
02437       }
02438   }
02439     }
02440 
02441   if (size == const0_rtx)
02442     return NULL;
02443 
02444   align = MEM_ALIGN (object);
02445 
02446   if (GET_CODE (size) == CONST_INT
02447       && CLEAR_BY_PIECES_P (INTVAL (size), align))
02448     clear_by_pieces (object, INTVAL (size), align);
02449   else if (clear_storage_via_clrmem (object, size, align))
02450     ;
02451   else
02452     return clear_storage_via_libcall (object, size,
02453               method == BLOCK_OP_TAILCALL);
02454 
02455   return NULL;
02456 }
02457 
02458 /* A subroutine of clear_storage.  Expand a clrmem pattern;
02459    return true if successful.  */
02460 
02461 static bool
02462 clear_storage_via_clrmem (rtx object, rtx size, unsigned int align)
02463 {
02464   /* Try the most limited insn first, because there's no point
02465      including more than one in the machine description unless
02466      the more limited one has some advantage.  */
02467 
02468   rtx opalign = GEN_INT (align / BITS_PER_UNIT);
02469   enum machine_mode mode;
02470 
02471   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
02472        mode = GET_MODE_WIDER_MODE (mode))
02473     {
02474       enum insn_code code = clrmem_optab[(int) mode];
02475       insn_operand_predicate_fn pred;
02476 
02477       if (code != CODE_FOR_nothing
02478     /* We don't need MODE to be narrower than
02479        BITS_PER_HOST_WIDE_INT here because if SIZE is less than
02480        the mode mask, as it is returned by the macro, it will
02481        definitely be less than the actual mode mask.  */
02482     && ((GET_CODE (size) == CONST_INT
02483          && ((unsigned HOST_WIDE_INT) INTVAL (size)
02484        <= (GET_MODE_MASK (mode) >> 1)))
02485         || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
02486     && ((pred = insn_data[(int) code].operand[0].predicate) == 0
02487         || (*pred) (object, BLKmode))
02488     && ((pred = insn_data[(int) code].operand[2].predicate) == 0
02489         || (*pred) (opalign, VOIDmode)))
02490   {
02491     rtx op1;
02492     rtx last = get_last_insn ();
02493     rtx pat;
02494 
02495     op1 = convert_to_mode (mode, size, 1);
02496     pred = insn_data[(int) code].operand[1].predicate;
02497     if (pred != 0 && ! (*pred) (op1, mode))
02498       op1 = copy_to_mode_reg (mode, op1);
02499 
02500     pat = GEN_FCN ((int) code) (object, op1, opalign);
02501     if (pat)
02502       {
02503         emit_insn (pat);
02504         return true;
02505       }
02506     else
02507       delete_insns_since (last);
02508   }
02509     }
02510 
02511   return false;
02512 }
02513 
02514 /* A subroutine of clear_storage.  Expand a call to memset.
02515    Return the return value of memset, 0 otherwise.  */
02516 
02517 static rtx
02518 clear_storage_via_libcall (rtx object, rtx size, bool tailcall)
02519 {
02520   tree call_expr, arg_list, fn, object_tree, size_tree;
02521   enum machine_mode size_mode;
02522   rtx retval;
02523 
02524   /* Emit code to copy OBJECT and SIZE into new pseudos.  We can then
02525      place those into new pseudos into a VAR_DECL and use them later.  */
02526 
02527   object = copy_to_mode_reg (Pmode, XEXP (object, 0));
02528 
02529   size_mode = TYPE_MODE (sizetype);
02530   size = convert_to_mode (size_mode, size, 1);
02531   size = copy_to_mode_reg (size_mode, size);
02532 
02533   /* It is incorrect to use the libcall calling conventions to call
02534      memset in this context.  This could be a user call to memset and
02535      the user may wish to examine the return value from memset.  For
02536      targets where libcalls and normal calls have different conventions
02537      for returning pointers, we could end up generating incorrect code.  */
02538 
02539   object_tree = make_tree (ptr_type_node, object);
02540   size_tree = make_tree (sizetype, size);
02541 
02542   fn = clear_storage_libcall_fn (true);
02543   arg_list = tree_cons (NULL_TREE, size_tree, NULL_TREE);
02544   arg_list = tree_cons (NULL_TREE, integer_zero_node, arg_list);
02545   arg_list = tree_cons (NULL_TREE, object_tree, arg_list);
02546 
02547   /* Now we have to build up the CALL_EXPR itself.  */
02548   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
02549   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
02550           call_expr, arg_list, NULL_TREE);
02551   CALL_EXPR_TAILCALL (call_expr) = tailcall;
02552 
02553   retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
02554 
02555   return retval;
02556 }
02557 
02558 /* A subroutine of clear_storage_via_libcall.  Create the tree node
02559    for the function we use for block clears.  The first time FOR_CALL
02560    is true, we call assemble_external.  */
02561 
02562 static GTY(()) tree block_clear_fn;
02563 
02564 void
02565 init_block_clear_fn (const char *asmspec)
02566 {
02567   if (!block_clear_fn)
02568     {
02569       tree fn, args;
02570 
02571       fn = get_identifier ("memset");
02572       args = build_function_type_list (ptr_type_node, ptr_type_node,
02573                integer_type_node, sizetype,
02574                NULL_TREE);
02575 
02576       fn = build_decl (FUNCTION_DECL, fn, args);
02577       DECL_EXTERNAL (fn) = 1;
02578       TREE_PUBLIC (fn) = 1;
02579       DECL_ARTIFICIAL (fn) = 1;
02580       TREE_NOTHROW (fn) = 1;
02581 
02582       block_clear_fn = fn;
02583     }
02584 
02585   if (asmspec)
02586     set_user_assembler_name (block_clear_fn, asmspec);
02587 }
02588 
02589 static tree
02590 clear_storage_libcall_fn (int for_call)
02591 {
02592   static bool emitted_extern;
02593 
02594   if (!block_clear_fn)
02595     init_block_clear_fn (NULL);
02596 
02597   if (for_call && !emitted_extern)
02598     {
02599       emitted_extern = true;
02600       make_decl_rtl (block_clear_fn);
02601       assemble_external (block_clear_fn);
02602     }
02603 
02604   return block_clear_fn;
02605 }
02606 
02607 /* Write to one of the components of the complex value CPLX.  Write VAL to
02608    the real part if IMAG_P is false, and the imaginary part if its true.  */
02609 
02610 static void
02611 write_complex_part (rtx cplx, rtx val, bool imag_p)
02612 {
02613   enum machine_mode cmode;
02614   enum machine_mode imode;
02615   unsigned ibitsize;
02616 
02617   if (GET_CODE (cplx) == CONCAT)
02618     {
02619       emit_move_insn (XEXP (cplx, imag_p), val);
02620       return;
02621     }
02622 
02623   cmode = GET_MODE (cplx);
02624   imode = GET_MODE_INNER (cmode);
02625   ibitsize = GET_MODE_BITSIZE (imode);
02626 
02627   /* If the sub-object is at least word sized, then we know that subregging
02628      will work.  This special case is important, since store_bit_field
02629      wants to operate on integer modes, and there's rarely an OImode to
02630      correspond to TCmode.  */
02631   if (ibitsize >= BITS_PER_WORD
02632       /* For hard regs we have exact predicates.  Assume we can split
02633    the original object if it spans an even number of hard regs.
02634    This special case is important for SCmode on 64-bit platforms
02635    where the natural size of floating-point regs is 32-bit.  */
02636       || (GET_CODE (cplx) == REG
02637     && REGNO (cplx) < FIRST_PSEUDO_REGISTER
02638     && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
02639       /* For MEMs we always try to make a "subreg", that is to adjust
02640    the MEM, because store_bit_field may generate overly
02641    convoluted RTL for sub-word fields.  */
02642       || MEM_P (cplx))
02643     {
02644       rtx part = simplify_gen_subreg (imode, cplx, cmode,
02645               imag_p ? GET_MODE_SIZE (imode) : 0);
02646       if (part)
02647         {
02648     emit_move_insn (part, val);
02649     return;
02650   }
02651       else
02652   /* simplify_gen_subreg may fail for sub-word MEMs.  */
02653   gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
02654     }
02655 
02656   store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, imode, val);
02657 }
02658 
02659 /* Extract one of the components of the complex value CPLX.  Extract the
02660    real part if IMAG_P is false, and the imaginary part if it's true.  */
02661 
02662 static rtx
02663 read_complex_part (rtx cplx, bool imag_p)
02664 {
02665   enum machine_mode cmode, imode;
02666   unsigned ibitsize;
02667 
02668   if (GET_CODE (cplx) == CONCAT)
02669     return XEXP (cplx, imag_p);
02670 
02671   cmode = GET_MODE (cplx);
02672   imode = GET_MODE_INNER (cmode);
02673   ibitsize = GET_MODE_BITSIZE (imode);
02674 
02675   /* Special case reads from complex constants that got spilled to memory.  */
02676   if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF)
02677     {
02678       tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0));
02679       if (decl && TREE_CODE (decl) == COMPLEX_CST)
02680   {
02681     tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
02682     if (CONSTANT_CLASS_P (part))
02683       return expand_expr (part, NULL_RTX, imode, EXPAND_NORMAL);
02684   }
02685     }
02686 
02687   /* If the sub-object is at least word sized, then we know that subregging
02688      will work.  This special case is important, since extract_bit_field
02689      wants to operate on integer modes, and there's rarely an OImode to
02690      correspond to TCmode.  */
02691   if (ibitsize >= BITS_PER_WORD
02692       /* For hard regs we have exact predicates.  Assume we can split
02693    the original object if it spans an even number of hard regs.
02694    This special case is important for SCmode on 64-bit platforms
02695    where the natural size of floating-point regs is 32-bit.  */
02696       || (GET_CODE (cplx) == REG
02697     && REGNO (cplx) < FIRST_PSEUDO_REGISTER
02698     && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
02699       /* For MEMs we always try to make a "subreg", that is to adjust
02700    the MEM, because extract_bit_field may generate overly
02701    convoluted RTL for sub-word fields.  */
02702       || MEM_P (cplx))
02703     {
02704       rtx ret = simplify_gen_subreg (imode, cplx, cmode,
02705              imag_p ? GET_MODE_SIZE (imode) : 0);
02706       if (ret)
02707         return ret;
02708       else
02709   /* simplify_gen_subreg may fail for sub-word MEMs.  */
02710   gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
02711     }
02712 
02713   return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
02714           true, NULL_RTX, imode, imode);
02715 }
02716 
02717 /* A subroutine of emit_move_insn_1.  Yet another lowpart generator.
02718    NEW_MODE and OLD_MODE are the same size.  Return NULL if X cannot be
02719    represented in NEW_MODE.  If FORCE is true, this will never happen, as
02720    we'll force-create a SUBREG if needed.  */
02721 
02722 static rtx
02723 emit_move_change_mode (enum machine_mode new_mode,
02724            enum machine_mode old_mode, rtx x, bool force)
02725 {
02726   rtx ret;
02727 
02728   if (reload_in_progress && MEM_P (x))
02729     {
02730       /* We can't use gen_lowpart here because it may call change_address
02731    which is not appropriate if we were called when a reload was in
02732    progress.  We don't have to worry about changing the address since
02733    the size in bytes is supposed to be the same.  Copy the MEM to
02734    change the mode and move any substitutions from the old MEM to
02735    the new one.  */
02736 
02737       ret = adjust_address_nv (x, new_mode, 0);
02738       copy_replacements (x, ret);
02739     }
02740   else
02741     {
02742       /* Note that we do want simplify_subreg's behavior of validating
02743    that the new mode is ok for a hard register.  If we were to use
02744    simplify_gen_subreg, we would create the subreg, but would
02745    probably run into the target not being able to implement it.  */
02746       /* Except, of course, when FORCE is true, when this is exactly what
02747    we want.  Which is needed for CCmodes on some targets.  */
02748       if (force)
02749   ret = simplify_gen_subreg (new_mode, x, old_mode, 0);
02750       else
02751   ret = simplify_subreg (new_mode, x, old_mode, 0);
02752     }
02753 
02754   return ret;
02755 }
02756 
02757 /* A subroutine of emit_move_insn_1.  Generate a move from Y into X using
02758    an integer mode of the same size as MODE.  Returns the instruction
02759    emitted, or NULL if such a move could not be generated.  */
02760 
02761 static rtx
02762 emit_move_via_integer (enum machine_mode mode, rtx x, rtx y)
02763 {
02764   enum machine_mode imode;
02765   enum insn_code code;
02766 
02767   /* There must exist a mode of the exact size we require.  */
02768   imode = int_mode_for_mode (mode);
02769   if (imode == BLKmode)
02770     return NULL_RTX;
02771 
02772   /* The target must support moves in this mode.  */
02773   code = mov_optab->handlers[imode].insn_code;
02774   if (code == CODE_FOR_nothing)
02775     return NULL_RTX;
02776 
02777   x = emit_move_change_mode (imode, mode, x, false);
02778   if (x == NULL_RTX)
02779     return NULL_RTX;
02780   y = emit_move_change_mode (imode, mode, y, false);
02781   if (y == NULL_RTX)
02782     return NULL_RTX;
02783   return emit_insn (GEN_FCN (code) (x, y));
02784 }
02785 
02786 /* A subroutine of emit_move_insn_1.  X is a push_operand in MODE.
02787    Return an equivalent MEM that does not use an auto-increment.  */
02788 
02789 static rtx
02790 emit_move_resolve_push (enum machine_mode mode, rtx x)
02791 {
02792   enum rtx_code code = GET_CODE (XEXP (x, 0));
02793   HOST_WIDE_INT adjust;
02794   rtx temp;
02795 
02796   adjust = GET_MODE_SIZE (mode);
02797 #ifdef PUSH_ROUNDING
02798   adjust = PUSH_ROUNDING (adjust);
02799 #endif
02800   if (code == PRE_DEC || code == POST_DEC)
02801     adjust = -adjust;
02802 
02803   /* Do not use anti_adjust_stack, since we don't want to update
02804      stack_pointer_delta.  */
02805   temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
02806             GEN_INT (adjust), stack_pointer_rtx,
02807             0, OPTAB_LIB_WIDEN);
02808   if (temp != stack_pointer_rtx)
02809     emit_move_insn (stack_pointer_rtx, temp);
02810 
02811   switch (code)
02812     {
02813     case PRE_INC:
02814     case PRE_DEC:
02815       temp = stack_pointer_rtx;
02816       break;
02817     case POST_INC:
02818       temp = plus_constant (stack_pointer_rtx, -GET_MODE_SIZE (mode));
02819       break;
02820     case POST_DEC:
02821       temp = plus_constant (stack_pointer_rtx, GET_MODE_SIZE (mode));
02822       break;
02823     default:
02824       gcc_unreachable ();
02825     }
02826 
02827   return replace_equiv_address (x, temp);
02828 }
02829 
02830 /* A subroutine of emit_move_complex.  Generate a move from Y into X.
02831    X is known to satisfy push_operand, and MODE is known to be complex.
02832    Returns the last instruction emitted.  */
02833 
02834 static rtx
02835 emit_move_complex_push (enum machine_mode mode, rtx x, rtx y)
02836 {
02837   enum machine_mode submode = GET_MODE_INNER (mode);
02838   bool imag_first;
02839 
02840 #ifdef PUSH_ROUNDING
02841   unsigned int submodesize = GET_MODE_SIZE (submode);
02842 
02843   /* In case we output to the stack, but the size is smaller than the
02844      machine can push exactly, we need to use move instructions.  */
02845   if (PUSH_ROUNDING (submodesize) != submodesize)
02846     {
02847       x = emit_move_resolve_push (mode, x);
02848       return emit_move_insn (x, y);
02849     }
02850 #endif
02851 
02852   /* Note that the real part always precedes the imag part in memory
02853      regardless of machine's endianness.  */
02854   switch (GET_CODE (XEXP (x, 0)))
02855     {
02856     case PRE_DEC:
02857     case POST_DEC:
02858       imag_first = true;
02859       break;
02860     case PRE_INC:
02861     case POST_INC:
02862       imag_first = false;
02863       break;
02864     default:
02865       gcc_unreachable ();
02866     }
02867 
02868   emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
02869       read_complex_part (y, imag_first));
02870   return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
02871        read_complex_part (y, !imag_first));
02872 }
02873 
02874 /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
02875    MODE is known to be complex.  Returns the last instruction emitted.  */
02876 
02877 static rtx
02878 emit_move_complex (enum machine_mode mode, rtx x, rtx y)
02879 {
02880   bool try_int;
02881 
02882   /* Need to take special care for pushes, to maintain proper ordering
02883      of the data, and possibly extra padding.  */
02884   if (push_operand (x, mode))
02885     return emit_move_complex_push (mode, x, y);
02886 
02887   /* See if we can coerce the target into moving both values at once.  */
02888 
02889   /* Move floating point as parts.  */
02890   if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
02891       && mov_optab->handlers[GET_MODE_INNER (mode)].insn_code != CODE_FOR_nothing)
02892     try_int = false;
02893   /* Not possible if the values are inherently not adjacent.  */
02894   else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
02895     try_int = false;
02896   /* Is possible if both are registers (or subregs of registers).  */
02897   else if (register_operand (x, mode) && register_operand (y, mode))
02898     try_int = true;
02899   /* If one of the operands is a memory, and alignment constraints
02900      are friendly enough, we may be able to do combined memory operations.
02901      We do not attempt this if Y is a constant because that combination is
02902      usually better with the by-parts thing below.  */
02903   else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
02904      && (!STRICT_ALIGNMENT
02905          || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
02906     try_int = true;
02907   else
02908     try_int = false;
02909 
02910   if (try_int)
02911     {
02912       rtx ret;
02913 
02914       /* For memory to memory moves, optimal behavior can be had with the
02915    existing block move logic.  */
02916       if (MEM_P (x) && MEM_P (y))
02917   {
02918     emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
02919          BLOCK_OP_NO_LIBCALL);
02920     return get_last_insn ();
02921   }
02922 
02923       ret = emit_move_via_integer (mode, x, y);
02924       if (ret)
02925   return ret;
02926     }
02927 
02928   /* Show the output dies here.  This is necessary for SUBREGs
02929      of pseudos since we cannot track their lifetimes correctly;
02930      hard regs shouldn't appear here except as return values.  */
02931   if (!reload_completed && !reload_in_progress
02932       && REG_P (x) && !reg_overlap_mentioned_p (x, y))
02933     emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
02934 
02935   write_complex_part (x, read_complex_part (y, false), false);
02936   write_complex_part (x, read_complex_part (y, true), true);
02937   return get_last_insn ();
02938 }
02939 
02940 /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
02941    MODE is known to be MODE_CC.  Returns the last instruction emitted.  */
02942 
02943 static rtx
02944 emit_move_ccmode (enum machine_mode mode, rtx x, rtx y)
02945 {
02946   rtx ret;
02947 
02948   /* Assume all MODE_CC modes are equivalent; if we have movcc, use it.  */
02949   if (mode != CCmode)
02950     {
02951       enum insn_code code = mov_optab->handlers[CCmode].insn_code;
02952       if (code != CODE_FOR_nothing)
02953   {
02954     x = emit_move_change_mode (CCmode, mode, x, true);
02955     y = emit_move_change_mode (CCmode, mode, y, true);
02956     return emit_insn (GEN_FCN (code) (x, y));
02957   }
02958     }
02959 
02960   /* Otherwise, find the MODE_INT mode of the same width.  */
02961   ret = emit_move_via_integer (mode, x, y);
02962   gcc_assert (ret != NULL);
02963   return ret;
02964 }
02965 
02966 /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
02967    MODE is any multi-word or full-word mode that lacks a move_insn
02968    pattern.  Note that you will get better code if you define such
02969    patterns, even if they must turn into multiple assembler instructions.  */
02970 
02971 static rtx
02972 emit_move_multi_word (enum machine_mode mode, rtx x, rtx y)
02973 {
02974   rtx last_insn = 0;
02975   rtx seq, inner;
02976   bool need_clobber;
02977   int i;
02978       
02979   gcc_assert (GET_MODE_SIZE (mode) >= UNITS_PER_WORD);
02980       
02981   /* If X is a push on the stack, do the push now and replace
02982      X with a reference to the stack pointer.  */
02983   if (push_operand (x, mode))
02984     x = emit_move_resolve_push (mode, x);
02985 
02986   /* If we are in reload, see if either operand is a MEM whose address
02987      is scheduled for replacement.  */
02988   if (reload_in_progress && MEM_P (x)
02989       && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
02990     x = replace_equiv_address_nv (x, inner);
02991   if (reload_in_progress && MEM_P (y)
02992       && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
02993     y = replace_equiv_address_nv (y, inner);
02994 
02995   start_sequence ();
02996 
02997   need_clobber = false;
02998   for (i = 0;
02999        i < (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
03000        i++)
03001     {
03002       rtx xpart = operand_subword (x, i, 1, mode);
03003       rtx ypart = operand_subword (y, i, 1, mode);
03004 
03005       /* If we can't get a part of Y, put Y into memory if it is a
03006    constant.  Otherwise, force it into a register.  If we still
03007    can't get a part of Y, abort.  */
03008       if (ypart == 0 && CONSTANT_P (y))
03009   {
03010     y = force_const_mem (mode, y);
03011     ypart = operand_subword (y, i, 1, mode);
03012   }
03013       else if (ypart == 0)
03014   ypart = operand_subword_force (y, i, mode);
03015 
03016       gcc_assert (xpart && ypart);
03017 
03018       need_clobber |= (GET_CODE (xpart) == SUBREG);
03019 
03020       last_insn = emit_move_insn (xpart, ypart);
03021     }
03022 
03023   seq = get_insns ();
03024   end_sequence ();
03025 
03026   /* Show the output dies here.  This is necessary for SUBREGs
03027      of pseudos since we cannot track their lifetimes correctly;
03028      hard regs shouldn't appear here except as return values.
03029      We never want to emit such a clobber after reload.  */
03030   if (x != y
03031       && ! (reload_in_progress || reload_completed)
03032       && need_clobber != 0)
03033     emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
03034 
03035   emit_insn (seq);
03036 
03037   return last_insn;
03038 }
03039 
03040 /* Low level part of emit_move_insn.
03041    Called just like emit_move_insn, but assumes X and Y
03042    are basically valid.  */
03043 
03044 rtx
03045 emit_move_insn_1 (rtx x, rtx y)
03046 {
03047   enum machine_mode mode = GET_MODE (x);
03048   enum insn_code code;
03049 
03050   gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);
03051 
03052   code = mov_optab->handlers[mode].insn_code;
03053   if (code != CODE_FOR_nothing)
03054     return emit_insn (GEN_FCN (code) (x, y));
03055 
03056   /* Expand complex moves by moving real part and imag part.  */
03057   if (COMPLEX_MODE_P (mode))
03058     return emit_move_complex (mode, x, y);
03059 
03060   if (GET_MODE_CLASS (mode) == MODE_CC)
03061     return emit_move_ccmode (mode, x, y);
03062 
03063   /* Try using a move pattern for the corresponding integer mode.  This is
03064      only safe when simplify_subreg can convert MODE constants into integer
03065      constants.  At present, it can only do this reliably if the value
03066      fits within a HOST_WIDE_INT.  */
03067   if (!CONSTANT_P (y) || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
03068     {
03069       rtx ret = emit_move_via_integer (mode, x, y);
03070       if (ret)
03071   return ret;
03072     }
03073 
03074   return emit_move_multi_word (mode, x, y);
03075 }
03076 
03077 /* Generate code to copy Y into X.
03078    Both Y and X must have the same mode, except that
03079    Y can be a constant with VOIDmode.
03080    This mode cannot be BLKmode; use emit_block_move for that.
03081 
03082    Return the last instruction emitted.  */
03083 
03084 rtx
03085 emit_move_insn (rtx x, rtx y)
03086 {
03087   enum machine_mode mode = GET_MODE (x);
03088   rtx y_cst = NULL_RTX;
03089   rtx last_insn, set;
03090 
03091   gcc_assert (mode != BLKmode
03092         && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
03093 
03094   if (CONSTANT_P (y))
03095     {
03096       if (optimize
03097     && SCALAR_FLOAT_MODE_P (GET_MODE (x))
03098     && (last_insn = compress_float_constant (x, y)))
03099   return last_insn;
03100 
03101       y_cst = y;
03102 
03103       if (!LEGITIMATE_CONSTANT_P (y))
03104   {
03105     y = force_const_mem (mode, y);
03106 
03107     /* If the target's cannot_force_const_mem prevented the spill,
03108        assume that the target's move expanders will also take care
03109        of the non-legitimate constant.  */
03110     if (!y)
03111       y = y_cst;
03112   }
03113     }
03114 
03115   /* If X or Y are memory references, verify that their addresses are valid
03116      for the machine.  */
03117   if (MEM_P (x)
03118       && ((! memory_address_p (GET_MODE (x), XEXP (x, 0))
03119      && ! push_operand (x, GET_MODE (x)))
03120     || (flag_force_addr
03121         && CONSTANT_ADDRESS_P (XEXP (x, 0)))))
03122     x = validize_mem (x);
03123 
03124   if (MEM_P (y)
03125       && (! memory_address_p (GET_MODE (y), XEXP (y, 0))
03126     || (flag_force_addr
03127         && CONSTANT_ADDRESS_P (XEXP (y, 0)))))
03128     y = validize_mem (y);
03129 
03130   gcc_assert (mode != BLKmode);
03131 
03132   last_insn = emit_move_insn_1 (x, y);
03133 
03134   if (y_cst && REG_P (x)
03135       && (set = single_set (last_insn)) != NULL_RTX
03136       && SET_DEST (set) == x
03137       && ! rtx_equal_p (y_cst, SET_SRC (set)))
03138     set_unique_reg_note (last_insn, REG_EQUAL, y_cst);
03139 
03140   return last_insn;
03141 }
03142 
03143 /* If Y is representable exactly in a narrower mode, and the target can
03144    perform the extension directly from constant or memory, then emit the
03145    move as an extension.  */
03146 
03147 static rtx
03148 compress_float_constant (rtx x, rtx y)
03149 {
03150   enum machine_mode dstmode = GET_MODE (x);
03151   enum machine_mode orig_srcmode = GET_MODE (y);
03152   enum machine_mode srcmode;
03153   REAL_VALUE_TYPE r;
03154 
03155   REAL_VALUE_FROM_CONST_DOUBLE (r, y);
03156 
03157   for (srcmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_srcmode));
03158        srcmode != orig_srcmode;
03159        srcmode = GET_MODE_WIDER_MODE (srcmode))
03160     {
03161       enum insn_code ic;
03162       rtx trunc_y, last_insn;
03163 
03164       /* Skip if the target can't extend this way.  */
03165       ic = can_extend_p (dstmode, srcmode, 0);
03166       if (ic == CODE_FOR_nothing)
03167   continue;
03168 
03169       /* Skip if the narrowed value isn't exact.  */
03170       if (! exact_real_truncate (srcmode, &r))
03171   continue;
03172 
03173       trunc_y = CONST_DOUBLE_FROM_REAL_VALUE (r, srcmode);
03174 
03175       if (LEGITIMATE_CONSTANT_P (trunc_y))
03176   {
03177     /* Skip if the target needs extra instructions to perform
03178        the extension.  */
03179     if (! (*insn_data[ic].operand[1].predicate) (trunc_y, srcmode))
03180       continue;
03181   }
03182       else if (float_extend_from_mem[dstmode][srcmode])
03183   trunc_y = validize_mem (force_const_mem (srcmode, trunc_y));
03184       else
03185   continue;
03186 
03187       emit_unop_insn (ic, x, trunc_y, UNKNOWN);
03188       last_insn = get_last_insn ();
03189 
03190       if (REG_P (x))
03191   set_unique_reg_note (last_insn, REG_EQUAL, y);
03192 
03193       return last_insn;
03194     }
03195 
03196   return NULL_RTX;
03197 }
03198 
03199 /* Pushing data onto the stack.  */
03200 
03201 /* Push a block of length SIZE (perhaps variable)
03202    and return an rtx to address the beginning of the block.
03203    The value may be virtual_outgoing_args_rtx.
03204 
03205    EXTRA is the number of bytes of padding to push in addition to SIZE.
03206    BELOW nonzero means this padding comes at low addresses;
03207    otherwise, the padding comes at high addresses.  */
03208 
03209 rtx
03210 push_block (rtx size, int extra, int below)
03211 {
03212   rtx temp;
03213 
03214   size = convert_modes (Pmode, ptr_mode, size, 1);
03215   if (CONSTANT_P (size))
03216     anti_adjust_stack (plus_constant (size, extra));
03217   else if (REG_P (size) && extra == 0)
03218     anti_adjust_stack (size);
03219   else
03220     {
03221       temp = copy_to_mode_reg (Pmode, size);
03222       if (extra != 0)
03223   temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra),
03224            temp, 0, OPTAB_LIB_WIDEN);
03225       anti_adjust_stack (temp);
03226     }
03227 
03228 #ifndef STACK_GROWS_DOWNWARD
03229   if (0)
03230 #else
03231   if (1)
03232 #endif
03233     {
03234       temp = virtual_outgoing_args_rtx;
03235       if (extra != 0 && below)
03236   temp = plus_constant (temp, extra);
03237     }
03238   else
03239     {
03240       if (GET_CODE (size) == CONST_INT)
03241   temp = plus_constant (virtual_outgoing_args_rtx,
03242             -INTVAL (size) - (below ? 0 : extra));
03243       else if (extra != 0 && !below)
03244   temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
03245            negate_rtx (Pmode, plus_constant (size, extra)));
03246       else
03247   temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
03248            negate_rtx (Pmode, size));
03249     }
03250 
03251   return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
03252 }
03253 
03254 #ifdef PUSH_ROUNDING
03255 
03256 /* Emit single push insn.  */
03257 
03258 static void
03259 emit_single_push_insn (enum machine_mode mode, rtx x, tree type)
03260 {
03261   rtx dest_addr;
03262   unsigned rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
03263   rtx dest;
03264   enum insn_code icode;
03265   insn_operand_predicate_fn pred;
03266 
03267   stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
03268   /* If there is push pattern, use it.  Otherwise try old way of throwing
03269      MEM representing push operation to move expander.  */
03270   icode = push_optab->handlers[(int) mode].insn_code;
03271   if (icode != CODE_FOR_nothing)
03272     {
03273       if (((pred = insn_data[(int) icode].operand[0].predicate)
03274      && !((*pred) (x, mode))))
03275   x = force_reg (mode, x);
03276       emit_insn (GEN_FCN (icode) (x));
03277       return;
03278     }
03279   if (GET_MODE_SIZE (mode) == rounded_size)
03280     dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
03281   /* If we are to pad downward, adjust the stack pointer first and
03282      then store X into the stack location using an offset.  This is
03283      because emit_move_insn does not know how to pad; it does not have
03284      access to type.  */
03285   else if (FUNCTION_ARG_PADDING (mode, type) == downward)
03286     {
03287       unsigned padding_size = rounded_size - GET_MODE_SIZE (mode);
03288       HOST_WIDE_INT offset;
03289 
03290       emit_move_insn (stack_pointer_rtx,
03291           expand_binop (Pmode,
03292 #ifdef STACK_GROWS_DOWNWARD
03293             sub_optab,
03294 #else
03295             add_optab,
03296 #endif
03297             stack_pointer_rtx,
03298             GEN_INT (rounded_size),
03299             NULL_RTX, 0, OPTAB_LIB_WIDEN));
03300 
03301       offset = (HOST_WIDE_INT) padding_size;
03302 #ifdef STACK_GROWS_DOWNWARD
03303       if (STACK_PUSH_CODE == POST_DEC)
03304   /* We have already decremented the stack pointer, so get the
03305      previous value.  */
03306   offset += (HOST_WIDE_INT) rounded_size;
03307 #else
03308       if (STACK_PUSH_CODE == POST_INC)
03309   /* We have already incremented the stack pointer, so get the
03310      previous value.  */
03311   offset -= (HOST_WIDE_INT) rounded_size;
03312 #endif
03313       dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
03314     }
03315   else
03316     {
03317 #ifdef STACK_GROWS_DOWNWARD
03318       /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC.  */
03319       dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
03320         GEN_INT (-(HOST_WIDE_INT) rounded_size));
03321 #else
03322       /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC.  */
03323       dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
03324         GEN_INT (rounded_size));
03325 #endif
03326       dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
03327     }
03328 
03329   dest = gen_rtx_MEM (mode, dest_addr);
03330 
03331   if (type != 0)
03332     {
03333       set_mem_attributes (dest, type, 1);
03334 
03335       if (flag_optimize_sibling_calls)
03336   /* Function incoming arguments may overlap with sibling call
03337      outgoing arguments and we cannot allow reordering of reads
03338      from function arguments with stores to outgoing arguments
03339      of sibling calls.  */
03340   set_mem_alias_set (dest, 0);
03341     }
03342   emit_move_insn (dest, x);
03343 }
03344 #endif
03345 
03346 /* Generate code to push X onto the stack, assuming it has mode MODE and
03347    type TYPE.
03348    MODE is redundant except when X is a CONST_INT (since they don't
03349    carry mode info).
03350    SIZE is an rtx for the size of data to be copied (in bytes),
03351    needed only if X is BLKmode.
03352 
03353    ALIGN (in bits) is maximum alignment we can assume.
03354 
03355    If PARTIAL and REG are both nonzero, then copy that many of the first
03356    bytes of X into registers starting with REG, and push the rest of X.
03357    The amount of space pushed is decreased by PARTIAL bytes.
03358    REG must be a hard register in this case.
03359    If REG is zero but PARTIAL is not, take any all others actions for an
03360    argument partially in registers, but do not actually load any
03361    registers.
03362 
03363    EXTRA is the amount in bytes of extra space to leave next to this arg.
03364    This is ignored if an argument block has already been allocated.
03365 
03366    On a machine that lacks real push insns, ARGS_ADDR is the address of
03367    the bottom of the argument block for this call.  We use indexing off there
03368    to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
03369    argument block has not been preallocated.
03370 
03371    ARGS_SO_FAR is the size of args previously pushed for this call.
03372 
03373    REG_PARM_STACK_SPACE is nonzero if functions require stack space
03374    for arguments passed in registers.  If nonzero, it will be the number
03375    of bytes required.  */
03376 
03377 void
03378 emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
03379     unsigned int align, int partial, rtx reg, int extra,
03380     rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
03381     rtx alignment_pad)
03382 {
03383   rtx xinner;
03384   enum direction stack_direction
03385 #ifdef STACK_GROWS_DOWNWARD
03386     = downward;
03387 #else
03388     = upward;
03389 #endif
03390 
03391   /* Decide where to pad the argument: `downward' for below,
03392      `upward' for above, or `none' for don't pad it.
03393      Default is below for small data on big-endian machines; else above.  */
03394   enum direction where_pad = FUNCTION_ARG_PADDING (mode, type);
03395 
03396   /* Invert direction if stack is post-decrement.
03397      FIXME: why?  */
03398   if (STACK_PUSH_CODE == POST_DEC)
03399     if (where_pad != none)
03400       where_pad = (where_pad == downward ? upward : downward);
03401 
03402   xinner = x;
03403 
03404   if (mode == BLKmode)
03405     {
03406       /* Copy a block into the stack, entirely or partially.  */
03407 
03408       rtx temp;
03409       int used;
03410       int offset;
03411       int skip;
03412 
03413       offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
03414       used = partial - offset;
03415 
03416       gcc_assert (size);
03417 
03418       /* USED is now the # of bytes we need not copy to the stack
03419    because registers will take care of them.  */
03420 
03421       if (partial != 0)
03422   xinner = adjust_address (xinner, BLKmode, used);
03423 
03424       /* If the partial register-part of the arg counts in its stack size,
03425    skip the part of stack space corresponding to the registers.
03426    Otherwise, start copying to the beginning of the stack space,
03427    by setting SKIP to 0.  */
03428       skip = (reg_parm_stack_space == 0) ? 0 : used;
03429 
03430 #ifdef PUSH_ROUNDING
03431       /* Do it with several push insns if that doesn't take lots of insns
03432    and if there is no difficulty with push insns that skip bytes
03433    on the stack for alignment purposes.  */
03434       if (args_addr == 0
03435     && PUSH_ARGS
03436     && GET_CODE (size) == CONST_INT
03437     && skip == 0
03438     && MEM_ALIGN (xinner) >= align
03439     && (MOVE_BY_PIECES_P ((unsigned) INTVAL (size) - used, align))
03440     /* Here we avoid the case of a structure whose weak alignment
03441        forces many pushes of a small amount of data,
03442        and such small pushes do rounding that causes trouble.  */
03443     && ((! SLOW_UNALIGNED_ACCESS (word_mode, align))
03444         || align >= BIGGEST_ALIGNMENT
03445         || (PUSH_ROUNDING (align / BITS_PER_UNIT)
03446       == (align / BITS_PER_UNIT)))
03447     && PUSH_ROUNDING (INTVAL (size)) == INTVAL (size))
03448   {
03449     /* Push padding now if padding above and stack grows down,
03450        or if padding below and stack grows up.
03451        But if space already allocated, this has already been done.  */
03452     if (extra && args_addr == 0
03453         && where_pad != none && where_pad != stack_direction)
03454       anti_adjust_stack (GEN_INT (extra));
03455 
03456     move_by_pieces (NULL, xinner, INTVAL (size) - used, align, 0);
03457   }
03458       else
03459 #endif /* PUSH_ROUNDING  */
03460   {
03461     rtx target;
03462 
03463     /* Otherwise make space on the stack and copy the data
03464        to the address of that space.  */
03465 
03466     /* Deduct words put into registers from the size we must copy.  */
03467     if (partial != 0)
03468       {
03469         if (GET_CODE (size) == CONST_INT)
03470     size = GEN_INT (INTVAL (size) - used);
03471         else
03472     size = expand_binop (GET_MODE (size), sub_optab, size,
03473              GEN_INT (used), NULL_RTX, 0,
03474              OPTAB_LIB_WIDEN);
03475       }
03476 
03477     /* Get the address of the stack space.
03478        In this case, we do not deal with EXTRA separately.
03479        A single stack adjust will do.  */
03480     if (! args_addr)
03481       {
03482         temp = push_block (size, extra, where_pad == downward);
03483         extra = 0;
03484       }
03485     else if (GET_CODE (args_so_far) == CONST_INT)
03486       temp = memory_address (BLKmode,
03487            plus_constant (args_addr,
03488               skip + INTVAL (args_so_far)));
03489     else
03490       temp = memory_address (BLKmode,
03491            plus_constant (gen_rtx_PLUS (Pmode,
03492                 args_addr,
03493                 args_so_far),
03494               skip));
03495 
03496     if (!ACCUMULATE_OUTGOING_ARGS)
03497       {
03498         /* If the source is referenced relative to the stack pointer,
03499      copy it to another register to stabilize it.  We do not need
03500      to do this if we know that we won't be changing sp.  */
03501 
03502         if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
03503       || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
03504     temp = copy_to_reg (temp);
03505       }
03506 
03507     target = gen_rtx_MEM (BLKmode, temp);
03508 
03509     /* We do *not* set_mem_attributes here, because incoming arguments
03510        may overlap with sibling call outgoing arguments and we cannot
03511        allow reordering of reads from function arguments with stores
03512        to outgoing arguments of sibling calls.  We do, however, want
03513        to record the alignment of the stack slot.  */
03514     /* ALIGN may well be better aligned than TYPE, e.g. due to
03515        PARM_BOUNDARY.  Assume the caller isn't lying.  */
03516     set_mem_align (target, align);
03517 
03518     emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
03519   }
03520     }
03521   else if (partial > 0)
03522     {
03523       /* Scalar partly in registers.  */
03524 
03525       int size = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
03526       int i;
03527       int not_stack;
03528       /* # bytes of start of argument
03529    that we must make space for but need not store.  */
03530       int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
03531       int args_offset = INTVAL (args_so_far);
03532       int skip;
03533 
03534       /* Push padding now if padding above and stack grows down,
03535    or if padding below and stack grows up.
03536    But if space already allocated, this has already been done.  */
03537       if (extra && args_addr == 0
03538     && where_pad != none && where_pad != stack_direction)
03539   anti_adjust_stack (GEN_INT (extra));
03540 
03541       /* If we make space by pushing it, we might as well push
03542    the real data.  Otherwise, we can leave OFFSET nonzero
03543    and leave the space uninitialized.  */
03544       if (args_addr == 0)
03545   offset = 0;
03546 
03547       /* Now NOT_STACK gets the number of words that we don't need to
03548    allocate on the stack.  */
03549       not_stack = (partial - offset) / UNITS_PER_WORD;
03550 
03551       /* If the partial register-part of the arg counts in its stack size,
03552    skip the part of stack space corresponding to the registers.
03553    Otherwise, start copying to the beginning of the stack space,
03554    by setting SKIP to 0.  */
03555       skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
03556 
03557       if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
03558   x = validize_mem (force_const_mem (mode, x));
03559 
03560       /* If X is a hard register in a non-integer mode, copy it into a pseudo;
03561    SUBREGs of such registers are not allowed.  */
03562       if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
03563      && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
03564   x = copy_to_reg (x);
03565 
03566       /* Loop over all the words allocated on the stack for this arg.  */
03567       /* We can do it by words, because any scalar bigger than a word
03568    has a size a multiple of a word.  */
03569 #ifndef PUSH_ARGS_REVERSED
03570       for (i = not_stack; i < size; i++)
03571 #else
03572       for (i = size - 1; i >= not_stack; i--)
03573 #endif
03574   if (i >= not_stack + offset)
03575     emit_push_insn (operand_subword_force (x, i, mode),
03576         word_mode, NULL_TREE, NULL_RTX, align, 0, NULL_RTX,
03577         0, args_addr,
03578         GEN_INT (args_offset + ((i - not_stack + skip)
03579               * UNITS_PER_WORD)),
03580         reg_parm_stack_space, alignment_pad);
03581     }
03582   else
03583     {
03584       rtx addr;
03585       rtx dest;
03586 
03587       /* Push padding now if padding above and stack grows down,
03588    or if padding below and stack grows up.
03589    But if space already allocated, this has already been done.  */
03590       if (extra && args_addr == 0
03591     && where_pad != none && where_pad != stack_direction)
03592   anti_adjust_stack (GEN_INT (extra));
03593 
03594 #ifdef PUSH_ROUNDING
03595       if (args_addr == 0 && PUSH_ARGS)
03596   emit_single_push_insn (mode, x, type);
03597       else
03598 #endif
03599   {
03600     if (GET_CODE (args_so_far) == CONST_INT)
03601       addr
03602         = memory_address (mode,
03603         plus_constant (args_addr,
03604                  INTVAL (args_so_far)));
03605     else
03606       addr = memory_address (mode, gen_rtx_PLUS (Pmode, args_addr,
03607                    args_so_far));
03608     dest = gen_rtx_MEM (mode, addr);
03609 
03610     /* We do *not* set_mem_attributes here, because incoming arguments
03611        may overlap with sibling call outgoing arguments and we cannot
03612        allow reordering of reads from function arguments with stores
03613        to outgoing arguments of sibling calls.  We do, however, want
03614        to record the alignment of the stack slot.  */
03615     /* ALIGN may well be better aligned than TYPE, e.g. due to
03616        PARM_BOUNDARY.  Assume the caller isn't lying.  */
03617     set_mem_align (dest, align);
03618 
03619     emit_move_insn (dest, x);
03620   }
03621     }
03622 
03623   /* If part should go in registers, copy that part
03624      into the appropriate registers.  Do this now, at the end,
03625      since mem-to-mem copies above may do function calls.  */
03626   if (partial > 0 && reg != 0)
03627     {
03628       /* Handle calls that pass values in multiple non-contiguous locations.
03629    The Irix 6 ABI has examples of this.  */
03630       if (GET_CODE (reg) == PARALLEL)
03631   emit_group_load (reg, x, type, -1);
03632       else
03633   {
03634     gcc_assert (partial % UNITS_PER_WORD == 0);
03635     move_block_to_reg (REGNO (reg), x, partial / UNITS_PER_WORD, mode);
03636   }
03637     }
03638 
03639   if (extra && args_addr == 0 && where_pad == stack_direction)
03640     anti_adjust_stack (GEN_INT (extra));
03641 
03642   if (alignment_pad && args_addr == 0)
03643     anti_adjust_stack (alignment_pad);
03644 }
03645 
03646 /* Return X if X can be used as a subtarget in a sequence of arithmetic
03647    operations.  */
03648 
03649 static rtx
03650 get_subtarget (rtx x)
03651 {
03652   return (optimize
03653           || x == 0
03654      /* Only registers can be subtargets.  */
03655      || !REG_P (x)
03656      /* Don't use hard regs to avoid extending their life.  */
03657      || REGNO (x) < FIRST_PSEUDO_REGISTER
03658     ? 0 : x);
03659 }
03660 
03661 /* A subroutine of expand_assignment.  Optimize FIELD op= VAL, where
03662    FIELD is a bitfield.  Returns true if the optimization was successful,
03663    and there's nothing else to do.  */
03664 
03665 static bool
03666 optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
03667          unsigned HOST_WIDE_INT bitpos,
03668          enum machine_mode mode1, rtx str_rtx,
03669          tree to, tree src)
03670 {
03671   enum machine_mode str_mode = GET_MODE (str_rtx);
03672   unsigned int str_bitsize = GET_MODE_BITSIZE (str_mode);
03673   tree op0, op1;
03674   rtx value, result;
03675   optab binop;
03676 
03677   if (mode1 != VOIDmode
03678       || bitsize >= BITS_PER_WORD
03679       || str_bitsize > BITS_PER_WORD
03680       || TREE_SIDE_EFFECTS (to)
03681       || TREE_THIS_VOLATILE (to))
03682     return false;
03683 
03684   STRIP_NOPS (src);
03685   if (!BINARY_CLASS_P (src)
03686       || TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
03687     return false;
03688 
03689   op0 = TREE_OPERAND (src, 0);
03690   op1 = TREE_OPERAND (src, 1);
03691   STRIP_NOPS (op0);
03692 
03693   if (!operand_equal_p (to, op0, 0))
03694     return false;
03695 
03696   if (MEM_P (str_rtx))
03697     {
03698       unsigned HOST_WIDE_INT offset1;
03699 
03700       if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
03701   str_mode = word_mode;
03702       str_mode = get_best_mode (bitsize, bitpos,
03703         MEM_ALIGN (str_rtx), str_mode, 0);
03704       if (str_mode == VOIDmode)
03705   return false;
03706       str_bitsize = GET_MODE_BITSIZE (str_mode);
03707 
03708       offset1 = bitpos;
03709       bitpos %= str_bitsize;
03710       offset1 = (offset1 - bitpos) / BITS_PER_UNIT;
03711       str_rtx = adjust_address (str_rtx, str_mode, offset1);
03712     }
03713   else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
03714     return false;
03715 
03716   /* If the bit field covers the whole REG/MEM, store_field
03717      will likely generate better code.  */
03718   if (bitsize >= str_bitsize)
03719     return false;
03720 
03721   /* We can't handle fields split across multiple entities.  */
03722   if (bitpos + bitsize > str_bitsize)
03723     return false;
03724 
03725   if (BYTES_BIG_ENDIAN)
03726     bitpos = str_bitsize - bitpos - bitsize;
03727 
03728   switch (TREE_CODE (src))
03729     {
03730     case PLUS_EXPR:
03731     case MINUS_EXPR:
03732       /* For now, just optimize the case of the topmost bitfield
03733    where we don't need to do any masking and also
03734    1 bit bitfields where xor can be used.
03735    We might win by one instruction for the other bitfields
03736    too if insv/extv instructions aren't used, so that
03737    can be added later.  */
03738       if (bitpos + bitsize != str_bitsize
03739     && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
03740   break;
03741 
03742       value = expand_expr (op1, NULL_RTX, str_mode, 0);
03743       value = convert_modes (str_mode,
03744            TYPE_MODE (TREE_TYPE (op1)), value,
03745            TYPE_UNSIGNED (TREE_TYPE (op1)));
03746 
03747       /* We may be accessing data outside the field, which means
03748    we can alias adjacent data.  */
03749       if (MEM_P (str_rtx))
03750   {
03751     str_rtx = shallow_copy_rtx (str_rtx);
03752     set_mem_alias_set (str_rtx, 0);
03753     set_mem_expr (str_rtx, 0);
03754   }
03755 
03756       binop = TREE_CODE (src) == PLUS_EXPR ? add_optab : sub_optab;
03757       if (bitsize == 1 && bitpos + bitsize != str_bitsize)
03758   {
03759     value = expand_and (str_mode, value, const1_rtx, NULL);
03760     binop = xor_optab;
03761   }
03762       value = expand_shift (LSHIFT_EXPR, str_mode, value,
03763           build_int_cst (NULL_TREE, bitpos),
03764           NULL_RTX, 1);
03765       result = expand_binop (str_mode, binop, str_rtx,
03766            value, str_rtx, 1, OPTAB_WIDEN);
03767       if (result != str_rtx)
03768   emit_move_insn (str_rtx, result);
03769       return true;
03770 
03771     default:
03772       break;
03773     }
03774 
03775   return false;
03776 }
03777 
03778 
03779 /* Expand an assignment that stores the value of FROM into TO.  */
03780 
03781 void
03782 expand_assignment (tree to, tree from)
03783 {
03784   rtx to_rtx = 0;
03785   rtx result;
03786 
03787   /* Don't crash if the lhs of the assignment was erroneous.  */
03788 
03789   if (TREE_CODE (to) == ERROR_MARK)
03790     {
03791       result = expand_expr (from, NULL_RTX, VOIDmode, 0);
03792       return;
03793     }
03794 
03795   /* Assignment of a structure component needs special treatment
03796      if the structure component's rtx is not simply a MEM.
03797      Assignment of an array element at a constant index, and assignment of
03798      an array element in an unaligned packed structure field, has the same
03799      problem.  */
03800   if (handled_component_p (to)
03801       || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
03802     {
03803       enum machine_mode mode1;
03804       HOST_WIDE_INT bitsize, bitpos;
03805       rtx orig_to_rtx;
03806       tree offset;
03807       int unsignedp;
03808       int volatilep = 0;
03809       tree tem;
03810 
03811       push_temp_slots ();
03812       tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
03813          &unsignedp, &volatilep, true);
03814 
03815       /* If we are going to use store_bit_field and extract_bit_field,
03816    make sure to_rtx will be safe for multiple use.  */
03817 
03818       orig_to_rtx = to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
03819 
03820       if (offset != 0)
03821   {
03822     rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
03823 
03824     gcc_assert (MEM_P (to_rtx));
03825 
03826 #ifdef POINTERS_EXTEND_UNSIGNED
03827     if (GET_MODE (offset_rtx) != Pmode)
03828       offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
03829 #else
03830     if (GET_MODE (offset_rtx) != ptr_mode)
03831       offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
03832 #endif
03833 
03834     /* A constant address in TO_RTX can have VOIDmode, we must not try
03835        to call force_reg for that case.  Avoid that case.  */
03836     if (MEM_P (to_rtx)
03837         && GET_MODE (to_rtx) == BLKmode
03838         && GET_MODE (XEXP (to_rtx, 0)) != VOIDmode
03839         && bitsize > 0
03840         && (bitpos % bitsize) == 0
03841         && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
03842         && MEM_ALIGN (to_rtx) == GET_MODE_ALIGNMENT (mode1))
03843       {
03844         to_rtx = adjust_address (to_rtx, mode1, bitpos / BITS_PER_UNIT);
03845         bitpos = 0;
03846       }
03847 
03848     to_rtx = offset_address (to_rtx, offset_rtx,
03849            highest_pow2_factor_for_target (to,
03850                      offset));
03851   }
03852 
03853       /* Handle expand_expr of a complex value returning a CONCAT.  */
03854       if (GET_CODE (to_rtx) == CONCAT)
03855   {
03856     if (TREE_CODE (TREE_TYPE (from)) == COMPLEX_TYPE)
03857       {
03858         gcc_assert (bitpos == 0);
03859         result = store_expr (from, to_rtx, false);
03860       }
03861     else
03862       {
03863         gcc_assert (bitpos == 0 || bitpos == GET_MODE_BITSIZE (mode1));
03864         result = store_expr (from, XEXP (to_rtx, bitpos != 0), false);
03865       }
03866   }
03867       else
03868   {
03869     if (MEM_P (to_rtx))
03870       {
03871         /* If the field is at offset zero, we could have been given the
03872      DECL_RTX of the parent struct.  Don't munge it.  */
03873         to_rtx = shallow_copy_rtx (to_rtx);
03874 
03875         set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos);
03876 
03877         /* Deal with volatile and readonly fields.  The former is only
03878      done for MEM.  Also set MEM_KEEP_ALIAS_SET_P if needed.  */
03879         if (volatilep)
03880     MEM_VOLATILE_P (to_rtx) = 1;
03881         if (component_uses_parent_alias_set (to))
03882     MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
03883       }
03884 
03885     if (optimize_bitfield_assignment_op (bitsize, bitpos, mode1,
03886                  to_rtx, to, from))
03887       result = NULL;
03888     else
03889       result = store_field (to_rtx, bitsize, bitpos, mode1, from,
03890           TREE_TYPE (tem), get_alias_set (to));
03891   }
03892 
03893       if (result)
03894   preserve_temp_slots (result);
03895       free_temp_slots ();
03896       pop_temp_slots ();
03897       return;
03898     }
03899 
03900   /* If the rhs is a function call and its value is not an aggregate,
03901      call the function before we start to compute the lhs.
03902      This is needed for correct code for cases such as
03903      val = setjmp (buf) on machines where reference to val
03904      requires loading up part of an address in a separate insn.
03905 
03906      Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
03907      since it might be a promoted variable where the zero- or sign- extension
03908      needs to be done.  Handling this in the normal way is safe because no
03909      computation is done before the call.  */
03910   if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
03911       && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
03912       && ! ((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
03913       && REG_P (DECL_RTL (to))))
03914     {
03915       rtx value;
03916 
03917       push_temp_slots ();
03918       value = expand_expr (from, NULL_RTX, VOIDmode, 0);
03919       if (to_rtx == 0)
03920   to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
03921 
03922       /* Handle calls that return values in multiple non-contiguous locations.
03923    The Irix 6 ABI has examples of this.  */
03924       if (GET_CODE (to_rtx) == PARALLEL)
03925   emit_group_load (to_rtx, value, TREE_TYPE (from),
03926        int_size_in_bytes (TREE_TYPE (from)));
03927       else if (GET_MODE (to_rtx) == BLKmode)
03928   emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
03929       else
03930   {
03931     if (POINTER_TYPE_P (TREE_TYPE (to)))
03932       value = convert_memory_address (GET_MODE (to_rtx), value);
03933     emit_move_insn (to_rtx, value);
03934   }
03935       preserve_temp_slots (to_rtx);
03936       free_temp_slots ();
03937       pop_temp_slots ();
03938       return;
03939     }
03940 
03941   /* Ordinary treatment.  Expand TO to get a REG or MEM rtx.
03942      Don't re-expand if it was expanded already (in COMPONENT_REF case).  */
03943 
03944   if (to_rtx == 0)
03945     to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
03946 
03947   /* Don't move directly into a return register.  */
03948   if (TREE_CODE (to) == RESULT_DECL
03949       && (REG_P (to_rtx) || GET_CODE (to_rtx) == PARALLEL))
03950     {
03951       rtx temp;
03952 
03953       push_temp_slots ();
03954       temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
03955 
03956       if (GET_CODE (to_rtx) == PARALLEL)
03957   emit_group_load (to_rtx, temp, TREE_TYPE (from),
03958        int_size_in_bytes (TREE_TYPE (from)));
03959       else
03960   emit_move_insn (to_rtx, temp);
03961 
03962       preserve_temp_slots (to_rtx);
03963       free_temp_slots ();
03964       pop_temp_slots ();
03965       return;
03966     }
03967 
03968   /* In case we are returning the contents of an object which overlaps
03969      the place the value is being stored, use a safe function when copying
03970      a value through a pointer into a structure value return block.  */
03971   if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF
03972       && current_function_returns_struct
03973       && !current_function_returns_pcc_struct)
03974     {
03975       rtx from_rtx, size;
03976 
03977       push_temp_slots ();
03978       size = expr_size (from);
03979       from_rtx = expand_expr (from, NULL_RTX, VOIDmode, 0);
03980 
03981       emit_library_call (memmove_libfunc, LCT_NORMAL,
03982        VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
03983        XEXP (from_rtx, 0), Pmode,
03984        convert_to_mode (TYPE_MODE (sizetype),
03985             size, TYPE_UNSIGNED (sizetype)),
03986        TYPE_MODE (sizetype));
03987 
03988       preserve_temp_slots (to_rtx);
03989       free_temp_slots ();
03990       pop_temp_slots ();
03991       return;
03992     }
03993 
03994   /* Compute FROM and store the value in the rtx we got.  */
03995 
03996   push_temp_slots ();
03997   result = store_expr (from, to_rtx, 0);
03998   preserve_temp_slots (result);
03999   free_temp_slots ();
04000   pop_temp_slots ();
04001   return;
04002 }
04003 
04004 /* Generate code for computing expression EXP,
04005    and storing the value into TARGET.
04006 
04007    If the mode is BLKmode then we may return TARGET itself.
04008    It turns out that in BLKmode it doesn't cause a problem.
04009    because C has no operators that could combine two different
04010    assignments into the same BLKmode object with different values
04011    with no sequence point.  Will other languages need this to
04012    be more thorough?
04013 
04014    If CALL_PARAM_P is nonzero, this is a store into a call param on the
04015    stack, and block moves may need to be treated specially.  */
04016 
04017 rtx
04018 store_expr (tree exp, rtx target, int call_param_p)
04019 {
04020   rtx temp;
04021   rtx alt_rtl = NULL_RTX;
04022   int dont_return_target = 0;
04023 
04024   if (VOID_TYPE_P (TREE_TYPE (exp)))
04025     {
04026       /* C++ can generate ?: expressions with a throw expression in one
04027    branch and an rvalue in the other. Here, we resolve attempts to
04028    store the throw expression's nonexistent result.  */
04029       gcc_assert (!call_param_p);
04030       expand_expr (exp, const0_rtx, VOIDmode, 0);
04031       return NULL_RTX;
04032     }
04033   if (TREE_CODE (exp) == COMPOUND_EXPR)
04034     {
04035       /* Perform first part of compound expression, then assign from second
04036    part.  */
04037       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
04038        call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
04039       return store_expr (TREE_OPERAND (exp, 1), target, call_param_p);
04040     }
04041   else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
04042     {
04043       /* For conditional expression, get safe form of the target.  Then
04044    test the condition, doing the appropriate assignment on either
04045    side.  This avoids the creation of unnecessary temporaries.
04046    For non-BLKmode, it is more efficient not to do this.  */
04047 
04048       rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
04049 
04050       do_pending_stack_adjust ();
04051       NO_DEFER_POP;
04052       jumpifnot (TREE_OPERAND (exp, 0), lab1);
04053       store_expr (TREE_OPERAND (exp, 1), target, call_param_p);
04054       emit_jump_insn (gen_jump (lab2));
04055       emit_barrier ();
04056       emit_label (lab1);
04057       store_expr (TREE_OPERAND (exp, 2), target, call_param_p);
04058       emit_label (lab2);
04059       OK_DEFER_POP;
04060 
04061       return NULL_RTX;
04062     }
04063   else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
04064     /* If this is a scalar in a register that is stored in a wider mode
04065        than the declared mode, compute the result into its declared mode
04066        and then convert to the wider mode.  Our value is the computed
04067        expression.  */
04068     {
04069       rtx inner_target = 0;
04070 
04071       /* We can do the conversion inside EXP, which will often result
04072    in some optimizations.  Do the conversion in two steps: first
04073    change the signedness, if needed, then the extend.  But don't
04074    do this if the type of EXP is a subtype of something else
04075    since then the conversion might involve more than just
04076    converting modes.  */
04077       if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
04078     && TREE_TYPE (TREE_TYPE (exp)) == 0
04079     && (!lang_hooks.reduce_bit_field_operations
04080         || (GET_MODE_PRECISION (GET_MODE (target))
04081       == TYPE_PRECISION (TREE_TYPE (exp)))))
04082   {
04083     if (TYPE_UNSIGNED (TREE_TYPE (exp))
04084         != SUBREG_PROMOTED_UNSIGNED_P (target))
04085       exp = convert
04086         (lang_hooks.types.signed_or_unsigned_type
04087          (SUBREG_PROMOTED_UNSIGNED_P (target), TREE_TYPE (exp)), exp);
04088 
04089     exp = convert (lang_hooks.types.type_for_mode
04090        (GET_MODE (SUBREG_REG (target)),
04091         SUBREG_PROMOTED_UNSIGNED_P (target)),
04092        exp);
04093 
04094     inner_target = SUBREG_REG (target);
04095   }
04096 
04097       temp = expand_expr (exp, inner_target, VOIDmode,
04098         call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
04099 
04100       /* If TEMP is a VOIDmode constant, use convert_modes to make
04101    sure that we properly convert it.  */
04102       if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
04103   {
04104     temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
04105         temp, SUBREG_PROMOTED_UNSIGNED_P (target));
04106     temp = convert_modes (GET_MODE (SUBREG_REG (target)),
04107               GET_MODE (target), temp,
04108               SUBREG_PROMOTED_UNSIGNED_P (target));
04109   }
04110 
04111       convert_move (SUBREG_REG (target), temp,
04112         SUBREG_PROMOTED_UNSIGNED_P (target));
04113 
04114       return NULL_RTX;
04115     }
04116   else
04117     {
04118       temp = expand_expr_real (exp, target, GET_MODE (target),
04119              (call_param_p
04120         ? EXPAND_STACK_PARM : EXPAND_NORMAL),
04121              &alt_rtl);
04122       /* Return TARGET if it's a specified hardware register.
04123    If TARGET is a volatile mem ref, either return TARGET
04124    or return a reg copied *from* TARGET; ANSI requires this.
04125 
04126    Otherwise, if TEMP is not TARGET, return TEMP
04127    if it is constant (for efficiency),
04128    or if we really want the correct value.  */
04129       if (!(target && REG_P (target)
04130       && REGNO (target) < FIRST_PSEUDO_REGISTER)
04131     && !(MEM_P (target) && MEM_VOLATILE_P (target))
04132     && ! rtx_equal_p (temp, target)
04133     && CONSTANT_P (temp))
04134   dont_return_target = 1;
04135     }
04136 
04137   /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
04138      the same as that of TARGET, adjust the constant.  This is needed, for
04139      example, in case it is a CONST_DOUBLE and we want only a word-sized
04140      value.  */
04141   if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
04142       && TREE_CODE (exp) != ERROR_MARK
04143       && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
04144     temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
04145         temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
04146 
04147   /* If value was not generated in the target, store it there.
04148      Convert the value to TARGET's type first if necessary and emit the
04149      pending incrementations that have been queued when expanding EXP.
04150      Note that we cannot emit the whole queue blindly because this will
04151      effectively disable the POST_INC optimization later.
04152 
04153      If TEMP and TARGET compare equal according to rtx_equal_p, but
04154      one or both of them are volatile memory refs, we have to distinguish
04155      two cases:
04156      - expand_expr has used TARGET.  In this case, we must not generate
04157        another copy.  This can be detected by TARGET being equal according
04158        to == .
04159      - expand_expr has not used TARGET - that means that the source just
04160        happens to have the same RTX form.  Since temp will have been created
04161        by expand_expr, it will compare unequal according to == .
04162        We must generate a copy in this case, to reach the correct number
04163        of volatile memory references.  */
04164 
04165   if ((! rtx_equal_p (temp, target)
04166        || (temp != target && (side_effects_p (temp)
04167             || side_effects_p (target))))
04168       && TREE_CODE (exp) != ERROR_MARK
04169       /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
04170    but TARGET is not valid memory reference, TEMP will differ
04171    from TARGET although it is really the same location.  */
04172       && !(alt_rtl && rtx_equal_p (alt_rtl, target))
04173       /* If there's nothing to copy, don't bother.  Don't call expr_size
04174    unless necessary, because some front-ends (C++) expr_size-hook
04175    aborts on objects that are not supposed to be bit-copied or
04176    bit-initialized.  */
04177       && expr_size (exp) != const0_rtx)
04178     {
04179       if (GET_MODE (temp) != GET_MODE (target)
04180     && GET_MODE (temp) != VOIDmode)
04181   {
04182     int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
04183     if (dont_return_target)
04184       {
04185         /* In this case, we will return TEMP,
04186      so make sure it has the proper mode.
04187      But don't forget to store the value into TARGET.  */
04188         temp = convert_to_mode (GET_MODE (target), temp, unsignedp);
04189         emit_move_insn (target, temp);
04190       }
04191     else
04192       convert_move (target, temp, unsignedp);
04193   }
04194 
04195       else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
04196   {
04197     /* Handle copying a string constant into an array.  The string
04198        constant may be shorter than the array.  So copy just the string's
04199        actual length, and clear the rest.  First get the size of the data
04200        type of the string, which is actually the size of the target.  */
04201     rtx size = expr_size (exp);
04202 
04203     if (GET_CODE (size) == CONST_INT
04204         && INTVAL (size) < TREE_STRING_LENGTH (exp))
04205       emit_block_move (target, temp, size,
04206            (call_param_p
04207             ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
04208     else
04209       {
04210         /* Compute the size of the data to copy from the string.  */
04211         tree copy_size
04212     = size_binop (MIN_EXPR,
04213             make_tree (sizetype, size),
04214             size_int (TREE_STRING_LENGTH (exp)));
04215         rtx copy_size_rtx
04216     = expand_expr (copy_size, NULL_RTX, VOIDmode,
04217              (call_param_p
04218         ? EXPAND_STACK_PARM : EXPAND_NORMAL));
04219         rtx label = 0;
04220 
04221         /* Copy that much.  */
04222         copy_size_rtx = convert_to_mode (ptr_mode, copy_size_rtx,
04223                  TYPE_UNSIGNED (sizetype));
04224         emit_block_move (target, temp, copy_size_rtx,
04225              (call_param_p
04226         ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
04227 
04228         /* Figure out how much is left in TARGET that we have to clear.
04229      Do all calculations in ptr_mode.  */
04230         if (GET_CODE (copy_size_rtx) == CONST_INT)
04231     {
04232       size = plus_constant (size, -INTVAL (copy_size_rtx));
04233       target = adjust_address (target, BLKmode,
04234              INTVAL (copy_size_rtx));
04235     }
04236         else
04237     {
04238       size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
04239                copy_size_rtx, NULL_RTX, 0,
04240                OPTAB_LIB_WIDEN);
04241 
04242 #ifdef POINTERS_EXTEND_UNSIGNED
04243       if (GET_MODE (copy_size_rtx) != Pmode)
04244         copy_size_rtx = convert_to_mode (Pmode, copy_size_rtx,
04245                  TYPE_UNSIGNED (sizetype));
04246 #endif
04247 
04248       target = offset_address (target, copy_size_rtx,
04249              highest_pow2_factor (copy_size));
04250       label = gen_label_rtx ();
04251       emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
04252              GET_MODE (size), 0, label);
04253     }
04254 
04255         if (size != const0_rtx)
04256     clear_storage (target, size, BLOCK_OP_NORMAL);
04257 
04258         if (label)
04259     emit_label (label);
04260       }
04261   }
04262       /* Handle calls that return values in multiple non-contiguous locations.
04263    The Irix 6 ABI has examples of this.  */
04264       else if (GET_CODE (target) == PARALLEL)
04265   emit_group_load (target, temp, TREE_TYPE (exp),
04266        int_size_in_bytes (TREE_TYPE (exp)));
04267       else if (GET_MODE (temp) == BLKmode)
04268   emit_block_move (target, temp, expr_size (exp),
04269        (call_param_p
04270         ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
04271       else
04272   {
04273     temp = force_operand (temp, target);
04274     if (temp != target)
04275       emit_move_insn (target, temp);
04276   }
04277     }
04278 
04279   return NULL_RTX;
04280 }
04281 
04282 /* Examine CTOR to discover:
04283    * how many scalar fields are set to nonzero values,
04284      and place it in *P_NZ_ELTS;
04285    * how many scalar fields are set to non-constant values,
04286      and place it in  *P_NC_ELTS; and
04287    * how many scalar fields in total are in CTOR,
04288      and place it in *P_ELT_COUNT.
04289    * if a type is a union, and the initializer from the constructor
04290      is not the largest element in the union, then set *p_must_clear.  */
04291 
04292 static void
04293 categorize_ctor_elements_1 (tree ctor, HOST_WIDE_INT *p_nz_elts,
04294           HOST_WIDE_INT *p_nc_elts,
04295           HOST_WIDE_INT *p_elt_count,
04296           bool *p_must_clear)
04297 {
04298   HOST_WIDE_INT nz_elts, nc_elts, elt_count;
04299   tree list;
04300 
04301   nz_elts = 0;
04302   nc_elts = 0;
04303   elt_count = 0;
04304 
04305   for (list = CONSTRUCTOR_ELTS (ctor); list; list = TREE_CHAIN (list))
04306     {
04307       tree value = TREE_VALUE (list);
04308       tree purpose = TREE_PURPOSE (list);
04309       HOST_WIDE_INT mult;
04310 
04311       mult = 1;
04312       if (TREE_CODE (purpose) == RANGE_EXPR)
04313   {
04314     tree lo_index = TREE_OPERAND (purpose, 0);
04315     tree hi_index = TREE_OPERAND (purpose, 1);
04316 
04317     if (host_integerp (lo_index, 1) && host_integerp (hi_index, 1))
04318       mult = (tree_low_cst (hi_index, 1)
04319         - tree_low_cst (lo_index, 1) + 1);
04320   }
04321 
04322       switch (TREE_CODE (value))
04323   {
04324   case CONSTRUCTOR:
04325     {
04326       HOST_WIDE_INT nz = 0, nc = 0, ic = 0;
04327       categorize_ctor_elements_1 (value, &nz, &nc, &ic, p_must_clear);
04328       nz_elts += mult * nz;
04329       nc_elts += mult * nc;
04330       elt_count += mult * ic;
04331     }
04332     break;
04333 
04334   case INTEGER_CST:
04335   case REAL_CST:
04336     if (!initializer_zerop (value))
04337       nz_elts += mult;
04338     elt_count += mult;
04339     break;
04340 
04341   case STRING_CST:
04342     nz_elts += mult * TREE_STRING_LENGTH (value);
04343     elt_count += mult * TREE_STRING_LENGTH (value);
04344     break;
04345 
04346   case COMPLEX_CST:
04347     if (!initializer_zerop (TREE_REALPART (value)))
04348       nz_elts += mult;
04349     if (!initializer_zerop (TREE_IMAGPART (value)))
04350       nz_elts += mult;
04351     elt_count += mult;
04352     break;
04353 
04354   case VECTOR_CST:
04355     {
04356       tree v;
04357       for (v = TREE_VECTOR_CST_ELTS (value); v; v = TREE_CHAIN (v))
04358         {
04359     if (!initializer_zerop (TREE_VALUE (v)))
04360       nz_elts += mult;
04361     elt_count += mult;
04362         }
04363     }
04364     break;
04365 
04366   default:
04367     nz_elts += mult;
04368     elt_count += mult;
04369     if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
04370       nc_elts += mult;
04371     break;
04372   }
04373     }
04374 
04375   if (!*p_must_clear
04376       && (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
04377     || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE))
04378     {
04379       tree init_sub_type;
04380       bool clear_this = true;
04381 
04382       list = CONSTRUCTOR_ELTS (ctor);
04383       if (list)
04384   {
04385     /* We don't expect more than one element of the union to be
04386        initialized.  Not sure what we should do otherwise... */
04387           gcc_assert (TREE_CHAIN (list) == NULL);
04388 
04389           init_sub_type = TREE_TYPE (TREE_VALUE (list));
04390 
04391     /* ??? We could look at each element of the union, and find the
04392        largest element.  Which would avoid comparing the size of the
04393        initialized element against any tail padding in the union.
04394        Doesn't seem worth the effort...  */
04395     if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)), 
04396         TYPE_SIZE (init_sub_type)) == 1)
04397       {
04398         /* And now we have to find out if the element itself is fully
04399      constructed.  E.g. for union { struct { int a, b; } s; } u
04400      = { .s = { .a = 1 } }.  */
04401         if (elt_count == count_type_elements (init_sub_type))
04402     clear_this = false;
04403       }
04404   }
04405 
04406       *p_must_clear = clear_this;
04407     }
04408 
04409   *p_nz_elts += nz_elts;
04410   *p_nc_elts += nc_elts;
04411   *p_elt_count += elt_count;
04412 }
04413 
04414 void
04415 categorize_ctor_elements (tree ctor, HOST_WIDE_INT *p_nz_elts,
04416         HOST_WIDE_INT *p_nc_elts,
04417         HOST_WIDE_INT *p_elt_count,
04418         bool *p_must_clear)
04419 {
04420   *p_nz_elts = 0;
04421   *p_nc_elts = 0;
04422   *p_elt_count = 0;
04423   *p_must_clear = false;
04424   categorize_ctor_elements_1 (ctor, p_nz_elts, p_nc_elts, p_elt_count,
04425             p_must_clear);
04426 }
04427 
04428 /* Count the number of scalars in TYPE.  Return -1 on overflow or
04429    variable-sized.  */
04430 
04431 HOST_WIDE_INT
04432 count_type_elements (tree type)
04433 {
04434   const HOST_WIDE_INT max = ~((HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1));
04435   switch (TREE_CODE (type))
04436     {
04437     case ARRAY_TYPE:
04438       {
04439   tree telts = array_type_nelts (type);
04440   if (telts && host_integerp (telts, 1))
04441     {
04442       HOST_WIDE_INT n = tree_low_cst (telts, 1) + 1;
04443       HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type));
04444       if (n == 0)
04445         return 0;
04446       else if (max / n > m)
04447         return n * m;
04448     }
04449   return -1;
04450       }
04451 
04452     case RECORD_TYPE:
04453       {
04454   HOST_WIDE_INT n = 0, t;
04455   tree f;
04456 
04457   for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
04458     if (TREE_CODE (f) == FIELD_DECL)
04459       {
04460         t = count_type_elements (TREE_TYPE (f));
04461         if (t < 0)
04462     return -1;
04463         n += t;
04464       }
04465 
04466   return n;
04467       }
04468 
04469     case UNION_TYPE:
04470     case QUAL_UNION_TYPE:
04471       {
04472   /* Ho hum.  How in the world do we guess here?  Clearly it isn't
04473      right to count the fields.  Guess based on the number of words.  */
04474         HOST_WIDE_INT n = int_size_in_bytes (type);
04475   if (n < 0)
04476     return -1;
04477   return n / UNITS_PER_WORD;
04478       }
04479 
04480     case COMPLEX_TYPE:
04481       return 2;
04482 
04483     case VECTOR_TYPE:
04484       return TYPE_VECTOR_SUBPARTS (type);
04485 
04486     case INTEGER_TYPE:
04487     case REAL_TYPE:
04488     case ENUMERAL_TYPE:
04489     case BOOLEAN_TYPE:
04490     case CHAR_TYPE:
04491     case POINTER_TYPE:
04492     case OFFSET_TYPE:
04493     case REFERENCE_TYPE:
04494       return 1;
04495 
04496     case VOID_TYPE:
04497     case METHOD_TYPE:
04498     case FILE_TYPE:
04499     case FUNCTION_TYPE:
04500     case LANG_TYPE:
04501     default:
04502       gcc_unreachable ();
04503     }
04504 }
04505 
04506 /* Return 1 if EXP contains mostly (3/4)  zeros.  */
04507 
04508 static int
04509 mostly_zeros_p (tree exp)
04510 {
04511   if (TREE_CODE (exp) == CONSTRUCTOR)
04512 
04513     {
04514       HOST_WIDE_INT nz_elts, nc_elts, count, elts;
04515       bool must_clear;
04516 
04517       categorize_ctor_elements (exp, &nz_elts, &nc_elts, &count, &must_clear);
04518       if (must_clear)
04519   return 1;
04520 
04521       elts = count_type_elements (TREE_TYPE (exp));
04522 
04523       return nz_elts < elts / 4;
04524     }
04525 
04526   return initializer_zerop (exp);
04527 }
04528 
04529 /* Helper function for store_constructor.
04530    TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
04531    TYPE is the type of the CONSTRUCTOR, not the element type.
04532    CLEARED is as for store_constructor.
04533    ALIAS_SET is the alias set to use for any stores.
04534 
04535    This provides a recursive shortcut back to store_constructor when it isn't
04536    necessary to go through store_field.  This is so that we can pass through
04537    the cleared field to let store_constructor know that we may not have to
04538    clear a substructure if the outer structure has already been cleared.  */
04539 
04540 static void
04541 store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
04542        HOST_WIDE_INT bitpos, enum machine_mode mode,
04543        tree exp, tree type, int cleared, int alias_set)
04544 {
04545   if (TREE_CODE (exp) == CONSTRUCTOR
04546       /* We can only call store_constructor recursively if the size and
04547    bit position are on a byte boundary.  */
04548       && bitpos % BITS_PER_UNIT == 0
04549       && (bitsize > 0 && bitsize % BITS_PER_UNIT == 0)
04550       /* If we have a nonzero bitpos for a register target, then we just
04551    let store_field do the bitfield handling.  This is unlikely to
04552    generate unnecessary clear instructions anyways.  */
04553       && (bitpos == 0 || MEM_P (target)))
04554     {
04555       if (MEM_P (target))
04556   target
04557     = adjust_address (target,
04558           GET_MODE (target) == BLKmode
04559           || 0 != (bitpos
04560              % GET_MODE_ALIGNMENT (GET_MODE (target)))
04561           ? BLKmode : VOIDmode, bitpos / BITS_PER_UNIT);
04562 
04563 
04564       /* Update the alias set, if required.  */
04565       if (MEM_P (target) && ! MEM_KEEP_ALIAS_SET_P (target)
04566     && MEM_ALIAS_SET (target) != 0)
04567   {
04568     target = copy_rtx (target);
04569     set_mem_alias_set (target, alias_set);
04570   }
04571 
04572       store_constructor (exp, target, cleared, bitsize / BITS_PER_UNIT);
04573     }
04574   else
04575     store_field (target, bitsize, bitpos, mode, exp, type, alias_set);
04576 }
04577 
04578 /* Store the value of constructor EXP into the rtx TARGET.
04579    TARGET is either a REG or a MEM; we know it cannot conflict, since
04580    safe_from_p has been called.
04581    CLEARED is true if TARGET is known to have been zero'd.
04582    SIZE is the number of bytes of TARGET we are allowed to modify: this
04583    may not be the same as the size of EXP if we are assigning to a field
04584    which has been packed to exclude padding bits.  */
04585 
04586 static void
04587 store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
04588 {
04589   tree type = TREE_TYPE (exp);
04590 #ifdef WORD_REGISTER_OPERATIONS
04591   HOST_WIDE_INT exp_size = int_size_in_bytes (type);
04592 #endif
04593 
04594   switch (TREE_CODE (type))
04595     {
04596     case RECORD_TYPE:
04597     case UNION_TYPE:
04598     case QUAL_UNION_TYPE:
04599       {
04600   tree elt;
04601 
04602   /* If size is zero or the target is already cleared, do nothing.  */
04603   if (size == 0 || cleared)
04604     cleared = 1;
04605   /* We either clear the aggregate or indicate the value is dead.  */
04606   else if ((TREE_CODE (type) == UNION_TYPE
04607       || TREE_CODE (type) == QUAL_UNION_TYPE)
04608      && ! CONSTRUCTOR_ELTS (exp))
04609     /* If the constructor is empty, clear the union.  */
04610     {
04611       clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
04612       cleared = 1;
04613     }
04614 
04615   /* If we are building a static constructor into a register,
04616      set the initial value as zero so we can fold the value into
04617      a constant.  But if more than one register is involved,
04618      this probably loses.  */
04619   else if (REG_P (target) && TREE_STATIC (exp)
04620      && GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD)
04621     {
04622       emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
04623       cleared = 1;
04624     }
04625 
04626         /* If the constructor has fewer fields than the structure or
04627      if we are initializing the structure to mostly zeros, clear
04628      the whole structure first.  Don't do this if TARGET is a
04629      register whose mode size isn't equal to SIZE since
04630      clear_storage can't handle this case.  */
04631   else if (size > 0
04632      && ((list_length (CONSTRUCTOR_ELTS (exp))
04633           != fields_length (type))
04634          || mostly_zeros_p (exp))
04635      && (!REG_P (target)
04636          || ((HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target))
04637        == size)))
04638     {
04639       clear_storage (target, GEN_INT (size), BLOCK_OP_NORMAL);
04640       cleared = 1;
04641     }
04642 
04643   if (! cleared)
04644     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
04645 
04646   /* Store each element of the constructor into the
04647      corresponding field of TARGET.  */
04648 
04649   for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
04650     {
04651       tree field = TREE_PURPOSE (elt);
04652       tree value = TREE_VALUE (elt);
04653       enum machine_mode mode;
04654       HOST_WIDE_INT bitsize;
04655       HOST_WIDE_INT bitpos = 0;
04656       tree offset;
04657       rtx to_rtx = target;
04658       
04659       /* Just ignore missing fields.  We cleared the whole
04660          structure, above, if any fields are missing.  */
04661       if (field == 0)
04662         continue;
04663       
04664       if (cleared && initializer_zerop (value))
04665         continue;
04666       
04667       if (host_integerp (DECL_SIZE (field), 1))
04668         bitsize = tree_low_cst (DECL_SIZE (field), 1);
04669       else
04670         bitsize = -1;
04671       
04672       mode = DECL_MODE (field);
04673       if (DECL_BIT_FIELD (field))
04674         mode = VOIDmode;
04675       
04676       offset = DECL_FIELD_OFFSET (field);
04677       if (host_integerp (offset, 0)
04678     && host_integerp (bit_position (field), 0))
04679         {
04680     bitpos = int_bit_position (field);
04681     offset = 0;
04682         }
04683       else
04684         bitpos = tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 0);
04685       
04686       if (offset)
04687         {
04688     rtx offset_rtx;
04689     
04690     offset
04691       = SUBSTITUTE_PLACEHOLDER_IN_EXPR (offset,
04692                 make_tree (TREE_TYPE (exp),
04693                      target));
04694 
04695     offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
04696     gcc_assert (MEM_P (to_rtx));
04697     
04698 #ifdef POINTERS_EXTEND_UNSIGNED
04699     if (GET_MODE (offset_rtx) != Pmode)
04700       offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
04701 #else
04702     if (GET_MODE (offset_rtx) != ptr_mode)
04703       offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
04704 #endif
04705 
04706     to_rtx = offset_address (to_rtx, offset_rtx,
04707            highest_pow2_factor (offset));
04708         }
04709 
04710 #ifdef WORD_REGISTER_OPERATIONS
04711       /* If this initializes a field that is smaller than a
04712          word, at the start of a word, try to widen it to a full
04713          word.  This special case allows us to output C++ member
04714          function initializations in a form that the optimizers
04715          can understand.  */
04716       if (REG_P (target)
04717     && bitsize < BITS_PER_WORD
04718     && bitpos % BITS_PER_WORD == 0
04719     && GET_MODE_CLASS (mode) == MODE_INT
04720     && TREE_CODE (value) == INTEGER_CST
04721     && exp_size >= 0
04722     && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
04723         {
04724     tree type = TREE_TYPE (value);
04725     
04726     if (TYPE_PRECISION (type) < BITS_PER_WORD)
04727       {
04728         type = lang_hooks.types.type_for_size
04729           (BITS_PER_WORD, TYPE_UNSIGNED (type));
04730         value = convert (type, value);
04731       }
04732     
04733     if (BYTES_BIG_ENDIAN)
04734       value
04735         = fold (build2 (LSHIFT_EXPR, type, value,
04736             build_int_cst (NULL_TREE,
04737                BITS_PER_WORD - bitsize)));
04738     bitsize = BITS_PER_WORD;
04739     mode = word_mode;
04740         }
04741 #endif
04742 
04743       if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
04744     && DECL_NONADDRESSABLE_P (field))
04745         {
04746     to_rtx = copy_rtx (to_rtx);
04747     MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
04748         }
04749       
04750       store_constructor_field (to_rtx, bitsize, bitpos, mode,
04751              value, type, cleared,
04752              get_alias_set (TREE_TYPE (field)));
04753     }
04754   break;
04755       }
04756     case ARRAY_TYPE:
04757       {
04758   tree elt;
04759   int i;
04760   int need_to_clear;
04761   tree domain;
04762   tree elttype = TREE_TYPE (type);
04763   int const_bounds_p;
04764   HOST_WIDE_INT minelt = 0;
04765   HOST_WIDE_INT maxelt = 0;
04766 
04767   domain = TYPE_DOMAIN (type);
04768   const_bounds_p = (TYPE_MIN_VALUE (domain)
04769         && TYPE_MAX_VALUE (domain)
04770         && host_integerp (TYPE_MIN_VALUE (domain), 0)
04771         && host_integerp (TYPE_MAX_VALUE (domain), 0));
04772 
04773   /* If we have constant bounds for the range of the type, get them.  */
04774   if (const_bounds_p)
04775     {
04776       minelt = tree_low_cst (TYPE_MIN_VALUE (domain), 0);
04777       maxelt = tree_low_cst (TYPE_MAX_VALUE (domain), 0);
04778     }
04779 
04780   /* If the constructor has fewer elements than the array, clear
04781            the whole array first.  Similarly if this is static
04782            constructor of a non-BLKmode object.  */
04783   if (cleared)
04784     need_to_clear = 0;
04785   else if (REG_P (target) && TREE_STATIC (exp))
04786     need_to_clear = 1;
04787   else
04788     {
04789       HOST_WIDE_INT count = 0, zero_count = 0;
04790       need_to_clear = ! const_bounds_p;
04791       
04792       /* This loop is a more accurate version of the loop in
04793          mostly_zeros_p (it handles RANGE_EXPR in an index).  It
04794          is also needed to check for missing elements.  */
04795       for (elt = CONSTRUCTOR_ELTS (exp);
04796      elt != NULL_TREE && ! need_to_clear;
04797      elt = TREE_CHAIN (elt))
04798         {
04799     tree index = TREE_PURPOSE (elt);
04800     HOST_WIDE_INT this_node_count;
04801     
04802     if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
04803       {
04804         tree lo_index = TREE_OPERAND (index, 0);
04805         tree hi_index = TREE_OPERAND (index, 1);
04806         
04807         if (! host_integerp (lo_index, 1)
04808       || ! host_integerp (hi_index, 1))
04809           {
04810       need_to_clear = 1;
04811       break;
04812           }
04813         
04814         this_node_count = (tree_low_cst (hi_index, 1)
04815                - tree_low_cst (lo_index, 1) + 1);
04816       }
04817     else
04818       this_node_count = 1;
04819     
04820     count += this_node_count;
04821     if (mostly_zeros_p (TREE_VALUE (elt)))
04822       zero_count += this_node_count;
04823         }
04824       
04825       /* Clear the entire array first if there are any missing
04826          elements, or if the incidence of zero elements is >=
04827          75%.  */
04828       if (! need_to_clear
04829     && (count < maxelt - minelt + 1
04830         || 4 * zero_count >= 3 * count))
04831         need_to_clear = 1;
04832     }
04833   
04834   if (need_to_clear && size > 0)
04835     {
04836       if (REG_P (target))
04837         emit_move_insn (target,  CONST0_RTX (GET_MODE (target)));
04838       else
04839         clear_storage (target, GEN_INT (size), BLOCK_OP_NORMAL);
04840       cleared = 1;
04841     }
04842 
04843   if (!cleared && REG_P (target))
04844     /* Inform later passes that the old value is dead.  */
04845     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
04846 
04847   /* Store each element of the constructor into the
04848      corresponding element of TARGET, determined by counting the
04849      elements.  */
04850   for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
04851        elt;
04852        elt = TREE_CHAIN (elt), i++)
04853     {
04854       enum machine_mode mode;
04855       HOST_WIDE_INT bitsize;
04856       HOST_WIDE_INT bitpos;
04857       int unsignedp;
04858       tree value = TREE_VALUE (elt);
04859       tree index = TREE_PURPOSE (elt);
04860       rtx xtarget = target;
04861       
04862       if (cleared && initializer_zerop (value))
04863         continue;
04864       
04865       unsignedp = TYPE_UNSIGNED (elttype);
04866       mode = TYPE_MODE (elttype);
04867       if (mode == BLKmode)
04868         bitsize = (host_integerp (TYPE_SIZE (elttype), 1)
04869        ? tree_low_cst (TYPE_SIZE (elttype), 1)
04870        : -1);
04871       else
04872         bitsize = GET_MODE_BITSIZE (mode);
04873       
04874       if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
04875         {
04876     tree lo_index = TREE_OPERAND (index, 0);
04877     tree hi_index = TREE_OPERAND (index, 1);
04878     rtx index_r, pos_rtx;
04879     HOST_WIDE_INT lo, hi, count;
04880     tree position;
04881     
04882     /* If the range is constant and "small", unroll the loop.  */
04883     if (const_bounds_p
04884         && host_integerp (lo_index, 0)
04885         && host_integerp (hi_index, 0)
04886         && (lo = tree_low_cst (lo_index, 0),
04887       hi = tree_low_cst (hi_index, 0),
04888       count = hi - lo + 1,
04889       (!MEM_P (target)
04890        || count <= 2
04891        || (host_integerp (TYPE_SIZE (elttype), 1)
04892            && (tree_low_cst (TYPE_SIZE (elttype), 1) * count
04893          <= 40 * 8)))))
04894       {
04895         lo -= minelt;  hi -= minelt;
04896         for (; lo <= hi; lo++)
04897           {
04898       bitpos = lo * tree_low_cst (TYPE_SIZE (elttype), 0);
04899       
04900       if (MEM_P (target)
04901           && !MEM_KEEP_ALIAS_SET_P (target)
04902           && TREE_CODE (type) == ARRAY_TYPE
04903           && TYPE_NONALIASED_COMPONENT (type))
04904         {
04905           target = copy_rtx (target);
04906           MEM_KEEP_ALIAS_SET_P (target) = 1;
04907         }
04908       
04909       store_constructor_field
04910         (target, bitsize, bitpos, mode, value, type, cleared,
04911          get_alias_set (elttype));
04912           }
04913       }
04914     else
04915       {
04916         rtx loop_start = gen_label_rtx ();
04917         rtx loop_end = gen_label_rtx ();
04918         tree exit_cond;
04919         
04920         expand_expr (hi_index, NULL_RTX, VOIDmode, 0);
04921         unsignedp = TYPE_UNSIGNED (domain);
04922         
04923         index = build_decl (VAR_DECL, NULL_TREE, domain);
04924         
04925         index_r
04926           = gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
04927                &unsignedp, 0));
04928         SET_DECL_RTL (index, index_r);
04929         store_expr (lo_index, index_r, 0);
04930         
04931         /* Build the head of the loop.  */
04932         do_pending_stack_adjust ();
04933         emit_label (loop_start);
04934 
04935         /* Assign value to element index.  */
04936         position
04937           = convert (ssizetype,
04938          fold (build2 (MINUS_EXPR, TREE_TYPE (index),
04939                  index, TYPE_MIN_VALUE (domain))));
04940         position = size_binop (MULT_EXPR, position,
04941              convert (ssizetype,
04942                 TYPE_SIZE_UNIT (elttype)));
04943         
04944         pos_rtx = expand_expr (position, 0, VOIDmode, 0);
04945         xtarget = offset_address (target, pos_rtx,
04946                 highest_pow2_factor (position));
04947         xtarget = adjust_address (xtarget, mode, 0);
04948         if (TREE_CODE (value) == CONSTRUCTOR)
04949           store_constructor (value, xtarget, cleared,
04950            bitsize / BITS_PER_UNIT);
04951         else
04952           store_expr (value, xtarget, 0);
04953 
04954         /* Generate a conditional jump to exit the loop.  */
04955         exit_cond = build2 (LT_EXPR, integer_type_node,
04956           index, hi_index);
04957         jumpif (exit_cond, loop_end);
04958         
04959         /* Update the loop counter, and jump to the head of
04960            the loop.  */
04961         expand_assignment (index,
04962                build2 (PLUS_EXPR, TREE_TYPE (index),
04963                  index, integer_one_node));
04964         
04965         emit_jump (loop_start);
04966         
04967         /* Build the end of the loop.  */
04968         emit_label (loop_end);
04969       }
04970         }
04971       else if ((index != 0 && ! host_integerp (index, 0))
04972          || ! host_integerp (TYPE_SIZE (elttype), 1))
04973         {
04974     tree position;
04975     
04976     if (index == 0)
04977       index = ssize_int (1);
04978     
04979     if (minelt)
04980       index = fold_convert (ssizetype,
04981           fold (build2 (MINUS_EXPR,
04982                   TREE_TYPE (index),
04983                   index,
04984                   TYPE_MIN_VALUE (domain))));
04985     
04986     position = size_binop (MULT_EXPR, index,
04987                convert (ssizetype,
04988             TYPE_SIZE_UNIT (elttype)));
04989     xtarget = offset_address (target,
04990             expand_expr (position, 0, VOIDmode, 0),
04991             highest_pow2_factor (position));
04992     xtarget = adjust_address (xtarget, mode, 0);
04993     store_expr (value, xtarget, 0);
04994         }
04995       else
04996         {
04997     if (index != 0)
04998       bitpos = ((tree_low_cst (index, 0) - minelt)
04999           * tree_low_cst (TYPE_SIZE (elttype), 1));
05000     else
05001       bitpos = (i * tree_low_cst (TYPE_SIZE (elttype), 1));
05002     
05003     if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
05004         && TREE_CODE (type) == ARRAY_TYPE
05005         && TYPE_NONALIASED_COMPONENT (type))
05006       {
05007         target = copy_rtx (target);
05008         MEM_KEEP_ALIAS_SET_P (target) = 1;
05009       }
05010     store_constructor_field (target, bitsize, bitpos, mode, value,
05011            type, cleared, get_alias_set (elttype));
05012         }
05013     }
05014   break;
05015       }
05016 
05017     case VECTOR_TYPE:
05018       {
05019   tree elt;
05020   int i;
05021   int need_to_clear;
05022   int icode = 0;
05023   tree elttype = TREE_TYPE (type);
05024   int elt_size = tree_low_cst (TYPE_SIZE (elttype), 1);
05025   enum machine_mode eltmode = TYPE_MODE (elttype);
05026   HOST_WIDE_INT bitsize;
05027   HOST_WIDE_INT bitpos;
05028   rtvec vector = NULL;
05029   unsigned n_elts;
05030   
05031   gcc_assert (eltmode != BLKmode);
05032   
05033   n_elts = TYPE_VECTOR_SUBPARTS (type);
05034   if (REG_P (target) && VECTOR_MODE_P (GET_MODE (target)))
05035     {
05036       enum machine_mode mode = GET_MODE (target);
05037       
05038       icode = (int) vec_init_optab->handlers[mode].insn_code;
05039       if (icode != CODE_FOR_nothing)
05040         {
05041     unsigned int i;
05042     
05043     vector = rtvec_alloc (n_elts);
05044     for (i = 0; i < n_elts; i++)
05045       RTVEC_ELT (vector, i) = CONST0_RTX (GET_MODE_INNER (mode));
05046         }
05047     }
05048   
05049   /* If the constructor has fewer elements than the vector,
05050      clear the whole array first.  Similarly if this is static
05051      constructor of a non-BLKmode object.  */
05052   if (cleared)
05053     need_to_clear = 0;
05054   else if (REG_P (target) && TREE_STATIC (exp))
05055     need_to_clear = 1;
05056   else
05057     {
05058       unsigned HOST_WIDE_INT count = 0, zero_count = 0;
05059       
05060       for (elt = CONSTRUCTOR_ELTS (exp);
05061      elt != NULL_TREE;
05062      elt = TREE_CHAIN (elt))
05063         {
05064     int n_elts_here = tree_low_cst
05065       (int_const_binop (TRUNC_DIV_EXPR,
05066             TYPE_SIZE (TREE_TYPE (TREE_VALUE (elt))),
05067             TYPE_SIZE (elttype), 0), 1);
05068     
05069     count += n_elts_here;
05070     if (mostly_zeros_p (TREE_VALUE (elt)))
05071       zero_count += n_elts_here;
05072         }
05073 
05074       /* Clear the entire vector first if there are any missing elements,
05075          or if the incidence of zero elements is >= 75%.  */
05076       need_to_clear = (count < n_elts || 4 * zero_count >= 3 * count);
05077     }
05078   
05079   if (need_to_clear && size > 0 && !vector)
05080     {
05081       if (REG_P (target))
05082         emit_move_insn (target,  CONST0_RTX (GET_MODE (target)));
05083       else
05084         clear_storage (target, GEN_INT (size), BLOCK_OP_NORMAL);
05085       cleared = 1;
05086     }
05087   
05088   if (!cleared && REG_P (target))
05089     /* Inform later passes that the old value is dead.  */
05090     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
05091 
05092         /* Store each element of the constructor into the corresponding
05093      element of TARGET, determined by counting the elements.  */
05094   for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
05095        elt;
05096        elt = TREE_CHAIN (elt), i += bitsize / elt_size)
05097     {
05098       tree value = TREE_VALUE (elt);
05099       tree index = TREE_PURPOSE (elt);
05100       HOST_WIDE_INT eltpos;
05101       
05102       bitsize = tree_low_cst (TYPE_SIZE (TREE_TYPE (value)), 1);
05103       if (cleared && initializer_zerop (value))
05104         continue;
05105       
05106       if (index != 0)
05107         eltpos = tree_low_cst (index, 1);
05108       else
05109         eltpos = i;
05110       
05111       if (vector)
05112         {
05113           /* Vector CONSTRUCTORs should only be built from smaller
05114        vectors in the case of BLKmode vectors.  */
05115     gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);
05116     RTVEC_ELT (vector, eltpos)
05117       = expand_expr (value, NULL_RTX, VOIDmode, 0);
05118         }
05119       else
05120         {
05121     enum machine_mode value_mode =
05122       TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE
05123       ? TYPE_MODE (TREE_TYPE (value))
05124       : eltmode;
05125     bitpos = eltpos * elt_size;
05126     store_constructor_field (target, bitsize, bitpos,
05127            value_mode, value, type,
05128            cleared, get_alias_set (elttype));
05129         }
05130     }
05131   
05132   if (vector)
05133     emit_insn (GEN_FCN (icode)
05134          (target,
05135           gen_rtx_PARALLEL (GET_MODE (target), vector)));
05136   break;
05137       }
05138       
05139     default:
05140       gcc_unreachable ();
05141     }
05142 }
05143 
05144 /* Store the value of EXP (an expression tree)
05145    into a subfield of TARGET which has mode MODE and occupies
05146    BITSIZE bits, starting BITPOS bits from the start of TARGET.
05147    If MODE is VOIDmode, it means that we are storing into a bit-field.
05148 
05149    Always return const0_rtx unless we have something particular to
05150    return.
05151 
05152    TYPE is the type of the underlying object,
05153 
05154    ALIAS_SET is the alias set for the destination.  This value will
05155    (in general) be different from that for TARGET, since TARGET is a
05156    reference to the containing structure.  */
05157 
05158 static rtx
05159 store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
05160        enum machine_mode mode, tree exp, tree type, int alias_set)
05161 {
05162   HOST_WIDE_INT width_mask = 0;
05163 
05164   if (TREE_CODE (exp) == ERROR_MARK)
05165     return const0_rtx;
05166 
05167   /* If we have nothing to store, do nothing unless the expression has
05168      side-effects.  */
05169   if (bitsize == 0)
05170     return expand_expr (exp, const0_rtx, VOIDmode, 0);
05171   else if (bitsize >= 0 && bitsize < HOST_BITS_PER_WIDE_INT)
05172     width_mask = ((HOST_WIDE_INT) 1 << bitsize) - 1;
05173 
05174   /* If we are storing into an unaligned field of an aligned union that is
05175      in a register, we may have the mode of TARGET being an integer mode but
05176      MODE == BLKmode.  In that case, get an aligned object whose size and
05177      alignment are the same as TARGET and store TARGET into it (we can avoid
05178      the store if the field being stored is the entire width of TARGET).  Then
05179      call ourselves recursively to store the field into a BLKmode version of
05180      that object.  Finally, load from the object into TARGET.  This is not
05181      very efficient in general, but should only be slightly more expensive
05182      than the otherwise-required unaligned accesses.  Perhaps this can be
05183      cleaned up later.  It's tempting to make OBJECT readonly, but it's set
05184      twice, once with emit_move_insn and once via store_field.  */
05185 
05186   if (mode == BLKmode
05187       && (REG_P (target) || GET_CODE (target) == SUBREG))
05188     {
05189       rtx object = assign_temp (type, 0, 1, 1);
05190       rtx blk_object = adjust_address (object, BLKmode, 0);
05191 
05192       if (bitsize != (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (target)))
05193   emit_move_insn (object, target);
05194 
05195       store_field (blk_object, bitsize, bitpos, mode, exp, type, alias_set);
05196 
05197       emit_move_insn (target, object);
05198 
05199       /* We want to return the BLKmode version of the data.  */
05200       return blk_object;
05201     }
05202 
05203   if (GET_CODE (target) == CONCAT)
05204     {
05205       /* We're storing into a struct containing a single __complex.  */
05206 
05207       gcc_assert (!bitpos);
05208       return store_expr (exp, target, 0);
05209     }
05210 
05211   /* If the structure is in a register or if the component
05212      is a bit field, we cannot use addressing to access it.
05213      Use bit-field techniques or SUBREG to store in it.  */
05214 
05215   if (mode == VOIDmode
05216       || (mode != BLKmode && ! direct_store[(int) mode]
05217     && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
05218     && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
05219       || REG_P (target)
05220       || GET_CODE (target) == SUBREG
05221       /* If the field isn't aligned enough to store as an ordinary memref,
05222    store it as a bit field.  */
05223       || (mode != BLKmode
05224     && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
05225     || bitpos % GET_MODE_ALIGNMENT (mode))
05226          && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (target)))
05227         || (bitpos % BITS_PER_UNIT != 0)))
05228       /* If the RHS and field are a constant size and the size of the
05229    RHS isn't the same size as the bitfield, we must use bitfield
05230    operations.  */
05231       || (bitsize >= 0
05232     && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
05233     && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0))
05234     {
05235       rtx temp;
05236 
05237       /* If EXP is a NOP_EXPR of precision less than its mode, then that
05238    implies a mask operation.  If the precision is the same size as
05239    the field we're storing into, that mask is redundant.  This is
05240    particularly common with bit field assignments generated by the
05241    C front end.  */
05242       if (TREE_CODE (exp) == NOP_EXPR)
05243   {
05244     tree type = TREE_TYPE (exp);
05245     if (INTEGRAL_TYPE_P (type)
05246         && TYPE_PRECISION (type) < GET_MODE_BITSIZE (TYPE_MODE (type))
05247         && bitsize == TYPE_PRECISION (type))
05248       {
05249         type = TREE_TYPE (TREE_OPERAND (exp, 0));
05250         if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) >= bitsize)
05251     exp = TREE_OPERAND (exp, 0);
05252       }
05253   }
05254 
05255       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
05256 
05257       /* If BITSIZE is narrower than the size of the type of EXP
05258    we will be narrowing TEMP.  Normally, what's wanted are the
05259    low-order bits.  However, if EXP's type is a record and this is
05260    big-endian machine, we want the upper BITSIZE bits.  */
05261       if (BYTES_BIG_ENDIAN && GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
05262     && bitsize < (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (temp))
05263     && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
05264   temp = expand_shift (RSHIFT_EXPR, GET_MODE (temp), temp,
05265            size_int (GET_MODE_BITSIZE (GET_MODE (temp))
05266                - bitsize),
05267            NULL_RTX, 1);
05268 
05269       /* Unless MODE is VOIDmode or BLKmode, convert TEMP to
05270    MODE.  */
05271       if (mode != VOIDmode && mode != BLKmode
05272     && mode != TYPE_MODE (TREE_TYPE (exp)))
05273   temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
05274 
05275       /* If the modes of TARGET and TEMP are both BLKmode, both
05276    must be in memory and BITPOS must be aligned on a byte
05277    boundary.  If so, we simply do a block copy.  */
05278       if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode)
05279   {
05280     gcc_assert (MEM_P (target) && MEM_P (temp)
05281           && !(bitpos % BITS_PER_UNIT));
05282 
05283     target = adjust_address (target, VOIDmode, bitpos / BITS_PER_UNIT);
05284     emit_block_move (target, temp,
05285          GEN_INT ((bitsize + BITS_PER_UNIT - 1)
05286             / BITS_PER_UNIT),
05287          BLOCK_OP_NORMAL);
05288 
05289     return const0_rtx;
05290   }
05291 
05292       /* Store the value in the bitfield.  */
05293       store_bit_field (target, bitsize, bitpos, mode, temp);
05294 
05295       return const0_rtx;
05296     }
05297   else
05298     {
05299       /* Now build a reference to just the desired component.  */
05300       rtx to_rtx = adjust_address (target, mode, bitpos / BITS_PER_UNIT);
05301 
05302       if (to_rtx == target)
05303   to_rtx = copy_rtx (to_rtx);
05304 
05305       MEM_SET_IN_STRUCT_P (to_rtx, 1);
05306       if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
05307   set_mem_alias_set (to_rtx, alias_set);
05308 
05309       return store_expr (exp, to_rtx, 0);
05310     }
05311 }
05312 
05313 /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
05314    an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
05315    codes and find the ultimate containing object, which we return.
05316 
05317    We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
05318    bit position, and *PUNSIGNEDP to the signedness of the field.
05319    If the position of the field is variable, we store a tree
05320    giving the variable offset (in units) in *POFFSET.
05321    This offset is in addition to the bit position.
05322    If the position is not variable, we store 0 in *POFFSET.
05323 
05324    If any of the extraction expressions is volatile,
05325    we store 1 in *PVOLATILEP.  Otherwise we don't change that.
05326 
05327    If the field is a bit-field, *PMODE is set to VOIDmode.  Otherwise, it
05328    is a mode that can be used to access the field.  In that case, *PBITSIZE
05329    is redundant.
05330 
05331    If the field describes a variable-sized object, *PMODE is set to
05332    VOIDmode and *PBITSIZE is set to -1.  An access cannot be made in
05333    this case, but the address of the object can be found.
05334 
05335    If KEEP_ALIGNING is true and the target is STRICT_ALIGNMENT, we don't
05336    look through nodes that serve as markers of a greater alignment than
05337    the one that can be deduced from the expression.  These nodes make it
05338    possible for front-ends to prevent temporaries from being created by
05339    the middle-end on alignment considerations.  For that purpose, the
05340    normal operating mode at high-level is to always pass FALSE so that
05341    the ultimate containing object is really returned; moreover, the
05342    associated predicate handled_component_p will always return TRUE
05343    on these nodes, thus indicating that they are essentially handled
05344    by get_inner_reference.  TRUE should only be passed when the caller
05345    is scanning the expression in order to build another representation
05346    and specifically knows how to handle these nodes; as such, this is
05347    the normal operating mode in the RTL expanders.  */
05348 
05349 tree
05350 get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
05351          HOST_WIDE_INT *pbitpos, tree *poffset,
05352          enum machine_mode *pmode, int *punsignedp,
05353          int *pvolatilep, bool keep_aligning)
05354 {
05355   tree size_tree = 0;
05356   enum machine_mode mode = VOIDmode;
05357   tree offset = size_zero_node;
05358   tree bit_offset = bitsize_zero_node;
05359   tree tem;
05360 
05361   /* First get the mode, signedness, and size.  We do this from just the
05362      outermost expression.  */
05363   if (TREE_CODE (exp) == COMPONENT_REF)
05364     {
05365       size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
05366       if (! DECL_BIT_FIELD (TREE_OPERAND (exp, 1)))
05367   mode = DECL_MODE (TREE_OPERAND (exp, 1));
05368 
05369       *punsignedp = DECL_UNSIGNED (TREE_OPERAND (exp, 1));
05370     }
05371   else if (TREE_CODE (exp) == BIT_FIELD_REF)
05372     {
05373       size_tree = TREE_OPERAND (exp, 1);
05374       *punsignedp = BIT_FIELD_REF_UNSIGNED (exp);
05375     }
05376   else
05377     {
05378       mode = TYPE_MODE (TREE_TYPE (exp));
05379       *punsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
05380 
05381       if (mode == BLKmode)
05382   size_tree = TYPE_SIZE (TREE_TYPE (exp));
05383       else
05384   *pbitsize = GET_MODE_BITSIZE (mode);
05385     }
05386 
05387   if (size_tree != 0)
05388     {
05389       if (! host_integerp (size_tree, 1))
05390   mode = BLKmode, *pbitsize = -1;
05391       else
05392   *pbitsize = tree_low_cst (size_tree, 1);
05393     }
05394 
05395   /* Compute cumulative bit-offset for nested component-refs and array-refs,
05396      and find the ultimate containing object.  */
05397   while (1)
05398     {
05399       switch (TREE_CODE (exp))
05400   {
05401   case BIT_FIELD_REF:
05402     bit_offset = size_binop (PLUS_EXPR, bit_offset,
05403            TREE_OPERAND (exp, 2));
05404     break;
05405 
05406   case COMPONENT_REF:
05407     {
05408       tree field = TREE_OPERAND (exp, 1);
05409       tree this_offset = component_ref_field_offset (exp);
05410 
05411       /* If this field hasn't been filled in yet, don't go past it.
05412          This should only happen when folding expressions made during
05413          type construction.  */
05414       if (this_offset == 0)
05415         break;
05416 
05417       offset = size_binop (PLUS_EXPR, offset, this_offset);
05418       bit_offset = size_binop (PLUS_EXPR, bit_offset,
05419              DECL_FIELD_BIT_OFFSET (field));
05420 
05421       /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN.  */
05422     }
05423     break;
05424 
05425   case ARRAY_REF:
05426   case ARRAY_RANGE_REF:
05427     {
05428       tree index = TREE_OPERAND (exp, 1);
05429       tree low_bound = array_ref_low_bound (exp);
05430       tree unit_size = array_ref_element_size (exp);
05431 
05432       /* We assume all arrays have sizes that are a multiple of a byte.
05433          First subtract the lower bound, if any, in the type of the
05434          index, then convert to sizetype and multiply by the size of
05435          the array element.  */
05436       if (! integer_zerop (low_bound))
05437         index = fold (build2 (MINUS_EXPR, TREE_TYPE (index),
05438             index, low_bound));
05439 
05440       offset = size_binop (PLUS_EXPR, offset,
05441                size_binop (MULT_EXPR,
05442                convert (sizetype, index),
05443                unit_size));
05444     }
05445     break;
05446 
05447   case REALPART_EXPR:
05448     break;
05449 
05450   case IMAGPART_EXPR:
05451     bit_offset = size_binop (PLUS_EXPR, bit_offset,
05452            bitsize_int (*pbitsize));
05453     break;
05454 
05455   case VIEW_CONVERT_EXPR:
05456     if (keep_aligning && STRICT_ALIGNMENT
05457         && (TYPE_ALIGN (TREE_TYPE (exp))
05458          > TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))))
05459         && (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
05460       < BIGGEST_ALIGNMENT)
05461         && (TYPE_ALIGN_OK (TREE_TYPE (exp))
05462       || TYPE_ALIGN_OK (TREE_TYPE (TREE_OPERAND (exp, 0)))))
05463       goto done;
05464     break;
05465 
05466   default:
05467     goto done;
05468   }
05469 
05470       /* If any reference in the chain is volatile, the effect is volatile.  */
05471       if (TREE_THIS_VOLATILE (exp))
05472   *pvolatilep = 1;
05473 
05474       exp = TREE_OPERAND (exp, 0);
05475     }
05476  done:
05477 
05478   /* If OFFSET is constant, see if we can return the whole thing as a
05479      constant bit position.  Otherwise, split it up.  */
05480   if (host_integerp (offset, 0)
05481       && 0 != (tem = size_binop (MULT_EXPR, convert (bitsizetype, offset),
05482          bitsize_unit_node))
05483       && 0 != (tem = size_binop (PLUS_EXPR, tem, bit_offset))
05484       && host_integerp (tem, 0))
05485     *pbitpos = tree_low_cst (tem, 0), *poffset = 0;
05486   else
05487     *pbitpos = tree_low_cst (bit_offset, 0), *poffset = offset;
05488 
05489   *pmode = mode;
05490   return exp;
05491 }
05492 
05493 /* Return a tree of sizetype representing the size, in bytes, of the element
05494    of EXP, an ARRAY_REF.  */
05495 
05496 tree
05497 array_ref_element_size (tree exp)
05498 {
05499   tree aligned_size = TREE_OPERAND (exp, 3);
05500   tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
05501 
05502   /* If a size was specified in the ARRAY_REF, it's the size measured
05503      in alignment units of the element type.  So multiply by that value.  */
05504   if (aligned_size)
05505     {
05506       /* ??? tree_ssa_useless_type_conversion will eliminate casts to
05507    sizetype from another type of the same width and signedness.  */
05508       if (TREE_TYPE (aligned_size) != sizetype)
05509   aligned_size = fold_convert (sizetype, aligned_size);
05510       return size_binop (MULT_EXPR, aligned_size,
05511              size_int (TYPE_ALIGN_UNIT (elmt_type)));
05512     }
05513 
05514   /* Otherwise, take the size from that of the element type.  Substitute
05515      any PLACEHOLDER_EXPR that we have.  */
05516   else
05517     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
05518 }
05519 
05520 /* Return a tree representing the lower bound of the array mentioned in
05521    EXP, an ARRAY_REF.  */
05522 
05523 tree
05524 array_ref_low_bound (tree exp)
05525 {
05526   tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
05527 
05528   /* If a lower bound is specified in EXP, use it.  */
05529   if (TREE_OPERAND (exp, 2))
05530     return TREE_OPERAND (exp, 2);
05531 
05532   /* Otherwise, if there is a domain type and it has a lower bound, use it,
05533      substituting for a PLACEHOLDER_EXPR as needed.  */
05534   if (domain_type && TYPE_MIN_VALUE (domain_type))
05535     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
05536 
05537   /* Otherwise, return a zero of the appropriate type.  */
05538   return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
05539 }
05540 
05541 /* Return a tree representing the upper bound of the array mentioned in
05542    EXP, an ARRAY_REF.  */
05543 
05544 tree
05545 array_ref_up_bound (tree exp)
05546 {
05547   tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
05548 
05549   /* If there is a domain type and it has an upper bound, use it, substituting
05550      for a PLACEHOLDER_EXPR as needed.  */
05551   if (domain_type && TYPE_MAX_VALUE (domain_type))
05552     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
05553 
05554   /* Otherwise fail.  */
05555   return NULL_TREE;
05556 }
05557 
05558 /* Return a tree representing the offset, in bytes, of the field referenced
05559    by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
05560 
05561 tree
05562 component_ref_field_offset (tree exp)
05563 {
05564   tree aligned_offset = TREE_OPERAND (exp, 2);
05565   tree field = TREE_OPERAND (exp, 1);
05566 
05567   /* If an offset was specified in the COMPONENT_REF, it's the offset measured
05568      in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
05569      value.  */
05570   if (aligned_offset)
05571     {
05572       /* ??? tree_ssa_useless_type_conversion will eliminate casts to
05573    sizetype from another type of the same width and signedness.  */
05574       if (TREE_TYPE (aligned_offset) != sizetype)
05575   aligned_offset = fold_convert (sizetype, aligned_offset);
05576       return size_binop (MULT_EXPR, aligned_offset,
05577              size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
05578     }
05579 
05580   /* Otherwise, take the offset from that of the field.  Substitute
05581      any PLACEHOLDER_EXPR that we have.  */
05582   else
05583     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
05584 }
05585 
05586 /* Return 1 if T is an expression that get_inner_reference handles.  */
05587 
05588 int
05589 handled_component_p (tree t)
05590 {
05591   switch (TREE_CODE (t))
05592     {
05593     case BIT_FIELD_REF:
05594     case COMPONENT_REF:
05595     case ARRAY_REF:
05596     case ARRAY_RANGE_REF:
05597     case VIEW_CONVERT_EXPR:
05598     case REALPART_EXPR:
05599     case IMAGPART_EXPR:
05600       return 1;
05601 
05602     default:
05603       return 0;
05604     }
05605 }
05606 
05607 /* Given an rtx VALUE that may contain additions and multiplications, return
05608    an equivalent value that just refers to a register, memory, or constant.
05609    This is done by generating instructions to perform the arithmetic and
05610    returning a pseudo-register containing the value.
05611 
05612    The returned value may be a REG, SUBREG, MEM or constant.  */
05613 
05614 rtx
05615 force_operand (rtx value, rtx target)
05616 {
05617   rtx op1, op2;
05618   /* Use subtarget as the target for operand 0 of a binary operation.  */
05619   rtx subtarget = get_subtarget (target);
05620   enum rtx_code code = GET_CODE (value);
05621 
05622   /* Check for subreg applied to an expression produced by loop optimizer.  */
05623   if (code == SUBREG
05624       && !REG_P (SUBREG_REG (value))
05625       && !MEM_P (SUBREG_REG (value)))
05626     {
05627       value = simplify_gen_subreg (GET_MODE (value),
05628            force_reg (GET_MODE (SUBREG_REG (value)),
05629                 force_operand (SUBREG_REG (value),
05630                    NULL_RTX)),
05631            GET_MODE (SUBREG_REG (value)),
05632            SUBREG_BYTE (value));
05633       code = GET_CODE (value);
05634     }
05635 
05636   /* Check for a PIC address load.  */
05637   if ((code == PLUS || code == MINUS)
05638       && XEXP (value, 0) == pic_offset_table_rtx
05639       && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
05640     || GET_CODE (XEXP (value, 1)) == LABEL_REF
05641     || GET_CODE (XEXP (value, 1)) == CONST))
05642     {
05643       if (!subtarget)
05644   subtarget = gen_reg_rtx (GET_MODE (value));
05645       emit_move_insn (subtarget, value);
05646       return subtarget;
05647     }
05648 
05649   if (code == ZERO_EXTEND || code == SIGN_EXTEND)
05650     {
05651       if (!target)
05652   target = gen_reg_rtx (GET_MODE (value));
05653       convert_move (target, force_operand (XEXP (value, 0), NULL),
05654         code == ZERO_EXTEND);
05655       return target;
05656     }
05657 
05658   if (ARITHMETIC_P (value))
05659     {
05660       op2 = XEXP (value, 1);
05661       if (!CONSTANT_P (op2) && !(REG_P (op2) && op2 != subtarget))
05662   subtarget = 0;
05663       if (code == MINUS && GET_CODE (op2) == CONST_INT)
05664   {
05665     code = PLUS;
05666     op2 = negate_rtx (GET_MODE (value), op2);
05667   }
05668 
05669       /* Check for an addition with OP2 a constant integer and our first
05670          operand a PLUS of a virtual register and something else.  In that
05671          case, we want to emit the sum of the virtual register and the
05672          constant first and then add the other value.  This allows virtual
05673          register instantiation to simply modify the constant rather than
05674          creating another one around this addition.  */
05675       if (code == PLUS && GET_CODE (op2) == CONST_INT
05676     && GET_CODE (XEXP (value, 0)) == PLUS
05677     && REG_P (XEXP (XEXP (value, 0), 0))
05678     && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
05679     && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
05680   {
05681     rtx temp = expand_simple_binop (GET_MODE (value), code,
05682             XEXP (XEXP (value, 0), 0), op2,
05683             subtarget, 0, OPTAB_LIB_WIDEN);
05684     return expand_simple_binop (GET_MODE (value), code, temp,
05685               force_operand (XEXP (XEXP (value,
05686                  0), 1), 0),
05687               target, 0, OPTAB_LIB_WIDEN);
05688   }
05689 
05690       op1 = force_operand (XEXP (value, 0), subtarget);
05691       op2 = force_operand (op2, NULL_RTX);
05692       switch (code)
05693   {
05694   case MULT:
05695     return expand_mult (GET_MODE (value), op1, op2, target, 1);
05696   case DIV:
05697     if (!INTEGRAL_MODE_P (GET_MODE (value)))
05698       return expand_simple_binop (GET_MODE (value), code, op1, op2,
05699           target, 1, OPTAB_LIB_WIDEN);
05700     else
05701       return expand_divmod (0,
05702           FLOAT_MODE_P (GET_MODE (value))
05703           ? RDIV_EXPR : TRUNC_DIV_EXPR,
05704           GET_MODE (value), op1, op2, target, 0);
05705     break;
05706   case MOD:
05707     return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
05708         target, 0);
05709     break;
05710   case UDIV:
05711     return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
05712         target, 1);
05713     break;
05714   case UMOD:
05715     return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
05716         target, 1);
05717     break;
05718   case ASHIFTRT:
05719     return expand_simple_binop (GET_MODE (value), code, op1, op2,
05720               target, 0, OPTAB_LIB_WIDEN);
05721     break;
05722   default:
05723     return expand_simple_binop (GET_MODE (value), code, op1, op2,
05724               target, 1, OPTAB_LIB_WIDEN);
05725   }
05726     }
05727   if (UNARY_P (value))
05728     {
05729       op1 = force_operand (XEXP (value, 0), NULL_RTX);
05730       return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
05731     }
05732 
05733 #ifdef INSN_SCHEDULING
05734   /* On machines that have insn scheduling, we want all memory reference to be
05735      explicit, so we need to deal with such paradoxical SUBREGs.  */
05736   if (GET_CODE (value) == SUBREG && MEM_P (SUBREG_REG (value))
05737       && (GET_MODE_SIZE (GET_MODE (value))
05738     > GET_MODE_SIZE (GET_MODE (SUBREG_REG (value)))))
05739     value
05740       = simplify_gen_subreg (GET_MODE (value),
05741            force_reg (GET_MODE (SUBREG_REG (value)),
05742           force_operand (SUBREG_REG (value),
05743                    NULL_RTX)),
05744            GET_MODE (SUBREG_REG (value)),
05745            SUBREG_BYTE (value));
05746 #endif
05747 
05748   return value;
05749 }
05750 
05751 /* Subroutine of expand_expr: return nonzero iff there is no way that
05752    EXP can reference X, which is being modified.  TOP_P is nonzero if this
05753    call is going to be used to determine whether we need a temporary
05754    for EXP, as opposed to a recursive call to this function.
05755 
05756    It is always safe for this routine to return zero since it merely
05757    searches for optimization opportunities.  */
05758 
05759 int
05760 safe_from_p (rtx x, tree exp, int top_p)
05761 {
05762   rtx exp_rtl = 0;
05763   int i, nops;
05764 
05765   if (x == 0
05766       /* If EXP has varying size, we MUST use a target since we currently
05767    have no way of allocating temporaries of variable size
05768    (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
05769    So we assume here that something at a higher level has prevented a
05770    clash.  This is somewhat bogus, but the best we can do.  Only
05771    do this when X is BLKmode and when we are at the top level.  */
05772       || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
05773     && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
05774     && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
05775         || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
05776         || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
05777         != INTEGER_CST)
05778     && GET_MODE (x) == BLKmode)
05779       /* If X is in the outgoing argument area, it is always safe.  */
05780       || (MEM_P (x)
05781     && (XEXP (x, 0) == virtual_outgoing_args_rtx
05782         || (GET_CODE (XEXP (x, 0)) == PLUS
05783       && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
05784     return 1;
05785 
05786   /* If this is a subreg of a hard register, declare it unsafe, otherwise,
05787      find the underlying pseudo.  */
05788   if (GET_CODE (x) == SUBREG)
05789     {
05790       x = SUBREG_REG (x);
05791       if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
05792   return 0;
05793     }
05794 
05795   /* Now look at our tree code and possibly recurse.  */
05796   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
05797     {
05798     case tcc_declaration:
05799       exp_rtl = DECL_RTL_IF_SET (exp);
05800       break;
05801 
05802     case tcc_constant:
05803       return 1;
05804 
05805     case tcc_exceptional:
05806       if (TREE_CODE (exp) == TREE_LIST)
05807   {
05808     while (1)
05809       {
05810         if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
05811     return 0;
05812         exp = TREE_CHAIN (exp);
05813         if (!exp)
05814     return 1;
05815         if (TREE_CODE (exp) != TREE_LIST)
05816     return safe_from_p (x, exp, 0);
05817       }
05818   }
05819       else if (TREE_CODE (exp) == ERROR_MARK)
05820   return 1; /* An already-visited SAVE_EXPR? */
05821       else
05822   return 0;
05823 
05824     case tcc_statement:
05825       /* The only case we look at here is the DECL_INITIAL inside a
05826    DECL_EXPR.  */
05827       return (TREE_CODE (exp) != DECL_EXPR
05828         || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
05829         || !DECL_INITIAL (DECL_EXPR_DECL (exp))
05830         || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0));
05831 
05832     case tcc_binary:
05833     case tcc_comparison:
05834       if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
05835   return 0;
05836       /* Fall through.  */
05837 
05838     case tcc_unary:
05839       return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
05840 
05841     case tcc_expression:
05842     case tcc_reference:
05843       /* Now do code-specific tests.  EXP_RTL is set to any rtx we find in
05844    the expression.  If it is set, we conflict iff we are that rtx or
05845    both are in memory.  Otherwise, we check all operands of the
05846    expression recursively.  */
05847 
05848       switch (TREE_CODE (exp))
05849   {
05850   case ADDR_EXPR:
05851     /* If the operand is static or we are static, we can't conflict.
05852        Likewise if we don't conflict with the operand at all.  */
05853     if (staticp (TREE_OPERAND (exp, 0))
05854         || TREE_STATIC (exp)
05855         || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
05856       return 1;
05857 
05858     /* Otherwise, the only way this can conflict is if we are taking
05859        the address of a DECL a that address if part of X, which is
05860        very rare.  */
05861     exp = TREE_OPERAND (exp, 0);
05862     if (DECL_P (exp))
05863       {
05864         if (!DECL_RTL_SET_P (exp)
05865       || !MEM_P (DECL_RTL (exp)))
05866     return 0;
05867         else
05868     exp_rtl = XEXP (DECL_RTL (exp), 0);
05869       }
05870     break;
05871 
05872   case MISALIGNED_INDIRECT_REF:
05873   case ALIGN_INDIRECT_REF:
05874   case INDIRECT_REF:
05875     if (MEM_P (x)
05876         && alias_sets_conflict_p (MEM_ALIAS_SET (x),
05877           get_alias_set (exp)))
05878       return 0;
05879     break;
05880 
05881   case CALL_EXPR:
05882     /* Assume that the call will clobber all hard registers and
05883        all of memory.  */
05884     if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
05885         || MEM_P (x))
05886       return 0;
05887     break;
05888 
05889   case WITH_CLEANUP_EXPR:
05890   case CLEANUP_POINT_EXPR:
05891     /* Lowered by gimplify.c.  */
05892     gcc_unreachable ();
05893 
05894   case SAVE_EXPR:
05895     return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
05896 
05897   default:
05898     break;
05899   }
05900 
05901       /* If we have an rtx, we do not need to scan our operands.  */
05902       if (exp_rtl)
05903   break;
05904 
05905       nops = TREE_CODE_LENGTH (TREE_CODE (exp));
05906       for (i = 0; i < nops; i++)
05907   if (TREE_OPERAND (exp, i) != 0
05908       && ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
05909     return 0;
05910 
05911       /* If this is a language-specific tree code, it may require
05912    special handling.  */
05913       if ((unsigned int) TREE_CODE (exp)
05914     >= (unsigned int) LAST_AND_UNUSED_TREE_CODE
05915     && !lang_hooks.safe_from_p (x, exp))
05916   return 0;
05917       break;
05918 
05919     case tcc_type:
05920       /* Should never get a type here.  */
05921       gcc_unreachable ();
05922     }
05923 
05924   /* If we have an rtl, find any enclosed object.  Then see if we conflict
05925      with it.  */
05926   if (exp_rtl)
05927     {
05928       if (GET_CODE (exp_rtl) == SUBREG)
05929   {
05930     exp_rtl = SUBREG_REG (exp_rtl);
05931     if (REG_P (exp_rtl)
05932         && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
05933       return 0;
05934   }
05935 
05936       /* If the rtl is X, then it is not safe.  Otherwise, it is unless both
05937    are memory and they conflict.  */
05938       return ! (rtx_equal_p (x, exp_rtl)
05939     || (MEM_P (x) && MEM_P (exp_rtl)
05940         && true_dependence (exp_rtl, VOIDmode, x,
05941           rtx_addr_varies_p)));
05942     }
05943 
05944   /* If we reach here, it is safe.  */
05945   return 1;
05946 }
05947 
05948 
05949 /* Return the highest power of two that EXP is known to be a multiple of.
05950    This is used in updating alignment of MEMs in array references.  */
05951 
05952 static unsigned HOST_WIDE_INT
05953 highest_pow2_factor (tree exp)
05954 {
05955   unsigned HOST_WIDE_INT c0, c1;
05956 
05957   switch (TREE_CODE (exp))
05958     {
05959     case INTEGER_CST:
05960       /* We can find the lowest bit that's a one.  If the low
05961    HOST_BITS_PER_WIDE_INT bits are zero, return BIGGEST_ALIGNMENT.
05962    We need to handle this case since we can find it in a COND_EXPR,
05963    a MIN_EXPR, or a MAX_EXPR.  If the constant overflows, we have an
05964    erroneous program, so return BIGGEST_ALIGNMENT to avoid any
05965    later ICE.  */
05966       if (TREE_CONSTANT_OVERFLOW (exp))
05967   return BIGGEST_ALIGNMENT;
05968       else
05969   {
05970     /* Note: tree_low_cst is intentionally not used here,
05971        we don't care about the upper bits.  */
05972     c0 = TREE_INT_CST_LOW (exp);
05973     c0 &= -c0;
05974     return c0 ? c0 : BIGGEST_ALIGNMENT;
05975   }
05976       break;
05977 
05978     case PLUS_EXPR:  case MINUS_EXPR:  case MIN_EXPR:  case MAX_EXPR:
05979       c0 = highest_pow2_factor (TREE_OPERAND (exp, 0));
05980       c1 = highest_pow2_factor (TREE_OPERAND (exp, 1));
05981       return MIN (c0, c1);
05982 
05983     case MULT_EXPR:
05984       c0 = highest_pow2_factor (TREE_OPERAND (exp, 0));
05985       c1 = highest_pow2_factor (TREE_OPERAND (exp, 1));
05986       return c0 * c1;
05987 
05988     case ROUND_DIV_EXPR:  case TRUNC_DIV_EXPR:  case FLOOR_DIV_EXPR:
05989     case CEIL_DIV_EXPR:
05990       if (integer_pow2p (TREE_OPERAND (exp, 1))
05991     && host_integerp (TREE_OPERAND (exp, 1), 1))
05992   {
05993     c0 = highest_pow2_factor (TREE_OPERAND (exp, 0));
05994     c1 = tree_low_cst (TREE_OPERAND (exp, 1), 1);
05995     return MAX (1, c0 / c1);
05996   }
05997       break;
05998 
05999     case NON_LVALUE_EXPR:  case NOP_EXPR:  case CONVERT_EXPR:
06000     case SAVE_EXPR:
06001       return highest_pow2_factor (TREE_OPERAND (exp, 0));
06002 
06003     case COMPOUND_EXPR:
06004       return highest_pow2_factor (TREE_OPERAND (exp, 1));
06005 
06006     case COND_EXPR:
06007       c0 = highest_pow2_factor (TREE_OPERAND (exp, 1));
06008       c1 = highest_pow2_factor (TREE_OPERAND (exp, 2));
06009       return MIN (c0, c1);
06010 
06011     default:
06012       break;
06013     }
06014 
06015   return 1;
06016 }
06017 
06018 /* Similar, except that the alignment requirements of TARGET are
06019    taken into account.  Assume it is at least as aligned as its
06020    type, unless it is a COMPONENT_REF in which case the layout of
06021    the structure gives the alignment.  */
06022 
06023 static unsigned HOST_WIDE_INT
06024 highest_pow2_factor_for_target (tree target, tree exp)
06025 {
06026   unsigned HOST_WIDE_INT target_align, factor;
06027 
06028   factor = highest_pow2_factor (exp);
06029   if (TREE_CODE (target) == COMPONENT_REF)
06030     target_align = DECL_ALIGN_UNIT (TREE_OPERAND (target, 1));
06031   else
06032     target_align = TYPE_ALIGN_UNIT (TREE_TYPE (target));
06033   return MAX (factor, target_align);
06034 }
06035 
06036 /* Expands variable VAR.  */
06037 
06038 void
06039 expand_var (tree var)
06040 {
06041   if (DECL_EXTERNAL (var))
06042     return;
06043 
06044   if (TREE_STATIC (var))
06045     /* If this is an inlined copy of a static local variable,
06046        look up the original decl.  */
06047     var = DECL_ORIGIN (var);
06048 
06049   if (TREE_STATIC (var)
06050       ? !TREE_ASM_WRITTEN (var)
06051       : !DECL_RTL_SET_P (var))
06052     {
06053       if (TREE_CODE (var) == VAR_DECL && DECL_VALUE_EXPR (var))
06054   /* Should be ignored.  */;
06055       else if (lang_hooks.expand_decl (var))
06056   /* OK.  */;
06057       else if (TREE_CODE (var) == VAR_DECL && !TREE_STATIC (var))
06058   expand_decl (var);
06059       else if (TREE_CODE (var) == VAR_DECL && TREE_STATIC (var))
06060   rest_of_decl_compilation (var, 0, 0);
06061       else
06062   /* No expansion needed.  */
06063   gcc_assert (TREE_CODE (var) == TYPE_DECL
06064         || TREE_CODE (var) == CONST_DECL
06065         || TREE_CODE (var) == FUNCTION_DECL
06066         || TREE_CODE (var) == LABEL_DECL);
06067     }
06068 }
06069 
06070 /* Subroutine of expand_expr.  Expand the two operands of a binary
06071    expression EXP0 and EXP1 placing the results in OP0 and OP1.
06072    The value may be stored in TARGET if TARGET is nonzero.  The
06073    MODIFIER argument is as documented by expand_expr.  */
06074 
06075 static void
06076 expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
06077      enum expand_modifier modifier)
06078 {
06079   if (! safe_from_p (target, exp1, 1))
06080     target = 0;
06081   if (operand_equal_p (exp0, exp1, 0))
06082     {
06083       *op0 = expand_expr (exp0, target, VOIDmode, modifier);
06084       *op1 = copy_rtx (*op0);
06085     }
06086   else
06087     {
06088       /* If we need to preserve evaluation order, copy exp0 into its own
06089    temporary variable so that it can't be clobbered by exp1.  */
06090       if (flag_evaluation_order && TREE_SIDE_EFFECTS (exp1))
06091   exp0 = save_expr (exp0);
06092       *op0 = expand_expr (exp0, target, VOIDmode, modifier);
06093       *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
06094     }
06095 }
06096 
06097 
06098 /* A subroutine of expand_expr_addr_expr.  Evaluate the address of EXP.
06099    The TARGET, TMODE and MODIFIER arguments are as for expand_expr.  */
06100 
06101 static rtx
06102 expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
06103              enum expand_modifier modifier)
06104 {
06105   rtx result, subtarget;
06106   tree inner, offset;
06107   HOST_WIDE_INT bitsize, bitpos;
06108   int volatilep, unsignedp;
06109   enum machine_mode mode1;
06110 
06111   /* If we are taking the address of a constant and are at the top level,
06112      we have to use output_constant_def since we can't call force_const_mem
06113      at top level.  */
06114   /* ??? This should be considered a front-end bug.  We should not be
06115      generating ADDR_EXPR of something that isn't an LVALUE.  The only
06116      exception here is STRING_CST.  */
06117   if (TREE_CODE (exp) == CONSTRUCTOR
06118       || CONSTANT_CLASS_P (exp))
06119     return XEXP (output_constant_def (exp, 0), 0);
06120 
06121   /* Everything must be something allowed by is_gimple_addressable.  */
06122   switch (TREE_CODE (exp))
06123     {
06124     case INDIRECT_REF:
06125       /* This case will happen via recursion for &a->b.  */
06126       return expand_expr (TREE_OPERAND (exp, 0), target, tmode, EXPAND_NORMAL);
06127 
06128     case CONST_DECL:
06129       /* Recurse and make the output_constant_def clause above handle this.  */
06130       return expand_expr_addr_expr_1 (DECL_INITIAL (exp), target,
06131               tmode, modifier);
06132 
06133     case REALPART_EXPR:
06134       /* The real part of the complex number is always first, therefore
06135    the address is the same as the address of the parent object.  */
06136       offset = 0;
06137       bitpos = 0;
06138       inner = TREE_OPERAND (exp, 0);
06139       break;
06140 
06141     case IMAGPART_EXPR:
06142       /* The imaginary part of the complex number is always second.
06143    The expression is therefore always offset by the size of the
06144    scalar type.  */
06145       offset = 0;
06146       bitpos = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)));
06147       inner = TREE_OPERAND (exp, 0);
06148       break;
06149 
06150     default:
06151       /* If the object is a DECL, then expand it for its rtl.  Don't bypass
06152    expand_expr, as that can have various side effects; LABEL_DECLs for
06153    example, may not have their DECL_RTL set yet.  Assume language
06154    specific tree nodes can be expanded in some interesting way.  */
06155       if (DECL_P (exp)
06156     || TREE_CODE (exp) >= LAST_AND_UNUSED_TREE_CODE)
06157   {
06158     result = expand_expr (exp, target, tmode,
06159         modifier == EXPAND_INITIALIZER
06160         ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
06161 
06162     /* If the DECL isn't in memory, then the DECL wasn't properly
06163        marked TREE_ADDRESSABLE, which will be either a front-end
06164        or a tree optimizer bug.  */
06165     gcc_assert (GET_CODE (result) == MEM);
06166     result = XEXP (result, 0);
06167 
06168     /* ??? Is this needed anymore?  */
06169     if (DECL_P (exp) && !TREE_USED (exp) == 0)
06170       {
06171         assemble_external (exp);
06172         TREE_USED (exp) = 1;
06173       }
06174 
06175     if (modifier != EXPAND_INITIALIZER
06176         && modifier != EXPAND_CONST_ADDRESS)
06177       result = force_operand (result, target);
06178     return result;
06179   }
06180 
06181       /* Pass FALSE as the last argument to get_inner_reference although
06182    we are expanding to RTL.  The rationale is that we know how to
06183    handle "aligning nodes" here: we can just bypass them because
06184    they won't change the final object whose address will be returned
06185    (they actually exist only for that purpose).  */
06186       inner = get_inner_reference (exp, &bitsize, &bitpos, &offset,
06187            &mode1, &unsignedp, &volatilep, false);
06188       break;
06189     }
06190 
06191   /* We must have made progress.  */
06192   gcc_assert (inner != exp);
06193 
06194   subtarget = offset || bitpos ? NULL_RTX : target;
06195   result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier);
06196 
06197   if (offset)
06198     {
06199       rtx tmp;
06200 
06201       if (modifier != EXPAND_NORMAL)
06202   result = force_operand (result, NULL);
06203       tmp = expand_expr (offset, NULL, tmode, EXPAND_NORMAL);
06204 
06205       result = convert_memory_address (tmode, result);
06206       tmp = convert_memory_address (tmode, tmp);
06207 
06208       if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
06209   result = gen_rtx_PLUS (tmode, result, tmp);
06210       else
06211   {
06212     subtarget = bitpos ? NULL_RTX : target;
06213     result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
06214           1, OPTAB_LIB_WIDEN);
06215   }
06216     }
06217 
06218   if (bitpos)
06219     {
06220       /* Someone beforehand should have rejected taking the address
06221    of such an object.  */
06222       gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
06223 
06224       result = plus_constant (result, bitpos / BITS_PER_UNIT);
06225       if (modifier < EXPAND_SUM)
06226   result = force_operand (result, target);
06227     }
06228 
06229   return result;
06230 }
06231 
06232 /* A subroutine of expand_expr.  Evaluate EXP, which is an ADDR_EXPR.
06233    The TARGET, TMODE and MODIFIER arguments are as for expand_expr.  */
06234 
06235 static rtx
06236 expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
06237            enum expand_modifier modifier)
06238 {
06239   enum machine_mode rmode;
06240   rtx result;
06241 
06242   /* Target mode of VOIDmode says "whatever's natural".  */
06243   if (tmode == VOIDmode)
06244     tmode = TYPE_MODE (TREE_TYPE (exp));
06245 
06246   /* We can get called with some Weird Things if the user does silliness
06247      like "(short) &a".  In that case, convert_memory_address won't do
06248      the right thing, so ignore the given target mode.  */
06249   if (tmode != Pmode && tmode != ptr_mode)
06250     tmode = Pmode;
06251 
06252   result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
06253             tmode, modifier);
06254 
06255   /* Despite expand_expr claims concerning ignoring TMODE when not
06256      strictly convenient, stuff breaks if we don't honor it.  Note
06257      that combined with the above, we only do this for pointer modes.  */
06258   rmode = GET_MODE (result);
06259   if (rmode == VOIDmode)
06260     rmode = tmode;
06261   if (rmode != tmode)
06262     result = convert_memory_address (tmode, result);
06263 
06264   return result;
06265 }
06266 
06267 
06268 /* expand_expr: generate code for computing expression EXP.
06269    An rtx for the computed value is returned.  The value is never null.
06270    In the case of a void EXP, const0_rtx is returned.
06271 
06272    The value may be stored in TARGET if TARGET is nonzero.
06273    TARGET is just a suggestion; callers must assume that
06274    the rtx returned may not be the same as TARGET.
06275 
06276    If TARGET is CONST0_RTX, it means that the value will be ignored.
06277 
06278    If TMODE is not VOIDmode, it suggests generating the
06279    result in mode TMODE.  But this is done only when convenient.
06280    Otherwise, TMODE is ignored and the value generated in its natural mode.
06281    TMODE is just a suggestion; callers must assume that
06282    the rtx returned may not have mode TMODE.
06283 
06284    Note that TARGET may have neither TMODE nor MODE.  In that case, it
06285    probably will not be used.
06286 
06287    If MODIFIER is EXPAND_SUM then when EXP is an addition
06288    we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
06289    or a nest of (PLUS ...) and (MINUS ...) where the terms are
06290    products as above, or REG or MEM, or constant.
06291    Ordinarily in such cases we would output mul or add instructions
06292    and then return a pseudo reg containing the sum.
06293 
06294    EXPAND_INITIALIZER is much like EXPAND_SUM except that
06295    it also marks a label as absolutely required (it can't be dead).
06296    It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
06297    This is used for outputting expressions used in initializers.
06298 
06299    EXPAND_CONST_ADDRESS says that it is okay to return a MEM
06300    with a constant address even if that address is not normally legitimate.
06301    EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
06302 
06303    EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
06304    a call parameter.  Such targets require special care as we haven't yet
06305    marked TARGET so that it's safe from being trashed by libcalls.  We
06306    don't want to use TARGET for anything but the final result;
06307    Intermediate values must go elsewhere.   Additionally, calls to
06308    emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
06309 
06310    If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
06311    address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
06312    DECL_RTL of the VAR_DECL.  *ALT_RTL is also set if EXP is a
06313    COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
06314    recursively.  */
06315 
06316 static rtx expand_expr_real_1 (tree, rtx, enum machine_mode,
06317              enum expand_modifier, rtx *);
06318 
06319 rtx
06320 expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
06321       enum expand_modifier modifier, rtx *alt_rtl)
06322 {
06323   int rn = -1;
06324   rtx ret, last = NULL;
06325 
06326   /* Handle ERROR_MARK before anybody tries to access its type.  */
06327   if (TREE_CODE (exp) == ERROR_MARK
06328       || TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK)
06329     {
06330       ret = CONST0_RTX (tmode);
06331       return ret ? ret : const0_rtx;
06332     }
06333 
06334   if (flag_non_call_exceptions)
06335     {
06336       rn = lookup_stmt_eh_region (exp);
06337       /* If rn < 0, then either (1) tree-ssa not used or (2) doesn't throw.  */
06338       if (rn >= 0)
06339   last = get_last_insn ();
06340     }
06341 
06342   /* If this is an expression of some kind and it has an associated line
06343      number, then emit the line number before expanding the expression.
06344 
06345      We need to save and restore the file and line information so that
06346      errors discovered during expansion are emitted with the right
06347      information.  It would be better of the diagnostic routines
06348      used the file/line information embedded in the tree nodes rather
06349      than globals.  */
06350   if (cfun && EXPR_HAS_LOCATION (exp))
06351     {
06352       location_t saved_location = input_location;
06353       input_location = EXPR_LOCATION (exp);
06354       emit_line_note (input_location);
06355 
06356       /* Record where the insns produced belong.  */
06357       record_block_change (TREE_BLOCK (exp));
06358 
06359       ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
06360 
06361       input_location = saved_location;
06362     }
06363   else
06364     {
06365       ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
06366     }
06367 
06368   /* If using non-call exceptions, mark all insns that may trap.
06369      expand_call() will mark CALL_INSNs before we get to this code,
06370      but it doesn't handle libcalls, and these may trap.  */
06371   if (rn >= 0)
06372     {
06373       rtx insn;
06374       for (insn = next_real_insn (last); insn;
06375      insn = next_real_insn (insn))
06376   {
06377     if (! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
06378         /* If we want exceptions for non-call insns, any
06379      may_trap_p instruction may throw.  */
06380         && GET_CODE (PATTERN (insn)) != CLOBBER
06381         && GET_CODE (PATTERN (insn)) != USE
06382         && (CALL_P (insn) || may_trap_p (PATTERN (insn))))
06383       {
06384         REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (rn),
06385               REG_NOTES (insn));
06386       }
06387   }
06388     }
06389 
06390   return ret;
06391 }
06392 
06393 static rtx
06394 expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
06395         enum expand_modifier modifier, rtx *alt_rtl)
06396 {
06397   rtx op0, op1, temp;
06398   tree type = TREE_TYPE (exp);
06399   int unsignedp;
06400   enum machine_mode mode;
06401   enum tree_code code = TREE_CODE (exp);
06402   optab this_optab;
06403   rtx subtarget, original_target;
06404   int ignore;
06405   tree context;
06406   bool reduce_bit_field = false;
06407 #define REDUCE_BIT_FIELD(expr)  (reduce_bit_field && !ignore      \
06408          ? reduce_to_bit_field_precision ((expr), \
06409                   target, \
06410                   type)   \
06411          : (expr))
06412 
06413   mode = TYPE_MODE (type);
06414   unsignedp = TYPE_UNSIGNED (type);
06415   if (lang_hooks.reduce_bit_field_operations
06416       && TREE_CODE (type) == INTEGER_TYPE
06417       && GET_MODE_PRECISION (mode) > TYPE_PRECISION (type))
06418     {
06419       /* An operation in what may be a bit-field type needs the
06420    result to be reduced to the precision of the bit-field type,
06421    which is narrower than that of the type's mode.  */
06422       reduce_bit_field = true;
06423       if (modifier == EXPAND_STACK_PARM)
06424   target = 0;
06425     }
06426 
06427   /* Use subtarget as the target for operand 0 of a binary operation.  */
06428   subtarget = get_subtarget (target);
06429   original_target = target;
06430   ignore = (target == const0_rtx
06431       || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
06432      || code == CONVERT_EXPR || code == COND_EXPR
06433      || code == VIEW_CONVERT_EXPR)
06434     && TREE_CODE (type) == VOID_TYPE));
06435 
06436   /* If we are going to ignore this result, we need only do something
06437      if there is a side-effect somewhere in the expression.  If there
06438      is, short-circuit the most common cases here.  Note that we must
06439      not call expand_expr with anything but const0_rtx in case this
06440      is an initial expansion of a size that contains a PLACEHOLDER_EXPR.  */
06441 
06442   if (ignore)
06443     {
06444       if (! TREE_SIDE_EFFECTS (exp))
06445   return const0_rtx;
06446 
06447       /* Ensure we reference a volatile object even if value is ignored, but
06448    don't do this if all we are doing is taking its address.  */
06449       if (TREE_THIS_VOLATILE (exp)
06450     && TREE_CODE (exp) != FUNCTION_DECL
06451     && mode != VOIDmode && mode != BLKmode
06452     && modifier != EXPAND_CONST_ADDRESS)
06453   {
06454     temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
06455     if (MEM_P (temp))
06456       temp = copy_to_reg (temp);
06457     return const0_rtx;
06458   }
06459 
06460       if (TREE_CODE_CLASS (code) == tcc_unary
06461     || code == COMPONENT_REF || code == INDIRECT_REF)
06462   return expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
06463           modifier);
06464 
06465       else if (TREE_CODE_CLASS (code) == tcc_binary
06466          || TREE_CODE_CLASS (code) == tcc_comparison
06467          || code == ARRAY_REF || code == ARRAY_RANGE_REF)
06468   {
06469     expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
06470     expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, modifier);
06471     return const0_rtx;
06472   }
06473       else if (code == BIT_FIELD_REF)
06474   {
06475     expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
06476     expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, modifier);
06477     expand_expr (TREE_OPERAND (exp, 2), const0_rtx, VOIDmode, modifier);
06478     return const0_rtx;
06479   }
06480 
06481       target = 0;
06482     }
06483 
06484   /* If will do cse, generate all results into pseudo registers
06485      since 1) that allows cse to find more things
06486      and 2) otherwise cse could produce an insn the machine
06487      cannot support.  An exception is a CONSTRUCTOR into a multi-word
06488      MEM: that's much more likely to be most efficient into the MEM.
06489      Another is a CALL_EXPR which must return in memory.  */
06490 
06491   if (! cse_not_expected && mode != BLKmode && target
06492       && (!REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
06493       && ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
06494       && ! (code == CALL_EXPR && aggregate_value_p (exp, exp)))
06495     target = 0;
06496 
06497   switch (code)
06498     {
06499     case LABEL_DECL:
06500       {
06501   tree function = decl_function_context (exp);
06502 
06503   temp = label_rtx (exp);
06504   temp = gen_rtx_LABEL_REF (Pmode, temp);
06505 
06506   if (function != current_function_decl
06507       && function != 0)
06508     LABEL_REF_NONLOCAL_P (temp) = 1;
06509 
06510   temp = gen_rtx_MEM (FUNCTION_MODE, temp);
06511   return temp;
06512       }
06513 
06514     case SSA_NAME:
06515       return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier,
06516          NULL);
06517 
06518     case PARM_DECL:
06519     case VAR_DECL:
06520       /* If a static var's type was incomplete when the decl was written,
06521    but the type is complete now, lay out the decl now.  */
06522       if (DECL_SIZE (exp) == 0
06523     && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
06524     && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
06525   layout_decl (exp, 0);
06526 
06527       /* ... fall through ...  */
06528 
06529     case FUNCTION_DECL:
06530     case RESULT_DECL:
06531       gcc_assert (DECL_RTL (exp));
06532 
06533       /* Ensure variable marked as used even if it doesn't go through
06534    a parser.  If it hasn't be used yet, write out an external
06535    definition.  */
06536       if (! TREE_USED (exp))
06537   {
06538     assemble_external (exp);
06539     TREE_USED (exp) = 1;
06540   }
06541 
06542       /* Show we haven't gotten RTL for this yet.  */
06543       temp = 0;
06544 
06545       /* Variables inherited from containing functions should have
06546    been lowered by this point.  */
06547       context = decl_function_context (exp);
06548       gcc_assert (!context
06549       || context == current_function_decl
06550       || TREE_STATIC (exp)
06551       /* ??? C++ creates functions that are not TREE_STATIC.  */
06552       || TREE_CODE (exp) == FUNCTION_DECL);
06553 
06554       /* This is the case of an array whose size is to be determined
06555    from its initializer, while the initializer is still being parsed.
06556    See expand_decl.  */
06557 
06558       if (MEM_P (DECL_RTL (exp))
06559          && REG_P (XEXP (DECL_RTL (exp), 0)))
06560   temp = validize_mem (DECL_RTL (exp));
06561 
06562       /* If DECL_RTL is memory, we are in the normal case and either
06563    the address is not valid or it is not a register and -fforce-addr
06564    is specified, get the address into a register.  */
06565 
06566       else if (MEM_P (DECL_RTL (exp))
06567          && modifier != EXPAND_CONST_ADDRESS
06568          && modifier != EXPAND_SUM
06569          && modifier != EXPAND_INITIALIZER
06570          && (! memory_address_p (DECL_MODE (exp),
06571                XEXP (DECL_RTL (exp), 0))
06572        || (flag_force_addr
06573            && !REG_P (XEXP (DECL_RTL (exp), 0)))))
06574   {
06575     if (alt_rtl)
06576       *alt_rtl = DECL_RTL (exp);
06577     temp = replace_equiv_address (DECL_RTL (exp),
06578           copy_rtx (XEXP (DECL_RTL (exp), 0)));
06579   }
06580 
06581       /* If we got something, return it.  But first, set the alignment
06582    if the address is a register.  */
06583       if (temp != 0)
06584   {
06585     if (MEM_P (temp) && REG_P (XEXP (temp, 0)))
06586       mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
06587 
06588     return temp;
06589   }
06590 
06591       /* If the mode of DECL_RTL does not match that of the decl, it
06592    must be a promoted value.  We return a SUBREG of the wanted mode,
06593    but mark it so that we know that it was already extended.  */
06594 
06595       if (REG_P (DECL_RTL (exp))
06596     && GET_MODE (DECL_RTL (exp)) != DECL_MODE (exp))
06597   {
06598     enum machine_mode pmode;
06599     
06600     /* Get the signedness used for this variable.  Ensure we get the
06601        same mode we got when the variable was declared.  */
06602     pmode = promote_mode (type, DECL_MODE (exp), &unsignedp,
06603         (TREE_CODE (exp) == RESULT_DECL ? 1 : 0));
06604     gcc_assert (GET_MODE (DECL_RTL (exp)) == pmode);
06605 
06606     temp = gen_lowpart_SUBREG (mode, DECL_RTL (exp));
06607     SUBREG_PROMOTED_VAR_P (temp) = 1;
06608     SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
06609     return temp;
06610   }
06611 
06612       return DECL_RTL (exp);
06613 
06614     case INTEGER_CST:
06615       temp = immed_double_const (TREE_INT_CST_LOW (exp),
06616          TREE_INT_CST_HIGH (exp), mode);
06617 
06618       /* ??? If overflow is set, fold will have done an incomplete job,
06619    which can result in (plus xx (const_int 0)), which can get
06620    simplified by validate_replace_rtx during virtual register
06621    instantiation, which can result in unrecognizable insns.
06622    Avoid this by forcing all overflows into registers.  */
06623       if (TREE_CONSTANT_OVERFLOW (exp)
06624     && modifier != EXPAND_INITIALIZER)
06625   temp = force_reg (mode, temp);
06626 
06627       return temp;
06628 
06629     case VECTOR_CST:
06630       if (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp))) == MODE_VECTOR_INT
06631     || GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp))) == MODE_VECTOR_FLOAT)
06632   return const_vector_from_tree (exp);
06633       else
06634   return expand_expr (build1 (CONSTRUCTOR, TREE_TYPE (exp),
06635             TREE_VECTOR_CST_ELTS (exp)),
06636           ignore ? const0_rtx : target, tmode, modifier);
06637 
06638     case CONST_DECL:
06639       return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
06640 
06641     case REAL_CST:
06642       /* If optimized, generate immediate CONST_DOUBLE
06643    which will be turned into memory by reload if necessary.
06644 
06645    We used to force a register so that loop.c could see it.  But
06646    this does not allow gen_* patterns to perform optimizations with
06647    the constants.  It also produces two insns in cases like "x = 1.0;".
06648    On most machines, floating-point constants are not permitted in
06649    many insns, so we'd end up copying it to a register in any case.
06650 
06651    Now, we do the copying in expand_binop, if appropriate.  */
06652       return CONST_DOUBLE_FROM_REAL_VALUE (TREE_REAL_CST (exp),
06653              TYPE_MODE (TREE_TYPE (exp)));
06654 
06655     case COMPLEX_CST:
06656       /* Handle evaluating a complex constant in a CONCAT target.  */
06657       if (original_target && GET_CODE (original_target) == CONCAT)
06658   {
06659     enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
06660     rtx rtarg, itarg;
06661 
06662     rtarg = XEXP (original_target, 0);
06663     itarg = XEXP (original_target, 1);
06664 
06665     /* Move the real and imaginary parts separately.  */
06666     op0 = expand_expr (TREE_REALPART (exp), rtarg, mode, 0);
06667     op1 = expand_expr (TREE_IMAGPART (exp), itarg, mode, 0);
06668 
06669     if (op0 != rtarg)
06670       emit_move_insn (rtarg, op0);
06671     if (op1 != itarg)
06672       emit_move_insn (itarg, op1);
06673 
06674     return original_target;
06675   }
06676 
06677       /* ... fall through ...  */
06678 
06679     case STRING_CST:
06680       temp = output_constant_def (exp, 1);
06681 
06682       /* temp contains a constant address.
06683    On RISC machines where a constant address isn't valid,
06684    make some insns to get that address into a register.  */
06685       if (modifier != EXPAND_CONST_ADDRESS
06686     && modifier != EXPAND_INITIALIZER
06687     && modifier != EXPAND_SUM
06688     && (! memory_address_p (mode, XEXP (temp, 0))
06689         || flag_force_addr))
06690   return replace_equiv_address (temp,
06691               copy_rtx (XEXP (temp, 0)));
06692       return temp;
06693 
06694     case SAVE_EXPR:
06695       {
06696   tree val = TREE_OPERAND (exp, 0);
06697   rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl);
06698 
06699   if (!SAVE_EXPR_RESOLVED_P (exp))
06700     {
06701       /* We can indeed still hit this case, typically via builtin
06702          expanders calling save_expr immediately before expanding
06703          something.  Assume this means that we only have to deal
06704          with non-BLKmode values.  */
06705       gcc_assert (GET_MODE (ret) != BLKmode);
06706 
06707       val = build_decl (VAR_DECL, NULL, TREE_TYPE (exp));
06708       DECL_ARTIFICIAL (val) = 1;
06709       DECL_IGNORED_P (val) = 1;
06710       TREE_OPERAND (exp, 0) = val;
06711       SAVE_EXPR_RESOLVED_P (exp) = 1;
06712 
06713       if (!CONSTANT_P (ret))
06714         ret = copy_to_reg (ret);
06715       SET_DECL_RTL (val, ret);
06716     }
06717 
06718         return ret;
06719       }
06720 
06721     case GOTO_EXPR:
06722       if (TREE_CODE (TREE_OPERAND (exp, 0)) == LABEL_DECL)
06723   expand_goto (TREE_OPERAND (exp, 0));
06724       else
06725   expand_computed_goto (TREE_OPERAND (exp, 0));
06726       return const0_rtx;
06727 
06728     case CONSTRUCTOR:
06729       /* If we don't need the result, just ensure we evaluate any
06730    subexpressions.  */
06731       if (ignore)
06732   {
06733     tree elt;
06734 
06735     for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
06736       expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
06737 
06738     return const0_rtx;
06739   }
06740 
06741       /* All elts simple constants => refer to a constant in memory.  But
06742    if this is a non-BLKmode mode, let it store a field at a time
06743    since that should make a CONST_INT or CONST_DOUBLE when we
06744    fold.  Likewise, if we have a target we can use, it is best to
06745    store directly into the target unless the type is large enough
06746    that memcpy will be used.  If we are making an initializer and
06747    all operands are constant, put it in memory as well.
06748 
06749   FIXME: Avoid trying to fill vector constructors piece-meal.
06750   Output them with output_constant_def below unless we're sure
06751   they're zeros.  This should go away when vector initializers
06752   are treated like VECTOR_CST instead of arrays.
06753       */
06754       else if ((TREE_STATIC (exp)
06755     && ((mode == BLKmode
06756          && ! (target != 0 && safe_from_p (target, exp, 1)))
06757         || TREE_ADDRESSABLE (exp)
06758         || (host_integerp (TYPE_SIZE_UNIT (type), 1)
06759       && (! MOVE_BY_PIECES_P
06760           (tree_low_cst (TYPE_SIZE_UNIT (type), 1),
06761            TYPE_ALIGN (type)))
06762       && ! mostly_zeros_p (exp))))
06763          || ((modifier == EXPAND_INITIALIZER
06764         || modifier == EXPAND_CONST_ADDRESS)
06765        && TREE_CONSTANT (exp)))
06766   {
06767     rtx constructor = output_constant_def (exp, 1);
06768 
06769     if (modifier != EXPAND_CONST_ADDRESS
06770         && modifier != EXPAND_INITIALIZER
06771         && modifier != EXPAND_SUM)
06772       constructor = validize_mem (constructor);
06773 
06774     return constructor;
06775   }
06776       else
06777   {
06778     /* Handle calls that pass values in multiple non-contiguous
06779        locations.  The Irix 6 ABI has examples of this.  */
06780     if (target == 0 || ! safe_from_p (target, exp, 1)
06781         || GET_CODE (target) == PARALLEL
06782         || modifier == EXPAND_STACK_PARM)
06783       target
06784         = assign_temp (build_qualified_type (type,
06785                (TYPE_QUALS (type)
06786                 | (TREE_READONLY (exp)
06787                    * TYPE_QUAL_CONST))),
06788            0, TREE_ADDRESSABLE (exp), 1);
06789 
06790     store_constructor (exp, target, 0, int_expr_size (exp));
06791     return target;
06792   }
06793 
06794     case MISALIGNED_INDIRECT_REF:
06795     case ALIGN_INDIRECT_REF:
06796     case INDIRECT_REF:
06797       {
06798   tree exp1 = TREE_OPERAND (exp, 0);
06799   tree orig;
06800 
06801   if (modifier != EXPAND_WRITE)
06802     {
06803       tree t;
06804 
06805       t = fold_read_from_constant_string (exp);
06806       if (t)
06807         return expand_expr (t, target, tmode, modifier);
06808     }
06809 
06810   op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
06811   op0 = memory_address (mode, op0);
06812 
06813   if (code == ALIGN_INDIRECT_REF)
06814     {
06815       int align = TYPE_ALIGN_UNIT (type);
06816       op0 = gen_rtx_AND (Pmode, op0, GEN_INT (-align));
06817       op0 = memory_address (mode, op0);
06818     }
06819 
06820   temp = gen_rtx_MEM (mode, op0);
06821 
06822   orig = REF_ORIGINAL (exp);
06823   if (!orig)
06824     orig = exp;
06825   set_mem_attributes (temp, orig, 0);
06826 
06827   /* Resolve the misalignment now, so that we don't have to remember
06828      to resolve it later.  Of course, this only works for reads.  */
06829   /* ??? When we get around to supporting writes, we'll have to handle
06830      this in store_expr directly.  The vectorizer isn't generating
06831      those yet, however.  */
06832   if (code == MISALIGNED_INDIRECT_REF)
06833     {
06834       int icode;
06835       rtx reg, insn;
06836 
06837       gcc_assert (modifier == EXPAND_NORMAL);
06838 
06839       /* The vectorizer should have already checked the mode.  */
06840       icode = movmisalign_optab->handlers[mode].insn_code;
06841       gcc_assert (icode != CODE_FOR_nothing);
06842 
06843       /* We've already validated the memory, and we're creating a
06844          new pseudo destination.  The predicates really can't fail.  */
06845       reg = gen_reg_rtx (mode);
06846 
06847       /* Nor can the insn generator.  */
06848       insn = GEN_FCN (icode) (reg, temp);
06849       emit_insn (insn);
06850 
06851       return reg;
06852     }
06853 
06854   return temp;
06855       }
06856 
06857     case ARRAY_REF:
06858 
06859       {
06860   tree array = TREE_OPERAND (exp, 0);
06861   tree index = TREE_OPERAND (exp, 1);
06862 
06863   /* Fold an expression like: "foo"[2].
06864      This is not done in fold so it won't happen inside &.
06865      Don't fold if this is for wide characters since it's too
06866      difficult to do correctly and this is a very rare case.  */
06867 
06868   if (modifier != EXPAND_CONST_ADDRESS
06869       && modifier != EXPAND_INITIALIZER
06870       && modifier != EXPAND_MEMORY)
06871     {
06872       tree t = fold_read_from_constant_string (exp);
06873 
06874       if (t)
06875         return expand_expr (t, target, tmode, modifier);
06876     }
06877 
06878   /* If this is a constant index into a constant array,
06879      just get the value from the array.  Handle both the cases when
06880      we have an explicit constructor and when our operand is a variable
06881      that was declared const.  */
06882 
06883   if (modifier != EXPAND_CONST_ADDRESS
06884       && modifier != EXPAND_INITIALIZER
06885       && modifier != EXPAND_MEMORY
06886       && TREE_CODE (array) == CONSTRUCTOR
06887       && ! TREE_SIDE_EFFECTS (array)
06888       && TREE_CODE (index) == INTEGER_CST)
06889     {
06890       tree elem;
06891 
06892       for (elem = CONSTRUCTOR_ELTS (array);
06893      (elem && !tree_int_cst_equal (TREE_PURPOSE (elem), index));
06894      elem = TREE_CHAIN (elem))
06895         ;
06896 
06897       if (elem && !TREE_SIDE_EFFECTS (TREE_VALUE (elem)))
06898         return expand_expr (fold (TREE_VALUE (elem)), target, tmode,
06899           modifier);
06900     }
06901 
06902   else if (optimize >= 1
06903      && modifier != EXPAND_CONST_ADDRESS
06904      && modifier != EXPAND_INITIALIZER
06905      && modifier != EXPAND_MEMORY
06906      && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
06907      && TREE_CODE (array) == VAR_DECL && DECL_INITIAL (array)
06908      && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK
06909      && targetm.binds_local_p (array))
06910     {
06911       if (TREE_CODE (index) == INTEGER_CST)
06912         {
06913     tree init = DECL_INITIAL (array);
06914 
06915     if (TREE_CODE (init) == CONSTRUCTOR)
06916       {
06917         tree elem;
06918 
06919         for (elem = CONSTRUCTOR_ELTS (init);
06920        (elem
06921         && !tree_int_cst_equal (TREE_PURPOSE (elem), index));
06922        elem = TREE_CHAIN (elem))
06923           ;
06924 
06925         if (elem && !TREE_SIDE_EFFECTS (TREE_VALUE (elem)))
06926           return expand_expr (fold (TREE_VALUE (elem)), target,
06927             tmode, modifier);
06928       }
06929     else if (TREE_CODE (init) == STRING_CST
06930        && 0 > compare_tree_int (index,
06931               TREE_STRING_LENGTH (init)))
06932       {
06933         tree type = TREE_TYPE (TREE_TYPE (init));
06934         enum machine_mode mode = TYPE_MODE (type);
06935 
06936         if (GET_MODE_CLASS (mode) == MODE_INT
06937       && GET_MODE_SIZE (mode) == 1)
06938           return gen_int_mode (TREE_STRING_POINTER (init)
06939              [TREE_INT_CST_LOW (index)], mode);
06940       }
06941         }
06942     }
06943       }
06944       goto normal_inner_ref;
06945 
06946     case COMPONENT_REF:
06947       /* If the operand is a CONSTRUCTOR, we can just extract the
06948    appropriate field if it is present.  */
06949       if (TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR)
06950   {
06951     tree elt;
06952 
06953     for (elt = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)); elt;
06954          elt = TREE_CHAIN (elt))
06955       if (TREE_PURPOSE (elt) == TREE_OPERAND (exp, 1)
06956     /* We can normally use the value of the field in the
06957        CONSTRUCTOR.  However, if this is a bitfield in
06958        an integral mode that we can fit in a HOST_WIDE_INT,
06959        we must mask only the number of bits in the bitfield,
06960        since this is done implicitly by the constructor.  If
06961        the bitfield does not meet either of those conditions,
06962        we can't do this optimization.  */
06963     && (! DECL_BIT_FIELD (TREE_PURPOSE (elt))
06964         || ((GET_MODE_CLASS (DECL_MODE (TREE_PURPOSE (elt)))
06965        == MODE_INT)
06966       && (GET_MODE_BITSIZE (DECL_MODE (TREE_PURPOSE (elt)))
06967           <= HOST_BITS_PER_WIDE_INT))))
06968         {
06969     if (DECL_BIT_FIELD (TREE_PURPOSE (elt))
06970         && modifier == EXPAND_STACK_PARM)
06971       target = 0;
06972     op0 = expand_expr (TREE_VALUE (elt), target, tmode, modifier);
06973     if (DECL_BIT_FIELD (TREE_PURPOSE (elt)))
06974       {
06975         HOST_WIDE_INT bitsize
06976           = TREE_INT_CST_LOW (DECL_SIZE (TREE_PURPOSE (elt)));
06977         enum machine_mode imode
06978           = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
06979 
06980         if (TYPE_UNSIGNED (TREE_TYPE (TREE_PURPOSE (elt))))
06981           {
06982       op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1);
06983       op0 = expand_and (imode, op0, op1, target);
06984           }
06985         else
06986           {
06987       tree count
06988         = build_int_cst (NULL_TREE,
06989              GET_MODE_BITSIZE (imode) - bitsize);
06990 
06991       op0 = expand_shift (LSHIFT_EXPR, imode, op0, count,
06992               target, 0);
06993       op0 = expand_shift (RSHIFT_EXPR, imode, op0, count,
06994               target, 0);
06995           }
06996       }
06997 
06998     return op0;
06999         }
07000   }
07001       goto normal_inner_ref;
07002 
07003     case BIT_FIELD_REF:
07004     case ARRAY_RANGE_REF:
07005     normal_inner_ref:
07006       {
07007   enum machine_mode mode1;
07008   HOST_WIDE_INT bitsize, bitpos;
07009   tree offset;
07010   int volatilep = 0;
07011   tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
07012           &mode1, &unsignedp, &volatilep, true);
07013   rtx orig_op0;
07014 
07015   /* If we got back the original object, something is wrong.  Perhaps
07016      we are evaluating an expression too early.  In any event, don't
07017      infinitely recurse.  */
07018   gcc_assert (tem != exp);
07019 
07020   /* If TEM's type is a union of variable size, pass TARGET to the inner
07021      computation, since it will need a temporary and TARGET is known
07022      to have to do.  This occurs in unchecked conversion in Ada.  */
07023 
07024   orig_op0 = op0
07025     = expand_expr (tem,
07026        (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
07027         && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
07028             != INTEGER_CST)
07029         && modifier != EXPAND_STACK_PARM
07030         ? target : NULL_RTX),
07031        VOIDmode,
07032        (modifier == EXPAND_INITIALIZER
07033         || modifier == EXPAND_CONST_ADDRESS
07034         || modifier == EXPAND_STACK_PARM)
07035        ? modifier : EXPAND_NORMAL);
07036 
07037   /* If this is a constant, put it into a register if it is a
07038      legitimate constant and OFFSET is 0 and memory if it isn't.  */
07039   if (CONSTANT_P (op0))
07040     {
07041       enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem));
07042       if (mode != BLKmode && LEGITIMATE_CONSTANT_P (op0)
07043     && offset == 0)
07044         op0 = force_reg (mode, op0);
07045       else
07046         op0 = validize_mem (force_const_mem (mode, op0));
07047     }
07048 
07049   /* Otherwise, if this object not in memory and we either have an
07050      offset or a BLKmode result, put it there.  This case can't occur in
07051      C, but can in Ada if we have unchecked conversion of an expression
07052      from a scalar type to an array or record type or for an
07053      ARRAY_RANGE_REF whose type is BLKmode.  */
07054   else if (!MEM_P (op0)
07055      && (offset != 0
07056          || (code == ARRAY_RANGE_REF && mode == BLKmode)))
07057     {
07058       tree nt = build_qualified_type (TREE_TYPE (tem),
07059               (TYPE_QUALS (TREE_TYPE (tem))
07060                | TYPE_QUAL_CONST));
07061       rtx memloc = assign_temp (nt, 1, 1, 1);
07062 
07063       emit_move_insn (memloc, op0);
07064       op0 = memloc;
07065     }
07066 
07067   if (offset != 0)
07068     {
07069       rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
07070             EXPAND_SUM);
07071 
07072       gcc_assert (MEM_P (op0));
07073 
07074 #ifdef POINTERS_EXTEND_UNSIGNED
07075       if (GET_MODE (offset_rtx) != Pmode)
07076         offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
07077 #else
07078       if (GET_MODE (offset_rtx) != ptr_mode)
07079         offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
07080 #endif
07081 
07082       if (GET_MODE (op0) == BLKmode
07083     /* A constant address in OP0 can have VOIDmode, we must
07084        not try to call force_reg in that case.  */
07085     && GET_MODE (XEXP (op0, 0)) != VOIDmode
07086     && bitsize != 0
07087     && (bitpos % bitsize) == 0
07088     && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
07089     && MEM_ALIGN (op0) == GET_MODE_ALIGNMENT (mode1))
07090         {
07091     op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
07092     bitpos = 0;
07093         }
07094 
07095       op0 = offset_address (op0, offset_rtx,
07096           highest_pow2_factor (offset));
07097     }
07098 
07099   /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
07100      record its alignment as BIGGEST_ALIGNMENT.  */
07101   if (MEM_P (op0) && bitpos == 0 && offset != 0
07102       && is_aligning_offset (offset, tem))
07103     set_mem_align (op0, BIGGEST_ALIGNMENT);
07104 
07105   /* Don't forget about volatility even if this is a bitfield.  */
07106   if (MEM_P (op0) && volatilep && ! MEM_VOLATILE_P (op0))
07107     {
07108       if (op0 == orig_op0)
07109         op0 = copy_rtx (op0);
07110 
07111       MEM_VOLATILE_P (op0) = 1;
07112     }
07113 
07114   /* The following code doesn't handle CONCAT.
07115      Assume only bitpos == 0 can be used for CONCAT, due to
07116      one element arrays having the same mode as its element.  */
07117   if (GET_CODE (op0) == CONCAT)
07118     {
07119       gcc_assert (bitpos == 0
07120       && bitsize == GET_MODE_BITSIZE (GET_MODE (op0)));
07121       return op0;
07122     }
07123 
07124   /* In cases where an aligned union has an unaligned object
07125      as a field, we might be extracting a BLKmode value from
07126      an integer-mode (e.g., SImode) object.  Handle this case
07127      by doing the extract into an object as wide as the field
07128      (which we know to be the width of a basic mode), then
07129      storing into memory, and changing the mode to BLKmode.  */
07130   if (mode1 == VOIDmode
07131       || REG_P (op0) || GET_CODE (op0) == SUBREG
07132       || (mode1 != BLKmode && ! direct_load[(int) mode1]
07133     && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
07134     && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
07135     && modifier != EXPAND_CONST_ADDRESS
07136     && modifier != EXPAND_INITIALIZER)
07137       /* If the field isn't aligned enough to fetch as a memref,
07138          fetch it as a bit field.  */
07139       || (mode1 != BLKmode
07140     && (((TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
07141           || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)
07142           || (MEM_P (op0)
07143         && (MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
07144             || (bitpos % GET_MODE_ALIGNMENT (mode1) != 0))))
07145          && ((modifier == EXPAND_CONST_ADDRESS
07146         || modifier == EXPAND_INITIALIZER)
07147        ? STRICT_ALIGNMENT
07148        : SLOW_UNALIGNED_ACCESS (mode1, MEM_ALIGN (op0))))
07149         || (bitpos % BITS_PER_UNIT != 0)))
07150       /* If the type and the field are a constant size and the
07151          size of the type isn't the same size as the bitfield,
07152          we must use bitfield operations.  */
07153       || (bitsize >= 0
07154     && TYPE_SIZE (TREE_TYPE (exp))
07155     && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
07156     && 0 != compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)),
07157             bitsize)))
07158     {
07159       enum machine_mode ext_mode = mode;
07160 
07161       if (ext_mode == BLKmode
07162     && ! (target != 0 && MEM_P (op0)
07163           && MEM_P (target)
07164           && bitpos % BITS_PER_UNIT == 0))
07165         ext_mode = mode_for_size (bitsize, MODE_INT, 1);
07166 
07167       if (ext_mode == BLKmode)
07168         {
07169     if (target == 0)
07170       target = assign_temp (type, 0, 1, 1);
07171 
07172     if (bitsize == 0)
07173       return target;
07174 
07175     /* In this case, BITPOS must start at a byte boundary and
07176        TARGET, if specified, must be a MEM.  */
07177     gcc_assert (MEM_P (op0)