OSDN Git Service

1dc79b67d38c6ca37138a9c85595cd6c85aae4df
[pf3gnuchains/gcc-fork.git] / gcc / expr.c
1 /* Convert tree expression to rtl instructions, for GNU compiler.
2    Copyright (C) 1988, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21
22 #include "config.h"
23 #include "machmode.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "obstack.h"
27 #include "flags.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "except.h"
31 #include "function.h"
32 #include "insn-flags.h"
33 #include "insn-codes.h"
34 #include "expr.h"
35 #include "insn-config.h"
36 #include "recog.h"
37 #include "output.h"
38 #include "typeclass.h"
39
40 #include "bytecode.h"
41 #include "bc-opcode.h"
42 #include "bc-typecd.h"
43 #include "bc-optab.h"
44 #include "bc-emit.h"
45
46
47 #define CEIL(x,y) (((x) + (y) - 1) / (y))
48
49 /* Decide whether a function's arguments should be processed
50    from first to last or from last to first.
51
52    They should if the stack and args grow in opposite directions, but
53    only if we have push insns.  */
54
55 #ifdef PUSH_ROUNDING
56
57 #if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
58 #define PUSH_ARGS_REVERSED      /* If it's last to first */
59 #endif
60
61 #endif
62
63 #ifndef STACK_PUSH_CODE
64 #ifdef STACK_GROWS_DOWNWARD
65 #define STACK_PUSH_CODE PRE_DEC
66 #else
67 #define STACK_PUSH_CODE PRE_INC
68 #endif
69 #endif
70
71 /* Like STACK_BOUNDARY but in units of bytes, not bits.  */
72 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
73
74 /* If this is nonzero, we do not bother generating VOLATILE
75    around volatile memory references, and we are willing to
76    output indirect addresses.  If cse is to follow, we reject
77    indirect addresses so a useful potential cse is generated;
78    if it is used only once, instruction combination will produce
79    the same indirect address eventually.  */
80 int cse_not_expected;
81
82 /* Nonzero to generate code for all the subroutines within an
83    expression before generating the upper levels of the expression.
84    Nowadays this is never zero.  */
85 int do_preexpand_calls = 1;
86
87 /* Number of units that we should eventually pop off the stack.
88    These are the arguments to function calls that have already returned.  */
89 int pending_stack_adjust;
90
91 /* Nonzero means stack pops must not be deferred, and deferred stack
92    pops must not be output.  It is nonzero inside a function call,
93    inside a conditional expression, inside a statement expression,
94    and in other cases as well.  */
95 int inhibit_defer_pop;
96
97 /* When temporaries are created by TARGET_EXPRs, they are created at
98    this level of temp_slot_level, so that they can remain allocated
99    until no longer needed.  CLEANUP_POINT_EXPRs define the lifetime
100    of TARGET_EXPRs.  */
101 int target_temp_slot_level;
102
103 /* Nonzero means __builtin_saveregs has already been done in this function.
104    The value is the pseudoreg containing the value __builtin_saveregs
105    returned.  */
106 static rtx saveregs_value;
107
108 /* Similarly for __builtin_apply_args.  */
109 static rtx apply_args_value;
110
111 /* This structure is used by move_by_pieces to describe the move to
112    be performed.  */
113
114 struct move_by_pieces
115 {
116   rtx to;
117   rtx to_addr;
118   int autinc_to;
119   int explicit_inc_to;
120   int to_struct;
121   rtx from;
122   rtx from_addr;
123   int autinc_from;
124   int explicit_inc_from;
125   int from_struct;
126   int len;
127   int offset;
128   int reverse;
129 };
130
131 /* This structure is used by clear_by_pieces to describe the clear to
132    be performed.  */
133
134 struct clear_by_pieces
135 {
136   rtx to;
137   rtx to_addr;
138   int autinc_to;
139   int explicit_inc_to;
140   int to_struct;
141   int len;
142   int offset;
143   int reverse;
144 };
145
146 /* Used to generate bytecodes: keep track of size of local variables,
147    as well as depth of arithmetic stack. (Notice that variables are
148    stored on the machine's stack, not the arithmetic stack.) */
149
150 extern int local_vars_size;
151 extern int stack_depth;
152 extern int max_stack_depth;
153 extern struct obstack permanent_obstack;
154 extern rtx arg_pointer_save_area;
155
156 static rtx enqueue_insn         PROTO((rtx, rtx));
157 static int queued_subexp_p      PROTO((rtx));
158 static void init_queue          PROTO((void));
159 static void move_by_pieces      PROTO((rtx, rtx, int, int));
160 static int move_by_pieces_ninsns PROTO((unsigned int, int));
161 static void move_by_pieces_1    PROTO((rtx (*) (), enum machine_mode,
162                                        struct move_by_pieces *));
163 static void clear_by_pieces     PROTO((rtx, int, int));
164 static void clear_by_pieces_1   PROTO((rtx (*) (), enum machine_mode,
165                                        struct clear_by_pieces *));
166 static int is_zeros_p           PROTO((tree));
167 static int mostly_zeros_p       PROTO((tree));
168 static void store_constructor   PROTO((tree, rtx, int));
169 static rtx store_field          PROTO((rtx, int, int, enum machine_mode, tree,
170                                        enum machine_mode, int, int, int));
171 static int get_inner_unaligned_p PROTO((tree));
172 static tree save_noncopied_parts PROTO((tree, tree));
173 static tree init_noncopied_parts PROTO((tree, tree));
174 static int safe_from_p          PROTO((rtx, tree));
175 static int fixed_type_p         PROTO((tree));
176 static rtx var_rtx              PROTO((tree));
177 static int get_pointer_alignment PROTO((tree, unsigned));
178 static tree string_constant     PROTO((tree, tree *));
179 static tree c_strlen            PROTO((tree));
180 static rtx expand_builtin       PROTO((tree, rtx, rtx,
181                                        enum machine_mode, int));
182 static int apply_args_size      PROTO((void));
183 static int apply_result_size    PROTO((void));
184 static rtx result_vector        PROTO((int, rtx));
185 static rtx expand_builtin_apply_args PROTO((void));
186 static rtx expand_builtin_apply PROTO((rtx, rtx, rtx));
187 static void expand_builtin_return PROTO((rtx));
188 static rtx expand_increment     PROTO((tree, int, int));
189 void bc_expand_increment        PROTO((struct increment_operator *, tree));
190 rtx bc_allocate_local           PROTO((int, int));
191 void bc_store_memory            PROTO((tree, tree));
192 tree bc_expand_component_address PROTO((tree));
193 tree bc_expand_address          PROTO((tree));
194 void bc_expand_constructor      PROTO((tree));
195 void bc_adjust_stack            PROTO((int));
196 tree bc_canonicalize_array_ref  PROTO((tree));
197 void bc_load_memory             PROTO((tree, tree));
198 void bc_load_externaddr         PROTO((rtx));
199 void bc_load_externaddr_id      PROTO((tree, int));
200 void bc_load_localaddr          PROTO((rtx));
201 void bc_load_parmaddr           PROTO((rtx));
202 static void preexpand_calls     PROTO((tree));
203 static void do_jump_by_parts_greater PROTO((tree, int, rtx, rtx));
204 void do_jump_by_parts_greater_rtx PROTO((enum machine_mode, int, rtx, rtx, rtx, rtx));
205 static void do_jump_by_parts_equality PROTO((tree, rtx, rtx));
206 static void do_jump_by_parts_equality_rtx PROTO((rtx, rtx, rtx));
207 static void do_jump_for_compare PROTO((rtx, rtx, rtx));
208 static rtx compare              PROTO((tree, enum rtx_code, enum rtx_code));
209 static rtx do_store_flag        PROTO((tree, rtx, enum machine_mode, int));
210 extern tree truthvalue_conversion       PROTO((tree));
211
212 /* Record for each mode whether we can move a register directly to or
213    from an object of that mode in memory.  If we can't, we won't try
214    to use that mode directly when accessing a field of that mode.  */
215
216 static char direct_load[NUM_MACHINE_MODES];
217 static char direct_store[NUM_MACHINE_MODES];
218
219 /* MOVE_RATIO is the number of move instructions that is better than
220    a block move.  */
221
222 #ifndef MOVE_RATIO
223 #if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi) || defined (HAVE_movstrti)
224 #define MOVE_RATIO 2
225 #else
226 /* A value of around 6 would minimize code size; infinity would minimize
227    execution time.  */
228 #define MOVE_RATIO 15
229 #endif
230 #endif
231
232 /* This array records the insn_code of insns to perform block moves.  */
233 enum insn_code movstr_optab[NUM_MACHINE_MODES];
234
235 /* This array records the insn_code of insns to perform block clears.  */
236 enum insn_code clrstr_optab[NUM_MACHINE_MODES];
237
238 /* SLOW_UNALIGNED_ACCESS is non-zero if unaligned accesses are very slow.  */
239
240 #ifndef SLOW_UNALIGNED_ACCESS
241 #define SLOW_UNALIGNED_ACCESS STRICT_ALIGNMENT
242 #endif
243
244 /* Register mappings for target machines without register windows.  */
245 #ifndef INCOMING_REGNO
246 #define INCOMING_REGNO(OUT) (OUT)
247 #endif
248 #ifndef OUTGOING_REGNO
249 #define OUTGOING_REGNO(IN) (IN)
250 #endif
251 \f
252 /* Maps used to convert modes to const, load, and store bytecodes.  */
253 enum bytecode_opcode mode_to_const_map[MAX_MACHINE_MODE];
254 enum bytecode_opcode mode_to_load_map[MAX_MACHINE_MODE];
255 enum bytecode_opcode mode_to_store_map[MAX_MACHINE_MODE];
256
257 /* Initialize maps used to convert modes to const, load, and store
258    bytecodes.  */
259
260 void
261 bc_init_mode_to_opcode_maps ()
262 {
263   int mode;
264
265   for (mode = 0; mode < (int) MAX_MACHINE_MODE; mode++)
266     mode_to_const_map[mode]
267       = mode_to_load_map[mode]
268       = mode_to_store_map[mode] = neverneverland;
269       
270 #define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \
271   mode_to_const_map[(int) SYM] = CONST; \
272   mode_to_load_map[(int) SYM] = LOAD; \
273   mode_to_store_map[(int) SYM] = STORE;
274
275 #include "modemap.def"
276 #undef DEF_MODEMAP
277 }
278 \f
279 /* This is run once per compilation to set up which modes can be used
280    directly in memory and to initialize the block move optab.  */
281
282 void
283 init_expr_once ()
284 {
285   rtx insn, pat;
286   enum machine_mode mode;
287   /* Try indexing by frame ptr and try by stack ptr.
288      It is known that on the Convex the stack ptr isn't a valid index.
289      With luck, one or the other is valid on any machine.  */
290   rtx mem = gen_rtx (MEM, VOIDmode, stack_pointer_rtx);
291   rtx mem1 = gen_rtx (MEM, VOIDmode, frame_pointer_rtx);
292
293   start_sequence ();
294   insn = emit_insn (gen_rtx (SET, 0, 0));
295   pat = PATTERN (insn);
296
297   for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
298        mode = (enum machine_mode) ((int) mode + 1))
299     {
300       int regno;
301       rtx reg;
302       int num_clobbers;
303
304       direct_load[(int) mode] = direct_store[(int) mode] = 0;
305       PUT_MODE (mem, mode);
306       PUT_MODE (mem1, mode);
307
308       /* See if there is some register that can be used in this mode and
309          directly loaded or stored from memory.  */
310
311       if (mode != VOIDmode && mode != BLKmode)
312         for (regno = 0; regno < FIRST_PSEUDO_REGISTER
313              && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
314              regno++)
315           {
316             if (! HARD_REGNO_MODE_OK (regno, mode))
317               continue;
318
319             reg = gen_rtx (REG, mode, regno);
320
321             SET_SRC (pat) = mem;
322             SET_DEST (pat) = reg;
323             if (recog (pat, insn, &num_clobbers) >= 0)
324               direct_load[(int) mode] = 1;
325
326             SET_SRC (pat) = mem1;
327             SET_DEST (pat) = reg;
328             if (recog (pat, insn, &num_clobbers) >= 0)
329               direct_load[(int) mode] = 1;
330
331             SET_SRC (pat) = reg;
332             SET_DEST (pat) = mem;
333             if (recog (pat, insn, &num_clobbers) >= 0)
334               direct_store[(int) mode] = 1;
335
336             SET_SRC (pat) = reg;
337             SET_DEST (pat) = mem1;
338             if (recog (pat, insn, &num_clobbers) >= 0)
339               direct_store[(int) mode] = 1;
340           }
341     }
342
343   end_sequence ();
344 }
345       
346 /* This is run at the start of compiling a function.  */
347
348 void
349 init_expr ()
350 {
351   init_queue ();
352
353   pending_stack_adjust = 0;
354   inhibit_defer_pop = 0;
355   saveregs_value = 0;
356   apply_args_value = 0;
357   forced_labels = 0;
358 }
359
360 /* Save all variables describing the current status into the structure *P.
361    This is used before starting a nested function.  */
362
363 void
364 save_expr_status (p)
365      struct function *p;
366 {
367   /* Instead of saving the postincrement queue, empty it.  */
368   emit_queue ();
369
370   p->pending_stack_adjust = pending_stack_adjust;
371   p->inhibit_defer_pop = inhibit_defer_pop;
372   p->saveregs_value = saveregs_value;
373   p->apply_args_value = apply_args_value;
374   p->forced_labels = forced_labels;
375
376   pending_stack_adjust = 0;
377   inhibit_defer_pop = 0;
378   saveregs_value = 0;
379   apply_args_value = 0;
380   forced_labels = 0;
381 }
382
383 /* Restore all variables describing the current status from the structure *P.
384    This is used after a nested function.  */
385
386 void
387 restore_expr_status (p)
388      struct function *p;
389 {
390   pending_stack_adjust = p->pending_stack_adjust;
391   inhibit_defer_pop = p->inhibit_defer_pop;
392   saveregs_value = p->saveregs_value;
393   apply_args_value = p->apply_args_value;
394   forced_labels = p->forced_labels;
395 }
396 \f
397 /* Manage the queue of increment instructions to be output
398    for POSTINCREMENT_EXPR expressions, etc.  */
399
400 static rtx pending_chain;
401
402 /* Queue up to increment (or change) VAR later.  BODY says how:
403    BODY should be the same thing you would pass to emit_insn
404    to increment right away.  It will go to emit_insn later on.
405
406    The value is a QUEUED expression to be used in place of VAR
407    where you want to guarantee the pre-incrementation value of VAR.  */
408
409 static rtx
410 enqueue_insn (var, body)
411      rtx var, body;
412 {
413   pending_chain = gen_rtx (QUEUED, GET_MODE (var),
414                            var, NULL_RTX, NULL_RTX, body, pending_chain);
415   return pending_chain;
416 }
417
418 /* Use protect_from_queue to convert a QUEUED expression
419    into something that you can put immediately into an instruction.
420    If the queued incrementation has not happened yet,
421    protect_from_queue returns the variable itself.
422    If the incrementation has happened, protect_from_queue returns a temp
423    that contains a copy of the old value of the variable.
424
425    Any time an rtx which might possibly be a QUEUED is to be put
426    into an instruction, it must be passed through protect_from_queue first.
427    QUEUED expressions are not meaningful in instructions.
428
429    Do not pass a value through protect_from_queue and then hold
430    on to it for a while before putting it in an instruction!
431    If the queue is flushed in between, incorrect code will result.  */
432
433 rtx
434 protect_from_queue (x, modify)
435      register rtx x;
436      int modify;
437 {
438   register RTX_CODE code = GET_CODE (x);
439
440 #if 0  /* A QUEUED can hang around after the queue is forced out.  */
441   /* Shortcut for most common case.  */
442   if (pending_chain == 0)
443     return x;
444 #endif
445
446   if (code != QUEUED)
447     {
448       /* A special hack for read access to (MEM (QUEUED ...)) to facilitate
449          use of autoincrement.  Make a copy of the contents of the memory
450          location rather than a copy of the address, but not if the value is
451          of mode BLKmode.  Don't modify X in place since it might be
452          shared.  */
453       if (code == MEM && GET_MODE (x) != BLKmode
454           && GET_CODE (XEXP (x, 0)) == QUEUED && !modify)
455         {
456           register rtx y = XEXP (x, 0);
457           register rtx new = gen_rtx (MEM, GET_MODE (x), QUEUED_VAR (y));
458
459           MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
460           RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
461           MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
462
463           if (QUEUED_INSN (y))
464             {
465               register rtx temp = gen_reg_rtx (GET_MODE (new));
466               emit_insn_before (gen_move_insn (temp, new),
467                                 QUEUED_INSN (y));
468               return temp;
469             }
470           return new;
471         }
472       /* Otherwise, recursively protect the subexpressions of all
473          the kinds of rtx's that can contain a QUEUED.  */
474       if (code == MEM)
475         {
476           rtx tem = protect_from_queue (XEXP (x, 0), 0);
477           if (tem != XEXP (x, 0))
478             {
479               x = copy_rtx (x);
480               XEXP (x, 0) = tem;
481             }
482         }
483       else if (code == PLUS || code == MULT)
484         {
485           rtx new0 = protect_from_queue (XEXP (x, 0), 0);
486           rtx new1 = protect_from_queue (XEXP (x, 1), 0);
487           if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
488             {
489               x = copy_rtx (x);
490               XEXP (x, 0) = new0;
491               XEXP (x, 1) = new1;
492             }
493         }
494       return x;
495     }
496   /* If the increment has not happened, use the variable itself.  */
497   if (QUEUED_INSN (x) == 0)
498     return QUEUED_VAR (x);
499   /* If the increment has happened and a pre-increment copy exists,
500      use that copy.  */
501   if (QUEUED_COPY (x) != 0)
502     return QUEUED_COPY (x);
503   /* The increment has happened but we haven't set up a pre-increment copy.
504      Set one up now, and use it.  */
505   QUEUED_COPY (x) = gen_reg_rtx (GET_MODE (QUEUED_VAR (x)));
506   emit_insn_before (gen_move_insn (QUEUED_COPY (x), QUEUED_VAR (x)),
507                     QUEUED_INSN (x));
508   return QUEUED_COPY (x);
509 }
510
511 /* Return nonzero if X contains a QUEUED expression:
512    if it contains anything that will be altered by a queued increment.
513    We handle only combinations of MEM, PLUS, MINUS and MULT operators
514    since memory addresses generally contain only those.  */
515
516 static int
517 queued_subexp_p (x)
518      rtx x;
519 {
520   register enum rtx_code code = GET_CODE (x);
521   switch (code)
522     {
523     case QUEUED:
524       return 1;
525     case MEM:
526       return queued_subexp_p (XEXP (x, 0));
527     case MULT:
528     case PLUS:
529     case MINUS:
530       return queued_subexp_p (XEXP (x, 0))
531         || queued_subexp_p (XEXP (x, 1));
532     }
533   return 0;
534 }
535
536 /* Perform all the pending incrementations.  */
537
538 void
539 emit_queue ()
540 {
541   register rtx p;
542   while (p = pending_chain)
543     {
544       QUEUED_INSN (p) = emit_insn (QUEUED_BODY (p));
545       pending_chain = QUEUED_NEXT (p);
546     }
547 }
548
549 static void
550 init_queue ()
551 {
552   if (pending_chain)
553     abort ();
554 }
555 \f
556 /* Copy data from FROM to TO, where the machine modes are not the same.
557    Both modes may be integer, or both may be floating.
558    UNSIGNEDP should be nonzero if FROM is an unsigned type.
559    This causes zero-extension instead of sign-extension.  */
560
561 void
562 convert_move (to, from, unsignedp)
563      register rtx to, from;
564      int unsignedp;
565 {
566   enum machine_mode to_mode = GET_MODE (to);
567   enum machine_mode from_mode = GET_MODE (from);
568   int to_real = GET_MODE_CLASS (to_mode) == MODE_FLOAT;
569   int from_real = GET_MODE_CLASS (from_mode) == MODE_FLOAT;
570   enum insn_code code;
571   rtx libcall;
572
573   /* rtx code for making an equivalent value.  */
574   enum rtx_code equiv_code = (unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
575
576   to = protect_from_queue (to, 1);
577   from = protect_from_queue (from, 0);
578
579   if (to_real != from_real)
580     abort ();
581
582   /* If FROM is a SUBREG that indicates that we have already done at least
583      the required extension, strip it.  We don't handle such SUBREGs as
584      TO here.  */
585
586   if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from)
587       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (from)))
588           >= GET_MODE_SIZE (to_mode))
589       && SUBREG_PROMOTED_UNSIGNED_P (from) == unsignedp)
590     from = gen_lowpart (to_mode, from), from_mode = to_mode;
591
592   if (GET_CODE (to) == SUBREG && SUBREG_PROMOTED_VAR_P (to))
593     abort ();
594
595   if (to_mode == from_mode
596       || (from_mode == VOIDmode && CONSTANT_P (from)))
597     {
598       emit_move_insn (to, from);
599       return;
600     }
601
602   if (to_real)
603     {
604       rtx value;
605
606       if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode))
607         {
608           /* Try converting directly if the insn is supported.  */
609           if ((code = can_extend_p (to_mode, from_mode, 0))
610               != CODE_FOR_nothing)
611             {
612               emit_unop_insn (code, to, from, UNKNOWN);
613               return;
614             }
615         }
616  
617 #ifdef HAVE_trunchfqf2
618       if (HAVE_trunchfqf2 && from_mode == HFmode && to_mode == QFmode)
619         {
620           emit_unop_insn (CODE_FOR_trunchfqf2, to, from, UNKNOWN);
621           return;
622         }
623 #endif
624 #ifdef HAVE_truncsfqf2
625       if (HAVE_truncsfqf2 && from_mode == SFmode && to_mode == QFmode)
626         {
627           emit_unop_insn (CODE_FOR_truncsfqf2, to, from, UNKNOWN);
628           return;
629         }
630 #endif
631 #ifdef HAVE_truncdfqf2
632       if (HAVE_truncdfqf2 && from_mode == DFmode && to_mode == QFmode)
633         {
634           emit_unop_insn (CODE_FOR_truncdfqf2, to, from, UNKNOWN);
635           return;
636         }
637 #endif
638 #ifdef HAVE_truncxfqf2
639       if (HAVE_truncxfqf2 && from_mode == XFmode && to_mode == QFmode)
640         {
641           emit_unop_insn (CODE_FOR_truncxfqf2, to, from, UNKNOWN);
642           return;
643         }
644 #endif
645 #ifdef HAVE_trunctfqf2
646       if (HAVE_trunctfqf2 && from_mode == TFmode && to_mode == QFmode)
647         {
648           emit_unop_insn (CODE_FOR_trunctfqf2, to, from, UNKNOWN);
649           return;
650         }
651 #endif
652
653 #ifdef HAVE_trunctqfhf2
654       if (HAVE_trunctqfhf2 && from_mode == TQFmode && to_mode == HFmode)
655         {
656           emit_unop_insn (CODE_FOR_trunctqfhf2, to, from, UNKNOWN);
657           return;
658         }
659 #endif
660 #ifdef HAVE_truncsfhf2
661       if (HAVE_truncsfhf2 && from_mode == SFmode && to_mode == HFmode)
662         {
663           emit_unop_insn (CODE_FOR_truncsfhf2, to, from, UNKNOWN);
664           return;
665         }
666 #endif
667 #ifdef HAVE_truncdfhf2
668       if (HAVE_truncdfhf2 && from_mode == DFmode && to_mode == HFmode)
669         {
670           emit_unop_insn (CODE_FOR_truncdfhf2, to, from, UNKNOWN);
671           return;
672         }
673 #endif
674 #ifdef HAVE_truncxfhf2
675       if (HAVE_truncxfhf2 && from_mode == XFmode && to_mode == HFmode)
676         {
677           emit_unop_insn (CODE_FOR_truncxfhf2, to, from, UNKNOWN);
678           return;
679         }
680 #endif
681 #ifdef HAVE_trunctfhf2
682       if (HAVE_trunctfhf2 && from_mode == TFmode && to_mode == HFmode)
683         {
684           emit_unop_insn (CODE_FOR_trunctfhf2, to, from, UNKNOWN);
685           return;
686         }
687 #endif
688
689 #ifdef HAVE_truncsftqf2
690       if (HAVE_truncsftqf2 && from_mode == SFmode && to_mode == TQFmode)
691         {
692           emit_unop_insn (CODE_FOR_truncsftqf2, to, from, UNKNOWN);
693           return;
694         }
695 #endif
696 #ifdef HAVE_truncdftqf2
697       if (HAVE_truncdftqf2 && from_mode == DFmode && to_mode == TQFmode)
698         {
699           emit_unop_insn (CODE_FOR_truncdftqf2, to, from, UNKNOWN);
700           return;
701         }
702 #endif
703 #ifdef HAVE_truncxftqf2
704       if (HAVE_truncxftqf2 && from_mode == XFmode && to_mode == TQFmode)
705         {
706           emit_unop_insn (CODE_FOR_truncxftqf2, to, from, UNKNOWN);
707           return;
708         }
709 #endif
710 #ifdef HAVE_trunctftqf2
711       if (HAVE_trunctftqf2 && from_mode == TFmode && to_mode == TQFmode)
712         {
713           emit_unop_insn (CODE_FOR_trunctftqf2, to, from, UNKNOWN);
714           return;
715         }
716 #endif
717
718 #ifdef HAVE_truncdfsf2
719       if (HAVE_truncdfsf2 && from_mode == DFmode && to_mode == SFmode)
720         {
721           emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
722           return;
723         }
724 #endif
725 #ifdef HAVE_truncxfsf2
726       if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)
727         {
728           emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);
729           return;
730         }
731 #endif
732 #ifdef HAVE_trunctfsf2
733       if (HAVE_trunctfsf2 && from_mode == TFmode && to_mode == SFmode)
734         {
735           emit_unop_insn (CODE_FOR_trunctfsf2, to, from, UNKNOWN);
736           return;
737         }
738 #endif
739 #ifdef HAVE_truncxfdf2
740       if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)
741         {
742           emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);
743           return;
744         }
745 #endif
746 #ifdef HAVE_trunctfdf2
747       if (HAVE_trunctfdf2 && from_mode == TFmode && to_mode == DFmode)
748         {
749           emit_unop_insn (CODE_FOR_trunctfdf2, to, from, UNKNOWN);
750           return;
751         }
752 #endif
753
754       libcall = (rtx) 0;
755       switch (from_mode)
756         {
757         case SFmode:
758           switch (to_mode)
759             {
760             case DFmode:
761               libcall = extendsfdf2_libfunc;
762               break;
763
764             case XFmode:
765               libcall = extendsfxf2_libfunc;
766               break;
767
768             case TFmode:
769               libcall = extendsftf2_libfunc;
770               break;
771             }
772           break;
773
774         case DFmode:
775           switch (to_mode)
776             {
777             case SFmode:
778               libcall = truncdfsf2_libfunc;
779               break;
780
781             case XFmode:
782               libcall = extenddfxf2_libfunc;
783               break;
784
785             case TFmode:
786               libcall = extenddftf2_libfunc;
787               break;
788             }
789           break;
790
791         case XFmode:
792           switch (to_mode)
793             {
794             case SFmode:
795               libcall = truncxfsf2_libfunc;
796               break;
797
798             case DFmode:
799               libcall = truncxfdf2_libfunc;
800               break;
801             }
802           break;
803
804         case TFmode:
805           switch (to_mode)
806             {
807             case SFmode:
808               libcall = trunctfsf2_libfunc;
809               break;
810
811             case DFmode:
812               libcall = trunctfdf2_libfunc;
813               break;
814             }
815           break;
816         }
817
818       if (libcall == (rtx) 0)
819         /* This conversion is not implemented yet.  */
820         abort ();
821
822       value = emit_library_call_value (libcall, NULL_RTX, 1, to_mode,
823                                        1, from, from_mode);
824       emit_move_insn (to, value);
825       return;
826     }
827
828   /* Now both modes are integers.  */
829
830   /* Handle expanding beyond a word.  */
831   if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode)
832       && GET_MODE_BITSIZE (to_mode) > BITS_PER_WORD)
833     {
834       rtx insns;
835       rtx lowpart;
836       rtx fill_value;
837       rtx lowfrom;
838       int i;
839       enum machine_mode lowpart_mode;
840       int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
841
842       /* Try converting directly if the insn is supported.  */
843       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
844           != CODE_FOR_nothing)
845         {
846           /* If FROM is a SUBREG, put it into a register.  Do this
847              so that we always generate the same set of insns for
848              better cse'ing; if an intermediate assignment occurred,
849              we won't be doing the operation directly on the SUBREG.  */
850           if (optimize > 0 && GET_CODE (from) == SUBREG)
851             from = force_reg (from_mode, from);
852           emit_unop_insn (code, to, from, equiv_code);
853           return;
854         }
855       /* Next, try converting via full word.  */
856       else if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD
857                && ((code = can_extend_p (to_mode, word_mode, unsignedp))
858                    != CODE_FOR_nothing))
859         {
860           if (GET_CODE (to) == REG)
861             emit_insn (gen_rtx (CLOBBER, VOIDmode, to));
862           convert_move (gen_lowpart (word_mode, to), from, unsignedp);
863           emit_unop_insn (code, to,
864                           gen_lowpart (word_mode, to), equiv_code);
865           return;
866         }
867
868       /* No special multiword conversion insn; do it by hand.  */
869       start_sequence ();
870
871       /* Since we will turn this into a no conflict block, we must ensure
872          that the source does not overlap the target.  */
873
874       if (reg_overlap_mentioned_p (to, from))
875         from = force_reg (from_mode, from);
876
877       /* Get a copy of FROM widened to a word, if necessary.  */
878       if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD)
879         lowpart_mode = word_mode;
880       else
881         lowpart_mode = from_mode;
882
883       lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
884
885       lowpart = gen_lowpart (lowpart_mode, to);
886       emit_move_insn (lowpart, lowfrom);
887
888       /* Compute the value to put in each remaining word.  */
889       if (unsignedp)
890         fill_value = const0_rtx;
891       else
892         {
893 #ifdef HAVE_slt
894           if (HAVE_slt
895               && insn_operand_mode[(int) CODE_FOR_slt][0] == word_mode
896               && STORE_FLAG_VALUE == -1)
897             {
898               emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,
899                              lowpart_mode, 0, 0);
900               fill_value = gen_reg_rtx (word_mode);
901               emit_insn (gen_slt (fill_value));
902             }
903           else
904 #endif
905             {
906               fill_value
907                 = expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom,
908                                 size_int (GET_MODE_BITSIZE (lowpart_mode) - 1),
909                                 NULL_RTX, 0);
910               fill_value = convert_to_mode (word_mode, fill_value, 1);
911             }
912         }
913
914       /* Fill the remaining words.  */
915       for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
916         {
917           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
918           rtx subword = operand_subword (to, index, 1, to_mode);
919
920           if (subword == 0)
921             abort ();
922
923           if (fill_value != subword)
924             emit_move_insn (subword, fill_value);
925         }
926
927       insns = get_insns ();
928       end_sequence ();
929
930       emit_no_conflict_block (insns, to, from, NULL_RTX,
931                               gen_rtx (equiv_code, to_mode, copy_rtx (from)));
932       return;
933     }
934
935   /* Truncating multi-word to a word or less.  */
936   if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD
937       && GET_MODE_BITSIZE (to_mode) <= BITS_PER_WORD)
938     {
939       if (!((GET_CODE (from) == MEM
940              && ! MEM_VOLATILE_P (from)
941              && direct_load[(int) to_mode]
942              && ! mode_dependent_address_p (XEXP (from, 0)))
943             || GET_CODE (from) == REG
944             || GET_CODE (from) == SUBREG))
945         from = force_reg (from_mode, from);
946       convert_move (to, gen_lowpart (word_mode, from), 0);
947       return;
948     }
949
950   /* Handle pointer conversion */                       /* SPEE 900220 */
951   if (to_mode == PSImode)
952     {
953       if (from_mode != SImode)
954         from = convert_to_mode (SImode, from, unsignedp);
955
956 #ifdef HAVE_truncsipsi2
957       if (HAVE_truncsipsi2)
958         {
959           emit_unop_insn (CODE_FOR_truncsipsi2, to, from, UNKNOWN);
960           return;
961         }
962 #endif /* HAVE_truncsipsi2 */
963       abort ();
964     }
965
966   if (from_mode == PSImode)
967     {
968       if (to_mode != SImode)
969         {
970           from = convert_to_mode (SImode, from, unsignedp);
971           from_mode = SImode;
972         }
973       else
974         {
975 #ifdef HAVE_extendpsisi2
976           if (HAVE_extendpsisi2)
977             {
978               emit_unop_insn (CODE_FOR_extendpsisi2, to, from, UNKNOWN);
979               return;
980             }
981 #endif /* HAVE_extendpsisi2 */
982           abort ();
983         }
984     }
985
986   if (to_mode == PDImode)
987     {
988       if (from_mode != DImode)
989         from = convert_to_mode (DImode, from, unsignedp);
990
991 #ifdef HAVE_truncdipdi2
992       if (HAVE_truncdipdi2)
993         {
994           emit_unop_insn (CODE_FOR_truncdipdi2, to, from, UNKNOWN);
995           return;
996         }
997 #endif /* HAVE_truncdipdi2 */
998       abort ();
999     }
1000
1001   if (from_mode == PDImode)
1002     {
1003       if (to_mode != DImode)
1004         {
1005           from = convert_to_mode (DImode, from, unsignedp);
1006           from_mode = DImode;
1007         }
1008       else
1009         {
1010 #ifdef HAVE_extendpdidi2
1011           if (HAVE_extendpdidi2)
1012             {
1013               emit_unop_insn (CODE_FOR_extendpdidi2, to, from, UNKNOWN);
1014               return;
1015             }
1016 #endif /* HAVE_extendpdidi2 */
1017           abort ();
1018         }
1019     }
1020
1021   /* Now follow all the conversions between integers
1022      no more than a word long.  */
1023
1024   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
1025   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
1026       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
1027                                 GET_MODE_BITSIZE (from_mode)))
1028     {
1029       if (!((GET_CODE (from) == MEM
1030              && ! MEM_VOLATILE_P (from)
1031              && direct_load[(int) to_mode]
1032              && ! mode_dependent_address_p (XEXP (from, 0)))
1033             || GET_CODE (from) == REG
1034             || GET_CODE (from) == SUBREG))
1035         from = force_reg (from_mode, from);
1036       if (GET_CODE (from) == REG && REGNO (from) < FIRST_PSEUDO_REGISTER
1037           && ! HARD_REGNO_MODE_OK (REGNO (from), to_mode))
1038         from = copy_to_reg (from);
1039       emit_move_insn (to, gen_lowpart (to_mode, from));
1040       return;
1041     }
1042
1043   /* Handle extension.  */
1044   if (GET_MODE_BITSIZE (to_mode) > GET_MODE_BITSIZE (from_mode))
1045     {
1046       /* Convert directly if that works.  */
1047       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
1048           != CODE_FOR_nothing)
1049         {
1050           emit_unop_insn (code, to, from, equiv_code);
1051           return;
1052         }
1053       else
1054         {
1055           enum machine_mode intermediate;
1056
1057           /* Search for a mode to convert via.  */
1058           for (intermediate = from_mode; intermediate != VOIDmode;
1059                intermediate = GET_MODE_WIDER_MODE (intermediate))
1060             if (((can_extend_p (to_mode, intermediate, unsignedp)
1061                   != CODE_FOR_nothing)
1062                  || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
1063                      && TRULY_NOOP_TRUNCATION (to_mode, intermediate)))
1064                 && (can_extend_p (intermediate, from_mode, unsignedp)
1065                     != CODE_FOR_nothing))
1066               {
1067                 convert_move (to, convert_to_mode (intermediate, from,
1068                                                    unsignedp), unsignedp);
1069                 return;
1070               }
1071
1072           /* No suitable intermediate mode.  */
1073           abort ();
1074         }
1075     }
1076
1077   /* Support special truncate insns for certain modes.  */ 
1078
1079   if (from_mode == DImode && to_mode == SImode)
1080     {
1081 #ifdef HAVE_truncdisi2
1082       if (HAVE_truncdisi2)
1083         {
1084           emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);
1085           return;
1086         }
1087 #endif
1088       convert_move (to, force_reg (from_mode, from), unsignedp);
1089       return;
1090     }
1091
1092   if (from_mode == DImode && to_mode == HImode)
1093     {
1094 #ifdef HAVE_truncdihi2
1095       if (HAVE_truncdihi2)
1096         {
1097           emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);
1098           return;
1099         }
1100 #endif
1101       convert_move (to, force_reg (from_mode, from), unsignedp);
1102       return;
1103     }
1104
1105   if (from_mode == DImode && to_mode == QImode)
1106     {
1107 #ifdef HAVE_truncdiqi2
1108       if (HAVE_truncdiqi2)
1109         {
1110           emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);
1111           return;
1112         }
1113 #endif
1114       convert_move (to, force_reg (from_mode, from), unsignedp);
1115       return;
1116     }
1117
1118   if (from_mode == SImode && to_mode == HImode)
1119     {
1120 #ifdef HAVE_truncsihi2
1121       if (HAVE_truncsihi2)
1122         {
1123           emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);
1124           return;
1125         }
1126 #endif
1127       convert_move (to, force_reg (from_mode, from), unsignedp);
1128       return;
1129     }
1130
1131   if (from_mode == SImode && to_mode == QImode)
1132     {
1133 #ifdef HAVE_truncsiqi2
1134       if (HAVE_truncsiqi2)
1135         {
1136           emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);
1137           return;
1138         }
1139 #endif
1140       convert_move (to, force_reg (from_mode, from), unsignedp);
1141       return;
1142     }
1143
1144   if (from_mode == HImode && to_mode == QImode)
1145     {
1146 #ifdef HAVE_trunchiqi2
1147       if (HAVE_trunchiqi2)
1148         {
1149           emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);
1150           return;
1151         }
1152 #endif
1153       convert_move (to, force_reg (from_mode, from), unsignedp);
1154       return;
1155     }
1156
1157   if (from_mode == TImode && to_mode == DImode)
1158     {
1159 #ifdef HAVE_trunctidi2
1160       if (HAVE_trunctidi2)
1161         {
1162           emit_unop_insn (CODE_FOR_trunctidi2, to, from, UNKNOWN);
1163           return;
1164         }
1165 #endif
1166       convert_move (to, force_reg (from_mode, from), unsignedp);
1167       return;
1168     }
1169
1170   if (from_mode == TImode && to_mode == SImode)
1171     {
1172 #ifdef HAVE_trunctisi2
1173       if (HAVE_trunctisi2)
1174         {
1175           emit_unop_insn (CODE_FOR_trunctisi2, to, from, UNKNOWN);
1176           return;
1177         }
1178 #endif
1179       convert_move (to, force_reg (from_mode, from), unsignedp);
1180       return;
1181     }
1182
1183   if (from_mode == TImode && to_mode == HImode)
1184     {
1185 #ifdef HAVE_trunctihi2
1186       if (HAVE_trunctihi2)
1187         {
1188           emit_unop_insn (CODE_FOR_trunctihi2, to, from, UNKNOWN);
1189           return;
1190         }
1191 #endif
1192       convert_move (to, force_reg (from_mode, from), unsignedp);
1193       return;
1194     }
1195
1196   if (from_mode == TImode && to_mode == QImode)
1197     {
1198 #ifdef HAVE_trunctiqi2
1199       if (HAVE_trunctiqi2)
1200         {
1201           emit_unop_insn (CODE_FOR_trunctiqi2, to, from, UNKNOWN);
1202           return;
1203         }
1204 #endif
1205       convert_move (to, force_reg (from_mode, from), unsignedp);
1206       return;
1207     }
1208
1209   /* Handle truncation of volatile memrefs, and so on;
1210      the things that couldn't be truncated directly,
1211      and for which there was no special instruction.  */
1212   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))
1213     {
1214       rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
1215       emit_move_insn (to, temp);
1216       return;
1217     }
1218
1219   /* Mode combination is not recognized.  */
1220   abort ();
1221 }
1222
1223 /* Return an rtx for a value that would result
1224    from converting X to mode MODE.
1225    Both X and MODE may be floating, or both integer.
1226    UNSIGNEDP is nonzero if X is an unsigned value.
1227    This can be done by referring to a part of X in place
1228    or by copying to a new temporary with conversion.
1229
1230    This function *must not* call protect_from_queue
1231    except when putting X into an insn (in which case convert_move does it).  */
1232
1233 rtx
1234 convert_to_mode (mode, x, unsignedp)
1235      enum machine_mode mode;
1236      rtx x;
1237      int unsignedp;
1238 {
1239   return convert_modes (mode, VOIDmode, x, unsignedp);
1240 }
1241
1242 /* Return an rtx for a value that would result
1243    from converting X from mode OLDMODE to mode MODE.
1244    Both modes may be floating, or both integer.
1245    UNSIGNEDP is nonzero if X is an unsigned value.
1246
1247    This can be done by referring to a part of X in place
1248    or by copying to a new temporary with conversion.
1249
1250    You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.
1251
1252    This function *must not* call protect_from_queue
1253    except when putting X into an insn (in which case convert_move does it).  */
1254
1255 rtx
1256 convert_modes (mode, oldmode, x, unsignedp)
1257      enum machine_mode mode, oldmode;
1258      rtx x;
1259      int unsignedp;
1260 {
1261   register rtx temp;
1262
1263   /* If FROM is a SUBREG that indicates that we have already done at least
1264      the required extension, strip it.  */
1265
1266   if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
1267       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode)
1268       && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp)
1269     x = gen_lowpart (mode, x);
1270
1271   if (GET_MODE (x) != VOIDmode)
1272     oldmode = GET_MODE (x);
1273  
1274   if (mode == oldmode)
1275     return x;
1276
1277   /* There is one case that we must handle specially: If we are converting
1278      a CONST_INT into a mode whose size is twice HOST_BITS_PER_WIDE_INT and
1279      we are to interpret the constant as unsigned, gen_lowpart will do
1280      the wrong if the constant appears negative.  What we want to do is
1281      make the high-order word of the constant zero, not all ones.  */
1282
1283   if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
1284       && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
1285       && GET_CODE (x) == CONST_INT && INTVAL (x) < 0)
1286     {
1287       HOST_WIDE_INT val = INTVAL (x);
1288
1289       if (oldmode != VOIDmode
1290           && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode))
1291         {
1292           int width = GET_MODE_BITSIZE (oldmode);
1293
1294           /* We need to zero extend VAL.  */
1295           val &= ((HOST_WIDE_INT) 1 << width) - 1;
1296         }
1297
1298       return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
1299     }
1300
1301   /* We can do this with a gen_lowpart if both desired and current modes
1302      are integer, and this is either a constant integer, a register, or a
1303      non-volatile MEM.  Except for the constant case where MODE is no
1304      wider than HOST_BITS_PER_WIDE_INT, we must be narrowing the operand.  */
1305
1306   if ((GET_CODE (x) == CONST_INT
1307        && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1308       || (GET_MODE_CLASS (mode) == MODE_INT
1309           && GET_MODE_CLASS (oldmode) == MODE_INT
1310           && (GET_CODE (x) == CONST_DOUBLE
1311               || (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (oldmode)
1312                   && ((GET_CODE (x) == MEM && ! MEM_VOLATILE_P (x)
1313                        && direct_load[(int) mode])
1314                       || (GET_CODE (x) == REG
1315                           && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1316                                                     GET_MODE_BITSIZE (GET_MODE (x)))))))))
1317     {
1318       /* ?? If we don't know OLDMODE, we have to assume here that
1319          X does not need sign- or zero-extension.   This may not be
1320          the case, but it's the best we can do.  */
1321       if (GET_CODE (x) == CONST_INT && oldmode != VOIDmode
1322           && GET_MODE_SIZE (mode) > GET_MODE_SIZE (oldmode))
1323         {
1324           HOST_WIDE_INT val = INTVAL (x);
1325           int width = GET_MODE_BITSIZE (oldmode);
1326
1327           /* We must sign or zero-extend in this case.  Start by
1328              zero-extending, then sign extend if we need to.  */
1329           val &= ((HOST_WIDE_INT) 1 << width) - 1;
1330           if (! unsignedp
1331               && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
1332             val |= (HOST_WIDE_INT) (-1) << width;
1333
1334           return GEN_INT (val);
1335         }
1336
1337       return gen_lowpart (mode, x);
1338     }
1339
1340   temp = gen_reg_rtx (mode);
1341   convert_move (temp, x, unsignedp);
1342   return temp;
1343 }
1344 \f
1345 /* Generate several move instructions to copy LEN bytes
1346    from block FROM to block TO.  (These are MEM rtx's with BLKmode).
1347    The caller must pass FROM and TO
1348     through protect_from_queue before calling.
1349    ALIGN (in bytes) is maximum alignment we can assume.  */
1350
1351 static void
1352 move_by_pieces (to, from, len, align)
1353      rtx to, from;
1354      int len, align;
1355 {
1356   struct move_by_pieces data;
1357   rtx to_addr = XEXP (to, 0), from_addr = XEXP (from, 0);
1358   int max_size = MOVE_MAX + 1;
1359
1360   data.offset = 0;
1361   data.to_addr = to_addr;
1362   data.from_addr = from_addr;
1363   data.to = to;
1364   data.from = from;
1365   data.autinc_to
1366     = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
1367        || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
1368   data.autinc_from
1369     = (GET_CODE (from_addr) == PRE_INC || GET_CODE (from_addr) == PRE_DEC
1370        || GET_CODE (from_addr) == POST_INC
1371        || GET_CODE (from_addr) == POST_DEC);
1372
1373   data.explicit_inc_from = 0;
1374   data.explicit_inc_to = 0;
1375   data.reverse
1376     = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
1377   if (data.reverse) data.offset = len;
1378   data.len = len;
1379
1380   data.to_struct = MEM_IN_STRUCT_P (to);
1381   data.from_struct = MEM_IN_STRUCT_P (from);
1382
1383   /* If copying requires more than two move insns,
1384      copy addresses to registers (to make displacements shorter)
1385      and use post-increment if available.  */
1386   if (!(data.autinc_from && data.autinc_to)
1387       && move_by_pieces_ninsns (len, align) > 2)
1388     {
1389 #ifdef HAVE_PRE_DECREMENT
1390       if (data.reverse && ! data.autinc_from)
1391         {
1392           data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
1393           data.autinc_from = 1;
1394           data.explicit_inc_from = -1;
1395         }
1396 #endif
1397 #ifdef HAVE_POST_INCREMENT
1398       if (! data.autinc_from)
1399         {
1400           data.from_addr = copy_addr_to_reg (from_addr);
1401           data.autinc_from = 1;
1402           data.explicit_inc_from = 1;
1403         }
1404 #endif
1405       if (!data.autinc_from && CONSTANT_P (from_addr))
1406         data.from_addr = copy_addr_to_reg (from_addr);
1407 #ifdef HAVE_PRE_DECREMENT
1408       if (data.reverse && ! data.autinc_to)
1409         {
1410           data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
1411           data.autinc_to = 1;
1412           data.explicit_inc_to = -1;
1413         }
1414 #endif
1415 #ifdef HAVE_POST_INCREMENT
1416       if (! data.reverse && ! data.autinc_to)
1417         {
1418           data.to_addr = copy_addr_to_reg (to_addr);
1419           data.autinc_to = 1;
1420           data.explicit_inc_to = 1;
1421         }
1422 #endif
1423       if (!data.autinc_to && CONSTANT_P (to_addr))
1424         data.to_addr = copy_addr_to_reg (to_addr);
1425     }
1426
1427   if (! SLOW_UNALIGNED_ACCESS
1428       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1429     align = MOVE_MAX;
1430
1431   /* First move what we can in the largest integer mode, then go to
1432      successively smaller modes.  */
1433
1434   while (max_size > 1)
1435     {
1436       enum machine_mode mode = VOIDmode, tmode;
1437       enum insn_code icode;
1438
1439       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1440            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
1441         if (GET_MODE_SIZE (tmode) < max_size)
1442           mode = tmode;
1443
1444       if (mode == VOIDmode)
1445         break;
1446
1447       icode = mov_optab->handlers[(int) mode].insn_code;
1448       if (icode != CODE_FOR_nothing
1449           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
1450                            GET_MODE_SIZE (mode)))
1451         move_by_pieces_1 (GEN_FCN (icode), mode, &data);
1452
1453       max_size = GET_MODE_SIZE (mode);
1454     }
1455
1456   /* The code above should have handled everything.  */
1457   if (data.len > 0)
1458     abort ();
1459 }
1460
1461 /* Return number of insns required to move L bytes by pieces.
1462    ALIGN (in bytes) is maximum alignment we can assume.  */
1463
1464 static int
1465 move_by_pieces_ninsns (l, align)
1466      unsigned int l;
1467      int align;
1468 {
1469   register int n_insns = 0;
1470   int max_size = MOVE_MAX + 1;
1471
1472   if (! SLOW_UNALIGNED_ACCESS
1473       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1474     align = MOVE_MAX;
1475
1476   while (max_size > 1)
1477     {
1478       enum machine_mode mode = VOIDmode, tmode;
1479       enum insn_code icode;
1480
1481       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1482            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
1483         if (GET_MODE_SIZE (tmode) < max_size)
1484           mode = tmode;
1485
1486       if (mode == VOIDmode)
1487         break;
1488
1489       icode = mov_optab->handlers[(int) mode].insn_code;
1490       if (icode != CODE_FOR_nothing
1491           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
1492                            GET_MODE_SIZE (mode)))
1493         n_insns += l / GET_MODE_SIZE (mode), l %= GET_MODE_SIZE (mode);
1494
1495       max_size = GET_MODE_SIZE (mode);
1496     }
1497
1498   return n_insns;
1499 }
1500
1501 /* Subroutine of move_by_pieces.  Move as many bytes as appropriate
1502    with move instructions for mode MODE.  GENFUN is the gen_... function
1503    to make a move insn for that mode.  DATA has all the other info.  */
1504
1505 static void
1506 move_by_pieces_1 (genfun, mode, data)
1507      rtx (*genfun) ();
1508      enum machine_mode mode;
1509      struct move_by_pieces *data;
1510 {
1511   register int size = GET_MODE_SIZE (mode);
1512   register rtx to1, from1;
1513
1514   while (data->len >= size)
1515     {
1516       if (data->reverse) data->offset -= size;
1517
1518       to1 = (data->autinc_to
1519              ? gen_rtx (MEM, mode, data->to_addr)
1520              : copy_rtx (change_address (data->to, mode,
1521                                          plus_constant (data->to_addr,
1522                                                         data->offset))));
1523       MEM_IN_STRUCT_P (to1) = data->to_struct;
1524
1525       from1
1526         = (data->autinc_from
1527            ? gen_rtx (MEM, mode, data->from_addr)
1528            : copy_rtx (change_address (data->from, mode,
1529                                        plus_constant (data->from_addr,
1530                                                       data->offset))));
1531       MEM_IN_STRUCT_P (from1) = data->from_struct;
1532
1533 #ifdef HAVE_PRE_DECREMENT
1534       if (data->explicit_inc_to < 0)
1535         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
1536       if (data->explicit_inc_from < 0)
1537         emit_insn (gen_add2_insn (data->from_addr, GEN_INT (-size)));
1538 #endif
1539
1540       emit_insn ((*genfun) (to1, from1));
1541 #ifdef HAVE_POST_INCREMENT
1542       if (data->explicit_inc_to > 0)
1543         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
1544       if (data->explicit_inc_from > 0)
1545         emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size)));
1546 #endif
1547
1548       if (! data->reverse) data->offset += size;
1549
1550       data->len -= size;
1551     }
1552 }
1553 \f
1554 /* Emit code to move a block Y to a block X.
1555    This may be done with string-move instructions,
1556    with multiple scalar move instructions, or with a library call.
1557
1558    Both X and Y must be MEM rtx's (perhaps inside VOLATILE)
1559    with mode BLKmode.
1560    SIZE is an rtx that says how long they are.
1561    ALIGN is the maximum alignment we can assume they have,
1562    measured in bytes.  */
1563
1564 void
1565 emit_block_move (x, y, size, align)
1566      rtx x, y;
1567      rtx size;
1568      int align;
1569 {
1570   if (GET_MODE (x) != BLKmode)
1571     abort ();
1572
1573   if (GET_MODE (y) != BLKmode)
1574     abort ();
1575
1576   x = protect_from_queue (x, 1);
1577   y = protect_from_queue (y, 0);
1578   size = protect_from_queue (size, 0);
1579
1580   if (GET_CODE (x) != MEM)
1581     abort ();
1582   if (GET_CODE (y) != MEM)
1583     abort ();
1584   if (size == 0)
1585     abort ();
1586
1587   if (GET_CODE (size) == CONST_INT
1588       && (move_by_pieces_ninsns (INTVAL (size), align) < MOVE_RATIO))
1589     move_by_pieces (x, y, INTVAL (size), align);
1590   else
1591     {
1592       /* Try the most limited insn first, because there's no point
1593          including more than one in the machine description unless
1594          the more limited one has some advantage.  */
1595
1596       rtx opalign = GEN_INT (align);
1597       enum machine_mode mode;
1598
1599       for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
1600            mode = GET_MODE_WIDER_MODE (mode))
1601         {
1602           enum insn_code code = movstr_optab[(int) mode];
1603
1604           if (code != CODE_FOR_nothing
1605               /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
1606                  here because if SIZE is less than the mode mask, as it is
1607                  returned by the macro, it will definitely be less than the
1608                  actual mode mask.  */
1609               && ((GET_CODE (size) == CONST_INT
1610                    && ((unsigned HOST_WIDE_INT) INTVAL (size)
1611                        <= GET_MODE_MASK (mode)))
1612                   || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
1613               && (insn_operand_predicate[(int) code][0] == 0
1614                   || (*insn_operand_predicate[(int) code][0]) (x, BLKmode))
1615               && (insn_operand_predicate[(int) code][1] == 0
1616                   || (*insn_operand_predicate[(int) code][1]) (y, BLKmode))
1617               && (insn_operand_predicate[(int) code][3] == 0
1618                   || (*insn_operand_predicate[(int) code][3]) (opalign,
1619                                                                VOIDmode)))
1620             {
1621               rtx op2;
1622               rtx last = get_last_insn ();
1623               rtx pat;
1624
1625               op2 = convert_to_mode (mode, size, 1);
1626               if (insn_operand_predicate[(int) code][2] != 0
1627                   && ! (*insn_operand_predicate[(int) code][2]) (op2, mode))
1628                 op2 = copy_to_mode_reg (mode, op2);
1629
1630               pat = GEN_FCN ((int) code) (x, y, op2, opalign);
1631               if (pat)
1632                 {
1633                   emit_insn (pat);
1634                   return;
1635                 }
1636               else
1637                 delete_insns_since (last);
1638             }
1639         }
1640
1641 #ifdef TARGET_MEM_FUNCTIONS
1642       emit_library_call (memcpy_libfunc, 0,
1643                          VOIDmode, 3, XEXP (x, 0), Pmode,
1644                          XEXP (y, 0), Pmode,
1645                          convert_to_mode (TYPE_MODE (sizetype), size,
1646                                           TREE_UNSIGNED (sizetype)),
1647                          TYPE_MODE (sizetype));
1648 #else
1649       emit_library_call (bcopy_libfunc, 0,
1650                          VOIDmode, 3, XEXP (y, 0), Pmode,
1651                          XEXP (x, 0), Pmode,
1652                          convert_to_mode (TYPE_MODE (integer_type_node), size,
1653                                           TREE_UNSIGNED (integer_type_node)),
1654                          TYPE_MODE (integer_type_node));
1655 #endif
1656     }
1657 }
1658 \f
1659 /* Copy all or part of a value X into registers starting at REGNO.
1660    The number of registers to be filled is NREGS.  */
1661
1662 void
1663 move_block_to_reg (regno, x, nregs, mode)
1664      int regno;
1665      rtx x;
1666      int nregs;
1667      enum machine_mode mode;
1668 {
1669   int i;
1670   rtx pat, last;
1671
1672   if (nregs == 0)
1673     return;
1674
1675   if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
1676     x = validize_mem (force_const_mem (mode, x));
1677
1678   /* See if the machine can do this with a load multiple insn.  */
1679 #ifdef HAVE_load_multiple
1680   if (HAVE_load_multiple)
1681     {
1682       last = get_last_insn ();
1683       pat = gen_load_multiple (gen_rtx (REG, word_mode, regno), x,
1684                                GEN_INT (nregs));
1685       if (pat)
1686         {
1687           emit_insn (pat);
1688           return;
1689         }
1690       else
1691         delete_insns_since (last);
1692     }
1693 #endif
1694
1695   for (i = 0; i < nregs; i++)
1696     emit_move_insn (gen_rtx (REG, word_mode, regno + i),
1697                     operand_subword_force (x, i, mode));
1698 }
1699
1700 /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
1701    The number of registers to be filled is NREGS.  SIZE indicates the number
1702    of bytes in the object X.  */
1703
1704
1705 void
1706 move_block_from_reg (regno, x, nregs, size)
1707      int regno;
1708      rtx x;
1709      int nregs;
1710      int size;
1711 {
1712   int i;
1713   rtx pat, last;
1714   enum machine_mode mode;
1715
1716   /* If SIZE is that of a mode no bigger than a word, just use that
1717      mode's store operation.  */
1718   if (size <= UNITS_PER_WORD
1719       && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode)
1720     {
1721       emit_move_insn (change_address (x, mode, NULL),
1722                       gen_rtx (REG, mode, regno));
1723       return;
1724     }
1725     
1726   /* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned
1727      to the left before storing to memory.  Note that the previous test
1728      doesn't handle all cases (e.g. SIZE == 3).  */
1729   if (size < UNITS_PER_WORD && BYTES_BIG_ENDIAN)
1730     {
1731       rtx tem = operand_subword (x, 0, 1, BLKmode);
1732       rtx shift;
1733
1734       if (tem == 0)
1735         abort ();
1736
1737       shift = expand_shift (LSHIFT_EXPR, word_mode,
1738                             gen_rtx (REG, word_mode, regno),
1739                             build_int_2 ((UNITS_PER_WORD - size)
1740                                          * BITS_PER_UNIT, 0), NULL_RTX, 0);
1741       emit_move_insn (tem, shift);
1742       return;
1743     }
1744
1745   /* See if the machine can do this with a store multiple insn.  */
1746 #ifdef HAVE_store_multiple
1747   if (HAVE_store_multiple)
1748     {
1749       last = get_last_insn ();
1750       pat = gen_store_multiple (x, gen_rtx (REG, word_mode, regno),
1751                                 GEN_INT (nregs));
1752       if (pat)
1753         {
1754           emit_insn (pat);
1755           return;
1756         }
1757       else
1758         delete_insns_since (last);
1759     }
1760 #endif
1761
1762   for (i = 0; i < nregs; i++)
1763     {
1764       rtx tem = operand_subword (x, i, 1, BLKmode);
1765
1766       if (tem == 0)
1767         abort ();
1768
1769       emit_move_insn (tem, gen_rtx (REG, word_mode, regno + i));
1770     }
1771 }
1772
1773 /* Emit code to move a block Y to a block X, where X is non-consecutive
1774    registers represented by a PARALLEL.  */
1775
1776 void
1777 emit_group_load (x, y)
1778      rtx x, y;
1779 {
1780   rtx target_reg, source;
1781   int i;
1782
1783   if (GET_CODE (x) != PARALLEL)
1784     abort ();
1785
1786   /* Check for a NULL entry, used to indicate that the parameter goes
1787      both on the stack and in registers.  */
1788   if (XEXP (XVECEXP (x, 0, 0), 0))
1789     i = 0;
1790   else
1791     i = 1;
1792
1793   for (; i < XVECLEN (x, 0); i++)
1794     {
1795       rtx element = XVECEXP (x, 0, i);
1796
1797       target_reg = XEXP (element, 0);
1798
1799       if (GET_CODE (y) == MEM)
1800         source = change_address (y, GET_MODE (target_reg),
1801                                  plus_constant (XEXP (y, 0),
1802                                                 INTVAL (XEXP (element, 1))));
1803       else if (XEXP (element, 1) == const0_rtx)
1804         {
1805           if (GET_MODE (target_reg) == GET_MODE (y))
1806             source = y;
1807           /* Allow for the target_reg to be smaller than the input register
1808              to allow for AIX with 4 DF arguments after a single SI arg.  The
1809              last DF argument will only load 1 word into the integer registers,
1810              but load a DF value into the float registers.  */
1811           else if ((GET_MODE_SIZE (GET_MODE (target_reg))
1812                     <= GET_MODE_SIZE (GET_MODE (y)))
1813                    && GET_MODE (target_reg) == word_mode)
1814             /* This might be a const_double, so we can't just use SUBREG.  */
1815             source = operand_subword (y, 0, 0, VOIDmode);
1816           else
1817             abort ();       
1818         }
1819       else
1820         abort ();
1821
1822       emit_move_insn (target_reg, source);
1823     }
1824 }
1825
1826 /* Emit code to move a block Y to a block X, where Y is non-consecutive
1827    registers represented by a PARALLEL.  */
1828
1829 void
1830 emit_group_store (x, y)
1831      rtx x, y;
1832 {
1833   rtx source_reg, target;
1834   int i;
1835
1836   if (GET_CODE (y) != PARALLEL)
1837     abort ();
1838
1839   /* Check for a NULL entry, used to indicate that the parameter goes
1840      both on the stack and in registers.  */
1841   if (XEXP (XVECEXP (y, 0, 0), 0))
1842     i = 0;
1843   else
1844     i = 1;
1845
1846   for (; i < XVECLEN (y, 0); i++)
1847     {
1848       rtx element = XVECEXP (y, 0, i);
1849
1850       source_reg = XEXP (element, 0);
1851
1852       if (GET_CODE (x) == MEM)
1853         target = change_address (x, GET_MODE (source_reg),
1854                                  plus_constant (XEXP (x, 0),
1855                                                 INTVAL (XEXP (element, 1))));
1856       else if (XEXP (element, 1) == const0_rtx)
1857         {
1858           target = x;
1859           if (GET_MODE (target) != GET_MODE (source_reg))
1860             target = gen_lowpart (GET_MODE (source_reg), target);
1861         }
1862       else
1863         abort ();
1864
1865       emit_move_insn (target, source_reg);
1866     }
1867 }
1868
1869 /* Add a USE expression for REG to the (possibly empty) list pointed
1870    to by CALL_FUSAGE.  REG must denote a hard register.  */
1871
1872 void
1873 use_reg (call_fusage, reg)
1874      rtx *call_fusage, reg;
1875 {
1876   if (GET_CODE (reg) != REG
1877       || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
1878     abort();
1879
1880   *call_fusage
1881     = gen_rtx (EXPR_LIST, VOIDmode,
1882                gen_rtx (USE, VOIDmode, reg), *call_fusage);
1883 }
1884
1885 /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
1886    starting at REGNO.  All of these registers must be hard registers.  */
1887
1888 void
1889 use_regs (call_fusage, regno, nregs)
1890      rtx *call_fusage;
1891      int regno;
1892      int nregs;
1893 {
1894   int i;
1895
1896   if (regno + nregs > FIRST_PSEUDO_REGISTER)
1897     abort ();
1898
1899   for (i = 0; i < nregs; i++)
1900     use_reg (call_fusage, gen_rtx (REG, reg_raw_mode[regno + i], regno + i));
1901 }
1902
1903 /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
1904    PARALLEL REGS.  This is for calls that pass values in multiple
1905    non-contiguous locations.  The Irix 6 ABI has examples of this.  */
1906
1907 void
1908 use_group_regs (call_fusage, regs)
1909      rtx *call_fusage;
1910      rtx regs;
1911 {
1912   int i;
1913
1914   /* Check for a NULL entry, used to indicate that the parameter goes
1915      both on the stack and in registers.  */
1916   if (XEXP (XVECEXP (regs, 0, 0), 0))
1917     i = 0;
1918   else
1919     i = 1;
1920
1921   for (; i < XVECLEN (regs, 0); i++)
1922     use_reg (call_fusage, XEXP (XVECEXP (regs, 0, i), 0));
1923 }
1924 \f
1925 /* Generate several move instructions to clear LEN bytes of block TO.
1926    (A MEM rtx with BLKmode).   The caller must pass TO through
1927    protect_from_queue before calling. ALIGN (in bytes) is maximum alignment
1928    we can assume.  */
1929
1930 static void
1931 clear_by_pieces (to, len, align)
1932      rtx to;
1933      int len, align;
1934 {
1935   struct clear_by_pieces data;
1936   rtx to_addr = XEXP (to, 0);
1937   int max_size = MOVE_MAX + 1;
1938
1939   data.offset = 0;
1940   data.to_addr = to_addr;
1941   data.to = to;
1942   data.autinc_to
1943     = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
1944        || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
1945
1946   data.explicit_inc_to = 0;
1947   data.reverse
1948     = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
1949   if (data.reverse) data.offset = len;
1950   data.len = len;
1951
1952   data.to_struct = MEM_IN_STRUCT_P (to);
1953
1954   /* If copying requires more than two move insns,
1955      copy addresses to registers (to make displacements shorter)
1956      and use post-increment if available.  */
1957   if (!data.autinc_to
1958       && move_by_pieces_ninsns (len, align) > 2)
1959     {
1960 #ifdef HAVE_PRE_DECREMENT
1961       if (data.reverse && ! data.autinc_to)
1962         {
1963           data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
1964           data.autinc_to = 1;
1965           data.explicit_inc_to = -1;
1966         }
1967 #endif
1968 #ifdef HAVE_POST_INCREMENT
1969       if (! data.reverse && ! data.autinc_to)
1970         {
1971           data.to_addr = copy_addr_to_reg (to_addr);
1972           data.autinc_to = 1;
1973           data.explicit_inc_to = 1;
1974         }
1975 #endif
1976       if (!data.autinc_to && CONSTANT_P (to_addr))
1977         data.to_addr = copy_addr_to_reg (to_addr);
1978     }
1979
1980   if (! SLOW_UNALIGNED_ACCESS
1981       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1982     align = MOVE_MAX;
1983
1984   /* First move what we can in the largest integer mode, then go to
1985      successively smaller modes.  */
1986
1987   while (max_size > 1)
1988     {
1989       enum machine_mode mode = VOIDmode, tmode;
1990       enum insn_code icode;
1991
1992       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1993            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
1994         if (GET_MODE_SIZE (tmode) < max_size)
1995           mode = tmode;
1996
1997       if (mode == VOIDmode)
1998         break;
1999
2000       icode = mov_optab->handlers[(int) mode].insn_code;
2001       if (icode != CODE_FOR_nothing
2002           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
2003                            GET_MODE_SIZE (mode)))
2004         clear_by_pieces_1 (GEN_FCN (icode), mode, &data);
2005
2006       max_size = GET_MODE_SIZE (mode);
2007     }
2008
2009   /* The code above should have handled everything.  */
2010   if (data.len != 0)
2011     abort ();
2012 }
2013
2014 /* Subroutine of clear_by_pieces.  Clear as many bytes as appropriate
2015    with move instructions for mode MODE.  GENFUN is the gen_... function
2016    to make a move insn for that mode.  DATA has all the other info.  */
2017
2018 static void
2019 clear_by_pieces_1 (genfun, mode, data)
2020      rtx (*genfun) ();
2021      enum machine_mode mode;
2022      struct clear_by_pieces *data;
2023 {
2024   register int size = GET_MODE_SIZE (mode);
2025   register rtx to1;
2026
2027   while (data->len >= size)
2028     {
2029       if (data->reverse) data->offset -= size;
2030
2031       to1 = (data->autinc_to
2032              ? gen_rtx (MEM, mode, data->to_addr)
2033              : copy_rtx (change_address (data->to, mode,
2034                                          plus_constant (data->to_addr,
2035                                                         data->offset))));
2036       MEM_IN_STRUCT_P (to1) = data->to_struct;
2037
2038 #ifdef HAVE_PRE_DECREMENT
2039       if (data->explicit_inc_to < 0)
2040         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
2041 #endif
2042
2043       emit_insn ((*genfun) (to1, const0_rtx));
2044 #ifdef HAVE_POST_INCREMENT
2045       if (data->explicit_inc_to > 0)
2046         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
2047 #endif
2048
2049       if (! data->reverse) data->offset += size;
2050
2051       data->len -= size;
2052     }
2053 }
2054 \f
2055 /* Write zeros through the storage of OBJECT.
2056    If OBJECT has BLKmode, SIZE is its length in bytes and ALIGN is
2057    the maximum alignment we can is has, measured in bytes.  */
2058
2059 void
2060 clear_storage (object, size, align)
2061      rtx object;
2062      rtx size;
2063      int align;
2064 {
2065   if (GET_MODE (object) == BLKmode)
2066     {
2067       object = protect_from_queue (object, 1);
2068       size = protect_from_queue (size, 0);
2069
2070       if (GET_CODE (size) == CONST_INT
2071           && (move_by_pieces_ninsns (INTVAL (size), align) < MOVE_RATIO))
2072         clear_by_pieces (object, INTVAL (size), align);
2073
2074       else
2075         {
2076           /* Try the most limited insn first, because there's no point
2077              including more than one in the machine description unless
2078              the more limited one has some advantage.  */
2079
2080           rtx opalign = GEN_INT (align);
2081           enum machine_mode mode;
2082
2083           for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
2084                mode = GET_MODE_WIDER_MODE (mode))
2085             {
2086               enum insn_code code = clrstr_optab[(int) mode];
2087
2088               if (code != CODE_FOR_nothing
2089                   /* We don't need MODE to be narrower than
2090                      BITS_PER_HOST_WIDE_INT here because if SIZE is less than
2091                      the mode mask, as it is returned by the macro, it will
2092                      definitely be less than the actual mode mask.  */
2093                   && ((GET_CODE (size) == CONST_INT
2094                        && ((unsigned HOST_WIDE_INT) INTVAL (size)
2095                            <= GET_MODE_MASK (mode)))
2096                       || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
2097                   && (insn_operand_predicate[(int) code][0] == 0
2098                       || (*insn_operand_predicate[(int) code][0]) (object,
2099                                                                    BLKmode))
2100                   && (insn_operand_predicate[(int) code][2] == 0
2101                       || (*insn_operand_predicate[(int) code][2]) (opalign,
2102                                                                    VOIDmode)))
2103                 {
2104                   rtx op1;
2105                   rtx last = get_last_insn ();
2106                   rtx pat;
2107
2108                   op1 = convert_to_mode (mode, size, 1);
2109                   if (insn_operand_predicate[(int) code][1] != 0
2110                       && ! (*insn_operand_predicate[(int) code][1]) (op1,
2111                                                                      mode))
2112                     op1 = copy_to_mode_reg (mode, op1);
2113
2114                   pat = GEN_FCN ((int) code) (object, op1, opalign);
2115                   if (pat)
2116                     {
2117                       emit_insn (pat);
2118                       return;
2119                     }
2120                   else
2121                     delete_insns_since (last);
2122                 }
2123             }
2124
2125
2126 #ifdef TARGET_MEM_FUNCTIONS
2127           emit_library_call (memset_libfunc, 0,
2128                              VOIDmode, 3,
2129                              XEXP (object, 0), Pmode,
2130                              const0_rtx, TYPE_MODE (integer_type_node),
2131                              convert_to_mode (TYPE_MODE (sizetype),
2132                                               size, TREE_UNSIGNED (sizetype)),
2133                              TYPE_MODE (sizetype));
2134 #else
2135           emit_library_call (bzero_libfunc, 0,
2136                              VOIDmode, 2,
2137                              XEXP (object, 0), Pmode,   
2138                              convert_to_mode (TYPE_MODE (integer_type_node),
2139                                               size,
2140                                               TREE_UNSIGNED (integer_type_node)),
2141                              TYPE_MODE (integer_type_node));
2142 #endif
2143         }
2144     }
2145   else
2146     emit_move_insn (object, const0_rtx);
2147 }
2148
2149 /* Generate code to copy Y into X.
2150    Both Y and X must have the same mode, except that
2151    Y can be a constant with VOIDmode.
2152    This mode cannot be BLKmode; use emit_block_move for that.
2153
2154    Return the last instruction emitted.  */
2155
2156 rtx
2157 emit_move_insn (x, y)
2158      rtx x, y;
2159 {
2160   enum machine_mode mode = GET_MODE (x);
2161
2162   x = protect_from_queue (x, 1);
2163   y = protect_from_queue (y, 0);
2164
2165   if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
2166     abort ();
2167
2168   if (CONSTANT_P (y) && ! LEGITIMATE_CONSTANT_P (y))
2169     y = force_const_mem (mode, y);
2170
2171   /* If X or Y are memory references, verify that their addresses are valid
2172      for the machine.  */
2173   if (GET_CODE (x) == MEM
2174       && ((! memory_address_p (GET_MODE (x), XEXP (x, 0))
2175            && ! push_operand (x, GET_MODE (x)))
2176           || (flag_force_addr
2177               && CONSTANT_ADDRESS_P (XEXP (x, 0)))))
2178     x = change_address (x, VOIDmode, XEXP (x, 0));
2179
2180   if (GET_CODE (y) == MEM
2181       && (! memory_address_p (GET_MODE (y), XEXP (y, 0))
2182           || (flag_force_addr
2183               && CONSTANT_ADDRESS_P (XEXP (y, 0)))))
2184     y = change_address (y, VOIDmode, XEXP (y, 0));
2185
2186   if (mode == BLKmode)
2187     abort ();
2188
2189   return emit_move_insn_1 (x, y);
2190 }
2191
2192 /* Low level part of emit_move_insn.
2193    Called just like emit_move_insn, but assumes X and Y
2194    are basically valid.  */
2195
2196 rtx
2197 emit_move_insn_1 (x, y)
2198      rtx x, y;
2199 {
2200   enum machine_mode mode = GET_MODE (x);
2201   enum machine_mode submode;
2202   enum mode_class class = GET_MODE_CLASS (mode);
2203   int i;
2204
2205   if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2206     return
2207       emit_insn (GEN_FCN (mov_optab->handlers[(int) mode].insn_code) (x, y));
2208
2209   /* Expand complex moves by moving real part and imag part, if possible.  */
2210   else if ((class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
2211            && BLKmode != (submode = mode_for_size ((GET_MODE_UNIT_SIZE (mode)
2212                                                     * BITS_PER_UNIT),
2213                                                    (class == MODE_COMPLEX_INT
2214                                                     ? MODE_INT : MODE_FLOAT),
2215                                                    0))
2216            && (mov_optab->handlers[(int) submode].insn_code
2217                != CODE_FOR_nothing))
2218     {
2219       /* Don't split destination if it is a stack push.  */
2220       int stack = push_operand (x, GET_MODE (x));
2221       rtx insns;
2222
2223       /* If this is a stack, push the highpart first, so it
2224          will be in the argument order.
2225
2226          In that case, change_address is used only to convert
2227          the mode, not to change the address.  */
2228       if (stack)
2229         {
2230           /* Note that the real part always precedes the imag part in memory
2231              regardless of machine's endianness.  */
2232 #ifdef STACK_GROWS_DOWNWARD
2233           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2234                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2235                       gen_imagpart (submode, y)));
2236           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2237                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2238                       gen_realpart (submode, y)));
2239 #else
2240           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2241                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2242                       gen_realpart (submode, y)));
2243           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2244                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2245                       gen_imagpart (submode, y)));
2246 #endif
2247         }
2248       else
2249         {
2250           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2251                      (gen_realpart (submode, x), gen_realpart (submode, y)));
2252           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2253                      (gen_imagpart (submode, x), gen_imagpart (submode, y)));
2254         }
2255
2256       return get_last_insn ();
2257     }
2258
2259   /* This will handle any multi-word mode that lacks a move_insn pattern.
2260      However, you will get better code if you define such patterns,
2261      even if they must turn into multiple assembler instructions.  */
2262   else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2263     {
2264       rtx last_insn = 0;
2265       rtx insns;
2266       
2267 #ifdef PUSH_ROUNDING
2268
2269       /* If X is a push on the stack, do the push now and replace
2270          X with a reference to the stack pointer.  */
2271       if (push_operand (x, GET_MODE (x)))
2272         {
2273           anti_adjust_stack (GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
2274           x = change_address (x, VOIDmode, stack_pointer_rtx);
2275         }
2276 #endif
2277                              
2278       /* Show the output dies here.  */
2279       if (x != y)
2280         emit_insn (gen_rtx (CLOBBER, VOIDmode, x));
2281
2282       for (i = 0;
2283            i < (GET_MODE_SIZE (mode)  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
2284            i++)
2285         {
2286           rtx xpart = operand_subword (x, i, 1, mode);
2287           rtx ypart = operand_subword (y, i, 1, mode);
2288
2289           /* If we can't get a part of Y, put Y into memory if it is a
2290              constant.  Otherwise, force it into a register.  If we still
2291              can't get a part of Y, abort.  */
2292           if (ypart == 0 && CONSTANT_P (y))
2293             {
2294               y = force_const_mem (mode, y);
2295               ypart = operand_subword (y, i, 1, mode);
2296             }
2297           else if (ypart == 0)
2298             ypart = operand_subword_force (y, i, mode);
2299
2300           if (xpart == 0 || ypart == 0)
2301             abort ();
2302
2303           last_insn = emit_move_insn (xpart, ypart);
2304         }
2305
2306       return last_insn;
2307     }
2308   else
2309     abort ();
2310 }
2311 \f
2312 /* Pushing data onto the stack.  */
2313
2314 /* Push a block of length SIZE (perhaps variable)
2315    and return an rtx to address the beginning of the block.
2316    Note that it is not possible for the value returned to be a QUEUED.
2317    The value may be virtual_outgoing_args_rtx.
2318
2319    EXTRA is the number of bytes of padding to push in addition to SIZE.
2320    BELOW nonzero means this padding comes at low addresses;
2321    otherwise, the padding comes at high addresses.  */
2322
2323 rtx
2324 push_block (size, extra, below)
2325      rtx size;
2326      int extra, below;
2327 {
2328   register rtx temp;
2329
2330   size = convert_modes (Pmode, ptr_mode, size, 1);
2331   if (CONSTANT_P (size))
2332     anti_adjust_stack (plus_constant (size, extra));
2333   else if (GET_CODE (size) == REG && extra == 0)
2334     anti_adjust_stack (size);
2335   else
2336     {
2337       rtx temp = copy_to_mode_reg (Pmode, size);
2338       if (extra != 0)
2339         temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra),
2340                              temp, 0, OPTAB_LIB_WIDEN);
2341       anti_adjust_stack (temp);
2342     }
2343
2344 #ifdef STACK_GROWS_DOWNWARD
2345   temp = virtual_outgoing_args_rtx;
2346   if (extra != 0 && below)
2347     temp = plus_constant (temp, extra);
2348 #else
2349   if (GET_CODE (size) == CONST_INT)
2350     temp = plus_constant (virtual_outgoing_args_rtx,
2351                           - INTVAL (size) - (below ? 0 : extra));
2352   else if (extra != 0 && !below)
2353     temp = gen_rtx (PLUS, Pmode, virtual_outgoing_args_rtx,
2354                     negate_rtx (Pmode, plus_constant (size, extra)));
2355   else
2356     temp = gen_rtx (PLUS, Pmode, virtual_outgoing_args_rtx,
2357                     negate_rtx (Pmode, size));
2358 #endif
2359
2360   return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
2361 }
2362
2363 rtx
2364 gen_push_operand ()
2365 {
2366   return gen_rtx (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
2367 }
2368
2369 /* Generate code to push X onto the stack, assuming it has mode MODE and
2370    type TYPE.
2371    MODE is redundant except when X is a CONST_INT (since they don't
2372    carry mode info).
2373    SIZE is an rtx for the size of data to be copied (in bytes),
2374    needed only if X is BLKmode.
2375
2376    ALIGN (in bytes) is maximum alignment we can assume.
2377
2378    If PARTIAL and REG are both nonzero, then copy that many of the first
2379    words of X into registers starting with REG, and push the rest of X.
2380    The amount of space pushed is decreased by PARTIAL words,
2381    rounded *down* to a multiple of PARM_BOUNDARY.
2382    REG must be a hard register in this case.
2383    If REG is zero but PARTIAL is not, take any all others actions for an
2384    argument partially in registers, but do not actually load any
2385    registers.
2386
2387    EXTRA is the amount in bytes of extra space to leave next to this arg.
2388    This is ignored if an argument block has already been allocated.
2389
2390    On a machine that lacks real push insns, ARGS_ADDR is the address of
2391    the bottom of the argument block for this call.  We use indexing off there
2392    to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
2393    argument block has not been preallocated.
2394
2395    ARGS_SO_FAR is the size of args previously pushed for this call.  */
2396
2397 void
2398 emit_push_insn (x, mode, type, size, align, partial, reg, extra,
2399                 args_addr, args_so_far)
2400      register rtx x;
2401      enum machine_mode mode;
2402      tree type;
2403      rtx size;
2404      int align;
2405      int partial;
2406      rtx reg;
2407      int extra;
2408      rtx args_addr;
2409      rtx args_so_far;
2410 {
2411   rtx xinner;
2412   enum direction stack_direction
2413 #ifdef STACK_GROWS_DOWNWARD
2414     = downward;
2415 #else
2416     = upward;
2417 #endif
2418
2419   /* Decide where to pad the argument: `downward' for below,
2420      `upward' for above, or `none' for don't pad it.
2421      Default is below for small data on big-endian machines; else above.  */
2422   enum direction where_pad = FUNCTION_ARG_PADDING (mode, type);
2423
2424   /* Invert direction if stack is post-update.  */
2425   if (STACK_PUSH_CODE == POST_INC || STACK_PUSH_CODE == POST_DEC)
2426     if (where_pad != none)
2427       where_pad = (where_pad == downward ? upward : downward);
2428
2429   xinner = x = protect_from_queue (x, 0);
2430
2431   if (mode == BLKmode)
2432     {
2433       /* Copy a block into the stack, entirely or partially.  */
2434
2435       register rtx temp;
2436       int used = partial * UNITS_PER_WORD;
2437       int offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
2438       int skip;
2439       
2440       if (size == 0)
2441         abort ();
2442
2443       used -= offset;
2444
2445       /* USED is now the # of bytes we need not copy to the stack
2446          because registers will take care of them.  */
2447
2448       if (partial != 0)
2449         xinner = change_address (xinner, BLKmode,
2450                                  plus_constant (XEXP (xinner, 0), used));
2451
2452       /* If the partial register-part of the arg counts in its stack size,
2453          skip the part of stack space corresponding to the registers.
2454          Otherwise, start copying to the beginning of the stack space,
2455          by setting SKIP to 0.  */
2456 #ifndef REG_PARM_STACK_SPACE
2457       skip = 0;
2458 #else
2459       skip = used;
2460 #endif
2461
2462 #ifdef PUSH_ROUNDING
2463       /* Do it with several push insns if that doesn't take lots of insns
2464          and if there is no difficulty with push insns that skip bytes
2465          on the stack for alignment purposes.  */
2466       if (args_addr == 0
2467           && GET_CODE (size) == CONST_INT
2468           && skip == 0
2469           && (move_by_pieces_ninsns ((unsigned) INTVAL (size) - used, align)
2470               < MOVE_RATIO)
2471           /* Here we avoid the case of a structure whose weak alignment
2472              forces many pushes of a small amount of data,
2473              and such small pushes do rounding that causes trouble.  */
2474           && ((! SLOW_UNALIGNED_ACCESS)
2475               || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT
2476               || PUSH_ROUNDING (align) == align)
2477           && PUSH_ROUNDING (INTVAL (size)) == INTVAL (size))
2478         {
2479           /* Push padding now if padding above and stack grows down,
2480              or if padding below and stack grows up.
2481              But if space already allocated, this has already been done.  */
2482           if (extra && args_addr == 0
2483               && where_pad != none && where_pad != stack_direction)
2484             anti_adjust_stack (GEN_INT (extra));
2485
2486           move_by_pieces (gen_rtx (MEM, BLKmode, gen_push_operand ()), xinner,
2487                           INTVAL (size) - used, align);
2488         }
2489       else
2490 #endif /* PUSH_ROUNDING */
2491         {
2492           /* Otherwise make space on the stack and copy the data
2493              to the address of that space.  */
2494
2495           /* Deduct words put into registers from the size we must copy.  */
2496           if (partial != 0)
2497             {
2498               if (GET_CODE (size) == CONST_INT)
2499                 size = GEN_INT (INTVAL (size) - used);
2500               else
2501                 size = expand_binop (GET_MODE (size), sub_optab, size,
2502                                      GEN_INT (used), NULL_RTX, 0,
2503                                      OPTAB_LIB_WIDEN);
2504             }
2505
2506           /* Get the address of the stack space.
2507              In this case, we do not deal with EXTRA separately.
2508              A single stack adjust will do.  */
2509           if (! args_addr)
2510             {
2511               temp = push_block (size, extra, where_pad == downward);
2512               extra = 0;
2513             }
2514           else if (GET_CODE (args_so_far) == CONST_INT)
2515             temp = memory_address (BLKmode,
2516                                    plus_constant (args_addr,
2517                                                   skip + INTVAL (args_so_far)));
2518           else
2519             temp = memory_address (BLKmode,
2520                                    plus_constant (gen_rtx (PLUS, Pmode,
2521                                                            args_addr, args_so_far),
2522                                                   skip));
2523
2524           /* TEMP is the address of the block.  Copy the data there.  */
2525           if (GET_CODE (size) == CONST_INT
2526               && (move_by_pieces_ninsns ((unsigned) INTVAL (size), align)
2527                   < MOVE_RATIO))
2528             {
2529               move_by_pieces (gen_rtx (MEM, BLKmode, temp), xinner,
2530                               INTVAL (size), align);
2531               goto ret;
2532             }
2533           /* Try the most limited insn first, because there's no point
2534              including more than one in the machine description unless
2535              the more limited one has some advantage.  */
2536 #ifdef HAVE_movstrqi
2537           if (HAVE_movstrqi
2538               && GET_CODE (size) == CONST_INT
2539               && ((unsigned) INTVAL (size)
2540                   < (1 << (GET_MODE_BITSIZE (QImode) - 1))))
2541             {
2542               rtx pat = gen_movstrqi (gen_rtx (MEM, BLKmode, temp),
2543                                       xinner, size, GEN_INT (align));
2544               if (pat != 0)
2545                 {
2546                   emit_insn (pat);
2547                   goto ret;
2548                 }
2549             }
2550 #endif
2551 #ifdef HAVE_movstrhi
2552           if (HAVE_movstrhi
2553               && GET_CODE (size) == CONST_INT
2554               && ((unsigned) INTVAL (size)
2555                   < (1 << (GET_MODE_BITSIZE (HImode) - 1))))
2556             {
2557               rtx pat = gen_movstrhi (gen_rtx (MEM, BLKmode, temp),
2558                                       xinner, size, GEN_INT (align));
2559               if (pat != 0)
2560                 {
2561                   emit_insn (pat);
2562                   goto ret;
2563                 }
2564             }
2565 #endif
2566 #ifdef HAVE_movstrsi
2567           if (HAVE_movstrsi)
2568             {
2569               rtx pat = gen_movstrsi (gen_rtx (MEM, BLKmode, temp),
2570                                       xinner, size, GEN_INT (align));
2571               if (pat != 0)
2572                 {
2573                   emit_insn (pat);
2574                   goto ret;
2575                 }
2576             }
2577 #endif
2578 #ifdef HAVE_movstrdi
2579           if (HAVE_movstrdi)
2580             {
2581               rtx pat = gen_movstrdi (gen_rtx (MEM, BLKmode, temp),
2582                                       xinner, size, GEN_INT (align));
2583               if (pat != 0)
2584                 {
2585                   emit_insn (pat);
2586                   goto ret;
2587                 }
2588             }
2589 #endif
2590
2591 #ifndef ACCUMULATE_OUTGOING_ARGS
2592           /* If the source is referenced relative to the stack pointer,
2593              copy it to another register to stabilize it.  We do not need
2594              to do this if we know that we won't be changing sp.  */
2595
2596           if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
2597               || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
2598             temp = copy_to_reg (temp);
2599 #endif
2600
2601           /* Make inhibit_defer_pop nonzero around the library call
2602              to force it to pop the bcopy-arguments right away.  */
2603           NO_DEFER_POP;
2604 #ifdef TARGET_MEM_FUNCTIONS
2605           emit_library_call (memcpy_libfunc, 0,
2606                              VOIDmode, 3, temp, Pmode, XEXP (xinner, 0), Pmode,
2607                              convert_to_mode (TYPE_MODE (sizetype),
2608                                               size, TREE_UNSIGNED (sizetype)),
2609                              TYPE_MODE (sizetype));
2610 #else
2611           emit_library_call (bcopy_libfunc, 0,
2612                              VOIDmode, 3, XEXP (xinner, 0), Pmode, temp, Pmode,
2613                              convert_to_mode (TYPE_MODE (integer_type_node),
2614                                               size,
2615                                               TREE_UNSIGNED (integer_type_node)),
2616                              TYPE_MODE (integer_type_node));
2617 #endif
2618           OK_DEFER_POP;
2619         }
2620     }
2621   else if (partial > 0)
2622     {
2623       /* Scalar partly in registers.  */
2624
2625       int size = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
2626       int i;
2627       int not_stack;
2628       /* # words of start of argument
2629          that we must make space for but need not store.  */
2630       int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
2631       int args_offset = INTVAL (args_so_far);
2632       int skip;
2633
2634       /* Push padding now if padding above and stack grows down,
2635          or if padding below and stack grows up.
2636          But if space already allocated, this has already been done.  */
2637       if (extra && args_addr == 0
2638           && where_pad != none && where_pad != stack_direction)
2639         anti_adjust_stack (GEN_INT (extra));
2640
2641       /* If we make space by pushing it, we might as well push
2642          the real data.  Otherwise, we can leave OFFSET nonzero
2643          and leave the space uninitialized.  */
2644       if (args_addr == 0)
2645         offset = 0;
2646
2647       /* Now NOT_STACK gets the number of words that we don't need to
2648          allocate on the stack.  */
2649       not_stack = partial - offset;
2650
2651       /* If the partial register-part of the arg counts in its stack size,
2652          skip the part of stack space corresponding to the registers.
2653          Otherwise, start copying to the beginning of the stack space,
2654          by setting SKIP to 0.  */
2655 #ifndef REG_PARM_STACK_SPACE
2656       skip = 0;
2657 #else
2658       skip = not_stack;
2659 #endif
2660
2661       if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
2662         x = validize_mem (force_const_mem (mode, x));
2663
2664       /* If X is a hard register in a non-integer mode, copy it into a pseudo;
2665          SUBREGs of such registers are not allowed.  */
2666       if ((GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER
2667            && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
2668         x = copy_to_reg (x);
2669
2670       /* Loop over all the words allocated on the stack for this arg.  */
2671       /* We can do it by words, because any scalar bigger than a word
2672          has a size a multiple of a word.  */
2673 #ifndef PUSH_ARGS_REVERSED
2674       for (i = not_stack; i < size; i++)
2675 #else
2676       for (i = size - 1; i >= not_stack; i--)
2677 #endif
2678         if (i >= not_stack + offset)
2679           emit_push_insn (operand_subword_force (x, i, mode),
2680                           word_mode, NULL_TREE, NULL_RTX, align, 0, NULL_RTX,
2681                           0, args_addr,
2682                           GEN_INT (args_offset + ((i - not_stack + skip)
2683                                                   * UNITS_PER_WORD)));
2684     }
2685   else
2686     {
2687       rtx addr;
2688
2689       /* Push padding now if padding above and stack grows down,
2690          or if padding below and stack grows up.
2691          But if space already allocated, this has already been done.  */
2692       if (extra && args_addr == 0
2693           && where_pad != none && where_pad != stack_direction)
2694         anti_adjust_stack (GEN_INT (extra));
2695
2696 #ifdef PUSH_ROUNDING
2697       if (args_addr == 0)
2698         addr = gen_push_operand ();
2699       else
2700 #endif
2701         if (GET_CODE (args_so_far) == CONST_INT)
2702           addr
2703             = memory_address (mode,
2704                               plus_constant (args_addr, INTVAL (args_so_far)));
2705       else
2706         addr = memory_address (mode, gen_rtx (PLUS, Pmode, args_addr,
2707                                               args_so_far));
2708
2709       emit_move_insn (gen_rtx (MEM, mode, addr), x);
2710     }
2711
2712  ret:
2713   /* If part should go in registers, copy that part
2714      into the appropriate registers.  Do this now, at the end,
2715      since mem-to-mem copies above may do function calls.  */
2716   if (partial > 0 && reg != 0)
2717     {
2718       /* Handle calls that pass values in multiple non-contiguous locations.
2719          The Irix 6 ABI has examples of this.  */
2720       if (GET_CODE (reg) == PARALLEL)
2721         emit_group_load (reg, x);
2722       else
2723         move_block_to_reg (REGNO (reg), x, partial, mode);
2724     }
2725
2726   if (extra && args_addr == 0 && where_pad == stack_direction)
2727     anti_adjust_stack (GEN_INT (extra));
2728 }
2729 \f
2730 /* Expand an assignment that stores the value of FROM into TO.
2731    If WANT_VALUE is nonzero, return an rtx for the value of TO.
2732    (This may contain a QUEUED rtx;
2733    if the value is constant, this rtx is a constant.)
2734    Otherwise, the returned value is NULL_RTX.
2735
2736    SUGGEST_REG is no longer actually used.
2737    It used to mean, copy the value through a register
2738    and return that register, if that is possible.
2739    We now use WANT_VALUE to decide whether to do this.  */
2740
2741 rtx
2742 expand_assignment (to, from, want_value, suggest_reg)
2743      tree to, from;
2744      int want_value;
2745      int suggest_reg;
2746 {
2747   register rtx to_rtx = 0;
2748   rtx result;
2749
2750   /* Don't crash if the lhs of the assignment was erroneous.  */
2751
2752   if (TREE_CODE (to) == ERROR_MARK)
2753     {
2754       result = expand_expr (from, NULL_RTX, VOIDmode, 0);
2755       return want_value ? result : NULL_RTX;
2756     }
2757
2758   if (output_bytecode)
2759     {
2760       tree dest_innermost;
2761
2762       bc_expand_expr (from);
2763       bc_emit_instruction (duplicate);
2764
2765       dest_innermost = bc_expand_address (to);
2766
2767       /* Can't deduce from TYPE that we're dealing with a bitfield, so
2768          take care of it here.  */
2769
2770       bc_store_memory (TREE_TYPE (to), dest_innermost);
2771       return NULL;
2772     }
2773
2774   /* Assignment of a structure component needs special treatment
2775      if the structure component's rtx is not simply a MEM.
2776      Assignment of an array element at a constant index, and assignment of
2777      an array element in an unaligned packed structure field, has the same
2778      problem.  */
2779
2780   if (TREE_CODE (to) == COMPONENT_REF
2781       || TREE_CODE (to) == BIT_FIELD_REF
2782       || (TREE_CODE (to) == ARRAY_REF
2783           && ((TREE_CODE (TREE_OPERAND (to, 1)) == INTEGER_CST
2784                && TREE_CODE (TYPE_SIZE (TREE_TYPE (to))) == INTEGER_CST)
2785               || (SLOW_UNALIGNED_ACCESS && get_inner_unaligned_p (to)))))
2786     {
2787       enum machine_mode mode1;
2788       int bitsize;
2789       int bitpos;
2790       tree offset;
2791       int unsignedp;
2792       int volatilep = 0;
2793       tree tem;
2794       int alignment;
2795
2796       push_temp_slots ();
2797       tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
2798                                  &unsignedp, &volatilep, &alignment);
2799
2800       /* If we are going to use store_bit_field and extract_bit_field,
2801          make sure to_rtx will be safe for multiple use.  */
2802
2803       if (mode1 == VOIDmode && want_value)
2804         tem = stabilize_reference (tem);
2805
2806       to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
2807       if (offset != 0)
2808         {
2809           rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
2810
2811           if (GET_CODE (to_rtx) != MEM)
2812             abort ();
2813           to_rtx = change_address (to_rtx, VOIDmode,
2814                                    gen_rtx (PLUS, ptr_mode, XEXP (to_rtx, 0),
2815                                             force_reg (ptr_mode, offset_rtx)));
2816         }
2817       if (volatilep)
2818         {
2819           if (GET_CODE (to_rtx) == MEM)
2820             {
2821               /* When the offset is zero, to_rtx is the address of the
2822                  structure we are storing into, and hence may be shared.
2823                  We must make a new MEM before setting the volatile bit.  */
2824               if (offset == 0)
2825                 to_rtx = copy_rtx (to_rtx);
2826
2827               MEM_VOLATILE_P (to_rtx) = 1;
2828             }
2829 #if 0  /* This was turned off because, when a field is volatile
2830           in an object which is not volatile, the object may be in a register,
2831           and then we would abort over here.  */
2832           else
2833             abort ();
2834 #endif
2835         }
2836
2837       result = store_field (to_rtx, bitsize, bitpos, mode1, from,
2838                             (want_value
2839                              /* Spurious cast makes HPUX compiler happy.  */
2840                              ? (enum machine_mode) TYPE_MODE (TREE_TYPE (to))
2841                              : VOIDmode),
2842                             unsignedp,
2843                             /* Required alignment of containing datum.  */
2844                             alignment,
2845                             int_size_in_bytes (TREE_TYPE (tem)));
2846       preserve_temp_slots (result);
2847       free_temp_slots ();
2848       pop_temp_slots ();
2849
2850       /* If the value is meaningful, convert RESULT to the proper mode.
2851          Otherwise, return nothing.  */
2852       return (want_value ? convert_modes (TYPE_MODE (TREE_TYPE (to)),
2853                                           TYPE_MODE (TREE_TYPE (from)),
2854                                           result,
2855                                           TREE_UNSIGNED (TREE_TYPE (to)))
2856               : NULL_RTX);
2857     }
2858
2859   /* If the rhs is a function call and its value is not an aggregate,
2860      call the function before we start to compute the lhs.
2861      This is needed for correct code for cases such as
2862      val = setjmp (buf) on machines where reference to val
2863      requires loading up part of an address in a separate insn.
2864
2865      Don't do this if TO is a VAR_DECL whose DECL_RTL is REG since it might be
2866      a promoted variable where the zero- or sign- extension needs to be done.
2867      Handling this in the normal way is safe because no computation is done
2868      before the call.  */
2869   if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from)
2870       && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
2871       && ! (TREE_CODE (to) == VAR_DECL && GET_CODE (DECL_RTL (to)) == REG))
2872     {
2873       rtx value;
2874
2875       push_temp_slots ();
2876       value = expand_expr (from, NULL_RTX, VOIDmode, 0);
2877       if (to_rtx == 0)
2878         to_rtx = expand_expr (to, NULL_RTX, VOIDmode, 0);
2879
2880       /* Handle calls that return values in multiple non-contiguous locations.
2881          The Irix 6 ABI has examples of this.  */
2882       if (GET_CODE (to_rtx) == PARALLEL)
2883         emit_group_load (to_rtx, value);
2884       else if (GET_MODE (to_rtx) == BLKmode)
2885         emit_block_move (to_rtx, value, expr_size (from),
2886                          TYPE_ALIGN (TREE_TYPE (from)) / BITS_PER_UNIT);
2887       else
2888         emit_move_insn (to_rtx, value);
2889       preserve_temp_slots (to_rtx);
2890       free_temp_slots ();
2891       pop_temp_slots ();
2892       return want_value ? to_rtx : NULL_RTX;
2893     }
2894
2895   /* Ordinary treatment.  Expand TO to get a REG or MEM rtx.
2896      Don't re-expand if it was expanded already (in COMPONENT_REF case).  */
2897
2898   if (to_rtx == 0)
2899     to_rtx = expand_expr (to, NULL_RTX, VOIDmode, 0);
2900
2901   /* Don't move directly into a return register.  */
2902   if (TREE_CODE (to) == RESULT_DECL && GET_CODE (to_rtx) == REG)
2903     {
2904       rtx temp;
2905
2906       push_temp_slots ();
2907       temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
2908       emit_move_insn (to_rtx, temp);
2909       preserve_temp_slots (to_rtx);
2910       free_temp_slots ();
2911       pop_temp_slots ();
2912       return want_value ? to_rtx : NULL_RTX;
2913     }
2914
2915   /* In case we are returning the contents of an object which overlaps
2916      the place the value is being stored, use a safe function when copying
2917      a value through a pointer into a structure value return block.  */
2918   if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF
2919       && current_function_returns_struct
2920       && !current_function_returns_pcc_struct)
2921     {
2922       rtx from_rtx, size;
2923
2924       push_temp_slots ();
2925       size = expr_size (from);
2926       from_rtx = expand_expr (from, NULL_RTX, VOIDmode, 0);
2927
2928 #ifdef TARGET_MEM_FUNCTIONS
2929       emit_library_call (memcpy_libfunc, 0,
2930                          VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
2931                          XEXP (from_rtx, 0), Pmode,
2932                          convert_to_mode (TYPE_MODE (sizetype),
2933                                           size, TREE_UNSIGNED (sizetype)),
2934                          TYPE_MODE (sizetype));
2935 #else
2936       emit_library_call (bcopy_libfunc, 0,
2937                          VOIDmode, 3, XEXP (from_rtx, 0), Pmode,
2938                          XEXP (to_rtx, 0), Pmode,
2939                          convert_to_mode (TYPE_MODE (integer_type_node),
2940                                           size, TREE_UNSIGNED (integer_type_node)),
2941                          TYPE_MODE (integer_type_node));
2942 #endif
2943
2944       preserve_temp_slots (to_rtx);
2945       free_temp_slots ();
2946       pop_temp_slots ();
2947       return want_value ? to_rtx : NULL_RTX;
2948     }
2949
2950   /* Compute FROM and store the value in the rtx we got.  */
2951
2952   push_temp_slots ();
2953   result = store_expr (from, to_rtx, want_value);
2954   preserve_temp_slots (result);
2955   free_temp_slots ();
2956   pop_temp_slots ();
2957   return want_value ? result : NULL_RTX;
2958 }
2959
2960 /* Generate code for computing expression EXP,
2961    and storing the value into TARGET.
2962    TARGET may contain a QUEUED rtx.
2963
2964    If WANT_VALUE is nonzero, return a copy of the value
2965    not in TARGET, so that we can be sure to use the proper
2966    value in a containing expression even if TARGET has something
2967    else stored in it.  If possible, we copy the value through a pseudo
2968    and return that pseudo.  Or, if the value is constant, we try to
2969    return the constant.  In some cases, we return a pseudo
2970    copied *from* TARGET.
2971
2972    If the mode is BLKmode then we may return TARGET itself.
2973    It turns out that in BLKmode it doesn't cause a problem.
2974    because C has no operators that could combine two different
2975    assignments into the same BLKmode object with different values
2976    with no sequence point.  Will other languages need this to
2977    be more thorough?
2978
2979    If WANT_VALUE is 0, we return NULL, to make sure
2980    to catch quickly any cases where the caller uses the value
2981    and fails to set WANT_VALUE.  */
2982
2983 rtx
2984 store_expr (exp, target, want_value)
2985      register tree exp;
2986      register rtx target;
2987      int want_value;
2988 {
2989   register rtx temp;
2990   int dont_return_target = 0;
2991
2992   if (TREE_CODE (exp) == COMPOUND_EXPR)
2993     {
2994       /* Perform first part of compound expression, then assign from second
2995          part.  */
2996       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
2997       emit_queue ();
2998       return store_expr (TREE_OPERAND (exp, 1), target, want_value);
2999     }
3000   else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
3001     {
3002       /* For conditional expression, get safe form of the target.  Then
3003          test the condition, doing the appropriate assignment on either
3004          side.  This avoids the creation of unnecessary temporaries.
3005          For non-BLKmode, it is more efficient not to do this.  */
3006
3007       rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
3008
3009       emit_queue ();
3010       target = protect_from_queue (target, 1);
3011
3012       do_pending_stack_adjust ();
3013       NO_DEFER_POP;
3014       jumpifnot (TREE_OPERAND (exp, 0), lab1);
3015       start_cleanup_deferal ();
3016       store_expr (TREE_OPERAND (exp, 1), target, 0);
3017       end_cleanup_deferal ();
3018       emit_queue ();
3019       emit_jump_insn (gen_jump (lab2));
3020       emit_barrier ();
3021       emit_label (lab1);
3022       start_cleanup_deferal ();
3023       store_expr (TREE_OPERAND (exp, 2), target, 0);
3024       end_cleanup_deferal ();
3025       emit_queue ();
3026       emit_label (lab2);
3027       OK_DEFER_POP;
3028
3029       return want_value ? target : NULL_RTX;
3030     }
3031   else if (want_value && GET_CODE (target) == MEM && ! MEM_VOLATILE_P (target)
3032            && GET_MODE (target) != BLKmode)
3033     /* If target is in memory and caller wants value in a register instead,
3034        arrange that.  Pass TARGET as target for expand_expr so that,
3035        if EXP is another assignment, WANT_VALUE will be nonzero for it.
3036        We know expand_expr will not use the target in that case.
3037        Don't do this if TARGET is volatile because we are supposed
3038        to write it and then read it.  */
3039     {
3040       temp = expand_expr (exp, cse_not_expected ? NULL_RTX : target,
3041                           GET_MODE (target), 0);
3042       if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
3043         temp = copy_to_reg (temp);
3044       dont_return_target = 1;
3045     }
3046   else if (queued_subexp_p (target))
3047     /* If target contains a postincrement, let's not risk
3048        using it as the place to generate the rhs.  */
3049     {
3050       if (GET_MODE (target) != BLKmode && GET_MODE (target) != VOIDmode)
3051         {
3052           /* Expand EXP into a new pseudo.  */
3053           temp = gen_reg_rtx (GET_MODE (target));
3054           temp = expand_expr (exp, temp, GET_MODE (target), 0);
3055         }
3056       else
3057         temp = expand_expr (exp, NULL_RTX, GET_MODE (target), 0);
3058
3059       /* If target is volatile, ANSI requires accessing the value
3060          *from* the target, if it is accessed.  So make that happen.
3061          In no case return the target itself.  */
3062       if (! MEM_VOLATILE_P (target) && want_value)
3063         dont_return_target = 1;
3064     }
3065   else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
3066     /* If this is an scalar in a register that is stored in a wider mode
3067        than the declared mode, compute the result into its declared mode
3068        and then convert to the wider mode.  Our value is the computed
3069        expression.  */
3070     {
3071       /* If we don't want a value, we can do the conversion inside EXP,
3072          which will often result in some optimizations.  Do the conversion
3073          in two steps: first change the signedness, if needed, then
3074          the extend.  But don't do this if the type of EXP is a subtype
3075          of something else since then the conversion might involve
3076          more than just converting modes.  */
3077       if (! want_value && INTEGRAL_TYPE_P (TREE_TYPE (exp))
3078           && TREE_TYPE (TREE_TYPE (exp)) == 0)
3079         {
3080           if (TREE_UNSIGNED (TREE_TYPE (exp))
3081               != SUBREG_PROMOTED_UNSIGNED_P (target))
3082             exp
3083               = convert
3084                 (signed_or_unsigned_type (SUBREG_PROMOTED_UNSIGNED_P (target),
3085                                           TREE_TYPE (exp)),
3086                  exp);
3087
3088           exp = convert (type_for_mode (GET_MODE (SUBREG_REG (target)),
3089                                         SUBREG_PROMOTED_UNSIGNED_P (target)),
3090                          exp);
3091         }
3092          
3093       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
3094
3095       /* If TEMP is a volatile MEM and we want a result value, make
3096          the access now so it gets done only once.  Likewise if
3097          it contains TARGET.  */
3098       if (GET_CODE (temp) == MEM && want_value
3099           && (MEM_VOLATILE_P (temp)
3100               || reg_mentioned_p (SUBREG_REG (target), XEXP (temp, 0))))
3101         temp = copy_to_reg (temp);
3102
3103       /* If TEMP is a VOIDmode constant, use convert_modes to make
3104          sure that we properly convert it.  */
3105       if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
3106         temp = convert_modes (GET_MODE (SUBREG_REG (target)),
3107                               TYPE_MODE (TREE_TYPE (exp)), temp,
3108                               SUBREG_PROMOTED_UNSIGNED_P (target));
3109
3110       convert_move (SUBREG_REG (target), temp,
3111                     SUBREG_PROMOTED_UNSIGNED_P (target));
3112       return want_value ? temp : NULL_RTX;
3113     }
3114   else
3115     {
3116       temp = expand_expr (exp, target, GET_MODE (target), 0);
3117       /* Return TARGET if it's a specified hardware register.
3118          If TARGET is a volatile mem ref, either return TARGET
3119          or return a reg copied *from* TARGET; ANSI requires this.
3120
3121          Otherwise, if TEMP is not TARGET, return TEMP
3122          if it is constant (for efficiency),
3123          or if we really want the correct value.  */
3124       if (!(target && GET_CODE (target) == REG
3125             && REGNO (target) < FIRST_PSEUDO_REGISTER)
3126           && !(GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
3127           && ! rtx_equal_p (temp, target)
3128           && (CONSTANT_P (temp) || want_value))
3129         dont_return_target = 1;
3130     }
3131
3132   /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
3133      the same as that of TARGET, adjust the constant.  This is needed, for
3134      example, in case it is a CONST_DOUBLE and we want only a word-sized
3135      value.  */
3136   if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
3137       && TREE_CODE (exp) != ERROR_MARK
3138       && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
3139     temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
3140                           temp, TREE_UNSIGNED (TREE_TYPE (exp)));
3141
3142   /* If value was not generated in the target, store it there.
3143      Convert the value to TARGET's type first if nec.  */
3144
3145   if (! rtx_equal_p (temp, target) && TREE_CODE (exp) != ERROR_MARK)
3146     {
3147       target = protect_from_queue (target, 1);
3148       if (GET_MODE (temp) != GET_MODE (target)
3149           && GET_MODE (temp) != VOIDmode)
3150         {
3151           int unsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
3152           if (dont_return_target)
3153             {
3154               /* In this case, we will return TEMP,
3155                  so make sure it has the proper mode.
3156                  But don't forget to store the value into TARGET.  */
3157               temp = convert_to_mode (GET_MODE (target), temp, unsignedp);
3158               emit_move_insn (target, temp);
3159             }
3160           else
3161             convert_move (target, temp, unsignedp);
3162         }
3163
3164       else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
3165         {
3166           /* Handle copying a string constant into an array.
3167              The string constant may be shorter than the array.
3168              So copy just the string's actual length, and clear the rest.  */
3169           rtx size;
3170           rtx addr;
3171
3172           /* Get the size of the data type of the string,
3173              which is actually the size of the target.  */
3174           size = expr_size (exp);
3175           if (GET_CODE (size) == CONST_INT
3176               && INTVAL (size) < TREE_STRING_LENGTH (exp))
3177             emit_block_move (target, temp, size,
3178                              TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
3179           else
3180             {
3181               /* Compute the size of the data to copy from the string.  */
3182               tree copy_size
3183                 = size_binop (MIN_EXPR,
3184                               make_tree (sizetype, size),
3185                               convert (sizetype,
3186                                        build_int_2 (TREE_STRING_LENGTH (exp), 0)));
3187               rtx copy_size_rtx = expand_expr (copy_size, NULL_RTX,
3188                                                VOIDmode, 0);
3189               rtx label = 0;
3190
3191               /* Copy that much.  */
3192               emit_block_move (target, temp, copy_size_rtx,
3193                                TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
3194
3195               /* Figure out how much is left in TARGET that we have to clear.
3196                  Do all calculations in ptr_mode.  */
3197
3198               addr = XEXP (target, 0);
3199               addr = convert_modes (ptr_mode, Pmode, addr, 1);
3200
3201               if (GET_CODE (copy_size_rtx) == CONST_INT)
3202                 {
3203                   addr = plus_constant (addr, TREE_STRING_LENGTH (exp));
3204                   size = plus_constant (size, - TREE_STRING_LENGTH (exp));
3205                 }
3206               else
3207                 {
3208                   addr = force_reg (ptr_mode, addr);
3209                   addr = expand_binop (ptr_mode, add_optab, addr,
3210                                        copy_size_rtx, NULL_RTX, 0,
3211                                        OPTAB_LIB_WIDEN);
3212
3213                   size = expand_binop (ptr_mode, sub_optab, size,
3214                                        copy_size_rtx, NULL_RTX, 0,
3215                                        OPTAB_LIB_WIDEN);
3216
3217                   emit_cmp_insn (size, const0_rtx, LT, NULL_RTX,
3218                                  GET_MODE (size), 0, 0);
3219                   label = gen_label_rtx ();
3220                   emit_jump_insn (gen_blt (label));
3221                 }
3222
3223               if (size != const0_rtx)
3224                 {
3225 #ifdef TARGET_MEM_FUNCTIONS
3226                   emit_library_call (memset_libfunc, 0, VOIDmode, 3,
3227                                      addr, ptr_mode,
3228                                      const0_rtx, TYPE_MODE (integer_type_node),
3229                                      convert_to_mode (TYPE_MODE (sizetype),
3230                                                       size,
3231                                                       TREE_UNSIGNED (sizetype)),
3232                                      TYPE_MODE (sizetype));
3233 #else
3234                   emit_library_call (bzero_libfunc, 0, VOIDmode, 2,
3235                                      addr, ptr_mode,
3236                                      convert_to_mode (TYPE_MODE (integer_type_node),
3237                                                       size,
3238                                                       TREE_UNSIGNED (integer_type_node)),
3239                                      TYPE_MODE (integer_type_node));
3240 #endif
3241                 }
3242
3243               if (label)
3244                 emit_label (label);
3245             }
3246         }
3247       /* Handle calls that return values in multiple non-contiguous locations.
3248          The Irix 6 ABI has examples of this.  */
3249       else if (GET_CODE (target) == PARALLEL)
3250         emit_group_load (target, temp);
3251       else if (GET_MODE (temp) == BLKmode)
3252         emit_block_move (target, temp, expr_size (exp),
3253                          TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
3254       else
3255         emit_move_insn (target, temp);
3256     }
3257
3258   /* If we don't want a value, return NULL_RTX.  */
3259   if (! want_value)
3260     return NULL_RTX;
3261
3262   /* If we are supposed to return TEMP, do so as long as it isn't a MEM.
3263      ??? The latter test doesn't seem to make sense.  */
3264   else if (dont_return_target && GET_CODE (temp) != MEM)
3265     return temp;
3266
3267   /* Return TARGET itself if it is a hard register.  */
3268   else if (want_value && GET_MODE (target) != BLKmode
3269            && ! (GET_CODE (target) == REG
3270                  && REGNO (target) < FIRST_PSEUDO_REGISTER))
3271     return copy_to_reg (target);
3272   
3273   else
3274     return target;
3275 }
3276 \f
3277 /* Return 1 if EXP just contains zeros.  */
3278
3279 static int
3280 is_zeros_p (exp)
3281      tree exp;
3282 {
3283   tree elt;
3284
3285   switch (TREE_CODE (exp))
3286     {
3287     case CONVERT_EXPR:
3288     case NOP_EXPR:
3289     case NON_LVALUE_EXPR:
3290       return is_zeros_p (TREE_OPERAND (exp, 0));
3291
3292     case INTEGER_CST:
3293       return TREE_INT_CST_LOW (exp) == 0 && TREE_INT_CST_HIGH (exp) == 0;
3294
3295     case COMPLEX_CST:
3296       return
3297         is_zeros_p (TREE_REALPART (exp)) && is_zeros_p (TREE_IMAGPART (exp));
3298
3299     case REAL_CST:
3300       return REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconst0);
3301
3302     case CONSTRUCTOR:
3303       if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
3304         return CONSTRUCTOR_ELTS (exp) == NULL_TREE;
3305       for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
3306         if (! is_zeros_p (TREE_VALUE (elt)))
3307           return 0;
3308
3309       return 1;
3310     }
3311
3312   return 0;
3313 }
3314
3315 /* Return 1 if EXP contains mostly (3/4)  zeros.  */
3316
3317 static int
3318 mostly_zeros_p (exp)
3319      tree exp;
3320 {
3321   if (TREE_CODE (exp) == CONSTRUCTOR)
3322     {
3323       int elts = 0, zeros = 0;
3324       tree elt = CONSTRUCTOR_ELTS (exp);
3325       if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
3326         {
3327           /* If there are no ranges of true bits, it is all zero.  */
3328           return elt == NULL_TREE;
3329         }
3330       for (; elt; elt = TREE_CHAIN (elt))
3331         {
3332           /* We do not handle the case where the index is a RANGE_EXPR,
3333              so the statistic will be somewhat inaccurate.
3334              We do make a more accurate count in store_constructor itself,
3335              so since this function is only used for nested array elements,
3336              this should be close enough.  */
3337           if (mostly_zeros_p (TREE_VALUE (elt)))
3338             zeros++;
3339           elts++;
3340         }
3341
3342       return 4 * zeros >= 3 * elts;
3343     }
3344
3345   return is_zeros_p (exp);
3346 }
3347 \f
3348 /* Helper function for store_constructor.
3349    TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
3350    TYPE is the type of the CONSTRUCTOR, not the element type.
3351    CLEARED is as for store_constructor.
3352
3353    This provides a recursive shortcut back to store_constructor when it isn't
3354    necessary to go through store_field.  This is so that we can pass through
3355    the cleared field to let store_constructor know that we may not have to
3356    clear a substructure if the outer structure has already been cleared.  */
3357
3358 static void
3359 store_constructor_field (target, bitsize, bitpos,
3360                          mode, exp, type, cleared)
3361      rtx target;
3362      int bitsize, bitpos;
3363      enum machine_mode mode;
3364      tree exp, type;
3365      int cleared;
3366 {
3367   if (TREE_CODE (exp) == CONSTRUCTOR
3368       && bitpos % BITS_PER_UNIT == 0
3369       /* If we have a non-zero bitpos for a register target, then we just
3370          let store_field do the bitfield handling.  This is unlikely to
3371          generate unnecessary clear instructions anyways.  */
3372       && (bitpos == 0 || GET_CODE (target) == MEM))
3373     {
3374       if (bitpos != 0)
3375         target = change_address (target, VOIDmode,
3376                                  plus_constant (XEXP (target, 0),
3377                                                 bitpos / BITS_PER_UNIT));
3378       store_constructor (exp, target, cleared);
3379     }
3380   else
3381     store_field (target, bitsize, bitpos, mode, exp,
3382                  VOIDmode, 0, TYPE_ALIGN (type) / BITS_PER_UNIT,
3383                  int_size_in_bytes (type));
3384 }
3385
3386 /* Store the value of constructor EXP into the rtx TARGET.
3387    TARGET is either a REG or a MEM.
3388    CLEARED is true if TARGET is known to have been zero'd.  */
3389
3390 static void
3391 store_constructor (exp, target, cleared)
3392      tree exp;
3393      rtx target;
3394      int cleared;
3395 {
3396   tree type = TREE_TYPE (exp);
3397
3398   /* We know our target cannot conflict, since safe_from_p has been called.  */
3399 #if 0
3400   /* Don't try copying piece by piece into a hard register
3401      since that is vulnerable to being clobbered by EXP.
3402      Instead, construct in a pseudo register and then copy it all.  */
3403   if (GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)
3404     {
3405       rtx temp = gen_reg_rtx (GET_MODE (target));
3406       store_constructor (exp, temp, 0);
3407       emit_move_insn (target, temp);
3408       return;
3409     }
3410 #endif
3411
3412   if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
3413       || TREE_CODE (type) == QUAL_UNION_TYPE)
3414     {
3415       register tree elt;
3416
3417       /* Inform later passes that the whole union value is dead.  */
3418       if (TREE_CODE (type) == UNION_TYPE
3419           || TREE_CODE (type) == QUAL_UNION_TYPE)
3420         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
3421
3422       /* If we are building a static constructor into a register,
3423          set the initial value as zero so we can fold the value into
3424          a constant.  But if more than one register is involved,
3425          this probably loses.  */
3426       else if (GET_CODE (target) == REG && TREE_STATIC (exp)
3427                && GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD)
3428         {
3429           if (! cleared)
3430             emit_move_insn (target, const0_rtx);
3431
3432           cleared = 1;
3433         }
3434
3435       /* If the constructor has fewer fields than the structure
3436          or if we are initializing the structure to mostly zeros,
3437          clear the whole structure first.  */
3438       else if ((list_length (CONSTRUCTOR_ELTS (exp))
3439                 != list_length (TYPE_FIELDS (type)))
3440                || mostly_zeros_p (exp))
3441         {
3442           if (! cleared)
3443             clear_storage (target, expr_size (exp),
3444                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3445
3446           cleared = 1;
3447         }
3448       else
3449         /* Inform later passes that the old value is dead.  */
3450         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
3451
3452       /* Store each element of the constructor into
3453          the corresponding field of TARGET.  */
3454
3455       for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
3456         {
3457           register tree field = TREE_PURPOSE (elt);
3458           register enum machine_mode mode;
3459           int bitsize;
3460           int bitpos = 0;
3461           int unsignedp;
3462           tree pos, constant = 0, offset = 0;
3463           rtx to_rtx = target;
3464
3465           /* Just ignore missing fields.
3466              We cleared the whole structure, above,
3467              if any fields are missing.  */
3468           if (field == 0)
3469             continue;
3470
3471           if (cleared && is_zeros_p (TREE_VALUE (elt)))
3472             continue;
3473
3474           bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
3475           unsignedp = TREE_UNSIGNED (field);
3476           mode = DECL_MODE (field);
3477           if (DECL_BIT_FIELD (field))
3478             mode = VOIDmode;
3479
3480           pos = DECL_FIELD_BITPOS (field);
3481           if (TREE_CODE (pos) == INTEGER_CST)
3482             constant = pos;
3483           else if (TREE_CODE (pos) == PLUS_EXPR
3484                    && TREE_CODE (TREE_OPERAND (pos, 1)) == INTEGER_CST)
3485             constant = TREE_OPERAND (pos, 1), offset = TREE_OPERAND (pos, 0);
3486           else
3487             offset = pos;
3488
3489           if (constant)
3490             bitpos = TREE_INT_CST_LOW (constant);
3491
3492           if (offset)
3493             {
3494               rtx offset_rtx;
3495
3496               if (contains_placeholder_p (offset))
3497                 offset = build (WITH_RECORD_EXPR, sizetype,
3498                                 offset, exp);
3499
3500               offset = size_binop (FLOOR_DIV_EXPR, offset,
3501                                    size_int (BITS_PER_UNIT));
3502
3503               offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
3504               if (GET_CODE (to_rtx) != MEM)
3505                 abort ();
3506
3507               to_rtx
3508                 = change_address (to_rtx, VOIDmode,
3509                                   gen_rtx (PLUS, ptr_mode, XEXP (to_rtx, 0),
3510                                            force_reg (ptr_mode, offset_rtx)));
3511             }
3512           if (TREE_READONLY (field))
3513             {
3514               if (GET_CODE (to_rtx) == MEM)
3515                 to_rtx = copy_rtx (to_rtx);
3516
3517               RTX_UNCHANGING_P (to_rtx) = 1;
3518             }
3519
3520           store_constructor_field (to_rtx, bitsize, bitpos,
3521                                    mode, TREE_VALUE (elt), type, cleared);
3522         }
3523     }
3524   else if (TREE_CODE (type) == ARRAY_TYPE)
3525     {
3526       register tree elt;
3527       register int i;
3528       int need_to_clear;
3529       tree domain = TYPE_DOMAIN (type);
3530       HOST_WIDE_INT minelt = TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain));
3531       HOST_WIDE_INT maxelt = TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain));
3532       tree elttype = TREE_TYPE (type);
3533
3534       /* If the constructor has fewer elements than the array,
3535          clear the whole array first.  Similarly if this this is
3536          static constructor of a non-BLKmode object.  */
3537       if (cleared || (GET_CODE (target) == REG && TREE_STATIC (exp)))
3538         need_to_clear = 1;
3539       else
3540         {
3541           HOST_WIDE_INT count = 0, zero_count = 0;
3542           need_to_clear = 0;
3543           /* This loop is a more accurate version of the loop in
3544              mostly_zeros_p (it handles RANGE_EXPR in an index).
3545              It is also needed to check for missing elements.  */
3546           for (elt = CONSTRUCTOR_ELTS (exp);
3547                elt != NULL_TREE;
3548                elt = TREE_CHAIN (elt))
3549             {
3550               tree index = TREE_PURPOSE (elt);
3551               HOST_WIDE_INT this_node_count;
3552               if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
3553                 {
3554                   tree lo_index = TREE_OPERAND (index, 0);
3555                   tree hi_index = TREE_OPERAND (index, 1);
3556                   if (TREE_CODE (lo_index) != INTEGER_CST
3557                       || TREE_CODE (hi_index) != INTEGER_CST)
3558                     {
3559                       need_to_clear = 1;
3560                       break;
3561                     }
3562                   this_node_count = TREE_INT_CST_LOW (hi_index)
3563                     - TREE_INT_CST_LOW (lo_index) + 1;
3564                 }
3565               else
3566                 this_node_count = 1;
3567               count += this_node_count;
3568               if (mostly_zeros_p (TREE_VALUE (elt)))
3569                 zero_count += this_node_count;
3570             }
3571           /* Clear the entire array first if there are any missing elements,
3572              or if the incidence of zero elements is >= 75%.  */
3573           if (count < maxelt - minelt + 1
3574               || 4 * zero_count >= 3 * count)
3575             need_to_clear = 1;
3576         }
3577       if (need_to_clear)
3578         {
3579           if (! cleared)
3580             clear_storage (target, expr_size (exp),
3581                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3582           cleared = 1;
3583         }
3584       else
3585         /* Inform later passes that the old value is dead.  */
3586         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
3587
3588       /* Store each element of the constructor into
3589          the corresponding element of TARGET, determined
3590          by counting the elements.  */
3591       for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
3592            elt;
3593            elt = TREE_CHAIN (elt), i++)
3594         {
3595           register enum machine_mode mode;
3596           int bitsize;
3597           int bitpos;
3598           int unsignedp;
3599           tree value = TREE_VALUE (elt);
3600           tree index = TREE_PURPOSE (elt);
3601           rtx xtarget = target;
3602
3603           if (cleared && is_zeros_p (value))
3604             continue;
3605
3606           mode = TYPE_MODE (elttype);
3607           bitsize = GET_MODE_BITSIZE (mode);
3608           unsignedp = TREE_UNSIGNED (elttype);
3609
3610           if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
3611             {
3612               tree lo_index = TREE_OPERAND (index, 0);
3613               tree hi_index = TREE_OPERAND (index, 1);
3614               rtx index_r, pos_rtx, addr, hi_r, loop_top, loop_end;
3615               struct nesting *loop;
3616               HOST_WIDE_INT lo, hi, count;
3617               tree position;
3618
3619               /* If the range is constant and "small", unroll the loop.  */
3620               if (TREE_CODE (lo_index) == INTEGER_CST
3621                   && TREE_CODE (hi_index) == INTEGER_CST
3622                   && (lo = TREE_INT_CST_LOW (lo_index),
3623                       hi = TREE_INT_CST_LOW (hi_index),
3624                       count = hi - lo + 1,
3625                       (GET_CODE (target) != MEM
3626                        || count <= 2
3627                        || (TREE_CODE (TYPE_SIZE (elttype)) == INTEGER_CST
3628                            && TREE_INT_CST_LOW (TYPE_SIZE (elttype)) * count
3629                            <= 40 * 8))))
3630                 {
3631                   lo -= minelt;  hi -= minelt;
3632                   for (; lo <= hi; lo++)
3633                     {
3634                       bitpos = lo * TREE_INT_CST_LOW (TYPE_SIZE (elttype));
3635                       store_constructor_field (target, bitsize, bitpos,
3636                                                mode, value, type, cleared);
3637                     }
3638                 }
3639               else
3640                 {
3641                   hi_r = expand_expr (hi_index, NULL_RTX, VOIDmode, 0);
3642                   loop_top = gen_label_rtx ();
3643                   loop_end = gen_label_rtx ();
3644
3645                   unsignedp = TREE_UNSIGNED (domain);
3646
3647                   index = build_decl (VAR_DECL, NULL_TREE, domain);
3648
3649                   DECL_RTL (index) = index_r
3650                     = gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
3651                                                  &unsignedp, 0));
3652
3653                   if (TREE_CODE (value) == SAVE_EXPR
3654                       && SAVE_EXPR_RTL (value) == 0)
3655                     {
3656                       /* Make sure value gets expanded once before the
3657                          loop.  */
3658                       expand_expr (value, const0_rtx, VOIDmode, 0);
3659                       emit_queue ();
3660                     }
3661                   store_expr (lo_index, index_r, 0);
3662                   loop = expand_start_loop (0);
3663
3664                   /* Assign value to element index.  */
3665                   position = size_binop (EXACT_DIV_EXPR, TYPE_SIZE (elttype),
3666                                          size_int (BITS_PER_UNIT));
3667                   position = size_binop (MULT_EXPR,
3668                                          size_binop (MINUS_EXPR, index,
3669                                                      TYPE_MIN_VALUE (domain)),
3670                                          position);
3671                   pos_rtx = expand_expr (position, 0, VOIDmode, 0);
3672                   addr = gen_rtx (PLUS, Pmode, XEXP (target, 0), pos_rtx);
3673                   xtarget = change_address (target, mode, addr);
3674                   if (TREE_CODE (value) == CONSTRUCTOR)
3675                     store_constructor (value, xtarget, cleared);
3676                   else
3677                     store_expr (value, xtarget, 0);
3678
3679                   expand_exit_loop_if_false (loop,
3680                                              build (LT_EXPR, integer_type_node,
3681                                                     index, hi_index));
3682
3683                   expand_increment (build (PREINCREMENT_EXPR,
3684                                            TREE_TYPE (index),
3685                                            index, integer_one_node), 0, 0);
3686                   expand_end_loop ();
3687                   emit_label (loop_end);
3688
3689                   /* Needed by stupid register allocation. to extend the
3690                      lifetime of pseudo-regs used by target past the end
3691                      of the loop.  */
3692                   emit_insn (gen_rtx (USE, GET_MODE (target), target));
3693                 }
3694             }
3695           else if ((index != 0 && TREE_CODE (index) != INTEGER_CST)
3696               || TREE_CODE (TYPE_SIZE (elttype)) != INTEGER_CST)
3697             {
3698               rtx pos_rtx, addr;
3699               tree position;
3700
3701               if (index == 0)
3702                 index = size_int (i);
3703
3704               if (minelt)
3705                 index = size_binop (MINUS_EXPR, index,
3706                                     TYPE_MIN_VALUE (domain));
3707               position = size_binop (EXACT_DIV_EXPR, TYPE_SIZE (elttype),
3708                                      size_int (BITS_PER_UNIT));
3709               position = size_binop (MULT_EXPR, index, position);
3710               pos_rtx = expand_expr (position, 0, VOIDmode, 0);
3711               addr = gen_rtx (PLUS, Pmode, XEXP (target, 0), pos_rtx);
3712               xtarget = change_address (target, mode, addr);
3713               store_expr (value, xtarget, 0);
3714             }
3715           else
3716             {
3717               if (index != 0)
3718                 bitpos = ((TREE_INT_CST_LOW (index) - minelt)
3719                           * TREE_INT_CST_LOW (TYPE_SIZE (elttype)));
3720               else
3721                 bitpos = (i * TREE_INT_CST_LOW (TYPE_SIZE (elttype)));
3722               store_constructor_field (target, bitsize, bitpos,
3723                                        mode, value, type, cleared);
3724             }
3725         }
3726     }
3727   /* set constructor assignments */
3728   else if (TREE_CODE (type) == SET_TYPE)
3729     {
3730       tree elt = CONSTRUCTOR_ELTS (exp);
3731       rtx xtarget = XEXP (target, 0);
3732       int set_word_size = TYPE_ALIGN (type);
3733       int nbytes = int_size_in_bytes (type), nbits;
3734       tree domain = TYPE_DOMAIN (type);
3735       tree domain_min, domain_max, bitlength;
3736
3737       /* The default implementation strategy is to extract the constant
3738          parts of the constructor, use that to initialize the target,
3739          and then "or" in whatever non-constant ranges we need in addition.
3740
3741          If a large set is all zero or all ones, it is
3742          probably better to set it using memset (if available) or bzero.
3743          Also, if a large set has just a single range, it may also be
3744          better to first clear all the first clear the set (using
3745          bzero/memset), and set the bits we want.  */
3746        
3747       /* Check for all zeros.  */
3748       if (elt == NULL_TREE)
3749         {
3750           if (!cleared)
3751             clear_storage (target, expr_size (exp),
3752                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3753           return;
3754         }
3755
3756       domain_min = convert (sizetype, TYPE_MIN_VALUE (domain));
3757       domain_max = convert (sizetype, TYPE_MAX_VALUE (domain));
3758       bitlength = size_binop (PLUS_EXPR,
3759                               size_binop (MINUS_EXPR, domain_max, domain_min),
3760                               size_one_node);
3761
3762       if (nbytes < 0 || TREE_CODE (bitlength) != INTEGER_CST)
3763         abort ();
3764       nbits = TREE_INT_CST_LOW (bitlength);
3765
3766       /* For "small" sets, or "medium-sized" (up to 32 bytes) sets that
3767          are "complicated" (more than one range), initialize (the
3768          constant parts) by copying from a constant.  */         
3769       if (GET_MODE (target) != BLKmode || nbits <= 2 * BITS_PER_WORD
3770           || (nbytes <= 32 && TREE_CHAIN (elt) != NULL_TREE))
3771         {
3772           int set_word_size = TYPE_ALIGN (TREE_TYPE (exp));
3773           enum machine_mode mode = mode_for_size (set_word_size, MODE_INT, 1);
3774           char *bit_buffer = (char *) alloca (nbits);
3775           HOST_WIDE_INT word = 0;
3776           int bit_pos = 0;
3777           int ibit = 0;
3778           int offset = 0;  /* In bytes from beginning of set.  */
3779           elt = get_set_constructor_bits (exp, bit_buffer, nbits);
3780           for (;;)
3781             {
3782               if (bit_buffer[ibit])
3783                 {
3784                   if (BYTES_BIG_ENDIAN)
3785                     word |= (1 << (set_word_size - 1 - bit_pos));
3786                   else
3787                     word |= 1 << bit_pos;
3788                 }
3789               bit_pos++;  ibit++;
3790               if (bit_pos >= set_word_size || ibit == nbits)
3791                 {
3792                   if (word != 0 || ! cleared)
3793                     {
3794                       rtx datum = GEN_INT (word);
3795                       rtx to_rtx;
3796                       /* The assumption here is that it is safe to use
3797                          XEXP if the set is multi-word, but not if
3798                          it's single-word.  */
3799                       if (GET_CODE (target) == MEM)
3800                         {
3801                           to_rtx = plus_constant (XEXP (target, 0), offset);
3802                           to_rtx = change_address (target, mode, to_rtx);
3803                         }
3804                       else if (offset == 0) 
3805                         to_rtx = target;
3806                       else
3807                         abort ();
3808                       emit_move_insn (to_rtx, datum);
3809                     }
3810                   if (ibit == nbits)
3811                     break;
3812                   word = 0;
3813                   bit_pos = 0;
3814                   offset += set_word_size / BITS_PER_UNIT;
3815                 }
3816             }
3817         }
3818       else if (!cleared)
3819         {
3820           /* Don't bother clearing storage if the set is all ones.  */
3821           if (TREE_CHAIN (elt) != NULL_TREE
3822               || (TREE_PURPOSE (elt) == NULL_TREE
3823                   ? nbits != 1
3824                   : (TREE_CODE (TREE_VALUE (elt)) != INTEGER_CST
3825                      || TREE_CODE (TREE_PURPOSE (elt)) != INTEGER_CST
3826                      || (TREE_INT_CST_LOW (TREE_VALUE (elt))
3827                          - TREE_INT_CST_LOW (TREE_PURPOSE (elt)) + 1
3828                          != nbits))))
3829             clear_storage (target, expr_size (exp),
3830                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3831         }
3832           
3833       for (; elt != NULL_TREE; elt = TREE_CHAIN (elt))
3834         {
3835           /* start of range of element or NULL */
3836           tree startbit = TREE_PURPOSE (elt);
3837           /* end of range of element, or element value */
3838           tree endbit   = TREE_VALUE (elt);
3839           HOST_WIDE_INT startb, endb;
3840           rtx  bitlength_rtx, startbit_rtx, endbit_rtx, targetx;
3841
3842           bitlength_rtx = expand_expr (bitlength,
3843                             NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
3844
3845           /* handle non-range tuple element like [ expr ]  */
3846           if (startbit == NULL_TREE)
3847             {
3848               startbit = save_expr (endbit);
3849               endbit = startbit;
3850             }
3851           startbit = convert (sizetype, startbit);
3852           endbit = convert (sizetype, endbit);
3853           if (! integer_zerop (domain_min))
3854             {
3855               startbit = size_binop (MINUS_EXPR, startbit, domain_min);
3856               endbit = size_binop (MINUS_EXPR, endbit, domain_min);
3857             }
3858           startbit_rtx = expand_expr (startbit, NULL_RTX, MEM, 
3859                                       EXPAND_CONST_ADDRESS);
3860           endbit_rtx = expand_expr (endbit, NULL_RTX, MEM, 
3861                                     EXPAND_CONST_ADDRESS);
3862
3863           if (REG_P (target))
3864             {
3865               targetx = assign_stack_temp (GET_MODE (target),
3866                                            GET_MODE_SIZE (GET_MODE (target)),
3867                                            0);
3868               emit_move_insn (targetx, target);
3869             }
3870           else if (GET_CODE (target) == MEM)
3871             targetx = target;
3872           else
3873             abort ();
3874
3875 #ifdef TARGET_MEM_FUNCTIONS
3876           /* Optimization:  If startbit and endbit are
3877              constants divisible by BITS_PER_UNIT,
3878              call memset instead.  */
3879           if (TREE_CODE (startbit) == INTEGER_CST
3880               && TREE_CODE (endbit) == INTEGER_CST
3881               && (startb = TREE_INT_CST_LOW (startbit)) % BITS_PER_UNIT == 0
3882               && (endb = TREE_INT_CST_LOW (endbit) + 1) % BITS_PER_UNIT == 0)
3883             {
3884               emit_library_call (memset_libfunc, 0,
3885                                  VOIDmode, 3,
3886                                  plus_constant (XEXP (targetx, 0),
3887                                                 startb / BITS_PER_UNIT),
3888                                  Pmode,
3889                                  constm1_rtx, TYPE_MODE (integer_type_node),
3890                                  GEN_INT ((endb - startb) / BITS_PER_UNIT),
3891                                  TYPE_MODE (sizetype));
3892             }
3893           else
3894 #endif
3895             {
3896               emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__setbits"),
3897                                  0, VOIDmode, 4, XEXP (targetx, 0), Pmode,
3898                                  bitlength_rtx, TYPE_MODE (sizetype),
3899                                  startbit_rtx, TYPE_MODE (sizetype),
3900                                  endbit_rtx, TYPE_MODE (sizetype));
3901             }
3902           if (REG_P (target))
3903             emit_move_insn (target, targetx);
3904         }
3905     }
3906
3907   else
3908     abort ();
3909 }
3910
3911 /* Store the value of EXP (an expression tree)
3912    into a subfield of TARGET which has mode MODE and occupies
3913    BITSIZE bits, starting BITPOS bits from the start of TARGET.
3914    If MODE is VOIDmode, it means that we are storing into a bit-field.
3915
3916    If VALUE_MODE is VOIDmode, return nothing in particular.
3917    UNSIGNEDP is not used in this case.
3918
3919    Otherwise, return an rtx for the value stored.  This rtx
3920    has mode VALUE_MODE if that is convenient to do.
3921    In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
3922
3923    ALIGN is the alignment that TARGET is known to have, measured in bytes.
3924    TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.  */
3925
3926 static rtx
3927 store_field (target, bitsize, bitpos, mode, exp, value_mode,
3928              unsignedp, align, total_size)
3929      rtx target;
3930      int bitsize, bitpos;
3931      enum machine_mode mode;
3932      tree exp;
3933      enum machine_mode value_mode;
3934      int unsignedp;
3935      int align;
3936      int total_size;
3937 {
3938   HOST_WIDE_INT width_mask = 0;
3939
3940   if (bitsize < HOST_BITS_PER_WIDE_INT)
3941     width_mask = ((HOST_WIDE_INT) 1 << bitsize) - 1;
3942
3943   /* If we are storing into an unaligned field of an aligned union that is
3944      in a register, we may have the mode of TARGET being an integer mode but
3945      MODE == BLKmode.  In that case, get an aligned object whose size and
3946      alignment are the same as TARGET and store TARGET into it (we can avoid
3947      the store if the field being stored is the entire width of TARGET).  Then
3948      call ourselves recursively to store the field into a BLKmode version of
3949      that object.  Finally, load from the object into TARGET.  This is not
3950      very efficient in general, but should only be slightly more expensive
3951      than the otherwise-required unaligned accesses.  Perhaps this can be
3952      cleaned up later.  */
3953
3954   if (mode == BLKmode
3955       && (GET_CODE (target) == REG || GET_CODE (target) == SUBREG))
3956     {
3957       rtx object = assign_stack_temp (GET_MODE (target),
3958                                       GET_MODE_SIZE (GET_MODE (target)), 0);
3959       rtx blk_object = copy_rtx (object);
3960
3961       MEM_IN_STRUCT_P (object) = 1;
3962       MEM_IN_STRUCT_P (blk_object) = 1;
3963       PUT_MODE (blk_object, BLKmode);
3964
3965       if (bitsize != GET_MODE_BITSIZE (GET_MODE (target)))
3966         emit_move_insn (object, target);
3967
3968       store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0,
3969                    align, total_size);
3970
3971       /* Even though we aren't returning target, we need to
3972          give it the updated value.  */
3973       emit_move_insn (target, object);
3974
3975       return blk_object;
3976     }
3977
3978   /* If the structure is in a register or if the component
3979      is a bit field, we cannot use addressing to access it.
3980      Use bit-field techniques or SUBREG to store in it.  */
3981
3982   if (mode == VOIDmode
3983       || (mode != BLKmode && ! direct_store[(int) mode])
3984       || GET_CODE (target) == REG
3985       || GET_CODE (target) == SUBREG
3986       /* If the field isn't aligned enough to store as an ordinary memref,
3987          store it as a bit field.  */
3988       || (SLOW_UNALIGNED_ACCESS
3989           && align * BITS_PER_UNIT < GET_MODE_ALIGNMENT (mode))
3990       || (SLOW_UNALIGNED_ACCESS && bitpos % GET_MODE_ALIGNMENT (mode) != 0))
3991     {
3992       rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
3993
3994       /* If BITSIZE is narrower than the size of the type of EXP
3995          we will be narrowing TEMP.  Normally, what's wanted are the
3996          low-order bits.  However, if EXP's type is a record and this is
3997          big-endian machine, we want the upper BITSIZE bits.  */
3998       if (BYTES_BIG_ENDIAN && GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
3999           && bitsize < GET_MODE_BITSIZE (GET_MODE (temp))
4000           && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
4001         temp = expand_shift (RSHIFT_EXPR, GET_MODE (temp), temp,
4002                              size_int (GET_MODE_BITSIZE (GET_MODE (temp))
4003                                        - bitsize),
4004                              temp, 1);
4005
4006       /* Unless MODE is VOIDmode or BLKmode, convert TEMP to
4007          MODE.  */
4008       if (mode != VOIDmode && mode != BLKmode
4009           && mode != TYPE_MODE (TREE_TYPE (exp)))
4010         temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
4011
4012       /* If the modes of TARGET and TEMP are both BLKmode, both
4013          must be in memory and BITPOS must be aligned on a byte
4014          boundary.  If so, we simply do a block copy.  */
4015       if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode)
4016         {
4017           if (GET_CODE (target) != MEM || GET_CODE (temp) != MEM
4018               || bitpos % BITS_PER_UNIT != 0)
4019             abort ();
4020
4021           target = change_address (target, VOIDmode,
4022                                    plus_constant (XEXP (target, 0),
4023                                                 bitpos / BITS_PER_UNIT));
4024
4025           emit_block_move (target, temp,
4026                            GEN_INT ((bitsize + BITS_PER_UNIT - 1)
4027                                     / BITS_PER_UNIT),
4028                            1);
4029
4030           return value_mode == VOIDmode ? const0_rtx : target;
4031         }
4032
4033       /* Store the value in the bitfield.  */
4034       store_bit_field (target, bitsize, bitpos, mode, temp, align, total_size);
4035       if (value_mode != VOIDmode)
4036         {
4037           /* The caller wants an rtx for the value.  */
4038           /* If possible, avoid refetching from the bitfield itself.  */
4039          &nbs