OSDN Git Service

Remove CYGNUS LOCAL tags.
[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, 1996 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 "function.h"
31 #include "insn-flags.h"
32 #include "insn-codes.h"
33 #include "expr.h"
34 #include "insn-config.h"
35 #include "recog.h"
36 #include "output.h"
37 #include "typeclass.h"
38
39 #include "bytecode.h"
40 #include "bc-opcode.h"
41 #include "bc-typecd.h"
42 #include "bc-optab.h"
43 #include "bc-emit.h"
44
45
46 #define CEIL(x,y) (((x) + (y) - 1) / (y))
47
48 /* Decide whether a function's arguments should be processed
49    from first to last or from last to first.
50
51    They should if the stack and args grow in opposite directions, but
52    only if we have push insns.  */
53
54 #ifdef PUSH_ROUNDING
55
56 #if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
57 #define PUSH_ARGS_REVERSED      /* If it's last to first */
58 #endif
59
60 #endif
61
62 #ifndef STACK_PUSH_CODE
63 #ifdef STACK_GROWS_DOWNWARD
64 #define STACK_PUSH_CODE PRE_DEC
65 #else
66 #define STACK_PUSH_CODE PRE_INC
67 #endif
68 #endif
69
70 /* Like STACK_BOUNDARY but in units of bytes, not bits.  */
71 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
72
73 /* If this is nonzero, we do not bother generating VOLATILE
74    around volatile memory references, and we are willing to
75    output indirect addresses.  If cse is to follow, we reject
76    indirect addresses so a useful potential cse is generated;
77    if it is used only once, instruction combination will produce
78    the same indirect address eventually.  */
79 int cse_not_expected;
80
81 /* Nonzero to generate code for all the subroutines within an
82    expression before generating the upper levels of the expression.
83    Nowadays this is never zero.  */
84 int do_preexpand_calls = 1;
85
86 /* Number of units that we should eventually pop off the stack.
87    These are the arguments to function calls that have already returned.  */
88 int pending_stack_adjust;
89
90 /* Nonzero means stack pops must not be deferred, and deferred stack
91    pops must not be output.  It is nonzero inside a function call,
92    inside a conditional expression, inside a statement expression,
93    and in other cases as well.  */
94 int inhibit_defer_pop;
95
96 /* A list of all cleanups which belong to the arguments of
97    function calls being expanded by expand_call.  */
98 tree cleanups_this_call;
99
100 /* When temporaries are created by TARGET_EXPRs, they are created at
101    this level of temp_slot_level, so that they can remain allocated
102    until no longer needed.  CLEANUP_POINT_EXPRs define the lifetime
103    of TARGET_EXPRs.  */
104 int target_temp_slot_level;
105
106 /* Nonzero means __builtin_saveregs has already been done in this function.
107    The value is the pseudoreg containing the value __builtin_saveregs
108    returned.  */
109 static rtx saveregs_value;
110
111 /* Similarly for __builtin_apply_args.  */
112 static rtx apply_args_value;
113
114 /* This structure is used by move_by_pieces to describe the move to
115    be performed.  */
116
117 struct move_by_pieces
118 {
119   rtx to;
120   rtx to_addr;
121   int autinc_to;
122   int explicit_inc_to;
123   int to_struct;
124   rtx from;
125   rtx from_addr;
126   int autinc_from;
127   int explicit_inc_from;
128   int from_struct;
129   int len;
130   int offset;
131   int reverse;
132 };
133
134 /* This structure is used by clear_by_pieces to describe the clear to
135    be performed.  */
136
137 struct clear_by_pieces
138 {
139   rtx to;
140   rtx to_addr;
141   int autinc_to;
142   int explicit_inc_to;
143   int to_struct;
144   int len;
145   int offset;
146   int reverse;
147 };
148
149 /* Used to generate bytecodes: keep track of size of local variables,
150    as well as depth of arithmetic stack. (Notice that variables are
151    stored on the machine's stack, not the arithmetic stack.) */
152
153 extern int local_vars_size;
154 extern int stack_depth;
155 extern int max_stack_depth;
156 extern struct obstack permanent_obstack;
157 extern rtx arg_pointer_save_area;
158
159 static rtx enqueue_insn         PROTO((rtx, rtx));
160 static int queued_subexp_p      PROTO((rtx));
161 static void init_queue          PROTO((void));
162 static void move_by_pieces      PROTO((rtx, rtx, int, int));
163 static int move_by_pieces_ninsns PROTO((unsigned int, int));
164 static void move_by_pieces_1    PROTO((rtx (*) (), enum machine_mode,
165                                        struct move_by_pieces *));
166 static void clear_by_pieces     PROTO((rtx, int, int));
167 static void clear_by_pieces_1   PROTO((rtx (*) (), enum machine_mode,
168                                        struct clear_by_pieces *));
169 static int is_zeros_p           PROTO((tree));
170 static int mostly_zeros_p       PROTO((tree));
171 static void store_constructor   PROTO((tree, rtx, int));
172 static rtx store_field          PROTO((rtx, int, int, enum machine_mode, tree,
173                                        enum machine_mode, int, int, int));
174 static int get_inner_unaligned_p PROTO((tree));
175 static tree save_noncopied_parts PROTO((tree, tree));
176 static tree init_noncopied_parts PROTO((tree, tree));
177 static int safe_from_p          PROTO((rtx, tree));
178 static int fixed_type_p         PROTO((tree));
179 static int get_pointer_alignment PROTO((tree, unsigned));
180 static tree string_constant     PROTO((tree, tree *));
181 static tree c_strlen            PROTO((tree));
182 static rtx expand_builtin       PROTO((tree, rtx, rtx,
183                                        enum machine_mode, int));
184 static int apply_args_size      PROTO((void));
185 static int apply_result_size    PROTO((void));
186 static rtx result_vector        PROTO((int, rtx));
187 static rtx expand_builtin_apply_args PROTO((void));
188 static rtx expand_builtin_apply PROTO((rtx, rtx, rtx));
189 static void expand_builtin_return PROTO((rtx));
190 static rtx expand_increment     PROTO((tree, int, int));
191 void bc_expand_increment        PROTO((struct increment_operator *, tree));
192 rtx bc_allocate_local           PROTO((int, int));
193 void bc_store_memory            PROTO((tree, tree));
194 tree bc_expand_component_address PROTO((tree));
195 tree bc_expand_address          PROTO((tree));
196 void bc_expand_constructor      PROTO((tree));
197 void bc_adjust_stack            PROTO((int));
198 tree bc_canonicalize_array_ref  PROTO((tree));
199 void bc_load_memory             PROTO((tree, tree));
200 void bc_load_externaddr         PROTO((rtx));
201 void bc_load_externaddr_id      PROTO((tree, int));
202 void bc_load_localaddr          PROTO((rtx));
203 void bc_load_parmaddr           PROTO((rtx));
204 static void preexpand_calls     PROTO((tree));
205 static void do_jump_by_parts_greater PROTO((tree, int, rtx, rtx));
206 void do_jump_by_parts_greater_rtx PROTO((enum machine_mode, int, rtx, rtx, rtx, rtx));
207 static void do_jump_by_parts_equality PROTO((tree, rtx, rtx));
208 static void do_jump_by_parts_equality_rtx PROTO((rtx, rtx, rtx));
209 static void do_jump_for_compare PROTO((rtx, rtx, rtx));
210 static rtx compare              PROTO((tree, enum rtx_code, enum rtx_code));
211 static rtx do_store_flag        PROTO((tree, rtx, enum machine_mode, int));
212 static tree defer_cleanups_to   PROTO((tree));
213 extern void (*interim_eh_hook)  PROTO((tree));
214 extern tree truthvalue_conversion       PROTO((tree));
215
216 /* Record for each mode whether we can move a register directly to or
217    from an object of that mode in memory.  If we can't, we won't try
218    to use that mode directly when accessing a field of that mode.  */
219
220 static char direct_load[NUM_MACHINE_MODES];
221 static char direct_store[NUM_MACHINE_MODES];
222
223 /* MOVE_RATIO is the number of move instructions that is better than
224    a block move.  */
225
226 #ifndef MOVE_RATIO
227 #if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi) || defined (HAVE_movstrti)
228 #define MOVE_RATIO 2
229 #else
230 /* A value of around 6 would minimize code size; infinity would minimize
231    execution time.  */
232 #define MOVE_RATIO 15
233 #endif
234 #endif
235
236 /* This array records the insn_code of insns to perform block moves.  */
237 enum insn_code movstr_optab[NUM_MACHINE_MODES];
238
239 /* This array records the insn_code of insns to perform block clears.  */
240 enum insn_code clrstr_optab[NUM_MACHINE_MODES];
241
242 /* SLOW_UNALIGNED_ACCESS is non-zero if unaligned accesses are very slow. */
243
244 #ifndef SLOW_UNALIGNED_ACCESS
245 #define SLOW_UNALIGNED_ACCESS STRICT_ALIGNMENT
246 #endif
247
248 /* Register mappings for target machines without register windows.  */
249 #ifndef INCOMING_REGNO
250 #define INCOMING_REGNO(OUT) (OUT)
251 #endif
252 #ifndef OUTGOING_REGNO
253 #define OUTGOING_REGNO(IN) (IN)
254 #endif
255 \f
256 /* Maps used to convert modes to const, load, and store bytecodes. */
257 enum bytecode_opcode mode_to_const_map[MAX_MACHINE_MODE];
258 enum bytecode_opcode mode_to_load_map[MAX_MACHINE_MODE];
259 enum bytecode_opcode mode_to_store_map[MAX_MACHINE_MODE];
260
261 /* Initialize maps used to convert modes to const, load, and store
262    bytecodes. */
263 void
264 bc_init_mode_to_opcode_maps ()
265 {
266   int mode;
267
268   for (mode = 0; mode < (int) MAX_MACHINE_MODE; mode++)
269     mode_to_const_map[mode] =
270       mode_to_load_map[mode] =
271         mode_to_store_map[mode] = neverneverland;
272       
273 #define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \
274   mode_to_const_map[(int) SYM] = CONST; \
275   mode_to_load_map[(int) SYM] = LOAD; \
276   mode_to_store_map[(int) SYM] = STORE;
277
278 #include "modemap.def"
279 #undef DEF_MODEMAP
280 }
281 \f
282 /* This is run once per compilation to set up which modes can be used
283    directly in memory and to initialize the block move optab.  */
284
285 void
286 init_expr_once ()
287 {
288   rtx insn, pat;
289   enum machine_mode mode;
290   /* Try indexing by frame ptr and try by stack ptr.
291      It is known that on the Convex the stack ptr isn't a valid index.
292      With luck, one or the other is valid on any machine.  */
293   rtx mem = gen_rtx (MEM, VOIDmode, stack_pointer_rtx);
294   rtx mem1 = gen_rtx (MEM, VOIDmode, frame_pointer_rtx);
295
296   start_sequence ();
297   insn = emit_insn (gen_rtx (SET, 0, 0));
298   pat = PATTERN (insn);
299
300   for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
301        mode = (enum machine_mode) ((int) mode + 1))
302     {
303       int regno;
304       rtx reg;
305       int num_clobbers;
306
307       direct_load[(int) mode] = direct_store[(int) mode] = 0;
308       PUT_MODE (mem, mode);
309       PUT_MODE (mem1, mode);
310
311       /* See if there is some register that can be used in this mode and
312          directly loaded or stored from memory.  */
313
314       if (mode != VOIDmode && mode != BLKmode)
315         for (regno = 0; regno < FIRST_PSEUDO_REGISTER
316              && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
317              regno++)
318           {
319             if (! HARD_REGNO_MODE_OK (regno, mode))
320               continue;
321
322             reg = gen_rtx (REG, mode, regno);
323
324             SET_SRC (pat) = mem;
325             SET_DEST (pat) = reg;
326             if (recog (pat, insn, &num_clobbers) >= 0)
327               direct_load[(int) mode] = 1;
328
329             SET_SRC (pat) = mem1;
330             SET_DEST (pat) = reg;
331             if (recog (pat, insn, &num_clobbers) >= 0)
332               direct_load[(int) mode] = 1;
333
334             SET_SRC (pat) = reg;
335             SET_DEST (pat) = mem;
336             if (recog (pat, insn, &num_clobbers) >= 0)
337               direct_store[(int) mode] = 1;
338
339             SET_SRC (pat) = reg;
340             SET_DEST (pat) = mem1;
341             if (recog (pat, insn, &num_clobbers) >= 0)
342               direct_store[(int) mode] = 1;
343           }
344     }
345
346   end_sequence ();
347 }
348       
349 /* This is run at the start of compiling a function.  */
350
351 void
352 init_expr ()
353 {
354   init_queue ();
355
356   pending_stack_adjust = 0;
357   inhibit_defer_pop = 0;
358   cleanups_this_call = 0;
359   saveregs_value = 0;
360   apply_args_value = 0;
361   forced_labels = 0;
362 }
363
364 /* Save all variables describing the current status into the structure *P.
365    This is used before starting a nested function.  */
366
367 void
368 save_expr_status (p)
369      struct function *p;
370 {
371   /* Instead of saving the postincrement queue, empty it.  */
372   emit_queue ();
373
374   p->pending_stack_adjust = pending_stack_adjust;
375   p->inhibit_defer_pop = inhibit_defer_pop;
376   p->cleanups_this_call = cleanups_this_call;
377   p->saveregs_value = saveregs_value;
378   p->apply_args_value = apply_args_value;
379   p->forced_labels = forced_labels;
380
381   pending_stack_adjust = 0;
382   inhibit_defer_pop = 0;
383   cleanups_this_call = 0;
384   saveregs_value = 0;
385   apply_args_value = 0;
386   forced_labels = 0;
387 }
388
389 /* Restore all variables describing the current status from the structure *P.
390    This is used after a nested function.  */
391
392 void
393 restore_expr_status (p)
394      struct function *p;
395 {
396   pending_stack_adjust = p->pending_stack_adjust;
397   inhibit_defer_pop = p->inhibit_defer_pop;
398   cleanups_this_call = p->cleanups_this_call;
399   saveregs_value = p->saveregs_value;
400   apply_args_value = p->apply_args_value;
401   forced_labels = p->forced_labels;
402 }
403 \f
404 /* Manage the queue of increment instructions to be output
405    for POSTINCREMENT_EXPR expressions, etc.  */
406
407 static rtx pending_chain;
408
409 /* Queue up to increment (or change) VAR later.  BODY says how:
410    BODY should be the same thing you would pass to emit_insn
411    to increment right away.  It will go to emit_insn later on.
412
413    The value is a QUEUED expression to be used in place of VAR
414    where you want to guarantee the pre-incrementation value of VAR.  */
415
416 static rtx
417 enqueue_insn (var, body)
418      rtx var, body;
419 {
420   pending_chain = gen_rtx (QUEUED, GET_MODE (var),
421                            var, NULL_RTX, NULL_RTX, body, pending_chain);
422   return pending_chain;
423 }
424
425 /* Use protect_from_queue to convert a QUEUED expression
426    into something that you can put immediately into an instruction.
427    If the queued incrementation has not happened yet,
428    protect_from_queue returns the variable itself.
429    If the incrementation has happened, protect_from_queue returns a temp
430    that contains a copy of the old value of the variable.
431
432    Any time an rtx which might possibly be a QUEUED is to be put
433    into an instruction, it must be passed through protect_from_queue first.
434    QUEUED expressions are not meaningful in instructions.
435
436    Do not pass a value through protect_from_queue and then hold
437    on to it for a while before putting it in an instruction!
438    If the queue is flushed in between, incorrect code will result.  */
439
440 rtx
441 protect_from_queue (x, modify)
442      register rtx x;
443      int modify;
444 {
445   register RTX_CODE code = GET_CODE (x);
446
447 #if 0  /* A QUEUED can hang around after the queue is forced out.  */
448   /* Shortcut for most common case.  */
449   if (pending_chain == 0)
450     return x;
451 #endif
452
453   if (code != QUEUED)
454     {
455       /* A special hack for read access to (MEM (QUEUED ...)) to facilitate
456          use of autoincrement.  Make a copy of the contents of the memory
457          location rather than a copy of the address, but not if the value is
458          of mode BLKmode.  Don't modify X in place since it might be
459          shared.  */
460       if (code == MEM && GET_MODE (x) != BLKmode
461           && GET_CODE (XEXP (x, 0)) == QUEUED && !modify)
462         {
463           register rtx y = XEXP (x, 0);
464           register rtx new = gen_rtx (MEM, GET_MODE (x), QUEUED_VAR (y));
465
466           MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
467           RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
468           MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
469
470           if (QUEUED_INSN (y))
471             {
472               register rtx temp = gen_reg_rtx (GET_MODE (new));
473               emit_insn_before (gen_move_insn (temp, new),
474                                 QUEUED_INSN (y));
475               return temp;
476             }
477           return new;
478         }
479       /* Otherwise, recursively protect the subexpressions of all
480          the kinds of rtx's that can contain a QUEUED.  */
481       if (code == MEM)
482         {
483           rtx tem = protect_from_queue (XEXP (x, 0), 0);
484           if (tem != XEXP (x, 0))
485             {
486               x = copy_rtx (x);
487               XEXP (x, 0) = tem;
488             }
489         }
490       else if (code == PLUS || code == MULT)
491         {
492           rtx new0 = protect_from_queue (XEXP (x, 0), 0);
493           rtx new1 = protect_from_queue (XEXP (x, 1), 0);
494           if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
495             {
496               x = copy_rtx (x);
497               XEXP (x, 0) = new0;
498               XEXP (x, 1) = new1;
499             }
500         }
501       return x;
502     }
503   /* If the increment has not happened, use the variable itself.  */
504   if (QUEUED_INSN (x) == 0)
505     return QUEUED_VAR (x);
506   /* If the increment has happened and a pre-increment copy exists,
507      use that copy.  */
508   if (QUEUED_COPY (x) != 0)
509     return QUEUED_COPY (x);
510   /* The increment has happened but we haven't set up a pre-increment copy.
511      Set one up now, and use it.  */
512   QUEUED_COPY (x) = gen_reg_rtx (GET_MODE (QUEUED_VAR (x)));
513   emit_insn_before (gen_move_insn (QUEUED_COPY (x), QUEUED_VAR (x)),
514                     QUEUED_INSN (x));
515   return QUEUED_COPY (x);
516 }
517
518 /* Return nonzero if X contains a QUEUED expression:
519    if it contains anything that will be altered by a queued increment.
520    We handle only combinations of MEM, PLUS, MINUS and MULT operators
521    since memory addresses generally contain only those.  */
522
523 static int
524 queued_subexp_p (x)
525      rtx x;
526 {
527   register enum rtx_code code = GET_CODE (x);
528   switch (code)
529     {
530     case QUEUED:
531       return 1;
532     case MEM:
533       return queued_subexp_p (XEXP (x, 0));
534     case MULT:
535     case PLUS:
536     case MINUS:
537       return queued_subexp_p (XEXP (x, 0))
538         || queued_subexp_p (XEXP (x, 1));
539     }
540   return 0;
541 }
542
543 /* Perform all the pending incrementations.  */
544
545 void
546 emit_queue ()
547 {
548   register rtx p;
549   while (p = pending_chain)
550     {
551       QUEUED_INSN (p) = emit_insn (QUEUED_BODY (p));
552       pending_chain = QUEUED_NEXT (p);
553     }
554 }
555
556 static void
557 init_queue ()
558 {
559   if (pending_chain)
560     abort ();
561 }
562 \f
563 /* Copy data from FROM to TO, where the machine modes are not the same.
564    Both modes may be integer, or both may be floating.
565    UNSIGNEDP should be nonzero if FROM is an unsigned type.
566    This causes zero-extension instead of sign-extension.  */
567
568 void
569 convert_move (to, from, unsignedp)
570      register rtx to, from;
571      int unsignedp;
572 {
573   enum machine_mode to_mode = GET_MODE (to);
574   enum machine_mode from_mode = GET_MODE (from);
575   int to_real = GET_MODE_CLASS (to_mode) == MODE_FLOAT;
576   int from_real = GET_MODE_CLASS (from_mode) == MODE_FLOAT;
577   enum insn_code code;
578   rtx libcall;
579
580   /* rtx code for making an equivalent value.  */
581   enum rtx_code equiv_code = (unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
582
583   to = protect_from_queue (to, 1);
584   from = protect_from_queue (from, 0);
585
586   if (to_real != from_real)
587     abort ();
588
589   /* If FROM is a SUBREG that indicates that we have already done at least
590      the required extension, strip it.  We don't handle such SUBREGs as
591      TO here.  */
592
593   if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from)
594       && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (from)))
595           >= GET_MODE_SIZE (to_mode))
596       && SUBREG_PROMOTED_UNSIGNED_P (from) == unsignedp)
597     from = gen_lowpart (to_mode, from), from_mode = to_mode;
598
599   if (GET_CODE (to) == SUBREG && SUBREG_PROMOTED_VAR_P (to))
600     abort ();
601
602   if (to_mode == from_mode
603       || (from_mode == VOIDmode && CONSTANT_P (from)))
604     {
605       emit_move_insn (to, from);
606       return;
607     }
608
609   if (to_real)
610     {
611       rtx value;
612
613 #ifdef HAVE_extendqfhf2
614       if (HAVE_extendqfhf2 && from_mode == QFmode && to_mode == HFmode)
615         {
616           emit_unop_insn (CODE_FOR_extendqfhf2, to, from, UNKNOWN);
617           return;
618         }
619 #endif
620 #ifdef HAVE_extendqfsf2
621       if (HAVE_extendqfsf2 && from_mode == QFmode && to_mode == SFmode)
622         {
623           emit_unop_insn (CODE_FOR_extendqfsf2, to, from, UNKNOWN);
624           return;
625         }
626 #endif
627 #ifdef HAVE_extendqfdf2
628       if (HAVE_extendqfdf2 && from_mode == QFmode && to_mode == DFmode)
629         {
630           emit_unop_insn (CODE_FOR_extendqfdf2, to, from, UNKNOWN);
631           return;
632         }
633 #endif
634 #ifdef HAVE_extendqfxf2
635       if (HAVE_extendqfxf2 && from_mode == QFmode && to_mode == XFmode)
636         {
637           emit_unop_insn (CODE_FOR_extendqfxf2, to, from, UNKNOWN);
638           return;
639         }
640 #endif
641 #ifdef HAVE_extendqftf2
642       if (HAVE_extendqftf2 && from_mode == QFmode && to_mode == TFmode)
643         {
644           emit_unop_insn (CODE_FOR_extendqftf2, to, from, UNKNOWN);
645           return;
646         }
647 #endif
648
649 #ifdef HAVE_extendhftqf2
650       if (HAVE_extendhftqf2 && from_mode == HFmode && to_mode == TQFmode)
651         {
652           emit_unop_insn (CODE_FOR_extendhftqf2, to, from, UNKNOWN);
653           return;
654         }
655 #endif
656
657 #ifdef HAVE_extendhfsf2
658       if (HAVE_extendhfsf2 && from_mode == HFmode && to_mode == SFmode)
659         {
660           emit_unop_insn (CODE_FOR_extendhfsf2, to, from, UNKNOWN);
661           return;
662         }
663 #endif
664 #ifdef HAVE_extendhfdf2
665       if (HAVE_extendhfdf2 && from_mode == HFmode && to_mode == DFmode)
666         {
667           emit_unop_insn (CODE_FOR_extendhfdf2, to, from, UNKNOWN);
668           return;
669         }
670 #endif
671 #ifdef HAVE_extendhfxf2
672       if (HAVE_extendhfxf2 && from_mode == HFmode && to_mode == XFmode)
673         {
674           emit_unop_insn (CODE_FOR_extendhfxf2, to, from, UNKNOWN);
675           return;
676         }
677 #endif
678 #ifdef HAVE_extendhftf2
679       if (HAVE_extendhftf2 && from_mode == HFmode && to_mode == TFmode)
680         {
681           emit_unop_insn (CODE_FOR_extendhftf2, to, from, UNKNOWN);
682           return;
683         }
684 #endif
685
686 #ifdef HAVE_extendsfdf2
687       if (HAVE_extendsfdf2 && from_mode == SFmode && to_mode == DFmode)
688         {
689           emit_unop_insn (CODE_FOR_extendsfdf2, to, from, UNKNOWN);
690           return;
691         }
692 #endif
693 #ifdef HAVE_extendsfxf2
694       if (HAVE_extendsfxf2 && from_mode == SFmode && to_mode == XFmode)
695         {
696           emit_unop_insn (CODE_FOR_extendsfxf2, to, from, UNKNOWN);
697           return;
698         }
699 #endif
700 #ifdef HAVE_extendsftf2
701       if (HAVE_extendsftf2 && from_mode == SFmode && to_mode == TFmode)
702         {
703           emit_unop_insn (CODE_FOR_extendsftf2, to, from, UNKNOWN);
704           return;
705         }
706 #endif
707 #ifdef HAVE_extenddfxf2
708       if (HAVE_extenddfxf2 && from_mode == DFmode && to_mode == XFmode)
709         {
710           emit_unop_insn (CODE_FOR_extenddfxf2, to, from, UNKNOWN);
711           return;
712         }
713 #endif
714 #ifdef HAVE_extenddftf2
715       if (HAVE_extenddftf2 && from_mode == DFmode && to_mode == TFmode)
716         {
717           emit_unop_insn (CODE_FOR_extenddftf2, to, from, UNKNOWN);
718           return;
719         }
720 #endif
721
722 #ifdef HAVE_trunchfqf2
723       if (HAVE_trunchfqf2 && from_mode == HFmode && to_mode == QFmode)
724         {
725           emit_unop_insn (CODE_FOR_trunchfqf2, to, from, UNKNOWN);
726           return;
727         }
728 #endif
729 #ifdef HAVE_truncsfqf2
730       if (HAVE_truncsfqf2 && from_mode == SFmode && to_mode == QFmode)
731         {
732           emit_unop_insn (CODE_FOR_truncsfqf2, to, from, UNKNOWN);
733           return;
734         }
735 #endif
736 #ifdef HAVE_truncdfqf2
737       if (HAVE_truncdfqf2 && from_mode == DFmode && to_mode == QFmode)
738         {
739           emit_unop_insn (CODE_FOR_truncdfqf2, to, from, UNKNOWN);
740           return;
741         }
742 #endif
743 #ifdef HAVE_truncxfqf2
744       if (HAVE_truncxfqf2 && from_mode == XFmode && to_mode == QFmode)
745         {
746           emit_unop_insn (CODE_FOR_truncxfqf2, to, from, UNKNOWN);
747           return;
748         }
749 #endif
750 #ifdef HAVE_trunctfqf2
751       if (HAVE_trunctfqf2 && from_mode == TFmode && to_mode == QFmode)
752         {
753           emit_unop_insn (CODE_FOR_trunctfqf2, to, from, UNKNOWN);
754           return;
755         }
756 #endif
757
758 #ifdef HAVE_trunctqfhf2
759       if (HAVE_trunctqfhf2 && from_mode == TQFmode && to_mode == HFmode)
760         {
761           emit_unop_insn (CODE_FOR_trunctqfhf2, to, from, UNKNOWN);
762           return;
763         }
764 #endif
765 #ifdef HAVE_truncsfhf2
766       if (HAVE_truncsfhf2 && from_mode == SFmode && to_mode == HFmode)
767         {
768           emit_unop_insn (CODE_FOR_truncsfhf2, to, from, UNKNOWN);
769           return;
770         }
771 #endif
772 #ifdef HAVE_truncdfhf2
773       if (HAVE_truncdfhf2 && from_mode == DFmode && to_mode == HFmode)
774         {
775           emit_unop_insn (CODE_FOR_truncdfhf2, to, from, UNKNOWN);
776           return;
777         }
778 #endif
779 #ifdef HAVE_truncxfhf2
780       if (HAVE_truncxfhf2 && from_mode == XFmode && to_mode == HFmode)
781         {
782           emit_unop_insn (CODE_FOR_truncxfhf2, to, from, UNKNOWN);
783           return;
784         }
785 #endif
786 #ifdef HAVE_trunctfhf2
787       if (HAVE_trunctfhf2 && from_mode == TFmode && to_mode == HFmode)
788         {
789           emit_unop_insn (CODE_FOR_trunctfhf2, to, from, UNKNOWN);
790           return;
791         }
792 #endif
793 #ifdef HAVE_truncdfsf2
794       if (HAVE_truncdfsf2 && from_mode == DFmode && to_mode == SFmode)
795         {
796           emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
797           return;
798         }
799 #endif
800 #ifdef HAVE_truncxfsf2
801       if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)
802         {
803           emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);
804           return;
805         }
806 #endif
807 #ifdef HAVE_trunctfsf2
808       if (HAVE_trunctfsf2 && from_mode == TFmode && to_mode == SFmode)
809         {
810           emit_unop_insn (CODE_FOR_trunctfsf2, to, from, UNKNOWN);
811           return;
812         }
813 #endif
814 #ifdef HAVE_truncxfdf2
815       if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)
816         {
817           emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);
818           return;
819         }
820 #endif
821 #ifdef HAVE_trunctfdf2
822       if (HAVE_trunctfdf2 && from_mode == TFmode && to_mode == DFmode)
823         {
824           emit_unop_insn (CODE_FOR_trunctfdf2, to, from, UNKNOWN);
825           return;
826         }
827 #endif
828
829       libcall = (rtx) 0;
830       switch (from_mode)
831         {
832         case SFmode:
833           switch (to_mode)
834             {
835             case DFmode:
836               libcall = extendsfdf2_libfunc;
837               break;
838
839             case XFmode:
840               libcall = extendsfxf2_libfunc;
841               break;
842
843             case TFmode:
844               libcall = extendsftf2_libfunc;
845               break;
846             }
847           break;
848
849         case DFmode:
850           switch (to_mode)
851             {
852             case SFmode:
853               libcall = truncdfsf2_libfunc;
854               break;
855
856             case XFmode:
857               libcall = extenddfxf2_libfunc;
858               break;
859
860             case TFmode:
861               libcall = extenddftf2_libfunc;
862               break;
863             }
864           break;
865
866         case XFmode:
867           switch (to_mode)
868             {
869             case SFmode:
870               libcall = truncxfsf2_libfunc;
871               break;
872
873             case DFmode:
874               libcall = truncxfdf2_libfunc;
875               break;
876             }
877           break;
878
879         case TFmode:
880           switch (to_mode)
881             {
882             case SFmode:
883               libcall = trunctfsf2_libfunc;
884               break;
885
886             case DFmode:
887               libcall = trunctfdf2_libfunc;
888               break;
889             }
890           break;
891         }
892
893       if (libcall == (rtx) 0)
894         /* This conversion is not implemented yet.  */
895         abort ();
896
897       value = emit_library_call_value (libcall, NULL_RTX, 1, to_mode,
898                                        1, from, from_mode);
899       emit_move_insn (to, value);
900       return;
901     }
902
903   /* Now both modes are integers.  */
904
905   /* Handle expanding beyond a word.  */
906   if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode)
907       && GET_MODE_BITSIZE (to_mode) > BITS_PER_WORD)
908     {
909       rtx insns;
910       rtx lowpart;
911       rtx fill_value;
912       rtx lowfrom;
913       int i;
914       enum machine_mode lowpart_mode;
915       int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
916
917       /* Try converting directly if the insn is supported.  */
918       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
919           != CODE_FOR_nothing)
920         {
921           /* If FROM is a SUBREG, put it into a register.  Do this
922              so that we always generate the same set of insns for
923              better cse'ing; if an intermediate assignment occurred,
924              we won't be doing the operation directly on the SUBREG.  */
925           if (optimize > 0 && GET_CODE (from) == SUBREG)
926             from = force_reg (from_mode, from);
927           emit_unop_insn (code, to, from, equiv_code);
928           return;
929         }
930       /* Next, try converting via full word.  */
931       else if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD
932                && ((code = can_extend_p (to_mode, word_mode, unsignedp))
933                    != CODE_FOR_nothing))
934         {
935           if (GET_CODE (to) == REG)
936             emit_insn (gen_rtx (CLOBBER, VOIDmode, to));
937           convert_move (gen_lowpart (word_mode, to), from, unsignedp);
938           emit_unop_insn (code, to,
939                           gen_lowpart (word_mode, to), equiv_code);
940           return;
941         }
942
943       /* No special multiword conversion insn; do it by hand.  */
944       start_sequence ();
945
946       /* Since we will turn this into a no conflict block, we must ensure
947          that the source does not overlap the target.  */
948
949       if (reg_overlap_mentioned_p (to, from))
950         from = force_reg (from_mode, from);
951
952       /* Get a copy of FROM widened to a word, if necessary.  */
953       if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD)
954         lowpart_mode = word_mode;
955       else
956         lowpart_mode = from_mode;
957
958       lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
959
960       lowpart = gen_lowpart (lowpart_mode, to);
961       emit_move_insn (lowpart, lowfrom);
962
963       /* Compute the value to put in each remaining word.  */
964       if (unsignedp)
965         fill_value = const0_rtx;
966       else
967         {
968 #ifdef HAVE_slt
969           if (HAVE_slt
970               && insn_operand_mode[(int) CODE_FOR_slt][0] == word_mode
971               && STORE_FLAG_VALUE == -1)
972             {
973               emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,
974                              lowpart_mode, 0, 0);
975               fill_value = gen_reg_rtx (word_mode);
976               emit_insn (gen_slt (fill_value));
977             }
978           else
979 #endif
980             {
981               fill_value
982                 = expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom,
983                                 size_int (GET_MODE_BITSIZE (lowpart_mode) - 1),
984                                 NULL_RTX, 0);
985               fill_value = convert_to_mode (word_mode, fill_value, 1);
986             }
987         }
988
989       /* Fill the remaining words.  */
990       for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
991         {
992           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
993           rtx subword = operand_subword (to, index, 1, to_mode);
994
995           if (subword == 0)
996             abort ();
997
998           if (fill_value != subword)
999             emit_move_insn (subword, fill_value);
1000         }
1001
1002       insns = get_insns ();
1003       end_sequence ();
1004
1005       emit_no_conflict_block (insns, to, from, NULL_RTX,
1006                               gen_rtx (equiv_code, to_mode, copy_rtx (from)));
1007       return;
1008     }
1009
1010   /* Truncating multi-word to a word or less.  */
1011   if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD
1012       && GET_MODE_BITSIZE (to_mode) <= BITS_PER_WORD)
1013     {
1014       if (!((GET_CODE (from) == MEM
1015              && ! MEM_VOLATILE_P (from)
1016              && direct_load[(int) to_mode]
1017              && ! mode_dependent_address_p (XEXP (from, 0)))
1018             || GET_CODE (from) == REG
1019             || GET_CODE (from) == SUBREG))
1020         from = force_reg (from_mode, from);
1021       convert_move (to, gen_lowpart (word_mode, from), 0);
1022       return;
1023     }
1024
1025   /* Handle pointer conversion */                       /* SPEE 900220 */
1026   if (to_mode == PSImode)
1027     {
1028       if (from_mode != SImode)
1029         from = convert_to_mode (SImode, from, unsignedp);
1030
1031 #ifdef HAVE_truncsipsi2
1032       if (HAVE_truncsipsi2)
1033         {
1034           emit_unop_insn (CODE_FOR_truncsipsi2, to, from, UNKNOWN);
1035           return;
1036         }
1037 #endif /* HAVE_truncsipsi2 */
1038       abort ();
1039     }
1040
1041   if (from_mode == PSImode)
1042     {
1043       if (to_mode != SImode)
1044         {
1045           from = convert_to_mode (SImode, from, unsignedp);
1046           from_mode = SImode;
1047         }
1048       else
1049         {
1050 #ifdef HAVE_extendpsisi2
1051           if (HAVE_extendpsisi2)
1052             {
1053               emit_unop_insn (CODE_FOR_extendpsisi2, to, from, UNKNOWN);
1054               return;
1055             }
1056 #endif /* HAVE_extendpsisi2 */
1057           abort ();
1058         }
1059     }
1060
1061   if (to_mode == PDImode)
1062     {
1063       if (from_mode != DImode)
1064         from = convert_to_mode (DImode, from, unsignedp);
1065
1066 #ifdef HAVE_truncdipdi2
1067       if (HAVE_truncdipdi2)
1068         {
1069           emit_unop_insn (CODE_FOR_truncdipdi2, to, from, UNKNOWN);
1070           return;
1071         }
1072 #endif /* HAVE_truncdipdi2 */
1073       abort ();
1074     }
1075
1076   if (from_mode == PDImode)
1077     {
1078       if (to_mode != DImode)
1079         {
1080           from = convert_to_mode (DImode, from, unsignedp);
1081           from_mode = DImode;
1082         }
1083       else
1084         {
1085 #ifdef HAVE_extendpdidi2
1086           if (HAVE_extendpdidi2)
1087             {
1088               emit_unop_insn (CODE_FOR_extendpdidi2, to, from, UNKNOWN);
1089               return;
1090             }
1091 #endif /* HAVE_extendpdidi2 */
1092           abort ();
1093         }
1094     }
1095
1096   /* Now follow all the conversions between integers
1097      no more than a word long.  */
1098
1099   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
1100   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
1101       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
1102                                 GET_MODE_BITSIZE (from_mode)))
1103     {
1104       if (!((GET_CODE (from) == MEM
1105              && ! MEM_VOLATILE_P (from)
1106              && direct_load[(int) to_mode]
1107              && ! mode_dependent_address_p (XEXP (from, 0)))
1108             || GET_CODE (from) == REG
1109             || GET_CODE (from) == SUBREG))
1110         from = force_reg (from_mode, from);
1111       if (GET_CODE (from) == REG && REGNO (from) < FIRST_PSEUDO_REGISTER
1112           && ! HARD_REGNO_MODE_OK (REGNO (from), to_mode))
1113         from = copy_to_reg (from);
1114       emit_move_insn (to, gen_lowpart (to_mode, from));
1115       return;
1116     }
1117
1118   /* Handle extension.  */
1119   if (GET_MODE_BITSIZE (to_mode) > GET_MODE_BITSIZE (from_mode))
1120     {
1121       /* Convert directly if that works.  */
1122       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
1123           != CODE_FOR_nothing)
1124         {
1125           emit_unop_insn (code, to, from, equiv_code);
1126           return;
1127         }
1128       else
1129         {
1130           enum machine_mode intermediate;
1131
1132           /* Search for a mode to convert via.  */
1133           for (intermediate = from_mode; intermediate != VOIDmode;
1134                intermediate = GET_MODE_WIDER_MODE (intermediate))
1135             if (((can_extend_p (to_mode, intermediate, unsignedp)
1136                   != CODE_FOR_nothing)
1137                  || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
1138                      && TRULY_NOOP_TRUNCATION (to_mode, intermediate)))
1139                 && (can_extend_p (intermediate, from_mode, unsignedp)
1140                     != CODE_FOR_nothing))
1141               {
1142                 convert_move (to, convert_to_mode (intermediate, from,
1143                                                    unsignedp), unsignedp);
1144                 return;
1145               }
1146
1147           /* No suitable intermediate mode.  */
1148           abort ();
1149         }
1150     }
1151
1152   /* Support special truncate insns for certain modes.  */ 
1153
1154   if (from_mode == DImode && to_mode == SImode)
1155     {
1156 #ifdef HAVE_truncdisi2
1157       if (HAVE_truncdisi2)
1158         {
1159           emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);
1160           return;
1161         }
1162 #endif
1163       convert_move (to, force_reg (from_mode, from), unsignedp);
1164       return;
1165     }
1166
1167   if (from_mode == DImode && to_mode == HImode)
1168     {
1169 #ifdef HAVE_truncdihi2
1170       if (HAVE_truncdihi2)
1171         {
1172           emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);
1173           return;
1174         }
1175 #endif
1176       convert_move (to, force_reg (from_mode, from), unsignedp);
1177       return;
1178     }
1179
1180   if (from_mode == DImode && to_mode == QImode)
1181     {
1182 #ifdef HAVE_truncdiqi2
1183       if (HAVE_truncdiqi2)
1184         {
1185           emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);
1186           return;
1187         }
1188 #endif
1189       convert_move (to, force_reg (from_mode, from), unsignedp);
1190       return;
1191     }
1192
1193   if (from_mode == SImode && to_mode == HImode)
1194     {
1195 #ifdef HAVE_truncsihi2
1196       if (HAVE_truncsihi2)
1197         {
1198           emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);
1199           return;
1200         }
1201 #endif
1202       convert_move (to, force_reg (from_mode, from), unsignedp);
1203       return;
1204     }
1205
1206   if (from_mode == SImode && to_mode == QImode)
1207     {
1208 #ifdef HAVE_truncsiqi2
1209       if (HAVE_truncsiqi2)
1210         {
1211           emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);
1212           return;
1213         }
1214 #endif
1215       convert_move (to, force_reg (from_mode, from), unsignedp);
1216       return;
1217     }
1218
1219   if (from_mode == HImode && to_mode == QImode)
1220     {
1221 #ifdef HAVE_trunchiqi2
1222       if (HAVE_trunchiqi2)
1223         {
1224           emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);
1225           return;
1226         }
1227 #endif
1228       convert_move (to, force_reg (from_mode, from), unsignedp);
1229       return;
1230     }
1231
1232   if (from_mode == TImode && to_mode == DImode)
1233     {
1234 #ifdef HAVE_trunctidi2
1235       if (HAVE_trunctidi2)
1236         {
1237           emit_unop_insn (CODE_FOR_trunctidi2, to, from, UNKNOWN);
1238           return;
1239         }
1240 #endif
1241       convert_move (to, force_reg (from_mode, from), unsignedp);
1242       return;
1243     }
1244
1245   if (from_mode == TImode && to_mode == SImode)
1246     {
1247 #ifdef HAVE_trunctisi2
1248       if (HAVE_trunctisi2)
1249         {
1250           emit_unop_insn (CODE_FOR_trunctisi2, to, from, UNKNOWN);
1251           return;
1252         }
1253 #endif
1254       convert_move (to, force_reg (from_mode, from), unsignedp);
1255       return;
1256     }
1257
1258   if (from_mode == TImode && to_mode == HImode)
1259     {
1260 #ifdef HAVE_trunctihi2
1261       if (HAVE_trunctihi2)
1262         {
1263           emit_unop_insn (CODE_FOR_trunctihi2, to, from, UNKNOWN);
1264           return;
1265         }
1266 #endif
1267       convert_move (to, force_reg (from_mode, from), unsignedp);
1268       return;
1269     }
1270
1271   if (from_mode == TImode && to_mode == QImode)
1272     {
1273 #ifdef HAVE_trunctiqi2
1274       if (HAVE_trunctiqi2)
1275         {
1276           emit_unop_insn (CODE_FOR_trunctiqi2, to, from, UNKNOWN);
1277           return;
1278         }
1279 #endif
1280       convert_move (to, force_reg (from_mode, from), unsignedp);
1281       return;
1282     }
1283
1284   /* Handle truncation of volatile memrefs, and so on;
1285      the things that couldn't be truncated directly,
1286      and for which there was no special instruction.  */
1287   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))
1288     {
1289       rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
1290       emit_move_insn (to, temp);
1291       return;
1292     }
1293
1294   /* Mode combination is not recognized.  */
1295   abort ();
1296 }
1297
1298 /* Return an rtx for a value that would result
1299    from converting X to mode MODE.
1300    Both X and MODE may be floating, or both integer.
1301    UNSIGNEDP is nonzero if X is an unsigned value.
1302    This can be done by referring to a part of X in place
1303    or by copying to a new temporary with conversion.
1304
1305    This function *must not* call protect_from_queue
1306    except when putting X into an insn (in which case convert_move does it).  */
1307
1308 rtx
1309 convert_to_mode (mode, x, unsignedp)
1310      enum machine_mode mode;
1311      rtx x;
1312      int unsignedp;
1313 {
1314   return convert_modes (mode, VOIDmode, x, unsignedp);
1315 }
1316
1317 /* Return an rtx for a value that would result
1318    from converting X from mode OLDMODE to mode MODE.
1319    Both modes may be floating, or both integer.
1320    UNSIGNEDP is nonzero if X is an unsigned value.
1321
1322    This can be done by referring to a part of X in place
1323    or by copying to a new temporary with conversion.
1324
1325    You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.
1326
1327    This function *must not* call protect_from_queue
1328    except when putting X into an insn (in which case convert_move does it).  */
1329
1330 rtx
1331 convert_modes (mode, oldmode, x, unsignedp)
1332      enum machine_mode mode, oldmode;
1333      rtx x;
1334      int unsignedp;
1335 {
1336   register rtx temp;
1337
1338   /* If FROM is a SUBREG that indicates that we have already done at least
1339      the required extension, strip it.  */
1340
1341   if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
1342       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode)
1343       && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp)
1344     x = gen_lowpart (mode, x);
1345
1346   if (GET_MODE (x) != VOIDmode)
1347     oldmode = GET_MODE (x);
1348  
1349   if (mode == oldmode)
1350     return x;
1351
1352   /* There is one case that we must handle specially: If we are converting
1353      a CONST_INT into a mode whose size is twice HOST_BITS_PER_WIDE_INT and
1354      we are to interpret the constant as unsigned, gen_lowpart will do
1355      the wrong if the constant appears negative.  What we want to do is
1356      make the high-order word of the constant zero, not all ones.  */
1357
1358   if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
1359       && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
1360       && GET_CODE (x) == CONST_INT && INTVAL (x) < 0)
1361     return immed_double_const (INTVAL (x), (HOST_WIDE_INT) 0, mode);
1362
1363   /* We can do this with a gen_lowpart if both desired and current modes
1364      are integer, and this is either a constant integer, a register, or a
1365      non-volatile MEM.  Except for the constant case where MODE is no
1366      wider than HOST_BITS_PER_WIDE_INT, we must be narrowing the operand.  */
1367
1368   if ((GET_CODE (x) == CONST_INT
1369        && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
1370       || (GET_MODE_CLASS (mode) == MODE_INT
1371           && GET_MODE_CLASS (oldmode) == MODE_INT
1372           && (GET_CODE (x) == CONST_DOUBLE
1373               || (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (oldmode)
1374                   && ((GET_CODE (x) == MEM && ! MEM_VOLATILE_P (x)
1375                        && direct_load[(int) mode])
1376                       || (GET_CODE (x) == REG
1377                           && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1378                                                     GET_MODE_BITSIZE (GET_MODE (x)))))))))
1379     {
1380       /* ?? If we don't know OLDMODE, we have to assume here that
1381          X does not need sign- or zero-extension.   This may not be
1382          the case, but it's the best we can do.  */
1383       if (GET_CODE (x) == CONST_INT && oldmode != VOIDmode
1384           && GET_MODE_SIZE (mode) > GET_MODE_SIZE (oldmode))
1385         {
1386           HOST_WIDE_INT val = INTVAL (x);
1387           int width = GET_MODE_BITSIZE (oldmode);
1388
1389           /* We must sign or zero-extend in this case.  Start by
1390              zero-extending, then sign extend if we need to.  */
1391           val &= ((HOST_WIDE_INT) 1 << width) - 1;
1392           if (! unsignedp
1393               && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
1394             val |= (HOST_WIDE_INT) (-1) << width;
1395
1396           return GEN_INT (val);
1397         }
1398
1399       return gen_lowpart (mode, x);
1400     }
1401
1402   temp = gen_reg_rtx (mode);
1403   convert_move (temp, x, unsignedp);
1404   return temp;
1405 }
1406 \f
1407 /* Generate several move instructions to copy LEN bytes
1408    from block FROM to block TO.  (These are MEM rtx's with BLKmode).
1409    The caller must pass FROM and TO
1410     through protect_from_queue before calling.
1411    ALIGN (in bytes) is maximum alignment we can assume.  */
1412
1413 static void
1414 move_by_pieces (to, from, len, align)
1415      rtx to, from;
1416      int len, align;
1417 {
1418   struct move_by_pieces data;
1419   rtx to_addr = XEXP (to, 0), from_addr = XEXP (from, 0);
1420   int max_size = MOVE_MAX + 1;
1421
1422   data.offset = 0;
1423   data.to_addr = to_addr;
1424   data.from_addr = from_addr;
1425   data.to = to;
1426   data.from = from;
1427   data.autinc_to
1428     = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
1429        || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
1430   data.autinc_from
1431     = (GET_CODE (from_addr) == PRE_INC || GET_CODE (from_addr) == PRE_DEC
1432        || GET_CODE (from_addr) == POST_INC
1433        || GET_CODE (from_addr) == POST_DEC);
1434
1435   data.explicit_inc_from = 0;
1436   data.explicit_inc_to = 0;
1437   data.reverse
1438     = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
1439   if (data.reverse) data.offset = len;
1440   data.len = len;
1441
1442   data.to_struct = MEM_IN_STRUCT_P (to);
1443   data.from_struct = MEM_IN_STRUCT_P (from);
1444
1445   /* If copying requires more than two move insns,
1446      copy addresses to registers (to make displacements shorter)
1447      and use post-increment if available.  */
1448   if (!(data.autinc_from && data.autinc_to)
1449       && move_by_pieces_ninsns (len, align) > 2)
1450     {
1451 #ifdef HAVE_PRE_DECREMENT
1452       if (data.reverse && ! data.autinc_from)
1453         {
1454           data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
1455           data.autinc_from = 1;
1456           data.explicit_inc_from = -1;
1457         }
1458 #endif
1459 #ifdef HAVE_POST_INCREMENT
1460       if (! data.autinc_from)
1461         {
1462           data.from_addr = copy_addr_to_reg (from_addr);
1463           data.autinc_from = 1;
1464           data.explicit_inc_from = 1;
1465         }
1466 #endif
1467       if (!data.autinc_from && CONSTANT_P (from_addr))
1468         data.from_addr = copy_addr_to_reg (from_addr);
1469 #ifdef HAVE_PRE_DECREMENT
1470       if (data.reverse && ! data.autinc_to)
1471         {
1472           data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
1473           data.autinc_to = 1;
1474           data.explicit_inc_to = -1;
1475         }
1476 #endif
1477 #ifdef HAVE_POST_INCREMENT
1478       if (! data.reverse && ! data.autinc_to)
1479         {
1480           data.to_addr = copy_addr_to_reg (to_addr);
1481           data.autinc_to = 1;
1482           data.explicit_inc_to = 1;
1483         }
1484 #endif
1485       if (!data.autinc_to && CONSTANT_P (to_addr))
1486         data.to_addr = copy_addr_to_reg (to_addr);
1487     }
1488
1489   if (! SLOW_UNALIGNED_ACCESS
1490       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1491     align = MOVE_MAX;
1492
1493   /* First move what we can in the largest integer mode, then go to
1494      successively smaller modes.  */
1495
1496   while (max_size > 1)
1497     {
1498       enum machine_mode mode = VOIDmode, tmode;
1499       enum insn_code icode;
1500
1501       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1502            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
1503         if (GET_MODE_SIZE (tmode) < max_size)
1504           mode = tmode;
1505
1506       if (mode == VOIDmode)
1507         break;
1508
1509       icode = mov_optab->handlers[(int) mode].insn_code;
1510       if (icode != CODE_FOR_nothing
1511           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
1512                            GET_MODE_SIZE (mode)))
1513         move_by_pieces_1 (GEN_FCN (icode), mode, &data);
1514
1515       max_size = GET_MODE_SIZE (mode);
1516     }
1517
1518   /* The code above should have handled everything.  */
1519   if (data.len != 0)
1520     abort ();
1521 }
1522
1523 /* Return number of insns required to move L bytes by pieces.
1524    ALIGN (in bytes) is maximum alignment we can assume.  */
1525
1526 static int
1527 move_by_pieces_ninsns (l, align)
1528      unsigned int l;
1529      int align;
1530 {
1531   register int n_insns = 0;
1532   int max_size = MOVE_MAX + 1;
1533
1534   if (! SLOW_UNALIGNED_ACCESS
1535       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1536     align = MOVE_MAX;
1537
1538   while (max_size > 1)
1539     {
1540       enum machine_mode mode = VOIDmode, tmode;
1541       enum insn_code icode;
1542
1543       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1544            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
1545         if (GET_MODE_SIZE (tmode) < max_size)
1546           mode = tmode;
1547
1548       if (mode == VOIDmode)
1549         break;
1550
1551       icode = mov_optab->handlers[(int) mode].insn_code;
1552       if (icode != CODE_FOR_nothing
1553           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
1554                            GET_MODE_SIZE (mode)))
1555         n_insns += l / GET_MODE_SIZE (mode), l %= GET_MODE_SIZE (mode);
1556
1557       max_size = GET_MODE_SIZE (mode);
1558     }
1559
1560   return n_insns;
1561 }
1562
1563 /* Subroutine of move_by_pieces.  Move as many bytes as appropriate
1564    with move instructions for mode MODE.  GENFUN is the gen_... function
1565    to make a move insn for that mode.  DATA has all the other info.  */
1566
1567 static void
1568 move_by_pieces_1 (genfun, mode, data)
1569      rtx (*genfun) ();
1570      enum machine_mode mode;
1571      struct move_by_pieces *data;
1572 {
1573   register int size = GET_MODE_SIZE (mode);
1574   register rtx to1, from1;
1575
1576   while (data->len >= size)
1577     {
1578       if (data->reverse) data->offset -= size;
1579
1580       to1 = (data->autinc_to
1581              ? gen_rtx (MEM, mode, data->to_addr)
1582              : change_address (data->to, mode,
1583                                plus_constant (data->to_addr, data->offset)));
1584       MEM_IN_STRUCT_P (to1) = data->to_struct;
1585       from1 =
1586         (data->autinc_from
1587          ? gen_rtx (MEM, mode, data->from_addr)
1588          : change_address (data->from, mode,
1589                            plus_constant (data->from_addr, data->offset)));
1590       MEM_IN_STRUCT_P (from1) = data->from_struct;
1591
1592 #ifdef HAVE_PRE_DECREMENT
1593       if (data->explicit_inc_to < 0)
1594         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
1595       if (data->explicit_inc_from < 0)
1596         emit_insn (gen_add2_insn (data->from_addr, GEN_INT (-size)));
1597 #endif
1598
1599       emit_insn ((*genfun) (to1, from1));
1600 #ifdef HAVE_POST_INCREMENT
1601       if (data->explicit_inc_to > 0)
1602         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
1603       if (data->explicit_inc_from > 0)
1604         emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size)));
1605 #endif
1606
1607       if (! data->reverse) data->offset += size;
1608
1609       data->len -= size;
1610     }
1611 }
1612 \f
1613 /* Emit code to move a block Y to a block X.
1614    This may be done with string-move instructions,
1615    with multiple scalar move instructions, or with a library call.
1616
1617    Both X and Y must be MEM rtx's (perhaps inside VOLATILE)
1618    with mode BLKmode.
1619    SIZE is an rtx that says how long they are.
1620    ALIGN is the maximum alignment we can assume they have,
1621    measured in bytes.  */
1622
1623 void
1624 emit_block_move (x, y, size, align)
1625      rtx x, y;
1626      rtx size;
1627      int align;
1628 {
1629   if (GET_MODE (x) != BLKmode)
1630     abort ();
1631
1632   if (GET_MODE (y) != BLKmode)
1633     abort ();
1634
1635   x = protect_from_queue (x, 1);
1636   y = protect_from_queue (y, 0);
1637   size = protect_from_queue (size, 0);
1638
1639   if (GET_CODE (x) != MEM)
1640     abort ();
1641   if (GET_CODE (y) != MEM)
1642     abort ();
1643   if (size == 0)
1644     abort ();
1645
1646   if (GET_CODE (size) == CONST_INT
1647       && (move_by_pieces_ninsns (INTVAL (size), align) < MOVE_RATIO))
1648     move_by_pieces (x, y, INTVAL (size), align);
1649   else
1650     {
1651       /* Try the most limited insn first, because there's no point
1652          including more than one in the machine description unless
1653          the more limited one has some advantage.  */
1654
1655       rtx opalign = GEN_INT (align);
1656       enum machine_mode mode;
1657
1658       for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
1659            mode = GET_MODE_WIDER_MODE (mode))
1660         {
1661           enum insn_code code = movstr_optab[(int) mode];
1662
1663           if (code != CODE_FOR_nothing
1664               /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
1665                  here because if SIZE is less than the mode mask, as it is
1666                  returned by the macro, it will definitely be less than the
1667                  actual mode mask.  */
1668               && ((GET_CODE (size) == CONST_INT
1669                    && ((unsigned HOST_WIDE_INT) INTVAL (size)
1670                        <= GET_MODE_MASK (mode)))
1671                   || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
1672               && (insn_operand_predicate[(int) code][0] == 0
1673                   || (*insn_operand_predicate[(int) code][0]) (x, BLKmode))
1674               && (insn_operand_predicate[(int) code][1] == 0
1675                   || (*insn_operand_predicate[(int) code][1]) (y, BLKmode))
1676               && (insn_operand_predicate[(int) code][3] == 0
1677                   || (*insn_operand_predicate[(int) code][3]) (opalign,
1678                                                                VOIDmode)))
1679             {
1680               rtx op2;
1681               rtx last = get_last_insn ();
1682               rtx pat;
1683
1684               op2 = convert_to_mode (mode, size, 1);
1685               if (insn_operand_predicate[(int) code][2] != 0
1686                   && ! (*insn_operand_predicate[(int) code][2]) (op2, mode))
1687                 op2 = copy_to_mode_reg (mode, op2);
1688
1689               pat = GEN_FCN ((int) code) (x, y, op2, opalign);
1690               if (pat)
1691                 {
1692                   emit_insn (pat);
1693                   return;
1694                 }
1695               else
1696                 delete_insns_since (last);
1697             }
1698         }
1699
1700 #ifdef TARGET_MEM_FUNCTIONS
1701       emit_library_call (memcpy_libfunc, 0,
1702                          VOIDmode, 3, XEXP (x, 0), Pmode,
1703                          XEXP (y, 0), Pmode,
1704                          convert_to_mode (TYPE_MODE (sizetype), size,
1705                                           TREE_UNSIGNED (sizetype)),
1706                          TYPE_MODE (sizetype));
1707 #else
1708       emit_library_call (bcopy_libfunc, 0,
1709                          VOIDmode, 3, XEXP (y, 0), Pmode,
1710                          XEXP (x, 0), Pmode,
1711                          convert_to_mode (TYPE_MODE (integer_type_node), size,
1712                                           TREE_UNSIGNED (integer_type_node)),
1713                          TYPE_MODE (integer_type_node));
1714 #endif
1715     }
1716 }
1717 \f
1718 /* Copy all or part of a value X into registers starting at REGNO.
1719    The number of registers to be filled is NREGS.  */
1720
1721 void
1722 move_block_to_reg (regno, x, nregs, mode)
1723      int regno;
1724      rtx x;
1725      int nregs;
1726      enum machine_mode mode;
1727 {
1728   int i;
1729   rtx pat, last;
1730
1731   if (nregs == 0)
1732     return;
1733
1734   if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
1735     x = validize_mem (force_const_mem (mode, x));
1736
1737   /* See if the machine can do this with a load multiple insn.  */
1738 #ifdef HAVE_load_multiple
1739   if (HAVE_load_multiple)
1740     {
1741       last = get_last_insn ();
1742       pat = gen_load_multiple (gen_rtx (REG, word_mode, regno), x,
1743                                GEN_INT (nregs));
1744       if (pat)
1745         {
1746           emit_insn (pat);
1747           return;
1748         }
1749       else
1750         delete_insns_since (last);
1751     }
1752 #endif
1753
1754   for (i = 0; i < nregs; i++)
1755     emit_move_insn (gen_rtx (REG, word_mode, regno + i),
1756                     operand_subword_force (x, i, mode));
1757 }
1758
1759 /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
1760    The number of registers to be filled is NREGS.  SIZE indicates the number
1761    of bytes in the object X.  */
1762
1763
1764 void
1765 move_block_from_reg (regno, x, nregs, size)
1766      int regno;
1767      rtx x;
1768      int nregs;
1769      int size;
1770 {
1771   int i;
1772   rtx pat, last;
1773
1774   /* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned
1775      to the left before storing to memory.  */
1776   if (size < UNITS_PER_WORD && BYTES_BIG_ENDIAN)
1777     {
1778       rtx tem = operand_subword (x, 0, 1, BLKmode);
1779       rtx shift;
1780
1781       if (tem == 0)
1782         abort ();
1783
1784       shift = expand_shift (LSHIFT_EXPR, word_mode,
1785                             gen_rtx (REG, word_mode, regno),
1786                             build_int_2 ((UNITS_PER_WORD - size)
1787                                          * BITS_PER_UNIT, 0), NULL_RTX, 0);
1788       emit_move_insn (tem, shift);
1789       return;
1790     }
1791
1792   /* See if the machine can do this with a store multiple insn.  */
1793 #ifdef HAVE_store_multiple
1794   if (HAVE_store_multiple)
1795     {
1796       last = get_last_insn ();
1797       pat = gen_store_multiple (x, gen_rtx (REG, word_mode, regno),
1798                                 GEN_INT (nregs));
1799       if (pat)
1800         {
1801           emit_insn (pat);
1802           return;
1803         }
1804       else
1805         delete_insns_since (last);
1806     }
1807 #endif
1808
1809   for (i = 0; i < nregs; i++)
1810     {
1811       rtx tem = operand_subword (x, i, 1, BLKmode);
1812
1813       if (tem == 0)
1814         abort ();
1815
1816       emit_move_insn (tem, gen_rtx (REG, word_mode, regno + i));
1817     }
1818 }
1819
1820 /* Add a USE expression for REG to the (possibly empty) list pointed
1821    to by CALL_FUSAGE.  REG must denote a hard register.  */
1822
1823 void
1824 use_reg (call_fusage, reg)
1825      rtx *call_fusage, reg;
1826 {
1827   if (GET_CODE (reg) != REG
1828       || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
1829     abort();
1830
1831   *call_fusage
1832     = gen_rtx (EXPR_LIST, VOIDmode,
1833                gen_rtx (USE, VOIDmode, reg), *call_fusage);
1834 }
1835
1836 /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
1837    starting at REGNO.  All of these registers must be hard registers.  */
1838
1839 void
1840 use_regs (call_fusage, regno, nregs)
1841      rtx *call_fusage;
1842      int regno;
1843      int nregs;
1844 {
1845   int i;
1846
1847   if (regno + nregs > FIRST_PSEUDO_REGISTER)
1848     abort ();
1849
1850   for (i = 0; i < nregs; i++)
1851     use_reg (call_fusage, gen_rtx (REG, reg_raw_mode[regno + i], regno + i));
1852 }
1853 \f
1854 /* Generate several move instructions to clear LEN bytes of block TO.
1855    (A MEM rtx with BLKmode).   The caller must pass TO through
1856    protect_from_queue before calling. ALIGN (in bytes) is maximum alignment
1857    we can assume.  */
1858
1859 static void
1860 clear_by_pieces (to, len, align)
1861      rtx to;
1862      int len, align;
1863 {
1864   struct clear_by_pieces data;
1865   rtx to_addr = XEXP (to, 0);
1866   int max_size = MOVE_MAX + 1;
1867
1868   data.offset = 0;
1869   data.to_addr = to_addr;
1870   data.to = to;
1871   data.autinc_to
1872     = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
1873        || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
1874
1875   data.explicit_inc_to = 0;
1876   data.reverse
1877     = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
1878   if (data.reverse) data.offset = len;
1879   data.len = len;
1880
1881   data.to_struct = MEM_IN_STRUCT_P (to);
1882
1883   /* If copying requires more than two move insns,
1884      copy addresses to registers (to make displacements shorter)
1885      and use post-increment if available.  */
1886   if (!data.autinc_to
1887       && move_by_pieces_ninsns (len, align) > 2)
1888     {
1889 #ifdef HAVE_PRE_DECREMENT
1890       if (data.reverse && ! data.autinc_to)
1891         {
1892           data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
1893           data.autinc_to = 1;
1894           data.explicit_inc_to = -1;
1895         }
1896 #endif
1897 #ifdef HAVE_POST_INCREMENT
1898       if (! data.reverse && ! data.autinc_to)
1899         {
1900           data.to_addr = copy_addr_to_reg (to_addr);
1901           data.autinc_to = 1;
1902           data.explicit_inc_to = 1;
1903         }
1904 #endif
1905       if (!data.autinc_to && CONSTANT_P (to_addr))
1906         data.to_addr = copy_addr_to_reg (to_addr);
1907     }
1908
1909   if (! SLOW_UNALIGNED_ACCESS
1910       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1911     align = MOVE_MAX;
1912
1913   /* First move what we can in the largest integer mode, then go to
1914      successively smaller modes.  */
1915
1916   while (max_size > 1)
1917     {
1918       enum machine_mode mode = VOIDmode, tmode;
1919       enum insn_code icode;
1920
1921       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1922            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
1923         if (GET_MODE_SIZE (tmode) < max_size)
1924           mode = tmode;
1925
1926       if (mode == VOIDmode)
1927         break;
1928
1929       icode = mov_optab->handlers[(int) mode].insn_code;
1930       if (icode != CODE_FOR_nothing
1931           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
1932                            GET_MODE_SIZE (mode)))
1933         clear_by_pieces_1 (GEN_FCN (icode), mode, &data);
1934
1935       max_size = GET_MODE_SIZE (mode);
1936     }
1937
1938   /* The code above should have handled everything.  */
1939   if (data.len != 0)
1940     abort ();
1941 }
1942
1943 /* Subroutine of clear_by_pieces.  Clear as many bytes as appropriate
1944    with move instructions for mode MODE.  GENFUN is the gen_... function
1945    to make a move insn for that mode.  DATA has all the other info.  */
1946
1947 static void
1948 clear_by_pieces_1 (genfun, mode, data)
1949      rtx (*genfun) ();
1950      enum machine_mode mode;
1951      struct clear_by_pieces *data;
1952 {
1953   register int size = GET_MODE_SIZE (mode);
1954   register rtx to1;
1955
1956   while (data->len >= size)
1957     {
1958       if (data->reverse) data->offset -= size;
1959
1960       to1 = (data->autinc_to
1961              ? gen_rtx (MEM, mode, data->to_addr)
1962              : change_address (data->to, mode,
1963                                plus_constant (data->to_addr, data->offset)));
1964       MEM_IN_STRUCT_P (to1) = data->to_struct;
1965
1966 #ifdef HAVE_PRE_DECREMENT
1967       if (data->explicit_inc_to < 0)
1968         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
1969 #endif
1970
1971       emit_insn ((*genfun) (to1, const0_rtx));
1972 #ifdef HAVE_POST_INCREMENT
1973       if (data->explicit_inc_to > 0)
1974         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
1975 #endif
1976
1977       if (! data->reverse) data->offset += size;
1978
1979       data->len -= size;
1980     }
1981 }
1982 \f
1983 /* Write zeros through the storage of OBJECT.
1984    If OBJECT has BLKmode, SIZE is its length in bytes and ALIGN is
1985    the maximum alignment we can is has, measured in bytes.  */
1986
1987 void
1988 clear_storage (object, size, align)
1989      rtx object;
1990      rtx size;
1991      int align;
1992 {
1993   if (GET_MODE (object) == BLKmode)
1994     {
1995       object = protect_from_queue (object, 1);
1996       size = protect_from_queue (size, 0);
1997
1998       if (GET_CODE (size) == CONST_INT
1999           && (move_by_pieces_ninsns (INTVAL (size), align) < MOVE_RATIO))
2000         clear_by_pieces (object, INTVAL (size), align);
2001
2002       else
2003         {
2004           /* Try the most limited insn first, because there's no point
2005              including more than one in the machine description unless
2006              the more limited one has some advantage.  */
2007
2008           rtx opalign = GEN_INT (align);
2009           enum machine_mode mode;
2010
2011           for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
2012                mode = GET_MODE_WIDER_MODE (mode))
2013             {
2014               enum insn_code code = clrstr_optab[(int) mode];
2015
2016               if (code != CODE_FOR_nothing
2017                   /* We don't need MODE to be narrower than
2018                      BITS_PER_HOST_WIDE_INT here because if SIZE is less than
2019                      the mode mask, as it is returned by the macro, it will
2020                      definitely be less than the actual mode mask.  */
2021                   && ((GET_CODE (size) == CONST_INT
2022                        && ((unsigned HOST_WIDE_INT) INTVAL (size)
2023                            <= GET_MODE_MASK (mode)))
2024                       || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
2025                   && (insn_operand_predicate[(int) code][0] == 0
2026                       || (*insn_operand_predicate[(int) code][0]) (object,
2027                                                                    BLKmode))
2028                   && (insn_operand_predicate[(int) code][2] == 0
2029                       || (*insn_operand_predicate[(int) code][2]) (opalign,
2030                                                                    VOIDmode)))
2031                 {
2032                   rtx op1;
2033                   rtx last = get_last_insn ();
2034                   rtx pat;
2035
2036                   op1 = convert_to_mode (mode, size, 1);
2037                   if (insn_operand_predicate[(int) code][1] != 0
2038                       && ! (*insn_operand_predicate[(int) code][1]) (op1,
2039                                                                      mode))
2040                     op1 = copy_to_mode_reg (mode, op1);
2041
2042                   pat = GEN_FCN ((int) code) (object, op1, opalign);
2043                   if (pat)
2044                     {
2045                       emit_insn (pat);
2046                       return;
2047                     }
2048                   else
2049                     delete_insns_since (last);
2050                 }
2051             }
2052
2053
2054 #ifdef TARGET_MEM_FUNCTIONS
2055           emit_library_call (memset_libfunc, 0,
2056                              VOIDmode, 3,
2057                              XEXP (object, 0), Pmode,
2058                              const0_rtx, TYPE_MODE (integer_type_node),
2059                              convert_to_mode (TYPE_MODE (sizetype),
2060                                               size, TREE_UNSIGNED (sizetype)),
2061                              TYPE_MODE (sizetype));
2062 #else
2063           emit_library_call (bzero_libfunc, 0,
2064                              VOIDmode, 2,
2065                              XEXP (object, 0), Pmode,   
2066                              convert_to_mode (TYPE_MODE (integer_type_node),
2067                                               size,
2068                                               TREE_UNSIGNED (integer_type_node)),
2069                              TYPE_MODE (integer_type_node));
2070 #endif
2071         }
2072     }
2073   else
2074     emit_move_insn (object, const0_rtx);
2075 }
2076
2077 /* Generate code to copy Y into X.
2078    Both Y and X must have the same mode, except that
2079    Y can be a constant with VOIDmode.
2080    This mode cannot be BLKmode; use emit_block_move for that.
2081
2082    Return the last instruction emitted.  */
2083
2084 rtx
2085 emit_move_insn (x, y)
2086      rtx x, y;
2087 {
2088   enum machine_mode mode = GET_MODE (x);
2089
2090   x = protect_from_queue (x, 1);
2091   y = protect_from_queue (y, 0);
2092
2093   if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
2094     abort ();
2095
2096   if (CONSTANT_P (y) && ! LEGITIMATE_CONSTANT_P (y))
2097     y = force_const_mem (mode, y);
2098
2099   /* If X or Y are memory references, verify that their addresses are valid
2100      for the machine.  */
2101   if (GET_CODE (x) == MEM
2102       && ((! memory_address_p (GET_MODE (x), XEXP (x, 0))
2103            && ! push_operand (x, GET_MODE (x)))
2104           || (flag_force_addr
2105               && CONSTANT_ADDRESS_P (XEXP (x, 0)))))
2106     x = change_address (x, VOIDmode, XEXP (x, 0));
2107
2108   if (GET_CODE (y) == MEM
2109       && (! memory_address_p (GET_MODE (y), XEXP (y, 0))
2110           || (flag_force_addr
2111               && CONSTANT_ADDRESS_P (XEXP (y, 0)))))
2112     y = change_address (y, VOIDmode, XEXP (y, 0));
2113
2114   if (mode == BLKmode)
2115     abort ();
2116
2117   return emit_move_insn_1 (x, y);
2118 }
2119
2120 /* Low level part of emit_move_insn.
2121    Called just like emit_move_insn, but assumes X and Y
2122    are basically valid.  */
2123
2124 rtx
2125 emit_move_insn_1 (x, y)
2126      rtx x, y;
2127 {
2128   enum machine_mode mode = GET_MODE (x);
2129   enum machine_mode submode;
2130   enum mode_class class = GET_MODE_CLASS (mode);
2131   int i;
2132
2133   if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2134     return
2135       emit_insn (GEN_FCN (mov_optab->handlers[(int) mode].insn_code) (x, y));
2136
2137   /* Expand complex moves by moving real part and imag part, if possible.  */
2138   else if ((class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
2139            && BLKmode != (submode = mode_for_size ((GET_MODE_UNIT_SIZE (mode)
2140                                                     * BITS_PER_UNIT),
2141                                                    (class == MODE_COMPLEX_INT
2142                                                     ? MODE_INT : MODE_FLOAT),
2143                                                    0))
2144            && (mov_optab->handlers[(int) submode].insn_code
2145                != CODE_FOR_nothing))
2146     {
2147       /* Don't split destination if it is a stack push.  */
2148       int stack = push_operand (x, GET_MODE (x));
2149       rtx insns;
2150
2151       /* If this is a stack, push the highpart first, so it
2152          will be in the argument order.
2153
2154          In that case, change_address is used only to convert
2155          the mode, not to change the address.  */
2156       if (stack)
2157         {
2158           /* Note that the real part always precedes the imag part in memory
2159              regardless of machine's endianness.  */
2160 #ifdef STACK_GROWS_DOWNWARD
2161           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2162                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2163                       gen_imagpart (submode, y)));
2164           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2165                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2166                       gen_realpart (submode, y)));
2167 #else
2168           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2169                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2170                       gen_realpart (submode, y)));
2171           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2172                      (gen_rtx (MEM, submode, (XEXP (x, 0))),
2173                       gen_imagpart (submode, y)));
2174 #endif
2175         }
2176       else
2177         {
2178           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2179                      (gen_realpart (submode, x), gen_realpart (submode, y)));
2180           emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
2181                      (gen_imagpart (submode, x), gen_imagpart (submode, y)));
2182         }
2183
2184       return get_last_insn ();
2185     }
2186
2187   /* This will handle any multi-word mode that lacks a move_insn pattern.
2188      However, you will get better code if you define such patterns,
2189      even if they must turn into multiple assembler instructions.  */
2190   else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
2191     {
2192       rtx last_insn = 0;
2193       rtx insns;
2194       
2195 #ifdef PUSH_ROUNDING
2196
2197       /* If X is a push on the stack, do the push now and replace
2198          X with a reference to the stack pointer.  */
2199       if (push_operand (x, GET_MODE (x)))
2200         {
2201           anti_adjust_stack (GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
2202           x = change_address (x, VOIDmode, stack_pointer_rtx);
2203         }
2204 #endif
2205                              
2206       /* Show the output dies here.  */
2207       if (x != y)
2208         emit_insn (gen_rtx (CLOBBER, VOIDmode, x));
2209
2210       for (i = 0;
2211            i < (GET_MODE_SIZE (mode)  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
2212            i++)
2213         {
2214           rtx xpart = operand_subword (x, i, 1, mode);
2215           rtx ypart = operand_subword (y, i, 1, mode);
2216
2217           /* If we can't get a part of Y, put Y into memory if it is a
2218              constant.  Otherwise, force it into a register.  If we still
2219              can't get a part of Y, abort.  */
2220           if (ypart == 0 && CONSTANT_P (y))
2221             {
2222               y = force_const_mem (mode, y);
2223               ypart = operand_subword (y, i, 1, mode);
2224             }
2225           else if (ypart == 0)
2226             ypart = operand_subword_force (y, i, mode);
2227
2228           if (xpart == 0 || ypart == 0)
2229             abort ();
2230
2231           last_insn = emit_move_insn (xpart, ypart);
2232         }
2233
2234       return last_insn;
2235     }
2236   else
2237     abort ();
2238 }
2239 \f
2240 /* Pushing data onto the stack.  */
2241
2242 /* Push a block of length SIZE (perhaps variable)
2243    and return an rtx to address the beginning of the block.
2244    Note that it is not possible for the value returned to be a QUEUED.
2245    The value may be virtual_outgoing_args_rtx.
2246
2247    EXTRA is the number of bytes of padding to push in addition to SIZE.
2248    BELOW nonzero means this padding comes at low addresses;
2249    otherwise, the padding comes at high addresses.  */
2250
2251 rtx
2252 push_block (size, extra, below)
2253      rtx size;
2254      int extra, below;
2255 {
2256   register rtx temp;
2257
2258   size = convert_modes (Pmode, ptr_mode, size, 1);
2259   if (CONSTANT_P (size))
2260     anti_adjust_stack (plus_constant (size, extra));
2261   else if (GET_CODE (size) == REG && extra == 0)
2262     anti_adjust_stack (size);
2263   else
2264     {
2265       rtx temp = copy_to_mode_reg (Pmode, size);
2266       if (extra != 0)
2267         temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra),
2268                              temp, 0, OPTAB_LIB_WIDEN);
2269       anti_adjust_stack (temp);
2270     }
2271
2272 #ifdef STACK_GROWS_DOWNWARD
2273   temp = virtual_outgoing_args_rtx;
2274   if (extra != 0 && below)
2275     temp = plus_constant (temp, extra);
2276 #else
2277   if (GET_CODE (size) == CONST_INT)
2278     temp = plus_constant (virtual_outgoing_args_rtx,
2279                           - INTVAL (size) - (below ? 0 : extra));
2280   else if (extra != 0 && !below)
2281     temp = gen_rtx (PLUS, Pmode, virtual_outgoing_args_rtx,
2282                     negate_rtx (Pmode, plus_constant (size, extra)));
2283   else
2284     temp = gen_rtx (PLUS, Pmode, virtual_outgoing_args_rtx,
2285                     negate_rtx (Pmode, size));
2286 #endif
2287
2288   return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
2289 }
2290
2291 rtx
2292 gen_push_operand ()
2293 {
2294   return gen_rtx (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
2295 }
2296
2297 /* Generate code to push X onto the stack, assuming it has mode MODE and
2298    type TYPE.
2299    MODE is redundant except when X is a CONST_INT (since they don't
2300    carry mode info).
2301    SIZE is an rtx for the size of data to be copied (in bytes),
2302    needed only if X is BLKmode.
2303
2304    ALIGN (in bytes) is maximum alignment we can assume.
2305
2306    If PARTIAL and REG are both nonzero, then copy that many of the first
2307    words of X into registers starting with REG, and push the rest of X.
2308    The amount of space pushed is decreased by PARTIAL words,
2309    rounded *down* to a multiple of PARM_BOUNDARY.
2310    REG must be a hard register in this case.
2311    If REG is zero but PARTIAL is not, take any all others actions for an
2312    argument partially in registers, but do not actually load any
2313    registers.
2314
2315    EXTRA is the amount in bytes of extra space to leave next to this arg.
2316    This is ignored if an argument block has already been allocated.
2317
2318    On a machine that lacks real push insns, ARGS_ADDR is the address of
2319    the bottom of the argument block for this call.  We use indexing off there
2320    to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
2321    argument block has not been preallocated.
2322
2323    ARGS_SO_FAR is the size of args previously pushed for this call.  */
2324
2325 void
2326 emit_push_insn (x, mode, type, size, align, partial, reg, extra,
2327                 args_addr, args_so_far)
2328      register rtx x;
2329      enum machine_mode mode;
2330      tree type;
2331      rtx size;
2332      int align;
2333      int partial;
2334      rtx reg;
2335      int extra;
2336      rtx args_addr;
2337      rtx args_so_far;
2338 {
2339   rtx xinner;
2340   enum direction stack_direction
2341 #ifdef STACK_GROWS_DOWNWARD
2342     = downward;
2343 #else
2344     = upward;
2345 #endif
2346
2347   /* Decide where to pad the argument: `downward' for below,
2348      `upward' for above, or `none' for don't pad it.
2349      Default is below for small data on big-endian machines; else above.  */
2350   enum direction where_pad = FUNCTION_ARG_PADDING (mode, type);
2351
2352   /* If we're placing part of X into a register and part of X onto
2353      the stack, indicate that the entire register is clobbered to
2354      keep flow from thinking the unused part of the register is live.  */
2355   if (partial > 0 && reg != 0)
2356     emit_insn (gen_rtx (CLOBBER, VOIDmode, reg));
2357
2358   /* Invert direction if stack is post-update.  */
2359   if (STACK_PUSH_CODE == POST_INC || STACK_PUSH_CODE == POST_DEC)
2360     if (where_pad != none)
2361       where_pad = (where_pad == downward ? upward : downward);
2362
2363   xinner = x = protect_from_queue (x, 0);
2364
2365   if (mode == BLKmode)
2366     {
2367       /* Copy a block into the stack, entirely or partially.  */
2368
2369       register rtx temp;
2370       int used = partial * UNITS_PER_WORD;
2371       int offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
2372       int skip;
2373       
2374       if (size == 0)
2375         abort ();
2376
2377       used -= offset;
2378
2379       /* USED is now the # of bytes we need not copy to the stack
2380          because registers will take care of them.  */
2381
2382       if (partial != 0)
2383         xinner = change_address (xinner, BLKmode,
2384                                  plus_constant (XEXP (xinner, 0), used));
2385
2386       /* If the partial register-part of the arg counts in its stack size,
2387          skip the part of stack space corresponding to the registers.
2388          Otherwise, start copying to the beginning of the stack space,
2389          by setting SKIP to 0.  */
2390 #ifndef REG_PARM_STACK_SPACE
2391       skip = 0;
2392 #else
2393       skip = used;
2394 #endif
2395
2396 #ifdef PUSH_ROUNDING
2397       /* Do it with several push insns if that doesn't take lots of insns
2398          and if there is no difficulty with push insns that skip bytes
2399          on the stack for alignment purposes.  */
2400       if (args_addr == 0
2401           && GET_CODE (size) == CONST_INT
2402           && skip == 0
2403           && (move_by_pieces_ninsns ((unsigned) INTVAL (size) - used, align)
2404               < MOVE_RATIO)
2405           /* Here we avoid the case of a structure whose weak alignment
2406              forces many pushes of a small amount of data,
2407              and such small pushes do rounding that causes trouble.  */
2408           && ((! SLOW_UNALIGNED_ACCESS)
2409               || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT
2410               || PUSH_ROUNDING (align) == align)
2411           && PUSH_ROUNDING (INTVAL (size)) == INTVAL (size))
2412         {
2413           /* Push padding now if padding above and stack grows down,
2414              or if padding below and stack grows up.
2415              But if space already allocated, this has already been done.  */
2416           if (extra && args_addr == 0
2417               && where_pad != none && where_pad != stack_direction)
2418             anti_adjust_stack (GEN_INT (extra));
2419
2420           move_by_pieces (gen_rtx (MEM, BLKmode, gen_push_operand ()), xinner,
2421                           INTVAL (size) - used, align);
2422         }
2423       else
2424 #endif /* PUSH_ROUNDING */
2425         {
2426           /* Otherwise make space on the stack and copy the data
2427              to the address of that space.  */
2428
2429           /* Deduct words put into registers from the size we must copy.  */
2430           if (partial != 0)
2431             {
2432               if (GET_CODE (size) == CONST_INT)
2433                 size = GEN_INT (INTVAL (size) - used);
2434               else
2435                 size = expand_binop (GET_MODE (size), sub_optab, size,
2436                                      GEN_INT (used), NULL_RTX, 0,
2437                                      OPTAB_LIB_WIDEN);
2438             }
2439
2440           /* Get the address of the stack space.
2441              In this case, we do not deal with EXTRA separately.
2442              A single stack adjust will do.  */
2443           if (! args_addr)
2444             {
2445               temp = push_block (size, extra, where_pad == downward);
2446               extra = 0;
2447             }
2448           else if (GET_CODE (args_so_far) == CONST_INT)
2449             temp = memory_address (BLKmode,
2450                                    plus_constant (args_addr,
2451                                                   skip + INTVAL (args_so_far)));
2452           else
2453             temp = memory_address (BLKmode,
2454                                    plus_constant (gen_rtx (PLUS, Pmode,
2455                                                            args_addr, args_so_far),
2456                                                   skip));
2457
2458           /* TEMP is the address of the block.  Copy the data there.  */
2459           if (GET_CODE (size) == CONST_INT
2460               && (move_by_pieces_ninsns ((unsigned) INTVAL (size), align)
2461                   < MOVE_RATIO))
2462             {
2463               move_by_pieces (gen_rtx (MEM, BLKmode, temp), xinner,
2464                               INTVAL (size), align);
2465               goto ret;
2466             }
2467           /* Try the most limited insn first, because there's no point
2468              including more than one in the machine description unless
2469              the more limited one has some advantage.  */
2470 #ifdef HAVE_movstrqi
2471           if (HAVE_movstrqi
2472               && GET_CODE (size) == CONST_INT
2473               && ((unsigned) INTVAL (size)
2474                   < (1 << (GET_MODE_BITSIZE (QImode) - 1))))
2475             {
2476               rtx pat = gen_movstrqi (gen_rtx (MEM, BLKmode, temp),
2477                                       xinner, size, GEN_INT (align));
2478               if (pat != 0)
2479                 {
2480                   emit_insn (pat);
2481                   goto ret;
2482                 }
2483             }
2484 #endif
2485 #ifdef HAVE_movstrhi
2486           if (HAVE_movstrhi
2487               && GET_CODE (size) == CONST_INT
2488               && ((unsigned) INTVAL (size)
2489                   < (1 << (GET_MODE_BITSIZE (HImode) - 1))))
2490             {
2491               rtx pat = gen_movstrhi (gen_rtx (MEM, BLKmode, temp),
2492                                       xinner, size, GEN_INT (align));
2493               if (pat != 0)
2494                 {
2495                   emit_insn (pat);
2496                   goto ret;
2497                 }
2498             }
2499 #endif
2500 #ifdef HAVE_movstrsi
2501           if (HAVE_movstrsi)
2502             {
2503               rtx pat = gen_movstrsi (gen_rtx (MEM, BLKmode, temp),
2504                                       xinner, size, GEN_INT (align));
2505               if (pat != 0)
2506                 {
2507                   emit_insn (pat);
2508                   goto ret;
2509                 }
2510             }
2511 #endif
2512 #ifdef HAVE_movstrdi
2513           if (HAVE_movstrdi)
2514             {
2515               rtx pat = gen_movstrdi (gen_rtx (MEM, BLKmode, temp),
2516                                       xinner, size, GEN_INT (align));
2517               if (pat != 0)
2518                 {
2519                   emit_insn (pat);
2520                   goto ret;
2521                 }
2522             }
2523 #endif
2524
2525 #ifndef ACCUMULATE_OUTGOING_ARGS
2526           /* If the source is referenced relative to the stack pointer,
2527              copy it to another register to stabilize it.  We do not need
2528              to do this if we know that we won't be changing sp.  */
2529
2530           if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
2531               || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
2532             temp = copy_to_reg (temp);
2533 #endif
2534
2535           /* Make inhibit_defer_pop nonzero around the library call
2536              to force it to pop the bcopy-arguments right away.  */
2537           NO_DEFER_POP;
2538 #ifdef TARGET_MEM_FUNCTIONS
2539           emit_library_call (memcpy_libfunc, 0,
2540                              VOIDmode, 3, temp, Pmode, XEXP (xinner, 0), Pmode,
2541                              convert_to_mode (TYPE_MODE (sizetype),
2542                                               size, TREE_UNSIGNED (sizetype)),
2543                              TYPE_MODE (sizetype));
2544 #else
2545           emit_library_call (bcopy_libfunc, 0,
2546                              VOIDmode, 3, XEXP (xinner, 0), Pmode, temp, Pmode,
2547                              convert_to_mode (TYPE_MODE (integer_type_node),
2548                                               size,
2549                                               TREE_UNSIGNED (integer_type_node)),
2550                              TYPE_MODE (integer_type_node));
2551 #endif
2552           OK_DEFER_POP;
2553         }
2554     }
2555   else if (partial > 0)
2556     {
2557       /* Scalar partly in registers.  */
2558
2559       int size = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
2560       int i;
2561       int not_stack;
2562       /* # words of start of argument
2563          that we must make space for but need not store.  */
2564       int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
2565       int args_offset = INTVAL (args_so_far);
2566       int skip;
2567
2568       /* Push padding now if padding above and stack grows down,
2569          or if padding below and stack grows up.
2570          But if space already allocated, this has already been done.  */
2571       if (extra && args_addr == 0
2572           && where_pad != none && where_pad != stack_direction)
2573         anti_adjust_stack (GEN_INT (extra));
2574
2575       /* If we make space by pushing it, we might as well push
2576          the real data.  Otherwise, we can leave OFFSET nonzero
2577          and leave the space uninitialized.  */
2578       if (args_addr == 0)
2579         offset = 0;
2580
2581       /* Now NOT_STACK gets the number of words that we don't need to
2582          allocate on the stack.  */
2583       not_stack = partial - offset;
2584
2585       /* If the partial register-part of the arg counts in its stack size,
2586          skip the part of stack space corresponding to the registers.
2587          Otherwise, start copying to the beginning of the stack space,
2588          by setting SKIP to 0.  */
2589 #ifndef REG_PARM_STACK_SPACE
2590       skip = 0;
2591 #else
2592       skip = not_stack;
2593 #endif
2594
2595       if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
2596         x = validize_mem (force_const_mem (mode, x));
2597
2598       /* If X is a hard register in a non-integer mode, copy it into a pseudo;
2599          SUBREGs of such registers are not allowed.  */
2600       if ((GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER
2601            && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
2602         x = copy_to_reg (x);
2603
2604       /* Loop over all the words allocated on the stack for this arg.  */
2605       /* We can do it by words, because any scalar bigger than a word
2606          has a size a multiple of a word.  */
2607 #ifndef PUSH_ARGS_REVERSED
2608       for (i = not_stack; i < size; i++)
2609 #else
2610       for (i = size - 1; i >= not_stack; i--)
2611 #endif
2612         if (i >= not_stack + offset)
2613           emit_push_insn (operand_subword_force (x, i, mode),
2614                           word_mode, NULL_TREE, NULL_RTX, align, 0, NULL_RTX,
2615                           0, args_addr,
2616                           GEN_INT (args_offset + ((i - not_stack + skip)
2617                                                   * UNITS_PER_WORD)));
2618     }
2619   else
2620     {
2621       rtx addr;
2622
2623       /* Push padding now if padding above and stack grows down,
2624          or if padding below and stack grows up.
2625          But if space already allocated, this has already been done.  */
2626       if (extra && args_addr == 0
2627           && where_pad != none && where_pad != stack_direction)
2628         anti_adjust_stack (GEN_INT (extra));
2629
2630 #ifdef PUSH_ROUNDING
2631       if (args_addr == 0)
2632         addr = gen_push_operand ();
2633       else
2634 #endif
2635         if (GET_CODE (args_so_far) == CONST_INT)
2636           addr
2637             = memory_address (mode,
2638                               plus_constant (args_addr, INTVAL (args_so_far)));
2639       else
2640         addr = memory_address (mode, gen_rtx (PLUS, Pmode, args_addr,
2641                                               args_so_far));
2642
2643       emit_move_insn (gen_rtx (MEM, mode, addr), x);
2644     }
2645
2646  ret:
2647   /* If part should go in registers, copy that part
2648      into the appropriate registers.  Do this now, at the end,
2649      since mem-to-mem copies above may do function calls.  */
2650   if (partial > 0 && reg != 0)
2651     move_block_to_reg (REGNO (reg), x, partial, mode);
2652
2653   if (extra && args_addr == 0 && where_pad == stack_direction)
2654     anti_adjust_stack (GEN_INT (extra));
2655 }
2656 \f
2657 /* Expand an assignment that stores the value of FROM into TO.
2658    If WANT_VALUE is nonzero, return an rtx for the value of TO.
2659    (This may contain a QUEUED rtx;
2660    if the value is constant, this rtx is a constant.)
2661    Otherwise, the returned value is NULL_RTX.
2662
2663    SUGGEST_REG is no longer actually used.
2664    It used to mean, copy the value through a register
2665    and return that register, if that is possible.
2666    We now use WANT_VALUE to decide whether to do this.  */
2667
2668 rtx
2669 expand_assignment (to, from, want_value, suggest_reg)
2670      tree to, from;
2671      int want_value;
2672      int suggest_reg;
2673 {
2674   register rtx to_rtx = 0;
2675   rtx result;
2676
2677   /* Don't crash if the lhs of the assignment was erroneous.  */
2678
2679   if (TREE_CODE (to) == ERROR_MARK)
2680     {
2681       result = expand_expr (from, NULL_RTX, VOIDmode, 0);
2682       return want_value ? result : NULL_RTX;
2683     }
2684
2685   if (output_bytecode)
2686     {
2687       tree dest_innermost;
2688
2689       bc_expand_expr (from);
2690       bc_emit_instruction (duplicate);
2691
2692       dest_innermost = bc_expand_address (to);
2693
2694       /* Can't deduce from TYPE that we're dealing with a bitfield, so
2695          take care of it here. */
2696
2697       bc_store_memory (TREE_TYPE (to), dest_innermost);
2698       return NULL;
2699     }
2700
2701   /* Assignment of a structure component needs special treatment
2702      if the structure component's rtx is not simply a MEM.
2703      Assignment of an array element at a constant index, and assignment of
2704      an array element in an unaligned packed structure field, has the same
2705      problem.  */
2706
2707   if (TREE_CODE (to) == COMPONENT_REF
2708       || TREE_CODE (to) == BIT_FIELD_REF
2709       || (TREE_CODE (to) == ARRAY_REF
2710           && ((TREE_CODE (TREE_OPERAND (to, 1)) == INTEGER_CST
2711                && TREE_CODE (TYPE_SIZE (TREE_TYPE (to))) == INTEGER_CST)
2712               || (SLOW_UNALIGNED_ACCESS && get_inner_unaligned_p (to)))))
2713     {
2714       enum machine_mode mode1;
2715       int bitsize;
2716       int bitpos;
2717       tree offset;
2718       int unsignedp;
2719       int volatilep = 0;
2720       tree tem;
2721       int alignment;
2722
2723       push_temp_slots ();
2724       tem = get_inner_reference (to, &bitsize, &bitpos, &offset,
2725                                       &mode1, &unsignedp, &volatilep);
2726
2727       /* If we are going to use store_bit_field and extract_bit_field,
2728          make sure to_rtx will be safe for multiple use.  */
2729
2730       if (mode1 == VOIDmode && want_value)
2731         tem = stabilize_reference (tem);
2732
2733       alignment = TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT;
2734       to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
2735       if (offset != 0)
2736         {
2737           rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
2738
2739           if (GET_CODE (to_rtx) != MEM)
2740             abort ();
2741           to_rtx = change_address (to_rtx, VOIDmode,
2742                                    gen_rtx (PLUS, ptr_mode, XEXP (to_rtx, 0),
2743                                             force_reg (ptr_mode, offset_rtx)));
2744           /* If we have a variable offset, the known alignment
2745              is only that of the innermost structure containing the field.
2746              (Actually, we could sometimes do better by using the
2747              align of an element of the innermost array, but no need.)  */
2748           if (TREE_CODE (to) == COMPONENT_REF
2749               || TREE_CODE (to) == BIT_FIELD_REF)
2750             alignment
2751               = TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (to, 0))) / BITS_PER_UNIT;
2752         }
2753       if (volatilep)
2754         {
2755           if (GET_CODE (to_rtx) == MEM)
2756             {
2757               /* When the offset is zero, to_rtx is the address of the
2758                  structure we are storing into, and hence may be shared.
2759                  We must make a new MEM before setting the volatile bit.  */
2760               if (offset == 0)
2761                 to_rtx = change_address (to_rtx, VOIDmode, XEXP (to_rtx, 0));
2762               MEM_VOLATILE_P (to_rtx) = 1;
2763             }
2764 #if 0  /* This was turned off because, when a field is volatile
2765           in an object which is not volatile, the object may be in a register,
2766           and then we would abort over here.  */
2767           else
2768             abort ();
2769 #endif
2770         }
2771
2772       result = store_field (to_rtx, bitsize, bitpos, mode1, from,
2773                             (want_value
2774                              /* Spurious cast makes HPUX compiler happy.  */
2775                              ? (enum machine_mode) TYPE_MODE (TREE_TYPE (to))
2776                              : VOIDmode),
2777                             unsignedp,
2778                             /* Required alignment of containing datum.  */
2779                             alignment,
2780                             int_size_in_bytes (TREE_TYPE (tem)));
2781       preserve_temp_slots (result);
2782       free_temp_slots ();
2783       pop_temp_slots ();
2784
2785       /* If the value is meaningful, convert RESULT to the proper mode.
2786          Otherwise, return nothing.  */
2787       return (want_value ? convert_modes (TYPE_MODE (TREE_TYPE (to)),
2788                                           TYPE_MODE (TREE_TYPE (from)),
2789                                           result,
2790                                           TREE_UNSIGNED (TREE_TYPE (to)))
2791               : NULL_RTX);
2792     }
2793
2794   /* If the rhs is a function call and its value is not an aggregate,
2795      call the function before we start to compute the lhs.
2796      This is needed for correct code for cases such as
2797      val = setjmp (buf) on machines where reference to val
2798      requires loading up part of an address in a separate insn.
2799
2800      Don't do this if TO is a VAR_DECL whose DECL_RTL is REG since it might be
2801      a promoted variable where the zero- or sign- extension needs to be done.
2802      Handling this in the normal way is safe because no computation is done
2803      before the call.  */
2804   if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from)
2805       && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
2806       && ! (TREE_CODE (to) == VAR_DECL && GET_CODE (DECL_RTL (to)) == REG))
2807     {
2808       rtx value;
2809
2810       push_temp_slots ();
2811       value = expand_expr (from, NULL_RTX, VOIDmode, 0);
2812       if (to_rtx == 0)
2813         to_rtx = expand_expr (to, NULL_RTX, VOIDmode, 0);
2814
2815       if (GET_MODE (to_rtx) == BLKmode)
2816         emit_block_move (to_rtx, value, expr_size (from),
2817                          TYPE_ALIGN (TREE_TYPE (from)) / BITS_PER_UNIT);
2818       else
2819         emit_move_insn (to_rtx, value);
2820       preserve_temp_slots (to_rtx);
2821       free_temp_slots ();
2822       pop_temp_slots ();
2823       return want_value ? to_rtx : NULL_RTX;
2824     }
2825
2826   /* Ordinary treatment.  Expand TO to get a REG or MEM rtx.
2827      Don't re-expand if it was expanded already (in COMPONENT_REF case).  */
2828
2829   if (to_rtx == 0)
2830     to_rtx = expand_expr (to, NULL_RTX, VOIDmode, 0);
2831
2832   /* Don't move directly into a return register.  */
2833   if (TREE_CODE (to) == RESULT_DECL && GET_CODE (to_rtx) == REG)
2834     {
2835       rtx temp;
2836
2837       push_temp_slots ();
2838       temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
2839       emit_move_insn (to_rtx, temp);
2840       preserve_temp_slots (to_rtx);
2841       free_temp_slots ();
2842       pop_temp_slots ();
2843       return want_value ? to_rtx : NULL_RTX;
2844     }
2845
2846   /* In case we are returning the contents of an object which overlaps
2847      the place the value is being stored, use a safe function when copying
2848      a value through a pointer into a structure value return block.  */
2849   if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF
2850       && current_function_returns_struct
2851       && !current_function_returns_pcc_struct)
2852     {
2853       rtx from_rtx, size;
2854
2855       push_temp_slots ();
2856       size = expr_size (from);
2857       from_rtx = expand_expr (from, NULL_RTX, VOIDmode, 0);
2858
2859 #ifdef TARGET_MEM_FUNCTIONS
2860       emit_library_call (memcpy_libfunc, 0,
2861                          VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
2862                          XEXP (from_rtx, 0), Pmode,
2863                          convert_to_mode (TYPE_MODE (sizetype),
2864                                           size, TREE_UNSIGNED (sizetype)),
2865                          TYPE_MODE (sizetype));
2866 #else
2867       emit_library_call (bcopy_libfunc, 0,
2868                          VOIDmode, 3, XEXP (from_rtx, 0), Pmode,
2869                          XEXP (to_rtx, 0), Pmode,
2870                          convert_to_mode (TYPE_MODE (integer_type_node),
2871                                           size, TREE_UNSIGNED (integer_type_node)),
2872                          TYPE_MODE (integer_type_node));
2873 #endif
2874
2875       preserve_temp_slots (to_rtx);
2876       free_temp_slots ();
2877       pop_temp_slots ();
2878       return want_value ? to_rtx : NULL_RTX;
2879     }
2880
2881   /* Compute FROM and store the value in the rtx we got.  */
2882
2883   push_temp_slots ();
2884   result = store_expr (from, to_rtx, want_value);
2885   preserve_temp_slots (result);
2886   free_temp_slots ();
2887   pop_temp_slots ();
2888   return want_value ? result : NULL_RTX;
2889 }
2890
2891 /* Generate code for computing expression EXP,
2892    and storing the value into TARGET.
2893    TARGET may contain a QUEUED rtx.
2894
2895    If WANT_VALUE is nonzero, return a copy of the value
2896    not in TARGET, so that we can be sure to use the proper
2897    value in a containing expression even if TARGET has something
2898    else stored in it.  If possible, we copy the value through a pseudo
2899    and return that pseudo.  Or, if the value is constant, we try to
2900    return the constant.  In some cases, we return a pseudo
2901    copied *from* TARGET.
2902
2903    If the mode is BLKmode then we may return TARGET itself.
2904    It turns out that in BLKmode it doesn't cause a problem.
2905    because C has no operators that could combine two different
2906    assignments into the same BLKmode object with different values
2907    with no sequence point.  Will other languages need this to
2908    be more thorough?
2909
2910    If WANT_VALUE is 0, we return NULL, to make sure
2911    to catch quickly any cases where the caller uses the value
2912    and fails to set WANT_VALUE.  */
2913
2914 rtx
2915 store_expr (exp, target, want_value)
2916      register tree exp;
2917      register rtx target;
2918      int want_value;
2919 {
2920   register rtx temp;
2921   int dont_return_target = 0;
2922
2923   if (TREE_CODE (exp) == COMPOUND_EXPR)
2924     {
2925       /* Perform first part of compound expression, then assign from second
2926          part.  */
2927       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
2928       emit_queue ();
2929       return store_expr (TREE_OPERAND (exp, 1), target, want_value);
2930     }
2931   else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
2932     {
2933       /* For conditional expression, get safe form of the target.  Then
2934          test the condition, doing the appropriate assignment on either
2935          side.  This avoids the creation of unnecessary temporaries.
2936          For non-BLKmode, it is more efficient not to do this.  */
2937
2938       rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
2939
2940       emit_queue ();
2941       target = protect_from_queue (target, 1);
2942
2943       do_pending_stack_adjust ();
2944       NO_DEFER_POP;
2945       jumpifnot (TREE_OPERAND (exp, 0), lab1);
2946       store_expr (TREE_OPERAND (exp, 1), target, 0);
2947       emit_queue ();
2948       emit_jump_insn (gen_jump (lab2));
2949       emit_barrier ();
2950       emit_label (lab1);
2951       store_expr (TREE_OPERAND (exp, 2), target, 0);
2952       emit_queue ();
2953       emit_label (lab2);
2954       OK_DEFER_POP;
2955       return want_value ? target : NULL_RTX;
2956     }
2957   else if (want_value && GET_CODE (target) == MEM && ! MEM_VOLATILE_P (target)
2958            && GET_MODE (target) != BLKmode)
2959     /* If target is in memory and caller wants value in a register instead,
2960        arrange that.  Pass TARGET as target for expand_expr so that,
2961        if EXP is another assignment, WANT_VALUE will be nonzero for it.
2962        We know expand_expr will not use the target in that case.
2963        Don't do this if TARGET is volatile because we are supposed
2964        to write it and then read it.  */
2965     {
2966       temp = expand_expr (exp, cse_not_expected ? NULL_RTX : target,
2967                           GET_MODE (target), 0);
2968       if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
2969         temp = copy_to_reg (temp);
2970       dont_return_target = 1;
2971     }
2972   else if (queued_subexp_p (target))
2973     /* If target contains a postincrement, let's not risk
2974        using it as the place to generate the rhs.  */
2975     {
2976       if (GET_MODE (target) != BLKmode && GET_MODE (target) != VOIDmode)
2977         {
2978           /* Expand EXP into a new pseudo.  */
2979           temp = gen_reg_rtx (GET_MODE (target));
2980           temp = expand_expr (exp, temp, GET_MODE (target), 0);
2981         }
2982       else
2983         temp = expand_expr (exp, NULL_RTX, GET_MODE (target), 0);
2984
2985       /* If target is volatile, ANSI requires accessing the value
2986          *from* the target, if it is accessed.  So make that happen.
2987          In no case return the target itself.  */
2988       if (! MEM_VOLATILE_P (target) && want_value)
2989         dont_return_target = 1;
2990     }
2991   else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
2992     /* If this is an scalar in a register that is stored in a wider mode
2993        than the declared mode, compute the result into its declared mode
2994        and then convert to the wider mode.  Our value is the computed
2995        expression.  */
2996     {
2997       /* If we don't want a value, we can do the conversion inside EXP,
2998          which will often result in some optimizations.  Do the conversion
2999          in two steps: first change the signedness, if needed, then
3000          the extend.  */
3001       if (! want_value)
3002         {
3003           if (TREE_UNSIGNED (TREE_TYPE (exp))
3004               != SUBREG_PROMOTED_UNSIGNED_P (target))
3005             exp
3006               = convert
3007                 (signed_or_unsigned_type (SUBREG_PROMOTED_UNSIGNED_P (target),
3008                                           TREE_TYPE (exp)),
3009                  exp);
3010
3011           exp = convert (type_for_mode (GET_MODE (SUBREG_REG (target)),
3012                                         SUBREG_PROMOTED_UNSIGNED_P (target)),
3013                          exp);
3014         }
3015          
3016       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
3017
3018       /* If TEMP is a volatile MEM and we want a result value, make
3019          the access now so it gets done only once.  Likewise if
3020          it contains TARGET.  */
3021       if (GET_CODE (temp) == MEM && want_value
3022           && (MEM_VOLATILE_P (temp)
3023               || reg_mentioned_p (SUBREG_REG (target), XEXP (temp, 0))))
3024         temp = copy_to_reg (temp);
3025
3026       /* If TEMP is a VOIDmode constant, use convert_modes to make
3027          sure that we properly convert it.  */
3028       if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
3029         temp = convert_modes (GET_MODE (SUBREG_REG (target)),
3030                               TYPE_MODE (TREE_TYPE (exp)), temp,
3031                               SUBREG_PROMOTED_UNSIGNED_P (target));
3032
3033       convert_move (SUBREG_REG (target), temp,
3034                     SUBREG_PROMOTED_UNSIGNED_P (target));
3035       return want_value ? temp : NULL_RTX;
3036     }
3037   else
3038     {
3039       temp = expand_expr (exp, target, GET_MODE (target), 0);
3040       /* Return TARGET if it's a specified hardware register.
3041          If TARGET is a volatile mem ref, either return TARGET
3042          or return a reg copied *from* TARGET; ANSI requires this.
3043
3044          Otherwise, if TEMP is not TARGET, return TEMP
3045          if it is constant (for efficiency),
3046          or if we really want the correct value.  */
3047       if (!(target && GET_CODE (target) == REG
3048             && REGNO (target) < FIRST_PSEUDO_REGISTER)
3049           && !(GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
3050           && temp != target
3051           && (CONSTANT_P (temp) || want_value))
3052         dont_return_target = 1;
3053     }
3054
3055   /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
3056      the same as that of TARGET, adjust the constant.  This is needed, for
3057      example, in case it is a CONST_DOUBLE and we want only a word-sized
3058      value.  */
3059   if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
3060       && TREE_CODE (exp) != ERROR_MARK
3061       && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
3062     temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
3063                           temp, TREE_UNSIGNED (TREE_TYPE (exp)));
3064
3065   /* If value was not generated in the target, store it there.
3066      Convert the value to TARGET's type first if nec.  */
3067
3068   if (temp != target && TREE_CODE (exp) != ERROR_MARK)
3069     {
3070       target = protect_from_queue (target, 1);
3071       if (GET_MODE (temp) != GET_MODE (target)
3072           && GET_MODE (temp) != VOIDmode)
3073         {
3074           int unsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
3075           if (dont_return_target)
3076             {
3077               /* In this case, we will return TEMP,
3078                  so make sure it has the proper mode.
3079                  But don't forget to store the value into TARGET.  */
3080               temp = convert_to_mode (GET_MODE (target), temp, unsignedp);
3081               emit_move_insn (target, temp);
3082             }
3083           else
3084             convert_move (target, temp, unsignedp);
3085         }
3086
3087       else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
3088         {
3089           /* Handle copying a string constant into an array.
3090              The string constant may be shorter than the array.
3091              So copy just the string's actual length, and clear the rest.  */
3092           rtx size;
3093           rtx addr;
3094
3095           /* Get the size of the data type of the string,
3096              which is actually the size of the target.  */
3097           size = expr_size (exp);
3098           if (GET_CODE (size) == CONST_INT
3099               && INTVAL (size) < TREE_STRING_LENGTH (exp))
3100             emit_block_move (target, temp, size,
3101                              TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
3102           else
3103             {
3104               /* Compute the size of the data to copy from the string.  */
3105               tree copy_size
3106                 = size_binop (MIN_EXPR,
3107                               make_tree (sizetype, size),
3108                               convert (sizetype,
3109                                        build_int_2 (TREE_STRING_LENGTH (exp), 0)));
3110               rtx copy_size_rtx = expand_expr (copy_size, NULL_RTX,
3111                                                VOIDmode, 0);
3112               rtx label = 0;
3113
3114               /* Copy that much.  */
3115               emit_block_move (target, temp, copy_size_rtx,
3116                                TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
3117
3118               /* Figure out how much is left in TARGET that we have to clear.
3119                  Do all calculations in ptr_mode.  */
3120
3121               addr = XEXP (target, 0);
3122               addr = convert_modes (ptr_mode, Pmode, addr, 1);
3123
3124               if (GET_CODE (copy_size_rtx) == CONST_INT)
3125                 {
3126                   addr = plus_constant (addr, TREE_STRING_LENGTH (exp));
3127                   size = plus_constant (size, - TREE_STRING_LENGTH (exp));
3128                 }
3129               else
3130                 {
3131                   addr = force_reg (ptr_mode, addr);
3132                   addr = expand_binop (ptr_mode, add_optab, addr,
3133                                        copy_size_rtx, NULL_RTX, 0,
3134                                        OPTAB_LIB_WIDEN);
3135
3136                   size = expand_binop (ptr_mode, sub_optab, size,
3137                                        copy_size_rtx, NULL_RTX, 0,
3138                                        OPTAB_LIB_WIDEN);
3139
3140                   emit_cmp_insn (size, const0_rtx, LT, NULL_RTX,
3141                                  GET_MODE (size), 0, 0);
3142                   label = gen_label_rtx ();
3143                   emit_jump_insn (gen_blt (label));
3144                 }
3145
3146               if (size != const0_rtx)
3147                 {
3148 #ifdef TARGET_MEM_FUNCTIONS
3149                   emit_library_call (memset_libfunc, 0, VOIDmode, 3,
3150                                      addr, Pmode,
3151                                      const0_rtx, TYPE_MODE (integer_type_node),
3152                                      convert_to_mode (TYPE_MODE (sizetype),
3153                                                       size,
3154                                                       TREE_UNSIGNED (sizetype)),
3155                                      TYPE_MODE (sizetype));
3156 #else
3157                   emit_library_call (bzero_libfunc, 0, VOIDmode, 2,
3158                                      addr, Pmode,
3159                                      convert_to_mode (TYPE_MODE (integer_type_node),
3160                                                       size,
3161                                                       TREE_UNSIGNED (integer_type_node)),
3162                                      TYPE_MODE (integer_type_node));
3163 #endif
3164                 }
3165
3166               if (label)
3167                 emit_label (label);
3168             }
3169         }
3170       else if (GET_MODE (temp) == BLKmode)
3171         emit_block_move (target, temp, expr_size (exp),
3172                          TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
3173       else
3174         emit_move_insn (target, temp);
3175     }
3176
3177   /* If we don't want a value, return NULL_RTX.  */
3178   if (! want_value)
3179     return NULL_RTX;
3180
3181   /* If we are supposed to return TEMP, do so as long as it isn't a MEM.
3182      ??? The latter test doesn't seem to make sense.  */
3183   else if (dont_return_target && GET_CODE (temp) != MEM)
3184     return temp;
3185
3186   /* Return TARGET itself if it is a hard register.  */
3187   else if (want_value && GET_MODE (target) != BLKmode
3188            && ! (GET_CODE (target) == REG
3189                  && REGNO (target) < FIRST_PSEUDO_REGISTER))
3190     return copy_to_reg (target);
3191   
3192   else
3193     return target;
3194 }
3195 \f
3196 /* Return 1 if EXP just contains zeros.  */
3197
3198 static int
3199 is_zeros_p (exp)
3200      tree exp;
3201 {
3202   tree elt;
3203
3204   switch (TREE_CODE (exp))
3205     {
3206     case CONVERT_EXPR:
3207     case NOP_EXPR:
3208     case NON_LVALUE_EXPR:
3209       return is_zeros_p (TREE_OPERAND (exp, 0));
3210
3211     case INTEGER_CST:
3212       return TREE_INT_CST_LOW (exp) == 0 && TREE_INT_CST_HIGH (exp) == 0;
3213
3214     case COMPLEX_CST:
3215       return
3216         is_zeros_p (TREE_REALPART (exp)) && is_zeros_p (TREE_IMAGPART (exp));
3217
3218     case REAL_CST:
3219       return REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconst0);
3220
3221     case CONSTRUCTOR:
3222       if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
3223         return CONSTRUCTOR_ELTS (exp) == NULL_TREE;
3224       for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
3225         if (! is_zeros_p (TREE_VALUE (elt)))
3226           return 0;
3227
3228       return 1;
3229     }
3230
3231   return 0;
3232 }
3233
3234 /* Return 1 if EXP contains mostly (3/4)  zeros.  */
3235
3236 static int
3237 mostly_zeros_p (exp)
3238      tree exp;
3239 {
3240   if (TREE_CODE (exp) == CONSTRUCTOR)
3241     {
3242       int elts = 0, zeros = 0;
3243       tree elt = CONSTRUCTOR_ELTS (exp);
3244       if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
3245         {
3246           /* If there are no ranges of true bits, it is all zero.  */
3247           return elt == NULL_TREE;
3248         }
3249       for (; elt; elt = TREE_CHAIN (elt))
3250         {
3251           /* We do not handle the case where the index is a RANGE_EXPR,
3252              so the statistic will be somewhat inaccurate.
3253              We do make a more accurate count in store_constructor itself,
3254              so since this function is only used for nested array elements,
3255              this should be close enough. */
3256           if (mostly_zeros_p (TREE_VALUE (elt)))
3257             zeros++;
3258           elts++;
3259         }
3260
3261       return 4 * zeros >= 3 * elts;
3262     }
3263
3264   return is_zeros_p (exp);
3265 }
3266 \f
3267 /* Helper function for store_constructor.
3268    TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
3269    TYPE is the type of the CONSTRUCTOR, not the element type.
3270    CLEARED is as for store_constructor.
3271
3272    This provides a recursive shortcut back to store_constructor when it isn't
3273    necessary to go through store_field.  This is so that we can pass through
3274    the cleared field to let store_constructor know that we may not have to
3275    clear a substructure if the outer structure has already been cleared.  */
3276
3277 static void
3278 store_constructor_field (target, bitsize, bitpos,
3279                          mode, exp, type, cleared)
3280      rtx target;
3281      int bitsize, bitpos;
3282      enum machine_mode mode;
3283      tree exp, type;
3284      int cleared;
3285 {
3286   if (TREE_CODE (exp) == CONSTRUCTOR
3287       && bitpos % BITS_PER_UNIT == 0
3288       /* If we have a non-zero bitpos for a register target, then we just
3289          let store_field do the bitfield handling.  This is unlikely to
3290          generate unnecessary clear instructions anyways.  */
3291       && (bitpos == 0 || GET_CODE (target) == MEM))
3292     {
3293       if (bitpos != 0)
3294         target = change_address (target, VOIDmode,
3295                                  plus_constant (XEXP (target, 0),
3296                                                 bitpos / BITS_PER_UNIT));
3297       store_constructor (exp, target, cleared);
3298     }
3299   else
3300     store_field (target, bitsize, bitpos, mode, exp,
3301                  VOIDmode, 0, TYPE_ALIGN (type) / BITS_PER_UNIT,
3302                  int_size_in_bytes (type));
3303 }
3304
3305 /* Store the value of constructor EXP into the rtx TARGET.
3306    TARGET is either a REG or a MEM.
3307    CLEARED is true if TARGET is known to have been zero'd. */
3308
3309 static void
3310 store_constructor (exp, target, cleared)
3311      tree exp;
3312      rtx target;
3313      int cleared;
3314 {
3315   tree type = TREE_TYPE (exp);
3316
3317   /* We know our target cannot conflict, since safe_from_p has been called.  */
3318 #if 0
3319   /* Don't try copying piece by piece into a hard register
3320      since that is vulnerable to being clobbered by EXP.
3321      Instead, construct in a pseudo register and then copy it all.  */
3322   if (GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)
3323     {
3324       rtx temp = gen_reg_rtx (GET_MODE (target));
3325       store_constructor (exp, temp, 0);
3326       emit_move_insn (target, temp);
3327       return;
3328     }
3329 #endif
3330
3331   if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
3332       || TREE_CODE (type) == QUAL_UNION_TYPE)
3333     {
3334       register tree elt;
3335
3336       /* Inform later passes that the whole union value is dead.  */
3337       if (TREE_CODE (type) == UNION_TYPE
3338           || TREE_CODE (type) == QUAL_UNION_TYPE)
3339         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
3340
3341       /* If we are building a static constructor into a register,
3342          set the initial value as zero so we can fold the value into
3343          a constant.  But if more than one register is involved,
3344          this probably loses.  */
3345       else if (GET_CODE (target) == REG && TREE_STATIC (exp)
3346                && GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD)
3347         {
3348           if (! cleared)
3349             emit_move_insn (target, const0_rtx);
3350
3351           cleared = 1;
3352         }
3353
3354       /* If the constructor has fewer fields than the structure
3355          or if we are initializing the structure to mostly zeros,
3356          clear the whole structure first.  */
3357       else if ((list_length (CONSTRUCTOR_ELTS (exp))
3358                 != list_length (TYPE_FIELDS (type)))
3359                || mostly_zeros_p (exp))
3360         {
3361           if (! cleared)
3362             clear_storage (target, expr_size (exp),
3363                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3364
3365           cleared = 1;
3366         }
3367       else
3368         /* Inform later passes that the old value is dead.  */
3369         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
3370
3371       /* Store each element of the constructor into
3372          the corresponding field of TARGET.  */
3373
3374       for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
3375         {
3376           register tree field = TREE_PURPOSE (elt);
3377           register enum machine_mode mode;
3378           int bitsize;
3379           int bitpos = 0;
3380           int unsignedp;
3381           tree pos, constant = 0, offset = 0;
3382           rtx to_rtx = target;
3383
3384           /* Just ignore missing fields.
3385              We cleared the whole structure, above,
3386              if any fields are missing.  */
3387           if (field == 0)
3388             continue;
3389
3390           if (cleared && is_zeros_p (TREE_VALUE (elt)))
3391             continue;
3392
3393           bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
3394           unsignedp = TREE_UNSIGNED (field);
3395           mode = DECL_MODE (field);
3396           if (DECL_BIT_FIELD (field))
3397             mode = VOIDmode;
3398
3399           pos = DECL_FIELD_BITPOS (field);
3400           if (TREE_CODE (pos) == INTEGER_CST)
3401             constant = pos;
3402           else if (TREE_CODE (pos) == PLUS_EXPR
3403                    && TREE_CODE (TREE_OPERAND (pos, 1)) == INTEGER_CST)
3404             constant = TREE_OPERAND (pos, 1), offset = TREE_OPERAND (pos, 0);
3405           else
3406             offset = pos;
3407
3408           if (constant)
3409             bitpos = TREE_INT_CST_LOW (constant);
3410
3411           if (offset)
3412             {
3413               rtx offset_rtx;
3414
3415               if (contains_placeholder_p (offset))
3416                 offset = build (WITH_RECORD_EXPR, sizetype,
3417                                 offset, exp);
3418
3419               offset = size_binop (FLOOR_DIV_EXPR, offset,
3420                                    size_int (BITS_PER_UNIT));
3421
3422               offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
3423               if (GET_CODE (to_rtx) != MEM)
3424                 abort ();
3425
3426               to_rtx
3427                 = change_address (to_rtx, VOIDmode,
3428                                   gen_rtx (PLUS, ptr_mode, XEXP (to_rtx, 0),
3429                                            force_reg (ptr_mode, offset_rtx)));
3430             }
3431           if (TREE_READONLY (field))
3432             {
3433               if (GET_CODE (to_rtx) == MEM)
3434                 to_rtx = change_address (to_rtx, GET_MODE (to_rtx),
3435                                          XEXP (to_rtx, 0));
3436               RTX_UNCHANGING_P (to_rtx) = 1;
3437             }
3438
3439           store_constructor_field (to_rtx, bitsize, bitpos,
3440                                    mode, TREE_VALUE (elt), type, cleared);
3441         }
3442     }
3443   else if (TREE_CODE (type) == ARRAY_TYPE)
3444     {
3445       register tree elt;
3446       register int i;
3447       int need_to_clear;
3448       tree domain = TYPE_DOMAIN (type);
3449       HOST_WIDE_INT minelt = TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain));
3450       HOST_WIDE_INT maxelt = TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain));
3451       tree elttype = TREE_TYPE (type);
3452
3453       /* If the constructor has fewer elements than the array,
3454          clear the whole array first.  Similarly if this this is
3455          static constructor of a non-BLKmode object.  */
3456       if (cleared || (GET_CODE (target) == REG && TREE_STATIC (exp)))
3457         need_to_clear = 1;
3458       else
3459         {
3460           HOST_WIDE_INT count = 0, zero_count = 0;
3461           need_to_clear = 0;
3462           /* This loop is a more accurate version of the loop in
3463              mostly_zeros_p (it handles RANGE_EXPR in an index).
3464              It is also needed to check for missing elements.  */
3465           for (elt = CONSTRUCTOR_ELTS (exp);
3466                elt != NULL_TREE;
3467                elt = TREE_CHAIN (elt), i++)
3468             {
3469               tree index = TREE_PURPOSE (elt);
3470               HOST_WIDE_INT this_node_count;
3471               if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
3472                 {
3473                   tree lo_index = TREE_OPERAND (index, 0);
3474                   tree hi_index = TREE_OPERAND (index, 1);
3475                   if (TREE_CODE (lo_index) != INTEGER_CST
3476                       || TREE_CODE (hi_index) != INTEGER_CST)
3477                     {
3478                       need_to_clear = 1;
3479                       break;
3480                     }
3481                   this_node_count = TREE_INT_CST_LOW (hi_index)
3482                     - TREE_INT_CST_LOW (lo_index) + 1;
3483                 }
3484               else
3485                 this_node_count = 1;
3486               count += this_node_count;
3487               if (mostly_zeros_p (TREE_VALUE (elt)))
3488                 zero_count += this_node_count;
3489             }
3490           /* Clear the entire array first if there are any missing elements,
3491              or if the incidence of zero elements is >= 75%. */
3492           if (count < maxelt - minelt + 1
3493               || 4 * zero_count >= 3 * count)
3494             need_to_clear = 1;
3495         }
3496       if (need_to_clear)
3497         {
3498           if (! cleared)
3499             clear_storage (target, expr_size (exp),
3500                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3501           cleared = 1;
3502         }
3503       else
3504         /* Inform later passes that the old value is dead.  */
3505         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
3506
3507       /* Store each element of the constructor into
3508          the corresponding element of TARGET, determined
3509          by counting the elements.  */
3510       for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
3511            elt;
3512            elt = TREE_CHAIN (elt), i++)
3513         {
3514           register enum machine_mode mode;
3515           int bitsize;
3516           int bitpos;
3517           int unsignedp;
3518           tree value = TREE_VALUE (elt);
3519           tree index = TREE_PURPOSE (elt);
3520           rtx xtarget = target;
3521
3522           if (cleared && is_zeros_p (value))
3523             continue;
3524
3525           mode = TYPE_MODE (elttype);
3526           bitsize = GET_MODE_BITSIZE (mode);
3527           unsignedp = TREE_UNSIGNED (elttype);
3528
3529           if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
3530             {
3531               tree lo_index = TREE_OPERAND (index, 0);
3532               tree hi_index = TREE_OPERAND (index, 1);
3533               rtx index_r, pos_rtx, addr, hi_r, loop_top, loop_end;
3534               struct nesting *loop;
3535               HOST_WIDE_INT lo, hi, count;
3536               tree position;
3537
3538               /* If the range is constant and "small", unroll the loop. */
3539               if (TREE_CODE (lo_index) == INTEGER_CST
3540                   && TREE_CODE (hi_index) == INTEGER_CST
3541                   && (lo = TREE_INT_CST_LOW (lo_index),
3542                       hi = TREE_INT_CST_LOW (hi_index),
3543                       count = hi - lo + 1,
3544                       (GET_CODE (target) != MEM
3545                        || count <= 2
3546                        || (TREE_CODE (TYPE_SIZE (elttype)) == INTEGER_CST
3547                            && TREE_INT_CST_LOW (TYPE_SIZE (elttype)) * count
3548                            <= 40 * 8))))
3549                 {
3550                   lo -= minelt;  hi -= minelt;
3551                   for (; lo <= hi; lo++)
3552                     {
3553                       bitpos = lo * TREE_INT_CST_LOW (TYPE_SIZE (elttype));
3554                       store_constructor_field (target, bitsize, bitpos,
3555                                                mode, value, type, cleared);
3556                     }
3557                 }
3558               else
3559                 {
3560                   hi_r = expand_expr (hi_index, NULL_RTX, VOIDmode, 0);
3561                   loop_top = gen_label_rtx ();
3562                   loop_end = gen_label_rtx ();
3563
3564                   unsignedp = TREE_UNSIGNED (domain);
3565
3566                   index = build_decl (VAR_DECL, NULL_TREE, domain);
3567
3568                   DECL_RTL (index) = index_r
3569                     = gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
3570                                                  &unsignedp, 0));
3571
3572                   if (TREE_CODE (value) == SAVE_EXPR
3573                       && SAVE_EXPR_RTL (value) == 0)
3574                     {
3575                       /* Make sure value gets expanded once before the loop. */
3576                       expand_expr (value, const0_rtx, VOIDmode, 0);
3577                       emit_queue ();
3578                     }
3579                   store_expr (lo_index, index_r, 0);
3580                   loop = expand_start_loop (0);
3581
3582                   /* Assign value to element index. */
3583                   position = size_binop (EXACT_DIV_EXPR, TYPE_SIZE (elttype),
3584                                          size_int (BITS_PER_UNIT));
3585                   position = size_binop (MULT_EXPR,
3586                                          size_binop (MINUS_EXPR, index,
3587                                                      TYPE_MIN_VALUE (domain)),
3588                                          position);
3589                   pos_rtx = expand_expr (position, 0, VOIDmode, 0);
3590                   addr = gen_rtx (PLUS, Pmode, XEXP (target, 0), pos_rtx);
3591                   xtarget = change_address (target, mode, addr);
3592                   if (TREE_CODE (value) == CONSTRUCTOR)
3593                     store_constructor (value, xtarget, cleared);
3594                   else
3595                     store_expr (value, xtarget, 0);
3596
3597                   expand_exit_loop_if_false (loop,
3598                                              build (LT_EXPR, integer_type_node,
3599                                                     index, hi_index));
3600
3601                   expand_increment (build (PREINCREMENT_EXPR,
3602                                            TREE_TYPE (index),
3603                                            index, integer_one_node), 0, 0);
3604                   expand_end_loop ();
3605                   emit_label (loop_end);
3606
3607                   /* Needed by stupid register allocation. to extend the
3608                      lifetime of pseudo-regs used by target past the end
3609                      of the loop.  */
3610                   emit_insn (gen_rtx (USE, GET_MODE (target), target));
3611                 }
3612             }
3613           else if ((index != 0 && TREE_CODE (index) != INTEGER_CST)
3614               || TREE_CODE (TYPE_SIZE (elttype)) != INTEGER_CST)
3615             {
3616               rtx pos_rtx, addr;
3617               tree position;
3618
3619               if (index == 0)
3620                 index = size_int (i);
3621
3622               if (minelt)
3623                 index = size_binop (MINUS_EXPR, index,
3624                                     TYPE_MIN_VALUE (domain));
3625               position = size_binop (EXACT_DIV_EXPR, TYPE_SIZE (elttype),
3626                                      size_int (BITS_PER_UNIT));
3627               position = size_binop (MULT_EXPR, index, position);
3628               pos_rtx = expand_expr (position, 0, VOIDmode, 0);
3629               addr = gen_rtx (PLUS, Pmode, XEXP (target, 0), pos_rtx);
3630               xtarget = change_address (target, mode, addr);
3631               store_expr (value, xtarget, 0);
3632             }
3633           else
3634             {
3635               if (index != 0)
3636                 bitpos = ((TREE_INT_CST_LOW (index) - minelt)
3637                           * TREE_INT_CST_LOW (TYPE_SIZE (elttype)));
3638               else
3639                 bitpos = (i * TREE_INT_CST_LOW (TYPE_SIZE (elttype)));
3640               store_constructor_field (target, bitsize, bitpos,
3641                                        mode, value, type, cleared);
3642             }
3643         }
3644     }
3645   /* set constructor assignments */
3646   else if (TREE_CODE (type) == SET_TYPE)
3647     {
3648       tree elt = CONSTRUCTOR_ELTS (exp);
3649       rtx xtarget = XEXP (target, 0);
3650       int set_word_size = TYPE_ALIGN (type);
3651       int nbytes = int_size_in_bytes (type), nbits;
3652       tree domain = TYPE_DOMAIN (type);
3653       tree domain_min, domain_max, bitlength;
3654
3655       /* The default implementation strategy is to extract the constant
3656          parts of the constructor, use that to initialize the target,
3657          and then "or" in whatever non-constant ranges we need in addition.
3658
3659          If a large set is all zero or all ones, it is
3660          probably better to set it using memset (if available) or bzero.
3661          Also, if a large set has just a single range, it may also be
3662          better to first clear all the first clear the set (using
3663          bzero/memset), and set the bits we want. */
3664        
3665       /* Check for all zeros. */
3666       if (elt == NULL_TREE)
3667         {
3668           if (!cleared)
3669             clear_storage (target, expr_size (exp),
3670                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3671           return;
3672         }
3673
3674       domain_min = convert (sizetype, TYPE_MIN_VALUE (domain));
3675       domain_max = convert (sizetype, TYPE_MAX_VALUE (domain));
3676       bitlength = size_binop (PLUS_EXPR,
3677                               size_binop (MINUS_EXPR, domain_max, domain_min),
3678                               size_one_node);
3679
3680       if (nbytes < 0 || TREE_CODE (bitlength) != INTEGER_CST)
3681         abort ();
3682       nbits = TREE_INT_CST_LOW (bitlength);
3683
3684       /* For "small" sets, or "medium-sized" (up to 32 bytes) sets that
3685          are "complicated" (more than one range), initialize (the
3686          constant parts) by copying from a constant.  */         
3687       if (GET_MODE (target) != BLKmode || nbits <= 2 * BITS_PER_WORD
3688           || (nbytes <= 32 && TREE_CHAIN (elt) != NULL_TREE))
3689         {
3690           int set_word_size = TYPE_ALIGN (TREE_TYPE (exp));
3691           enum machine_mode mode = mode_for_size (set_word_size, MODE_INT, 1);
3692           char *bit_buffer = (char*) alloca (nbits);
3693           HOST_WIDE_INT word = 0;
3694           int bit_pos = 0;
3695           int ibit = 0;
3696           int offset = 0;  /* In bytes from beginning of set. */
3697           elt = get_set_constructor_bits (exp, bit_buffer, nbits);
3698           for (;;)
3699             {
3700               if (bit_buffer[ibit])
3701                 {
3702                   if (BYTES_BIG_ENDIAN)
3703                     word |= (1 << (set_word_size - 1 - bit_pos));
3704                   else
3705                     word |= 1 << bit_pos;
3706                 }
3707               bit_pos++;  ibit++;
3708               if (bit_pos >= set_word_size || ibit == nbits)
3709                 {
3710                   if (word != 0 || ! cleared)
3711                     {
3712                       rtx datum = GEN_INT (word);
3713                       rtx to_rtx;
3714                       /* The assumption here is that it is safe to use XEXP if
3715                          the set is multi-word, but not if it's single-word. */
3716                       if (GET_CODE (target) == MEM)
3717                         {
3718                           to_rtx = plus_constant (XEXP (target, 0), offset);
3719                           to_rtx = change_address (target, mode, to_rtx);
3720                         }
3721                       else if (offset == 0) 
3722                         to_rtx = target;
3723                       else
3724                         abort ();
3725                       emit_move_insn (to_rtx, datum);
3726                     }
3727                   if (ibit == nbits)
3728                     break;
3729                   word = 0;
3730                   bit_pos = 0;
3731                   offset += set_word_size / BITS_PER_UNIT;
3732                 }
3733             }
3734         }
3735       else if (!cleared)
3736         {
3737           /* Don't bother clearing storage if the set is all ones. */
3738           if (TREE_CHAIN (elt) != NULL_TREE
3739               || (TREE_PURPOSE (elt) == NULL_TREE
3740                   ? nbits != 1
3741                   : (TREE_CODE (TREE_VALUE (elt)) != INTEGER_CST
3742                      || TREE_CODE (TREE_PURPOSE (elt)) != INTEGER_CST
3743                      || (TREE_INT_CST_LOW (TREE_VALUE (elt))
3744                          - TREE_INT_CST_LOW (TREE_PURPOSE (elt)) + 1
3745                          != nbits))))
3746             clear_storage (target, expr_size (exp),
3747                            TYPE_ALIGN (type) / BITS_PER_UNIT);
3748         }
3749           
3750       for (; elt != NULL_TREE; elt = TREE_CHAIN (elt))
3751         {
3752           /* start of range of element or NULL */
3753           tree startbit = TREE_PURPOSE (elt);
3754           /* end of range of element, or element value */
3755           tree endbit   = TREE_VALUE (elt);
3756           HOST_WIDE_INT startb, endb;
3757           rtx  bitlength_rtx, startbit_rtx, endbit_rtx, targetx;
3758
3759           bitlength_rtx = expand_expr (bitlength,
3760                             NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
3761
3762           /* handle non-range tuple element like [ expr ]  */
3763           if (startbit == NULL_TREE)
3764             {
3765               startbit = save_expr (endbit);
3766               endbit = startbit;
3767             }
3768           startbit = convert (sizetype, startbit);
3769           endbit = convert (sizetype, endbit);
3770           if (! integer_zerop (domain_min))
3771             {
3772               startbit = size_binop (MINUS_EXPR, startbit, domain_min);
3773               endbit = size_binop (MINUS_EXPR, endbit, domain_min);
3774             }
3775           startbit_rtx = expand_expr (startbit, NULL_RTX, MEM, 
3776                                       EXPAND_CONST_ADDRESS);
3777           endbit_rtx = expand_expr (endbit, NULL_RTX, MEM, 
3778                                     EXPAND_CONST_ADDRESS);
3779
3780           if (REG_P (target))
3781             {
3782               targetx = assign_stack_temp (GET_MODE (target),
3783                                            GET_MODE_SIZE (GET_MODE (target)),
3784                                            0);
3785               emit_move_insn (targetx, target);
3786             }
3787           else if (GET_CODE (target) == MEM)
3788             targetx = target;
3789           else
3790             abort ();
3791
3792 #ifdef TARGET_MEM_FUNCTIONS
3793           /* Optimization:  If startbit and endbit are
3794              constants divisible by BITS_PER_UNIT,
3795              call memset instead. */
3796           if (TREE_CODE (startbit) == INTEGER_CST
3797               && TREE_CODE (endbit) == INTEGER_CST
3798               && (startb = TREE_INT_CST_LOW (startbit)) % BITS_PER_UNIT == 0
3799               && (endb = TREE_INT_CST_LOW (endbit) + 1) % BITS_PER_UNIT == 0)
3800             {
3801               emit_library_call (memset_libfunc, 0,
3802                                  VOIDmode, 3,
3803                                  plus_constant (XEXP (targetx, 0),
3804                                                 startb / BITS_PER_UNIT),
3805                                  Pmode,
3806                                  constm1_rtx, TYPE_MODE (integer_type_node),
3807                                  GEN_INT ((endb - startb) / BITS_PER_UNIT),
3808                                  TYPE_MODE (sizetype));
3809             }
3810           else
3811 #endif
3812             {
3813               emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__setbits"),
3814                                  0, VOIDmode, 4, XEXP (targetx, 0), Pmode,
3815                                  bitlength_rtx, TYPE_MODE (sizetype),
3816                                  startbit_rtx, TYPE_MODE (sizetype),
3817                                  endbit_rtx, TYPE_MODE (sizetype));
3818             }
3819           if (REG_P (target))
3820             emit_move_insn (target, targetx);
3821         }
3822     }
3823
3824   else
3825     abort ();
3826 }
3827
3828 /* Store the value of EXP (an expression tree)
3829    into a subfield of TARGET which has mode MODE and occupies
3830    BITSIZE bits, starting BITPOS bits from the start of TARGET.
3831    If MODE is VOIDmode, it means that we are storing into a bit-field.
3832
3833    If VALUE_MODE is VOIDmode, return nothing in particular.
3834    UNSIGNEDP is not used in this case.
3835
3836    Otherwise, return an rtx for the value stored.  This rtx
3837    has mode VALUE_MODE if that is convenient to do.
3838    In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
3839
3840    ALIGN is the alignment that TARGET is known to have, measured in bytes.
3841    TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.  */
3842
3843 static rtx
3844 store_field (target, bitsize, bitpos, mode, exp, value_mode,
3845              unsignedp, align, total_size)
3846      rtx target;
3847      int bitsize, bitpos;
3848      enum machine_mode mode;
3849      tree exp;
3850      enum machine_mode value_mode;
3851      int unsignedp;
3852      int align;
3853      int total_size;
3854 {
3855   HOST_WIDE_INT width_mask = 0;
3856
3857   if (bitsize < HOST_BITS_PER_WIDE_INT)
3858     width_mask = ((HOST_WIDE_INT) 1 << bitsize) - 1;
3859
3860   /* If we are storing into an unaligned field of an aligned union that is
3861      in a register, we may have the mode of TARGET being an integer mode but
3862      MODE == BLKmode.  In that case, get an aligned object whose size and
3863      alignment are the same as TARGET and store TARGET into it (we can avoid
3864      the store if the field being stored is the entire width of TARGET).  Then
3865      call ourselves recursively to store the field into a BLKmode version of
3866      that object.  Finally, load from the object into TARGET.  This is not
3867      very efficient in general, but should only be slightly more expensive
3868      than the otherwise-required unaligned accesses.  Perhaps this can be
3869      cleaned up later.  */
3870
3871   if (mode == BLKmode
3872       && (GET_CODE (target) == REG || GET_CODE (target) == SUBREG))
3873     {
3874       rtx object = assign_stack_temp (GET_MODE (target),
3875                                       GET_MODE_SIZE (GET_MODE (target)), 0);
3876       rtx blk_object = copy_rtx (object);
3877
3878       MEM_IN_STRUCT_P (object) = 1;
3879       MEM_IN_STRUCT_P (blk_object) = 1;
3880       PUT_MODE (blk_object, BLKmode);
3881
3882       if (bitsize != GET_MODE_BITSIZE (GET_MODE (target)))
3883         emit_move_insn (object, target);
3884
3885       store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0,
3886                    align, total_size);
3887
3888       /* Even though we aren't returning target, we need to
3889          give it the updated value.  */
3890       emit_move_insn (target, object);
3891
3892       return blk_object;
3893     }
3894
3895   /* If the structure is in a register or if the component
3896      is a bit field, we cannot use addressing to access it.
3897      Use bit-field techniques or SUBREG to store in it.  */
3898
3899   if (mode == VOIDmode
3900       || (mode != BLKmode && ! direct_store[(int) mode])
3901       || GET_CODE (target) == REG
3902       || GET_CODE (target) == SUBREG
3903       /* If the field isn't aligned enough to store as an ordinary memref,
3904          store it as a bit field.  */
3905       || (SLOW_UNALIGNED_ACCESS
3906           && align * BITS_PER_UNIT < GET_MODE_ALIGNMENT (mode))
3907       || (SLOW_UNALIGNED_ACCESS && bitpos % GET_MODE_ALIGNMENT (mode) != 0))
3908     {
3909       rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
3910
3911       /* Unless MODE is VOIDmode or BLKmode, convert TEMP to
3912          MODE.  */
3913       if (mode != VOIDmode && mode != BLKmode
3914           && mode != TYPE_MODE (TREE_TYPE (exp)))
3915         temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
3916
3917       /* If the modes of TARGET and TEMP are both BLKmode, both
3918          must be in memory and BITPOS must be aligned on a byte
3919          boundary.  If so, we simply do a block copy.  */
3920       if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode)
3921         {
3922           if (GET_CODE (target) != MEM || GET_CODE (temp) != MEM
3923               || bitpos % BITS_PER_UNIT != 0)
3924             abort ();
3925
3926           target = change_address (target, VOIDmode,
3927                                    plus_constant (XEXP (target, 0),
3928                                                 bitpos / BITS_PER_UNIT));
3929
3930           emit_block_move (target, temp,
3931                            GEN_INT ((bitsize + BITS_PER_UNIT - 1)
3932                                     / BITS_PER_UNIT),
3933                            1);
3934
3935           return value_mode == VOIDmode ? const0_rtx : target;
3936         }
3937
3938       /* Store the value in the bitfield.  */
3939       store_bit_field (target, bitsize, bitpos, mode, temp, align, total_size);
3940       if (value_mode != VOIDmode)
3941         {
3942           /* The caller wants an rtx for the value.  */
3943           /* If possible, avoid refetching from the bitfield itself.  */
3944           if (width_mask != 0
3945               && ! (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)))
3946             {
3947               tree count;
3948               enum machine_mode tmode;
3949
3950               if (unsignedp)
3951                 return expand_and (temp, GEN_INT (width_mask), NULL_RTX);
3952               tmode = GET_MODE (temp);
3953               if (tmode == VOIDmode)
3954                 tmode = value_mode;
3955               count = build_int_2 (GET_MODE_BITSIZE (tmode) - bitsize, 0);
3956               temp = expand_shift (LSHIFT_EXPR, tmode, temp, count, 0, 0);
3957               return expand_shift (RSHIFT_EXPR, tmode, temp, count, 0, 0);
3958             }
3959           return extract_bit_field (target, bitsize, bitpos, unsignedp,
3960                                     NULL_RTX, value_mode, 0, align,
3961                                     total_size);
3962         }
3963       return const0_rtx;
3964     }
3965   else
3966     {
3967       rtx addr = XEXP (target, 0);
3968       rtx to_rtx;
3969
3970       /* If a value is wanted, it must be the lhs;
3971          so make the address stable for multiple use.  */
3972
3973       if (value_mode != VOIDmode && GET_CODE (addr) != REG
3974           && ! CONSTANT_ADDRESS_P (addr)
3975           /* A frame-pointer reference is already stable.  */
3976           && ! (GET_CODE (addr) == PLUS
3977                 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3978                 && (XEXP (addr, 0) == virtual_incoming_args_rtx
3979                     || XEXP (addr, 0) == virtual_stack_vars_rtx)))
3980         addr = copy_to_reg (addr);
3981
3982       /* Now build a reference to just the desired component.  */
3983
3984       to_rtx = change_address (target, mode,
3985                                plus_constant (addr, (bitpos / BITS_PER_UNIT)));
3986       MEM_IN_STRUCT_P (to_rtx) = 1;
3987
3988       return store_expr (exp, to_rtx, value_mode != VOIDmode);
3989     }
3990 }
3991 \f
3992 /* Return true if any object containing the innermost array is an unaligned
3993    packed structure field.  */
3994
3995 static int
3996 get_inner_unaligned_p (exp)
3997      tree exp;
3998 {
3999   int needed_alignment = TYPE_ALIGN (TREE_TYPE (exp));
4000
4001   while (1)
4002     {
4003       if (TREE_CODE (exp) == COMPONENT_REF || TREE_CODE (exp) == BIT_FIELD_REF)
4004         {
4005           if (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
4006               < needed_alignment)
4007             return 1;
4008         }
4009       else if (TREE_CODE (exp) != ARRAY_REF
4010                && TREE_CODE (exp) != NON_LVALUE_EXPR
4011                && ! ((TREE_CODE (exp) == NOP_EXPR
4012                       || TREE_CODE (exp) == CONVERT_EXPR)
4013                      && (TYPE_MODE (TREE_TYPE (exp))
4014                          == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))))
4015         break;
4016
4017       exp = TREE_OPERAND (exp, 0);
4018     }
4019
4020   return 0;
4021 }
4022
4023 /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
4024    or an ARRAY_REF, look for nested COMPONENT_REFs, BIT_FIELD_REFs, or
4025    ARRAY_REFs and find the ultimate containing object, which we return.
4026
4027    We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
4028    bit position, and *PUNSIGNEDP to the signedness of the field.
4029    If the position of the field is variable, we store a tree
4030    giving the variable offset (in units) in *POFFSET.
4031    This offset is in addition to the bit position.
4032    If the position is not variable, we store 0 in *POFFSET.
4033
4034    If any of the extraction expressions is volatile,
4035    we store 1 in *PVOLATILEP.  Otherwise we don't change that.
4036
4037    If the field is a bit-field, *PMODE is set to VOIDmode.  Otherwise, it
4038    is a mode that can be used to access the field.  In that case, *PBITSIZE
4039    is redundant.
4040
4041    If the field describes a variable-sized object, *PMODE is set to
4042    VOIDmode and *PBITSIZE is set to -1.  An access cannot be made in
4043    this case, but the address of the object can be found.  */
4044
4045 tree
4046 get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
4047                      punsignedp, pvolatilep)
4048      tree exp;
4049      int *pbitsize;
4050      int *pbitpos;
4051      tree *poffset;
4052      enum machine_mode *pmode;
4053      int *punsignedp;
4054      int *pvolatilep;
4055 {
4056   tree orig_exp = exp;
4057   tree size_tree = 0;
4058   enum machine_mode mode = VOIDmode;
4059   tree offset = integer_zero_node;
4060
4061   if (TREE_CODE (exp) == COMPONENT_REF)
4062     {
4063       size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
4064       if (! DECL_BIT_FIELD (TREE_OPERAND (exp, 1)))
4065         mode = DECL_MODE (TREE_OPERAND (exp, 1));
4066       *punsignedp = TREE_UNSIGNED (TREE_OPERAND (exp, 1));
4067     }
4068   else if (TREE_CODE (exp) == BIT_FIELD_REF)
4069     {
4070       size_tree = TREE_OPERAND (exp, 1);
4071       *punsignedp = TREE_UNSIGNED (exp);
4072     }
4073   else
4074     {
4075       mode = TYPE_MODE (TREE_TYPE (exp));
4076       *pbitsize = GET_MODE_BITSIZE (mode);
4077       *punsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
4078     }
4079       
4080   if (size_tree)
4081     {
4082       if (TREE_CODE (size_tree) != INTEGER_CST)
4083         mode = BLKmode, *pbitsize = -1;
4084       else
4085         *pbitsize = TREE_INT_CST_LOW (size_tree);
4086     }
4087
4088   /* Compute cumulative bit-offset for nested component-refs and array-refs,
4089      and find the ultimate containing object.  */
4090
4091   *pbitpos = 0;
4092
4093   while (1)
4094     {
4095       if (TREE_CODE (exp) == COMPONENT_REF || TREE_CODE (exp) == BIT_FIELD_REF)
4096         {
4097           tree pos = (TREE_CODE (exp) == COMPONENT_REF
4098                       ? DECL_FIELD_BITPOS (TREE_OPERAND (exp, 1))
4099                       : TREE_OPERAND (exp, 2));
4100           tree constant = integer_zero_node, var = pos;
4101
4102           /* If this field hasn't been filled in yet, don't go
4103              past it.  This should only happen when folding expressions
4104              made during type construction.  */
4105           if (pos == 0)
4106             break;
4107
4108           /* Assume here that the offset is a multiple of a unit.
4109              If not, there should be an explicitly added constant.  */
4110           if (TREE_CODE (pos) == PLUS_EXPR
4111               && TREE_CODE (TREE_OPERAND (pos, 1)) == INTEGER_CST)
4112             constant = TREE_OPERAND (pos, 1), var = TREE_OPERAND (pos, 0);
4113           else if (TREE_CODE (pos) == INTEGER_CST)
4114             constant = pos, var = integer_zero_node;
4115
4116           *pbitpos += TREE_INT_CST_LOW (constant);
4117
4118           if (var)
4119             offset = size_binop (PLUS_EXPR, offset,
4120                                  size_binop (EXACT_DIV_EXPR, var,
4121                                              size_int (BITS_PER_UNIT)));
4122         }
4123
4124       else if (TREE_CODE (exp) == ARRAY_REF)
4125         {
4126           /* This code is based on the code in case ARRAY_REF in expand_expr
4127              below.  We assume here that the size of an array element is
4128              always an integral multiple of BITS_PER_UNIT.  */
4129
4130           tree index = TREE_OPERAND (exp, 1);
4131           tree domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
4132           tree low_bound
4133             = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
4134           tree index_type = TREE_TYPE (index);
4135
4136           if (! integer_zerop (low_bound))
4137             index = fold (build (MINUS_EXPR, index_type, index, low_bound));
4138
4139           if (TYPE_PRECISION (index_type) != TYPE_PRECISION (sizetype))
4140             {
4141               index = convert (type_for_size (TYPE_PRECISION (sizetype), 0),
4142                                index);
4143               index_type = TREE_TYPE (index);
4144             }
4145
4146           index = fold (build (MULT_EXPR, index_type, index,
4147                                TYPE_SIZE (TREE_TYPE (exp))));
4148
4149           if (TREE_CODE (index) == INTEGER_CST
4150               && TREE_INT_CST_HIGH (index) == 0)
4151             *pbitpos += TREE_INT_CST_LOW (index);
4152           else
4153             offset = size_binop (PLUS_EXPR, offset,
4154                                  size_binop (FLOOR_DIV_EXPR, index,
4155                                              size_int (BITS_PER_UNIT)));
4156         }
4157       else if (TREE_CODE (exp) != NON_LVALUE_EXPR
4158                && ! ((TREE_CODE (exp) == NOP_EXPR
4159                       || TREE_CODE (exp) == CONVERT_EXPR)
4160                      && ! (TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE
4161                            && (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0)))
4162                                != UNION_TYPE))
4163                      && (TYPE_MODE (TREE_TYPE (exp))
4164                          == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))))
4165         break;
4166
4167       /* If any reference in the chain is volatile, the effect is volatile.  */
4168       if (TREE_THIS_VOLATILE (exp))
4169         *pvolatilep = 1;
4170       exp = TREE_OPERAND (exp, 0);
4171     }
4172
4173   /* If this was a bit-field, see if there is a mode that allows direct
4174      access in case EXP is in memory.  */
4175   if (mode == VOIDmode && *pbitsize != 0 && *pbitpos % *pbitsize == 0)
4176     {
4177       mode = mode_for_size (*pbitsize,
4178                             (TYPE_MODE (TREE_TYPE (orig_exp)) == BLKmode
4179                              ? MODE_INT
4180                              : GET_MODE_CLASS (TYPE_MODE
4181                                                (TREE_TYPE (orig_exp)))),
4182                             0);
4183       if (mode == BLKmode)
4184         mode = VOIDmode;
4185     }
4186
4187   if (integer_zerop (offset))
4188     offset = 0;
4189
4190   if (offset != 0 && contains_placeholder_p (offset))
4191     offset = build (WITH_RECORD_EXPR, sizetype, offset, orig_exp);
4192
4193   *pmode = mode;
4194   *poffset = offset;
4195   return exp;
4196 }
4197 \f
4198 /* Given an rtx VALUE that may contain additions and multiplications,
4199    return an equivalent value that just refers to a register or memory.
4200    This is done by generating instructions to perform the arithmetic
4201    and returning a pseudo-register containing the value.
4202
4203    The returned value may be a REG, SUBREG, MEM or constant.  */
4204
4205 rtx
4206 force_operand (value, target)
4207      rtx value, target;
4208 {
4209   register optab binoptab = 0;
4210   /* Use a temporary to force order of execution of calls to
4211      `force_operand'.  */
4212   rtx tmp;
4213   register rtx op2;
4214   /* Use subtarget as the target for operand 0 of a binary operation.  */
4215   register rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
4216
4217   if (GET_CODE (value) == PLUS)
4218     binoptab = add_optab;
4219   else if (GET_CODE (value) == MINUS)
4220     binoptab = sub_optab;
4221   else if (GET_CODE (value) == MULT)
4222     {
4223       op2 = XEXP (value, 1);
4224       if (!CONSTANT_P (op2)
4225           && !(GET_CODE (op2) == REG && op2 != subtarget))
4226         subtarget = 0;
4227       tmp = force_operand (XEXP (value, 0), subtarget);
4228       return expand_mult (GET_MODE (value), tmp,
4229                           force_operand (op2, NULL_RTX),
4230                           target, 0);
4231     }
4232
4233   if (binoptab)
4234     {
4235       op2 = XEXP (value, 1);
4236       if (!CONSTANT_P (op2)
4237           && !(GET_CODE (op2) == REG && op2 != subtarget))
4238         subtarget = 0;
4239       if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT)
4240         {
4241           binoptab = add_optab;
4242           op2 = negate_rtx (GET_MODE (value), op2);
4243         }
4244
4245       /* Check for an addition with OP2 a constant integer and our first
4246          operand a PLUS of a virtual register and something else.  In that
4247          case, we want to emit the sum of the virtual register and the
4248          constant first and then add the other value.  This allows virtual
4249          register instantiation to simply modify the constant rather than
4250          creating another one around this addition.  */
4251       if (binoptab == add_optab && GET_CODE (op2) == CONST_INT
4252           && GET_CODE (XEXP (value, 0)) == PLUS
4253           && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
4254           && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
4255           && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
4256         {
4257           rtx temp = expand_binop (GET_MODE (value), binoptab,
4258                                    XEXP (XEXP (value, 0), 0), op2,
4259                                    subtarget, 0, OPTAB_LIB_WIDEN);
4260           return expand_binop (GET_MODE (value), binoptab, temp,
4261                                force_operand (XEXP (XEXP (value, 0), 1), 0),
4262                                target, 0, OPTAB_LIB_WIDEN);
4263         }
4264                                    
4265       tmp = force_operand (XEXP (value, 0), subtarget);
4266       return expand_binop (GET_MODE (value), binoptab, tmp,
4267                            force_operand (op2, NULL_RTX),
4268                            target, 0, OPTAB_LIB_WIDEN);
4269       /* We give UNSIGNEDP = 0 to expand_binop
4270          because the only operations we are expanding here are signed ones.  */
4271     }
4272   return value;
4273 }
4274 \f
4275 /* Subroutine of expand_expr:
4276    save the non-copied parts (LIST) of an expr (LHS), and return a list
4277    which can restore these values to their previous values,
4278    should something modify their storage.  */
4279
4280 static tree
4281 save_noncopied_parts (lhs, list)
4282      tree lhs;
4283      tree list;
4284 {
4285   tree tail;
4286   tree parts = 0;
4287
4288   for (tail = list; tail; tail = TREE_CHAIN (tail))
4289     if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
4290       parts = chainon (parts, save_noncopied_parts (lhs, TREE_VALUE (tail)));
4291     else
4292       {
4293         tree part = TREE_VALUE (tail);
4294         tree part_type = TREE_TYPE (part);
4295         tree to_be_saved = build (COMPONENT_REF, part_type, lhs, part);
4296         rtx target = assign_temp (part_type, 0, 1, 1);
4297         if (! memory_address_p (TYPE_MODE (part_type), XEXP (target, 0)))
4298           target = change_address (target, TYPE_MODE (part_type), NULL_RTX);
4299         parts = tree_cons (to_be_saved,
4300                            build (RTL_EXPR, part_type, NULL_TREE,
4301                                   (tree) target),
4302                            parts);
4303         store_expr (TREE_PURPOSE (parts), RTL_EXPR_RTL (TREE_VALUE (parts)), 0);
4304       }
4305   return parts;
4306 }
4307
4308 /* Subroutine of expand_expr:
4309    record the non-copied parts (LIST) of an expr (LHS), and return a list
4310    which specifies the initial values of these parts.  */
4311
4312 static tree
4313 init_noncopied_parts (lhs, list)
4314      tree lhs;
4315      tree list;
4316 {
4317   tree tail;
4318   tree parts = 0;
4319
4320   for (tail = list; tail; tail = TREE_CHAIN (tail))
4321     if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
4322       parts = chainon (parts, init_noncopied_parts (lhs, TREE_VALUE (tail)));
4323     else
4324       {
4325         tree part = TREE_VALUE (tail);
4326         tree part_type = TREE_TYPE (part);
4327         tree to_be_initialized = build (COMPONENT_REF, part_type, lhs, part);
4328         parts = tree_cons (TREE_PURPOSE (tail), to_be_initialized, parts);
4329       }
4330   return parts;
4331 }
4332
4333 /* Subroutine of expand_expr: return nonzero iff there is no way that
4334    EXP can reference X, which is being modified.  */
4335
4336 static int
4337 safe_from_p (x, exp)
4338      rtx x;
4339      tree exp;
4340 {
4341   rtx exp_rtl = 0;
4342   int i, nops;
4343
4344   if (x == 0
4345       /* If EXP has varying size, we MUST use a target since we currently
4346          have no way of allocating temporaries of variable size.  So we
4347          assume here that something at a higher level has prevented a
4348          clash.  This is somewhat bogus, but the best we can do.  Only
4349          do this when X is BLKmode.  */
4350       || (TREE_TYPE (exp) != 0 && TYPE_SIZE (TREE_TYPE (exp)) != 0
4351           && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
4352           && GET_MODE (x) == BLKmode))
4353     return 1;
4354
4355   /* If this is a subreg of a hard register, declare it unsafe, otherwise,
4356      find the underlying pseudo.  */
4357   if (GET_CODE (x) == SUBREG)
4358     {
4359       x = SUBREG_REG (x);
4360       if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
4361         return 0;
4362     }
4363
4364   /* If X is a location in the outgoing argument area, it is always safe.  */
4365   if (GET_CODE (x) == MEM
4366       && (XEXP (x, 0) == virtual_outgoing_args_rtx
4367           || (GET_CODE (XEXP (x, 0)) == PLUS
4368               && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx)))
4369     return 1;
4370
4371   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
4372     {
4373     case 'd':
4374       exp_rtl = DECL_RTL (exp);
4375       break;
4376
4377     case 'c':
4378       return 1;
4379
4380     case 'x':
4381       if (TREE_CODE (exp) == TREE_LIST)
4382         return ((TREE_VALUE (exp) == 0
4383                  || safe_from_p (x, TREE_VALUE (exp)))
4384                 && (TREE_CHAIN (exp) == 0
4385                     || safe_from_p (x, TREE_CHAIN (exp))));
4386       else
4387         return 0;
4388
4389     case '1':
4390       return safe_from_p (x, TREE_OPERAND (exp, 0));
4391
4392     case '2':
4393     case '<':
4394       return (safe_from_p (x, TREE_OPERAND (exp, 0))
4395               && safe_from_p (x, TREE_OPERAND (exp, 1)));
4396
4397     case 'e':
4398     case 'r':
4399       /* Now do code-specific tests.  EXP_RTL is set to any rtx we find in
4400          the expression.  If it is set, we conflict iff we are that rtx or
4401          both are in memory.  Otherwise, we check all operands of the
4402          expression recursively.  */
4403
4404       switch (TREE_CODE (exp))
4405         {
4406         case ADDR_EXPR:
4407           return (staticp (TREE_OPERAND (exp, 0))
4408                   || safe_from_p (x, TREE_OPERAND (exp, 0)));
4409
4410         case INDIRECT_REF:
4411           if (GET_CODE (x) == MEM)
4412             return 0;
4413           break;
4414
4415         case CALL_EXPR:
4416           exp_rtl = CALL_EXPR_RTL (exp);
4417           if (exp_rtl == 0)
4418             {
4419               /* Assume that the call will clobber all hard registers and
4420                  all of memory.  */
4421               if ((GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
4422                   || GET_CODE (x) == MEM)
4423                 return 0;
4424             }
4425
4426           break;
4427
4428         case RTL_EXPR:
4429           /* If a sequence exists, we would have to scan every instruction
4430              in the sequence to see if it was safe.  This is probably not
4431              worthwhile.  */
4432           if (RTL_EXPR_SEQUENCE (exp))
4433             return 0;
4434
4435           exp_rtl = RTL_EXPR_RTL (exp);
4436           break;
4437
4438         case WITH_CLEANUP_EXPR:
4439           exp_rtl = RTL_EXPR_RTL (exp);
4440           break;
4441
4442         case CLEANUP_POINT_EXPR:
4443           return safe_from_p (x, TREE_OPERAND (exp, 0));
4444
4445         case SAVE_EXPR:
4446           exp_rtl = SAVE_EXPR_RTL (exp);
4447           break;
4448
4449         case BIND_EXPR:
4450           /* The only operand we look at is operand 1.  The rest aren't
4451              part of the expression.  */
4452           return safe_from_p (x, TREE_OPERAND (exp, 1));
4453
4454         case METHOD_CALL_EXPR:
4455           /* This takes a rtx argument, but shouldn't appear here. */
4456           abort ();
4457         }
4458
4459       /* If we have an rtx, we do not need to scan our operands.  */
4460       if (exp_rtl)
4461         break;
4462
4463       nops = tree_code_length[(int) TREE_CODE (exp)];
4464       for (i = 0; i < nops; i++)
4465         if (TREE_OPERAND (exp, i) != 0
4466             && ! safe_from_p (x, TREE_OPERAND (exp, i)))
4467           return 0;
4468     }
4469
4470   /* If we have an rtl, find any enclosed object.  Then see if we conflict
4471      with it.  */
4472   if (exp_rtl)
4473     {
4474       if (GET_CODE (exp_rtl) == SUBREG)
4475         {
4476           exp_rtl = SUBREG_REG (exp_rtl);
4477           if (GET_CODE (exp_rtl) == REG
4478               && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
4479             return 0;
4480         }
4481
4482       /* If the rtl is X, then it is not safe.  Otherwise, it is unless both
4483          are memory and EXP is not readonly.  */
4484       return ! (rtx_equal_p (x, exp_rtl)
4485                 || (GET_CODE (x) == MEM && GET_CODE (exp_rtl) == MEM
4486                     && ! TREE_READONLY (exp)));
4487     }
4488
4489   /* If we reach here, it is safe.  */
4490   return 1;
4491 }
4492
4493 /* Subroutine of expand_expr: return nonzero iff EXP is an
4494    expression whose type is statically determinable.  */
4495
4496 static int
4497 fixed_type_p (exp)
4498      tree exp;
4499 {
4500   if (TREE_CODE (exp) == PARM_DECL
4501       || TREE_CODE (exp) == VAR_DECL
4502       || TREE_CODE (exp) == CALL_EXPR || TREE_CODE (exp) == TARGET_EXPR
4503       || TREE_CODE (exp) == COMPONENT_REF
4504       || TREE_CODE (exp) == ARRAY_REF)
4505     return 1;
4506   return 0;
4507 }
4508 \f
4509 /* expand_expr: generate code for computing expression EXP.
4510    An rtx for the computed value is returned.  The value is never null.
4511    In the case of a void EXP, const0_rtx is returned.
4512
4513    The value may be stored in TARGET if TARGET is nonzero.
4514    TARGET is just a suggestion; callers must assume that
4515    the rtx returned may not be the same as TARGET.
4516
4517    If TARGET is CONST0_RTX, it means that the value will be ignored.
4518
4519    If TMODE is not VOIDmode, it suggests generating the
4520    result in mode TMODE.  But this is done only when convenient.
4521    Otherwise, TMODE is ignored and the value generated in its natural mode.
4522    TMODE is just a suggestion; callers must assume that
4523    the rtx returned may not have mode TMODE.
4524
4525    Note that TARGET may have neither TMODE nor MODE.  In that case, it
4526    probably will not be used.
4527
4528    If MODIFIER is EXPAND_SUM then when EXP is an addition
4529    we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
4530    or a nest of (PLUS ...) and (MINUS ...) where the terms are
4531    products as above, or REG or MEM, or constant.
4532    Ordinarily in such cases we would output mul or add instructions
4533    and then return a pseudo reg containing the sum.
4534
4535    EXPAND_INITIALIZER is much like EXPAND_SUM except that
4536    it also marks a label as absolutely required (it can't be dead).
4537    It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
4538    This is used for outputting expressions used in initializers.
4539
4540    EXPAND_CONST_ADDRESS says that it is okay to return a MEM
4541    with a constant address even if that address is not normally legitimate.
4542    EXPAND_INITIALIZER and EXPAND_SUM also have this effect.  */
4543
4544 rtx
4545 expand_expr (exp, target, tmode, modifier)
4546      register tree exp;
4547      rtx target;
4548      enum machine_mode tmode;
4549      enum expand_modifier modifier;
4550 {
4551   /* Chain of pending expressions for PLACEHOLDER_EXPR to replace.
4552      This is static so it will be accessible to our recursive callees.  */
4553   static tree placeholder_list = 0;
4554   register rtx op0, op1, temp;
4555   tree type = TREE_TYPE (exp);
4556   int unsignedp = TREE_UNSIGNED (type);
4557   register enum machine_mode mode = TYPE_MODE (type);
4558   register enum tree_code code = TREE_CODE (exp);
4559   optab this_optab;
4560   /* Use subtarget as the target for operand 0 of a binary operation.  */
4561   rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
4562   rtx original_target = target;
4563   /* Maybe defer this until sure not doing bytecode?  */
4564   int ignore = (target == const0_rtx
4565                 || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
4566                      || code == CONVERT_EXPR || code == REFERENCE_EXPR
4567                      || code == COND_EXPR)
4568                     && TREE_CODE (type) == VOID_TYPE));
4569   tree context;
4570
4571
4572   if (output_bytecode && modifier != EXPAND_INITIALIZER)
4573     {
4574       bc_expand_expr (exp);
4575       return NULL;
4576     }
4577
4578   /* Don't use hard regs as subtargets, because the combiner
4579      can only handle pseudo regs.  */
4580   if (subtarget && REGNO (subtarget) < FIRST_PSEUDO_REGISTER)
4581     subtarget = 0;
4582   /* Avoid subtargets inside loops,
4583      since they hide some invariant expressions.  */
4584   if (preserve_subexpressions_p ())
4585     subtarget = 0;
4586
4587   /* If we are going to ignore this result, we need only do something
4588      if there is a side-effect somewhere in the expression.  If there
4589      is, short-circuit the most common cases here.  Note that we must
4590      not call expand_expr with anything but const0_rtx in case this
4591      is an initial expansion of a size that contains a PLACEHOLDER_EXPR.  */
4592
4593   if (ignore)
4594     {
4595       if (! TREE_SIDE_EFFECTS (exp))
4596         return const0_rtx;
4597
4598       /* Ensure we reference a volatile object even if value is ignored.  */
4599       if (TREE_THIS_VOLATILE (exp)
4600           && TREE_CODE (exp) != FUNCTION_DECL
4601           && mode != VOIDmode && mode != BLKmode)
4602         {
4603           temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
4604           if (GET_CODE (temp) == MEM)
4605             temp = copy_to_reg (temp);
4606           return const0_rtx;
4607         }
4608
4609       if (TREE_CODE_CLASS (code) == '1')
4610         return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
4611                             VOIDmode, modifier);
4612       else if (TREE_CODE_CLASS (code) == '2'
4613                || TREE_CODE_CLASS (code) == '<')
4614         {
4615           expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
4616           expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, modifier);
4617           return const0_rtx;
4618         }
4619       else if ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
4620                && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
4621         /* If the second operand has no side effects, just evaluate
4622            the first. */
4623         return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
4624                             VOIDmode, modifier);
4625
4626       target = 0;
4627     }
4628
4629   /* If will do cse, generate all results into pseudo registers
4630      since 1) that allows cse to find more things
4631      and 2) otherwise cse could produce an insn the machine
4632      cannot support.  */
4633
4634   if (! cse_not_expected && mode != BLKmode && target
4635       && (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER))
4636     target = subtarget;
4637
4638   switch (code)
4639     {
4640     case LABEL_DECL:
4641       {
4642         tree function = decl_function_context (exp);
4643         /* Handle using a label in a containing function.  */
4644         if (function != current_function_decl && function != 0)
4645           {
4646             struct function *p = find_function_data (function);
4647             /* Allocate in the memory associated with the function
4648                that the label is in.  */
4649             push_obstacks (p->function_obstack,
4650                            p->function_maybepermanent_obstack);
4651
4652             p->forced_labels = gen_rtx (EXPR_LIST, VOIDmode,
4653                                         label_rtx (exp), p->forced_labels);
4654             pop_obstacks ();
4655           }
4656         else if (modifier == EXPAND_INITIALIZER)
4657           forced_labels = gen_rtx (EXPR_LIST, VOIDmode,
4658                                    label_rtx (exp), forced_labels);
4659         temp = gen_rtx (MEM, FUNCTION_MODE,
4660                         gen_rtx (LABEL_REF, Pmode, label_rtx (exp)));
4661         if (function != current_function_decl && function != 0)
4662           LABEL_REF_NONLOCAL_P (XEXP (temp, 0)) = 1;
4663         return temp;
4664       }
4665
4666     case PARM_DECL:
4667       if (DECL_RTL (exp) == 0)
4668         {
4669           error_with_decl (exp, "prior parameter's size depends on `%s'");
4670           return CONST0_RTX (mode);
4671         }
4672
4673       /* ... fall through ... */
4674
4675     case VAR_DECL:
4676       /* If a static var's type was incomplete when the decl was written,
4677          but the type is complete now, lay out the decl now.  */
4678       if (DECL_SIZE (exp) == 0 && TYPE_SIZE (TREE_TYPE (exp)) != 0
4679           && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
4680         {
4681           push_obstacks_nochange ();
4682           end_temporary_allocation ();
4683           layout_decl (exp, 0);
4684           PUT_MODE (DECL_RTL (exp), DECL_MODE (exp));
4685           pop_obstacks ();
4686         }
4687
4688       /* ... fall through ... */
4689
4690     case FUNCTION_DECL:
4691     case RESULT_DECL:
4692       if (DECL_RTL (exp) == 0)
4693         abort ();
4694
4695       /* Ensure variable marked as used even if it doesn't go through
4696          a parser.  If it hasn't be used yet, write out an external
4697          definition.  */
4698       if (! TREE_USED (exp))
4699         {
4700           assemble_external (exp);
4701           TREE_USED (exp) = 1;
4702         }
4703
4704       /* Show we haven't gotten RTL for this yet.  */
4705       temp = 0;
4706
4707       /* Handle variables inherited from containing functions.  */
4708       context = decl_function_context (exp);
4709
4710       /* We treat inline_function_decl as an alias for the current function
4711          because that is the inline function whose vars, types, etc.
4712          are being merged into the current function.
4713          See expand_inline_function.  */
4714
4715       if (context != 0 && context != current_function_decl
4716           && context != inline_function_decl
4717           /* If var is static, we don't need a static chain to access it.  */
4718           && ! (GET_CODE (DECL_RTL (exp)) == MEM
4719                 && CONSTANT_P (XEXP (DECL_RTL (exp), 0))))
4720         {
4721           rtx addr;
4722
4723           /* Mark as non-local and addressable.  */
4724           DECL_NONLOCAL (exp) = 1;
4725           if (DECL_NO_STATIC_CHAIN (current_function_decl))
4726             abort ();
4727           mark_addressable (exp);
4728           if (GET_CODE (DECL_RTL (exp)) != MEM)
4729             abort ();
4730           addr = XEXP (DECL_RTL (exp), 0);
4731           if (GET_CODE (addr) == MEM)
4732             addr = gen_rtx (MEM, Pmode,
4733                             fix_lexical_addr (XEXP (addr, 0), exp));
4734           else
4735             addr = fix_lexical_addr (addr, exp);
4736           temp = change_address (DECL_RTL (exp), mode, addr);
4737         }
4738
4739       /* This is the case of an array whose size is to be determined
4740          from its initializer, while the initializer is still being parsed.
4741          See expand_decl.  */
4742
4743       else if (GET_CODE (DECL_RTL (exp)) == MEM
4744                && GET_CODE (XEXP (DECL_RTL (exp), 0)) == REG)
4745         temp = change_address (DECL_RTL (exp), GET_MODE (DECL_RTL (exp)),
4746                                XEXP (DECL_RTL (exp), 0));
4747
4748       /* If DECL_RTL is memory, we are in the normal case and either
4749          the address is not valid or it is not a register and -fforce-addr
4750          is specified, get the address into a register.  */
4751
4752       else if (GET_CODE (DECL_RTL (exp)) == MEM
4753                && modifier != EXPAND_CONST_ADDRESS
4754                && modifier != EXPAND_SUM
4755                && modifier != EXPAND_INITIALIZER
4756                && (! memory_address_p (DECL_MODE (exp),
4757                                        XEXP (DECL_RTL (exp), 0))
4758                    || (flag_force_addr
4759                        && GET_CODE (XEXP (DECL_RTL (exp), 0)) != REG)))
4760         temp = change_address (DECL_RTL (exp), VOIDmode,
4761                                copy_rtx (XEXP (DECL_RTL (exp), 0)));
4762
4763       /* If we got something, return it.  But first, set the alignment
4764          the address is a register.  */
4765       if (temp != 0)
4766         {
4767           if (GET_CODE (temp) == MEM && GET_CODE (XEXP (temp, 0)) == REG)
4768             mark_reg_pointer (XEXP (temp, 0),
4769                               DECL_ALIGN (exp) / BITS_PER_UNIT);
4770
4771           return temp;
4772         }
4773
4774       /* If the mode of DECL_RTL does not match that of the decl, it
4775          must be a promoted value.  We return a SUBREG of the wanted mode,
4776          but mark it so that we know that it was already extended.  */
4777
4778       if (GET_CODE (DECL_RTL (exp)) == REG
4779           && GET_MODE (DECL_RTL (exp)) != mode)
4780         {
4781           /* Get the signedness used for this variable.  Ensure we get the
4782              same mode we got when the variable was declared.  */
4783           if (GET_MODE (DECL_RTL (exp))
4784               != promote_mode (type, DECL_MODE (exp), &unsignedp, 0))
4785             abort ();
4786
4787           temp = gen_rtx (SUBREG, mode, DECL_RTL (exp), 0);
4788           SUBREG_PROMOTED_VAR_P (temp) = 1;
4789           SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
4790           return temp;
4791         }
4792
4793       return DECL_RTL (exp);
4794
4795     case INTEGER_CST:
4796       return immed_double_const (TREE_INT_CST_LOW (exp),
4797                                  TREE_INT_CST_HIGH (exp),
4798                                  mode);
4799
4800     case CONST_DECL:
4801       return expand_expr (DECL_INITIAL (exp), target, VOIDmode, 0);
4802
4803     case REAL_CST:
4804       /* If optimized, generate immediate CONST_DOUBLE
4805          which will be turned into memory by reload if necessary. 
4806      
4807          We used to force a register so that loop.c could see it.  But
4808          this does not allow gen_* patterns to perform optimizations with
4809          the constants.  It also produces two insns in cases like "x = 1.0;".
4810          On most machines, floating-point constants are not permitted in
4811          many insns, so we'd end up copying it to a register in any case.
4812
4813          Now, we do the copying in expand_binop, if appropriate.  */
4814       return immed_real_const (exp);
4815
4816     case COMPLEX_CST:
4817     case STRING_CST:
4818       if (! TREE_CST_RTL (exp))
4819         output_constant_def (exp);
4820
4821       /* TREE_CST_RTL probably contains a constant address.
4822          On RISC machines where a constant address isn't valid,
4823          make some insns to get that address into a register.  */
4824       if (GET_CODE (TREE_CST_RTL (exp)) == MEM
4825           && modifier != EXPAND_CONST_ADDRESS
4826           && modifier != EXPAND_INITIALIZER
4827           && modifier != EXPAND_SUM
4828           && (! memory_address_p (mode, XEXP (TREE_CST_RTL (exp), 0))
4829               || (flag_force_addr
4830                   && GET_CODE (XEXP (TREE_CST_RTL (exp), 0)) != REG)))
4831         return change_address (TREE_CST_RTL (exp), VOIDmode,
4832                                copy_rtx (XEXP (TREE_CST_RTL (exp), 0)));
4833       return TREE_CST_RTL (exp);
4834
4835     case SAVE_EXPR:
4836       context = decl_function_context (exp);
4837
4838       /* We treat inline_function_decl as an alias for the current function
4839          because that is the inline function whose vars, types, etc.
4840          are being merged into the current function.
4841          See expand_inline_function.  */
4842       if (context == current_function_decl || context == inline_function_decl)
4843         context = 0;
4844
4845       /* If this is non-local, handle it.  */
4846       if (context)
4847         {
4848           temp = SAVE_EXPR_RTL (exp);
4849           if (temp && GET_CODE (temp) == REG)
4850             {
4851               put_var_into_stack (exp);
4852               temp = SAVE_EXPR_RTL (exp);
4853             }
4854           if (temp == 0 || GET_CODE (temp) != MEM)
4855             abort ();
4856           return change_address (temp, mode,
4857                                  fix_lexical_addr (XEXP (temp, 0), exp));
4858         }
4859       if (SAVE_EXPR_RTL (exp) == 0)
4860         {
4861           if (mode == VOIDmode)
4862             temp = const0_rtx;
4863           else
4864             temp = assign_temp (type, 0, 0, 0);
4865
4866           SAVE_EXPR_RTL (exp) = temp;
4867           if (!optimize && GET_CODE (temp) == REG)
4868             save_expr_regs = gen_rtx (EXPR_LIST, VOIDmode, temp,
4869                                       save_expr_regs);
4870
4871           /* If the mode of TEMP does not match that of the expression, it
4872              must be a promoted value.  We pass store_expr a SUBREG of the
4873              wanted mode but mark it so that we know that it was already
4874              extended.  Note that `unsignedp' was modified above in
4875              this case.  */
4876
4877           if (GET_CODE (temp) == REG && GET_MODE (temp) != mode)
4878             {
4879               temp = gen_rtx (SUBREG, mode, SAVE_EXPR_RTL (exp), 0);
4880               SUBREG_PROMOTED_VAR_P (temp) = 1;
4881               SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
4882             }
4883
4884           if (temp == const0_rtx)
4885             expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
4886           else
4887             store_expr (TREE_OPERAND (exp, 0), temp, 0);
4888         }
4889
4890       /* If the mode of SAVE_EXPR_RTL does not match that of the expression, it
4891          must be a promoted value.  We return a SUBREG of the wanted mode,
4892          but mark it so that we know that it was already extended. */
4893
4894       if (GET_CODE (SAVE_EXPR_RTL (exp)) == REG
4895           && GET_MODE (SAVE_EXPR_RTL (exp)) != mode)
4896         {
4897           /* Compute the signedness and make the proper SUBREG.  */
4898           promote_mode (type, mode, &unsignedp, 0);
4899           temp = gen_rtx (SUBREG, mode, SAVE_EXPR_RTL (exp), 0);
4900           SUBREG_PROMOTED_VAR_P (temp) = 1;
4901           SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
4902           return temp;
4903         }
4904
4905       return SAVE_EXPR_RTL (exp);
4906
4907     case UNSAVE_EXPR:
4908       {
4909         rtx temp;
4910         temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
4911         TREE_OPERAND (exp, 0) = unsave_expr_now (TREE_OPERAND (exp, 0));
4912         return temp;
4913       }
4914
4915     case PLACEHOLDER_EXPR:
4916       /* If there is an object on the head of the placeholder list,
4917          see if some object in it's references is of type TYPE.  For
4918          further information, see tree.def.  */
4919       if (placeholder_list)
4920         {
4921           tree object;
4922           tree old_list = placeholder_list;
4923
4924           for (object = TREE_PURPOSE (placeholder_list);
4925                (TYPE_MAIN_VARIANT (TREE_TYPE (object))
4926                 != TYPE_MAIN_VARIANT (type))
4927                && (TREE_CODE_CLASS (TREE_CODE (object)) == 'r'
4928                    || TREE_CODE_CLASS (TREE_CODE (object)) == '1'
4929                    || TREE_CODE_CLASS (TREE_CODE (object)) == '2'
4930                    || TREE_CODE_CLASS (TREE_CODE (object)) == 'e');
4931                object = TREE_OPERAND (object, 0))
4932             ;
4933
4934           if (object != 0
4935               && (TYPE_MAIN_VARIANT (TREE_TYPE (object))
4936                   == TYPE_MAIN_VARIANT (type)))
4937             {
4938               /* Expand this object skipping the list entries before
4939                  it was found in case it is also a PLACEHOLDER_EXPR.
4940                  In that case, we want to translate it using subsequent
4941                  entries.  */
4942               placeholder_list = TREE_CHAIN (placeholder_list);
4943               temp = expand_expr (object, original_target, tmode, modifier);
4944               placeholder_list = old_list;
4945               return temp;
4946             }
4947         }
4948
4949       /* We can't find the object or there was a missing WITH_RECORD_EXPR.  */
4950       abort ();
4951
4952     case WITH_RECORD_EXPR:
4953       /* Put the object on the placeholder list, expand our first operand,
4954          and pop the list.  */
4955       placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
4956                                     placeholder_list);
4957       target = expand_expr (TREE_OPERAND (exp, 0), original_target,
4958                             tmode, modifier);
4959       placeholder_list = TREE_CHAIN (placeholder_list);
4960       return target;
4961
4962     case EXIT_EXPR:
4963       expand_exit_loop_if_false (NULL_PTR,
4964                                  invert_truthvalue (TREE_OPERAND (exp, 0)));
4965       return const0_rtx;
4966
4967     case LOOP_EXPR:
4968       push_temp_slots ();
4969       expand_start_loop (1);
4970       expand_expr_stmt (TREE_OPERAND (exp, 0));
4971       expand_end_loop ();
4972       pop_temp_slots ();
4973
4974       return const0_rtx;
4975
4976     case BIND_EXPR:
4977       {
4978         tree vars = TREE_OPERAND (exp, 0);
4979         int vars_need_expansion = 0;
4980
4981         /* Need to open a binding contour here because
4982            if there are any cleanups they most be contained here.  */
4983         expand_start_bindings (0);
4984
4985         /* Mark the corresponding BLOCK for output in its proper place.  */
4986         if (TREE_OPERAND (exp, 2) != 0
4987             && ! TREE_USED (TREE_OPERAND (exp, 2)))
4988           insert_block (TREE_OPERAND (exp, 2));
4989
4990         /* If VARS have not yet been expanded, expand them now.  */
4991         while (vars)
4992           {
4993             if (DECL_RTL (vars) == 0)
4994               {
4995                 vars_need_expansion = 1;
4996                 expand_decl (vars);
4997               }
4998             expand_decl_init (vars);
4999             vars = TREE_CHAIN (vars);
5000           }
5001
5002         temp = expand_expr (TREE_OPERAND (exp, 1), target, tmode, modifier);
5003
5004         expand_end_bindings (TREE_OPERAND (exp, 0), 0, 0);
5005
5006         return temp;
5007       }
5008
5009     case RTL_EXPR:
5010       if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
5011         abort ();
5012       emit_insns (RTL_EXPR_SEQUENCE (exp));
5013       RTL_EXPR_SEQUENCE (exp) = const0_rtx;
5014       preserve_rtl_expr_result (RTL_EXPR_RTL (exp));
5015       free_temps_for_rtl_expr (exp);
5016       return RTL_EXPR_RTL (exp);
5017
5018     case CONSTRUCTOR:
5019       /* If we don't need the result, just ensure we evaluate any
5020          subexpressions.  */
5021       if (ignore)
5022         {
5023           tree elt;
5024           for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
5025             expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
5026           return const0_rtx;
5027         }
5028
5029       /* All elts simple constants => refer to a constant in memory.  But
5030          if this is a non-BLKmode mode, let it store a field at a time
5031          since that should make a CONST_INT or CONST_DOUBLE when we
5032          fold.  Likewise, if we have a target we can use, it is best to
5033          store directly into the target unless the type is large enough
5034          that memcpy will be used.  If we are making an initializer and
5035          all operands are constant, put it in memory as well.  */
5036       else if ((TREE_STATIC (exp)
5037                 && ((mode == BLKmode
5038                      && ! (target != 0 && safe_from_p (target, exp)))
5039                     || TREE_ADDRESSABLE (exp)
5040                     || (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
5041                         && (move_by_pieces_ninsns
5042                             (TREE_INT_CST_LOW (TYPE_SIZE (type))/BITS_PER_UNIT,
5043                              TYPE_ALIGN (type) / BITS_PER_UNIT)
5044                             > MOVE_RATIO)
5045                         && ! mostly_zeros_p (exp))))
5046                || (modifier == EXPAND_INITIALIZER && TREE_CONSTANT (exp)))
5047         {
5048           rtx constructor = output_constant_def (exp);
5049           if (modifier != EXPAND_CONST_ADDRESS
5050               && modifier != EXPAND_INITIALIZER
5051               && modifier != EXPAND_SUM
5052               && (! memory_address_p (GET_MODE (constructor),
5053                                       XEXP (constructor, 0))
5054                   || (flag_force_addr
5055                       && GET_CODE (XEXP (constructor, 0)) != REG)))
5056             constructor = change_address (constructor, VOIDmode,
5057                                           XEXP (constructor, 0));
5058           return constructor;
5059         }
5060
5061       else
5062         {
5063           if (target == 0 || ! safe_from_p (target, exp))
5064             {
5065               if (mode != BLKmode && ! TREE_ADDRESSABLE (exp))
5066                 target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
5067               else
5068                 target = assign_temp (type, 0, 1, 1);
5069             }
5070
5071           if (TREE_READONLY (exp))
5072             {
5073               if (GET_CODE (target) == MEM)
5074                 target = change_address (target, GET_MODE (target),
5075                                          XEXP (target, 0));
5076               RTX_UNCHANGING_P (target) = 1;
5077             }
5078
5079           store_constructor (exp, target, 0);
5080           return target;
5081         }
5082
5083     case INDIRECT_REF:
5084       {
5085         tree exp1 = TREE_OPERAND (exp, 0);
5086         tree exp2;
5087
5088         op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
5089         op0 = memory_address (mode, op0);
5090
5091         temp = gen_rtx (MEM, mode, op0);
5092         /* If address was computed by addition,
5093            mark this as an element of an aggregate.  */
5094         if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
5095             || (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR
5096                 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == PLUS_EXPR)
5097             || AGGREGATE_TYPE_P (TREE_TYPE (exp))
5098             || (TREE_CODE (exp1) == ADDR_EXPR
5099                 && (exp2 = TREE_OPERAND (exp1, 0))
5100                 && AGGREGATE_TYPE_P (TREE_TYPE (exp2))))
5101           MEM_IN_STRUCT_P (temp) = 1;
5102         MEM_VOLATILE_P (temp) = TREE_THIS_VOLATILE (exp) | flag_volatile;
5103
5104         /* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY
5105            here, because, in C and C++, the fact that a location is accessed
5106            through a pointer to const does not mean that the value there can
5107            never change.  Languages where it can never change should
5108            also set TREE_STATIC.  */
5109         RTX_UNCHANGING_P (temp) = TREE_READONLY (exp) & TREE_STATIC (exp);
5110         return temp;
5111       }
5112
5113     case ARRAY_REF:
5114       if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) != ARRAY_TYPE)
5115         abort ();
5116
5117       {
5118         tree array = TREE_OPERAND (exp, 0);
5119         tree domain = TYPE_DOMAIN (TREE_TYPE (array));
5120         tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
5121         tree index = TREE_OPERAND (exp, 1);
5122         tree index_type = TREE_TYPE (index);
5123         int i;
5124
5125         if (TREE_CODE (low_bound) != INTEGER_CST
5126             && contains_placeholder_p (low_bound))
5127           low_bound = build (WITH_RECORD_EXPR, sizetype, low_bound, exp);
5128
5129         /* Optimize the special-case of a zero lower bound.
5130
5131            We convert the low_bound to sizetype to avoid some problems
5132            with constant folding.  (E.g. suppose the lower bound is 1,
5133            and its mode is QI.  Without the conversion,  (ARRAY
5134            +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
5135            +INDEX), which becomes (ARRAY+255+INDEX).  Oops!)
5136
5137            But sizetype isn't quite right either (especially if
5138            the lowbound is negative).  FIXME */
5139
5140         if (! integer_zerop (low_bound))
5141           index = fold (build (MINUS_EXPR, index_type, index,
5142                                convert (sizetype, low_bound)));
5143
5144         if ((TREE_CODE (index) != INTEGER_CST
5145              || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
5146             && (! SLOW_UNALIGNED_ACCESS || ! get_inner_unaligned_p (exp)))
5147           {
5148             /* Nonconstant array index or nonconstant element size, and
5149                not an array in an unaligned (packed) structure field.
5150                Generate the tree for *(&array+index) and expand that,
5151                except do it in a language-independent way
5152                and don't complain about non-lvalue arrays.
5153                `mark_addressable' should already have been called
5154                for any array for which this case will be reached.  */
5155
5156             /* Don't forget the const or volatile flag from the array
5157                element. */
5158             tree variant_type = build_type_variant (type,
5159                                                     TREE_READONLY (exp),
5160                                                     TREE_THIS_VOLATILE (exp));
5161             tree array_adr = build1 (ADDR_EXPR,
5162                                      build_pointer_type (variant_type), array);
5163             tree elt;
5164             tree size = size_in_bytes (type);
5165
5166             /* Convert the integer argument to a type the same size as sizetype
5167                so the multiply won't overflow spuriously.  */
5168             if (TYPE_PRECISION (index_type) != TYPE_PRECISION (sizetype))
5169               index = convert (type_for_size (TYPE_PRECISION (sizetype), 0),
5170                                index);
5171
5172             if (TREE_CODE (size) != INTEGER_CST
5173                 && contains_placeholder_p (size))
5174               size = build (WITH_RECORD_EXPR, sizetype, size, exp);
5175
5176             /* Don't think the address has side effects
5177                just because the array does.
5178                (In some cases the address might have side effects,
5179                and we fail to record that fact here.  However, it should not
5180                matter, since expand_expr should not care.)  */
5181             TREE_SIDE_EFFECTS (array_adr) = 0;
5182
5183             elt
5184               = build1
5185                 (INDIRECT_REF, type,
5186                  fold (build (PLUS_EXPR,
5187                               TYPE_POINTER_TO (variant_type),
5188                               array_adr,
5189                               fold
5190                               (build1
5191                                (NOP_EXPR,
5192                                 TYPE_POINTER_TO (variant_type),
5193                                 fold (build (MULT_EXPR, TREE_TYPE (index),
5194                                              index,
5195                                              convert (TREE_TYPE (index),
5196                                                       size))))))));;
5197
5198             /* Volatility, etc., of new expression is same as old
5199                expression.  */
5200             TREE_SIDE_EFFECTS (elt) = TREE_SIDE_EFFECTS (exp);
5201             TREE_THIS_VOLATILE (elt) = TREE_THIS_VOLATILE (exp);
5202             TREE_READONLY (elt) = TREE_READONLY (exp);
5203
5204             return expand_expr (elt, target, tmode, modifier);
5205           }
5206
5207         /* Fold an expression like: "foo"[2].
5208            This is not done in fold so it won't happen inside &.
5209            Don't fold if this is for wide characters since it's too
5210            difficult to do correctly and this is a very rare case.  */
5211
5212         if (TREE_CODE (array) == STRING_CST
5213             && TREE_CODE (index) == INTEGER_CST
5214             && !TREE_INT_CST_HIGH (index)
5215             && (i = TREE_INT_CST_LOW (index)) < TREE_STRING_LENGTH (array)
5216             && GET_MODE_CLASS (mode) == MODE_INT
5217             && GET_MODE_SIZE (mode) == 1)
5218           return GEN_INT (TREE_STRING_POINTER (array)[i]);
5219
5220         /* If this is a constant index into a constant array,
5221            just get the value from the array.  Handle both the cases when
5222            we have an explicit constructor and when our operand is a variable
5223            that was declared const.  */
5224
5225         if (TREE_CODE (array) == CONSTRUCTOR && ! TREE_SIDE_EFFECTS (array))
5226           {
5227             if (TREE_CODE (index) == INTEGER_CST
5228                 && TREE_INT_CST_HIGH (index) == 0)
5229               {
5230                 tree elem = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
5231
5232                 i = TREE_INT_CST_LOW (index);
5233                 while (elem && i--)
5234                   elem = TREE_CHAIN (elem);
5235                 if (elem)
5236                   return expand_expr (fold (TREE_VALUE (elem)), target,
5237                                       tmode, modifier);
5238               }
5239           }
5240           
5241         else if (optimize >= 1
5242                  && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
5243                  && TREE_CODE (array) == VAR_DECL && DECL_INITIAL (array)
5244                  && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK)
5245           {
5246             if (TREE_CODE (index) == INTEGER_CST
5247                 && TREE_INT_CST_HIGH (index) == 0)
5248               {
5249                 tree init = DECL_INITIAL (array);
5250
5251                 i = TREE_INT_CST_LOW (index);
5252                 if (TREE_CODE (init) == CONSTRUCTOR)
5253                   {
5254                     tree elem = CONSTRUCTOR_ELTS (init);
5255
5256                     while (elem
5257                            && !tree_int_cst_equal (TREE_PURPOSE (elem), index))
5258                       elem = TREE_CHAIN (elem);
5259                     if (elem)
5260                       return expand_expr (fold (TREE_VALUE (elem)), target,
5261                                           tmode, modifier);
5262                   }
5263                 else if (TREE_CODE (init) == STRING_CST
5264                          && i < TREE_STRING_LENGTH (init))
5265                   return GEN_INT (TREE_STRING_POINTER (init)[i]);
5266               }
5267           }
5268       }
5269
5270       /* Treat array-ref with constant index as a component-ref.  */
5271
5272     case COMPONENT_REF:
5273     case BIT_FIELD_REF:
5274       /* If the operand is a CONSTRUCTOR, we can just extract the
5275          appropriate field if it is present.  Don't do this if we have
5276          already written the data since we want to refer to that copy
5277          and varasm.c assumes that's what we'll do.  */
5278       if (code != ARRAY_REF
5279           && TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR
5280           && TREE_CST_RTL (TREE_OPERAND (exp, 0)) == 0)
5281         {
5282           tree elt;
5283
5284           for (elt = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)); elt;
5285                elt = TREE_CHAIN (elt))
5286             if (TREE_PURPOSE (elt) == TREE_OPERAND (exp, 1))
5287               return expand_expr (TREE_VALUE (elt), target, tmode, modifier);
5288         }
5289
5290       {
5291         enum machine_mode mode1;
5292         int bitsize;
5293         int bitpos;
5294         tree offset;
5295         int volatilep = 0;
5296         tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
5297                                         &mode1, &unsignedp, &volatilep);
5298         int alignment;
5299
5300         /* If we got back the original object, something is wrong.  Perhaps
5301            we are evaluating an expression too early.  In any event, don't
5302            infinitely recurse.  */
5303         if (tem == exp)
5304           abort ();
5305
5306         /* If TEM's type is a union of variable size, pass TARGET to the inner
5307            computation, since it will need a temporary and TARGET is known
5308            to have to do.  This occurs in unchecked conversion in Ada.  */
5309   
5310         op0 = expand_expr (tem,
5311                            (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
5312                             && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
5313                                 != INTEGER_CST)
5314                             ? target : NULL_RTX),
5315                            VOIDmode,
5316                            modifier == EXPAND_INITIALIZER ? modifier : 0);
5317
5318         /* If this is a constant, put it into a register if it is a
5319            legitimate constant and memory if it isn't.  */
5320         if (CONSTANT_P (op0))
5321           {
5322             enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem));
5323             if (mode != BLKmode && LEGITIMATE_CONSTANT_P (op0))
5324               op0 = force_reg (mode, op0);
5325             else
5326               op0 = validize_mem (force_const_mem (mode, op0));
5327           }
5328
5329         alignment = TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT;
5330         if (offset != 0)
5331           {
5332             rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
5333
5334             if (GET_CODE (op0) != MEM)
5335               abort ();
5336             op0 = change_address (op0, VOIDmode,
5337                                   gen_rtx (PLUS, ptr_mode, XEXP (op0, 0),
5338                                            force_reg (ptr_mode, offset_rtx)));
5339           /* If we have a variable offset, the known alignment
5340              is only that of the innermost structure containing the field.
5341              (Actually, we could sometimes do better by using the
5342              size of an element of the innermost array, but no need.)  */
5343           if (TREE_CODE (exp) == COMPONENT_REF
5344               || TREE_CODE (exp) == BIT_FIELD_REF)
5345             alignment = (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
5346                          / BITS_PER_UNIT);
5347           }
5348
5349         /* Don't forget about volatility even if this is a bitfield.  */
5350         if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0))
5351           {
5352             op0 = copy_rtx (op0);
5353             MEM_VOLATILE_P (op0) = 1;
5354           }
5355
5356         /* In cases where an aligned union has an unaligned object
5357            as a field, we might be extracting a BLKmode value from
5358            an integer-mode (e.g., SImode) object.  Handle this case
5359            by doing the extract into an object as wide as the field
5360            (which we know to be the width of a basic mode), then
5361            storing into memory, and changing the mode to BLKmode.
5362            If we ultimately want the address (EXPAND_CONST_ADDRESS or
5363            EXPAND_INITIALIZER), then we must not copy to a temporary.  */
5364         if (mode1 == VOIDmode
5365             || GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
5366             || (modifier != EXPAND_CONST_ADDRESS
5367                 && modifier != EXPAND_INITIALIZER
5368                 && ((mode1 != BLKmode && ! direct_load[(int) mode1])
5369                     /* If the field isn't aligned enough to fetch as a memref,
5370                        fetch it as a bit field.  */
5371                     || (SLOW_UNALIGNED_ACCESS
5372                         && ((TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode))
5373                             || (bitpos % GET_MODE_ALIGNMENT (mode) != 0))))))
5374           {
5375             enum machine_mode ext_mode = mode;
5376
5377             if (ext_mode == BLKmode)
5378               ext_mode = mode_for_size (bitsize, MODE_INT, 1);
5379
5380             if (ext_mode == BLKmode)
5381               {
5382                 /* In this case, BITPOS must start at a byte boundary and
5383                    TARGET, if specified, must be a MEM.  */
5384                 if (GET_CODE (op0) != MEM
5385                     || (target != 0 && GET_CODE (target) != MEM)
5386                     || bitpos % BITS_PER_UNIT != 0)
5387                   abort ();
5388
5389                 op0 = change_address (op0, VOIDmode,
5390                                       plus_constant (XEXP (op0, 0),
5391                                                      bitpos / BITS_PER_UNIT));
5392                 if (target == 0)
5393                   target = assign_temp (type, 0, 1, 1);
5394
5395                 emit_block_move (target, op0,
5396                                  GEN_INT ((bitsize + BITS_PER_UNIT - 1)
5397                                           / BITS_PER_UNIT),
5398                                  1);
5399                 
5400                 return target;
5401               }
5402
5403             op0 = validize_mem (op0);
5404
5405             if (GET_CODE (op0) == MEM && GET_CODE (XEXP (op0, 0)) == REG)
5406               mark_reg_pointer (XEXP (op0, 0), alignment);
5407
5408             op0 = extract_bit_field (op0, bitsize, bitpos,
5409                                      unsignedp, target, ext_mode, ext_mode,
5410                                      alignment,
5411                                      int_size_in_bytes (TREE_TYPE (tem)));
5412             if (mode == BLKmode)
5413               {
5414                 rtx new = assign_stack_temp (ext_mode,
5415                                              bitsize / BITS_PER_UNIT, 0);
5416
5417                 emit_move_insn (new, op0);
5418                 op0 = copy_rtx (new);
5419                 PUT_MODE (op0, BLKmode);
5420                 MEM_IN_STRUCT_P (op0) = 1;
5421               }
5422
5423             return op0;
5424           }
5425
5426         /* If the result is BLKmode, use that to access the object
5427            now as well.  */
5428         if (mode == BLKmode)
5429           mode1 = BLKmode;
5430
5431         /* Get a reference to just this component.  */
5432         if (modifier == EXPAND_CONST_ADDRESS
5433             || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
5434           op0 = gen_rtx (MEM, mode1, plus_constant (XEXP (op0, 0),
5435                                                     (bitpos / BITS_PER_UNIT)));
5436         else
5437           op0 = change_address (op0, mode1,
5438                                 plus_constant (XEXP (op0, 0),
5439                                                (bitpos / BITS_PER_UNIT)));
5440         if (GET_CODE (XEXP (op0, 0)) == REG)
5441           mark_reg_pointer (XEXP (op0, 0), alignment);
5442
5443         MEM_IN_STRUCT_P (op0) = 1;
5444         MEM_VOLATILE_P (op0) |= volatilep;
5445         if (mode == mode1 || mode1 == BLKmode || mode1 == tmode)
5446           return op0;
5447         if (target == 0)
5448           target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
5449         convert_move (target, op0, unsignedp);
5450         return target;
5451       }
5452
5453       /* Intended for a reference to a buffer of a file-object in Pascal.
5454          But it's not certain that a special tree code will really be
5455          necessary for these.  INDIRECT_REF might work for them.  */
5456     case BUFFER_REF:
5457       abort ();
5458
5459     case IN_EXPR:
5460       {
5461         /* Pascal set IN expression.
5462
5463            Algorithm:
5464                rlo       = set_low - (set_low%bits_per_word);
5465                the_word  = set [ (index - rlo)/bits_per_word ];
5466                bit_index = index % bits_per_word;
5467                bitmask   = 1 << bit_index;
5468                return !!(the_word & bitmask);  */
5469
5470         tree set = TREE_OPERAND (exp, 0);
5471         tree index = TREE_OPERAND (exp, 1);
5472         int iunsignedp = TREE_UNSIGNED (TREE_TYPE (index));
5473         tree set_type = TREE_TYPE (set);
5474         tree set_low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (set_type));
5475         tree set_high_bound = TYPE_MAX_VALUE (TYPE_DOMAIN (set_type));
5476         rtx index_val = expand_expr (index, 0, VOIDmode, 0);
5477         rtx lo_r = expand_expr (set_low_bound, 0, VOIDmode, 0);
5478         rtx hi_r = expand_expr (set_high_bound, 0, VOIDmode, 0);
5479         rtx setval = expand_expr (set, 0, VOIDmode, 0);
5480         rtx setaddr = XEXP (setval, 0);
5481         enum machine_mode index_mode = TYPE_MODE (TREE_TYPE (index));
5482         rtx rlow;
5483         rtx diff, quo, rem, addr, bit, result;
5484
5485         preexpand_calls (exp);
5486
5487         /* If domain is empty, answer is no.  Likewise if index is constant
5488            and out of bounds.  */
5489         if ((TREE_CODE (set_high_bound) == INTEGER_CST
5490              && TREE_CODE (set_low_bound) == INTEGER_CST
5491              && tree_int_cst_lt (set_high_bound, set_low_bound)
5492              || (TREE_CODE (index) == INTEGER_CST
5493                  && TREE_CODE (set_low_bound) == INTEGER_CST
5494                  && tree_int_cst_lt (index, set_low_bound))
5495              || (TREE_CODE (set_high_bound) == INTEGER_CST
5496                  && TREE_CODE (index) == INTEGER_CST
5497                  && tree_int_cst_lt (set_high_bound, index))))
5498           return const0_rtx;
5499
5500         if (target == 0)
5501           target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
5502
5503         /* If we get here, we have to generate the code for both cases
5504            (in range and out of range).  */
5505
5506         op0 = gen_label_rtx ();
5507         op1 = gen_label_rtx ();
5508
5509         if (! (GET_CODE (index_val) == CONST_INT
5510                && GET_CODE (lo_r) == CONST_INT))
5511           {
5512             emit_cmp_insn (index_val, lo_r, LT, NULL_RTX,
5513                            GET_MODE (index_val), iunsignedp, 0);
5514             emit_jump_insn (gen_blt (op1));
5515           }
5516
5517         if (! (GET_CODE (index_val) == CONST_INT
5518                && GET_CODE (hi_r) == CONST_INT))
5519           {
5520             emit_cmp_insn (index_val, hi_r, GT, NULL_RTX,
5521                            GET_MODE (index_val), iunsignedp, 0);
5522             emit_jump_insn (gen_bgt (op1));
5523           }
5524
5525         /* Calculate the element number of bit zero in the first word
5526            of the set.  */
5527         if (GET_CODE (lo_r) == CONST_INT)
5528           rlow = GEN_INT (INTVAL (lo_r)
5529                           & ~ ((HOST_WIDE_INT) 1 << BITS_PER_UNIT));
5530         else
5531           rlow = expand_binop (index_mode, and_optab, lo_r,
5532                                GEN_INT (~((HOST_WIDE_INT) 1 << BITS_PER_UNIT)),
5533                                NULL_RTX, iunsignedp, OPTAB_LIB_WIDEN);
5534
5535         diff = expand_binop (index_mode, sub_optab, index_val, rlow,
5536                              NULL_RTX, iunsignedp, OPTAB_LIB_WIDEN);
5537
5538         quo = expand_divmod (0, TRUNC_DIV_EXPR, index_mode, diff,
5539                              GEN_INT (BITS_PER_UNIT), NULL_RTX, iunsignedp);
5540         rem = expand_divmod (1, TRUNC_MOD_EXPR, index_mode, index_val,
5541                              GEN_INT (BITS_PER_UNIT), NULL_RTX, iunsignedp);
5542
5543         addr = memory_address (byte_mode,
5544                                expand_binop (index_mode, add_optab, diff,
5545                                              setaddr, NULL_RTX, iunsignedp,
5546                                              OPTAB_LIB_WIDEN));
5547
5548         /* Extract the bit we want to examine */
5549         bit = expand_shift (RSHIFT_EXPR, byte_mode,
5550                             gen_rtx (MEM, byte_mode, addr),
5551                             make_tree (TREE_TYPE (index), rem),
5552                             NULL_RTX, 1);
5553         result = expand_binop (byte_mode, and_optab, bit, const1_rtx,
5554                                GET_MODE (target) == byte_mode ? target : 0,
5555                                1, OPTAB_LIB_WIDEN);
5556
5557         if (result != target)
5558           convert_move (target, result, 1);
5559
5560         /* Output the code to handle the out-of-range case.  */
5561         emit_jump (op0);
5562         emit_label (op1);
5563         emit_move_insn (target, const0_rtx);
5564         emit_label (op0);
5565         return target;
5566       }
5567
5568     case WITH_CLEANUP_EXPR:
5569       if (RTL_EXPR_RTL (exp) == 0)
5570         {
5571           RTL_EXPR_RTL (exp)
5572             = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
5573           cleanups_this_call
5574             = tree_cons (NULL_TREE, TREE_OPERAND (exp, 2), cleanups_this_call);
5575           /* That's it for this cleanup.  */
5576           TREE_OPERAND (exp, 2) = 0;
5577           (*interim_eh_hook) (NULL_TREE);
5578         }
5579       return RTL_EXPR_RTL (exp);
5580
5581     case CLEANUP_POINT_EXPR:
5582       {
5583         extern int temp_slot_level;
5584         tree old_cleanups = cleanups_this_call;
5585         int old_temp_level = target_temp_slot_level;
5586         push_temp_slots ();
5587         target_temp_slot_level = temp_slot_level;
5588         op0 = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
5589         /* If we're going to use this value, load it up now.  */
5590         if (! ignore)
5591           op0 = force_not_mem (op0);
5592         expand_cleanups_to (old_cleanups);
5593         preserve_temp_slots (op0);
5594         free_temp_slots ();
5595         pop_temp_slots ();
5596         target_temp_slot_level = old_temp_level;
5597       }
5598       return op0;
5599
5600     case CALL_EXPR:
5601       /* Check for a built-in function.  */
5602       if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
5603           && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
5604               == FUNCTION_DECL)
5605           && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
5606         return expand_builtin (exp, target, subtarget, tmode, ignore);
5607
5608       /* If this call was expanded already by preexpand_calls,
5609          just return the result we got.  */
5610       if (CALL_EXPR_RTL (exp) != 0)
5611         return CALL_EXPR_RTL (exp);
5612
5613       return expand_call (exp, target, ignore);
5614
5615     case NON_LVALUE_EXPR:
5616     case NOP_EXPR:
5617     case CONVERT_EXPR:
5618     case REFERENCE_EXPR:
5619       if (TREE_CODE (type) == UNION_TYPE)
5620         {
5621           tree valtype = TREE_TYPE (TREE_OPERAND (exp, 0));
5622           if (target == 0)
5623             {
5624               if (mode != BLKmode)
5625                 target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
5626               else
5627                 target = assign_temp (type, 0, 1, 1);
5628             }
5629
5630           if (GET_CODE (target) == MEM)
5631             /* Store data into beginning of memory target.  */
5632             store_expr (TREE_OPERAND (exp, 0),
5633                         change_address (target, TYPE_MODE (valtype), 0), 0);
5634
5635           else if (GET_CODE (target) == REG)
5636             /* Store this field into a union of the proper type.  */
5637             store_field (target, GET_MODE_BITSIZE (TYPE_MODE (valtype)), 0,
5638                          TYPE_MODE (valtype), TREE_OPERAND (exp, 0),
5639                          VOIDmode, 0, 1,
5640                          int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0))));
5641           else
5642             abort ();
5643
5644           /* Return the entire union.  */
5645           return target;
5646         }
5647
5648       if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
5649         {
5650           op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode,
5651                              modifier);
5652
5653           /* If the signedness of the conversion differs and OP0 is
5654              a promoted SUBREG, clear that indication since we now
5655              have to do the proper extension.  */
5656           if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))) != unsignedp
5657               && GET_CODE (op0) == SUBREG)
5658             SUBREG_PROMOTED_VAR_P (op0) = 0;
5659
5660           return op0;
5661         }
5662
5663       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, 0);
5664       if (GET_MODE (op0) == mode)
5665         return op0;
5666
5667       /* If OP0 is a constant, just convert it into the proper mode.  */
5668       if (CONSTANT_P (op0))
5669         return
5670           convert_modes (mode, TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))),
5671                          op0, TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
5672
5673       if (modifier == EXPAND_INITIALIZER)
5674         return gen_rtx (unsignedp ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
5675
5676       if (target == 0)
5677         return
5678           convert_to_mode (mode, op0,
5679                            TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
5680       else
5681         convert_move (target, op0,
5682                       TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
5683       return target;
5684
5685     case PLUS_EXPR:
5686       /* We come here from MINUS_EXPR when the second operand is a constant. */
5687     plus_expr:
5688       this_optab = add_optab;
5689
5690       /* If we are adding a constant, an RTL_EXPR that is sp, fp, or ap, and
5691          something else, make sure we add the register to the constant and
5692          then to the other thing.  This case can occur during strength
5693          reduction and doing it this way will produce better code if the
5694          frame pointer or argument pointer is eliminated.
5695
5696          fold-const.c will ensure that the constant is always in the inner
5697          PLUS_EXPR, so the only case we need to do anything about is if
5698          sp, ap, or fp is our second argument, in which case we must swap
5699          the innermost first argument and our second argument.  */
5700
5701       if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
5702           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 1)) == INTEGER_CST
5703           && TREE_CODE (TREE_OPERAND (exp, 1)) == RTL_EXPR
5704           && (RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == frame_pointer_rtx
5705               || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == stack_pointer_rtx
5706               || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == arg_pointer_rtx))
5707         {
5708           tree t = TREE_OPERAND (exp, 1);
5709
5710           TREE_OPERAND (exp, 1) = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5711           TREE_OPERAND (TREE_OPERAND (exp, 0), 0) = t;
5712         }
5713
5714       /* If the result is to be ptr_mode and we are adding an integer to
5715          something, we might be forming a constant.  So try to use
5716          plus_constant.  If it produces a sum and we can't accept it,
5717          use force_operand.  This allows P = &ARR[const] to generate
5718          efficient code on machines where a SYMBOL_REF is not a valid
5719          address.
5720
5721          If this is an EXPAND_SUM call, always return the sum.  */
5722       if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
5723           || mode == ptr_mode)
5724         {
5725           if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
5726               && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
5727               && TREE_CONSTANT (TREE_OPERAND (exp, 1)))
5728             {
5729               op1 = expand_expr (TREE_OPERAND (exp, 1), subtarget, VOIDmode,
5730                                  EXPAND_SUM);
5731               op1 = plus_constant (op1, TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)));
5732               if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
5733                 op1 = force_operand (op1, target);
5734               return op1;
5735             }
5736
5737           else if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
5738                    && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_INT
5739                    && TREE_CONSTANT (TREE_OPERAND (exp, 0)))
5740             {
5741               op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
5742                                  EXPAND_SUM);
5743               if (! CONSTANT_P (op0))
5744                 {
5745                   op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
5746                                      VOIDmode, modifier);
5747                   /* Don't go to both_summands if modifier
5748                      says it's not right to return a PLUS.  */
5749                   if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
5750                     goto binop2;
5751                   goto both_summands;
5752                 }
5753               op0 = plus_constant (op0, TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)));
5754               if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
5755                 op0 = force_operand (op0, target);
5756               return op0;
5757             }
5758         }
5759
5760       /* No sense saving up arithmetic to be done
5761          if it's all in the wrong mode to form part of an address.
5762          And force_operand won't know whether to sign-extend or
5763          zero-extend.  */
5764       if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
5765           || mode != ptr_mode)
5766         goto binop;
5767
5768       preexpand_calls (exp);
5769       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
5770         subtarget = 0;
5771
5772       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
5773       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
5774
5775     both_summands:
5776       /* Make sure any term that's a sum with a constant comes last.  */
5777       if (GET_CODE (op0) == PLUS
5778           && CONSTANT_P (XEXP (op0, 1)))
5779         {
5780           temp = op0;
5781           op0 = op1;
5782           op1 = temp;
5783         }
5784       /* If adding to a sum including a constant,
5785          associate it to put the constant outside.  */
5786       if (GET_CODE (op1) == PLUS
5787           && CONSTANT_P (XEXP (op1, 1)))
5788         {
5789           rtx constant_term = const0_rtx;
5790
5791           temp = simplify_binary_operation (PLUS, mode, XEXP (op1, 0), op0);
5792           if (temp != 0)
5793             op0 = temp;
5794           /* Ensure that MULT comes first if there is one.  */
5795           else if (GET_CODE (op0) == MULT)
5796             op0 = gen_rtx (PLUS, mode, op0, XEXP (op1, 0));
5797           else
5798             op0 = gen_rtx (PLUS, mode, XEXP (op1, 0), op0);
5799
5800           /* Let's also eliminate constants from op0 if possible.  */
5801           op0 = eliminate_constant_term (op0, &constant_term);
5802
5803           /* CONSTANT_TERM and XEXP (op1, 1) are known to be constant, so
5804              their sum should be a constant.  Form it into OP1, since the 
5805              result we want will then be OP0 + OP1.  */
5806
5807           temp = simplify_binary_operation (PLUS, mode, constant_term,
5808                                             XEXP (op1, 1));
5809           if (temp != 0)
5810             op1 = temp;
5811           else
5812             op1 = gen_rtx (PLUS, mode, constant_term, XEXP (op1, 1));
5813         }
5814
5815       /* Put a constant term last and put a multiplication first.  */
5816       if (CONSTANT_P (op0) || GET_CODE (op1) == MULT)
5817         temp = op1, op1 = op0, op0 = temp;
5818
5819       temp = simplify_binary_operation (PLUS, mode, op0, op1);
5820       return temp ? temp : gen_rtx (PLUS, mode, op0, op1);
5821
5822     case MINUS_EXPR:
5823       /* For initializers, we are allowed to return a MINUS of two
5824          symbolic constants.  Here we handle all cases when both operands
5825          are constant.  */
5826       /* Handle difference of two symbolic constants,
5827          for the sake of an initializer.  */
5828       if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
5829           && really_constant_p (TREE_OPERAND (exp, 0))
5830           && really_constant_p (TREE_OPERAND (exp, 1)))
5831         {
5832           rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX,
5833                                  VOIDmode, modifier);
5834           rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
5835                                  VOIDmode, modifier);
5836
5837           /* If the last operand is a CONST_INT, use plus_constant of
5838              the negated constant.  Else make the MINUS.  */
5839           if (GET_CODE (op1) == CONST_INT)
5840             return plus_constant (op0, - INTVAL (op1));
5841           else
5842             return gen_rtx (MINUS, mode, op0, op1);
5843         }
5844       /* Convert A - const to A + (-const).  */
5845       if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
5846         {
5847           tree negated = fold (build1 (NEGATE_EXPR, type,
5848                                        TREE_OPERAND (exp, 1)));
5849
5850           /* Deal with the case where we can't negate the constant
5851              in TYPE.  */
5852           if (TREE_UNSIGNED (type) || TREE_OVERFLOW (negated))
5853             {
5854               tree newtype = signed_type (type);
5855               tree newop0 = convert (newtype, TREE_OPERAND (exp, 0));
5856               tree newop1 = convert (newtype, TREE_OPERAND (exp, 1));
5857               tree newneg = fold (build1 (NEGATE_EXPR, newtype, newop1));
5858
5859               if (! TREE_OVERFLOW (newneg))
5860                 return expand_expr (convert (type, 
5861                                              build (PLUS_EXPR, newtype,
5862                                                     newop0, newneg)),
5863                                     target, tmode, modifier);
5864             }
5865           else
5866             {
5867               exp = build (PLUS_EXPR, type, TREE_OPERAND (exp, 0), negated);
5868               goto plus_expr;
5869             }
5870         }
5871       this_optab = sub_optab;
5872       goto binop;
5873
5874     case MULT_EXPR:
5875       preexpand_calls (exp);
5876       /* If first operand is constant, swap them.
5877          Thus the following special case checks need only
5878          check the second operand.  */
5879       if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST)
5880         {
5881           register tree t1 = TREE_OPERAND (exp, 0);
5882           TREE_OPERAND (exp, 0) = TREE_OPERAND (exp, 1);
5883           TREE_OPERAND (exp, 1) = t1;
5884         }
5885
5886       /* Attempt to return something suitable for generating an
5887          indexed address, for machines that support that.  */
5888
5889       if (modifier == EXPAND_SUM && mode == ptr_mode
5890           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
5891           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
5892         {
5893           op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, EXPAND_SUM);
5894
5895           /* Apply distributive law if OP0 is x+c.  */
5896           if (GET_CODE (op0) == PLUS
5897               && GET_CODE (XEXP (op0, 1)) == CONST_INT)
5898             return gen_rtx (PLUS, mode,
5899                             gen_rtx (MULT, mode, XEXP (op0, 0),
5900                                      GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))),
5901                             GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))
5902                                      * INTVAL (XEXP (op0, 1))));
5903
5904           if (GET_CODE (op0) != REG)
5905             op0 = force_operand (op0, NULL_RTX);
5906           if (GET_CODE (op0) != REG)
5907             op0 = copy_to_mode_reg (mode, op0);
5908
5909           return gen_rtx (MULT, mode, op0,
5910                           GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))));
5911         }
5912
5913       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
5914         subtarget = 0;
5915
5916       /* Check for multiplying things that have been extended
5917          from a narrower type.  If this machine supports multiplying
5918          in that narrower type with a result in the desired type,
5919          do it that way, and avoid the explicit type-conversion.  */
5920       if (TREE_CODE (TREE_OPERAND (exp, 0)) == NOP_EXPR
5921           && TREE_CODE (type) == INTEGER_TYPE
5922           && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
5923               < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))
5924           && ((TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
5925                && int_fits_type_p (TREE_OPERAND (exp, 1),
5926                                    TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
5927                /* Don't use a widening multiply if a shift will do.  */
5928                && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1))))
5929                     > HOST_BITS_PER_WIDE_INT)
5930                    || exact_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))) < 0))
5931               ||
5932               (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
5933                && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
5934                    ==
5935                    TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))))
5936                /* If both operands are extended, they must either both
5937                   be zero-extended or both be sign-extended.  */
5938                && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
5939                    ==
5940                    TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))))))
5941         {
5942           enum machine_mode innermode
5943             = TYPE_MODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)));
5944           optab other_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
5945                         ? smul_widen_optab : umul_widen_optab);
5946           this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
5947                         ? umul_widen_optab : smul_widen_optab);
5948           if (mode == GET_MODE_WIDER_MODE (innermode))
5949             {
5950               if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
5951                 {
5952                   op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
5953                                      NULL_RTX, VOIDmode, 0);
5954                   if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
5955                     op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
5956                                        VOIDmode, 0);
5957                   else
5958                     op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
5959                                        NULL_RTX, VOIDmode, 0);
5960                   goto binop2;
5961                 }
5962               else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
5963                        && innermode == word_mode)
5964                 {
5965                   rtx htem;
5966                   op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
5967                                      NULL_RTX, VOIDmode, 0);
5968                   if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
5969                     op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
5970                                        VOIDmode, 0);
5971                   else
5972                     op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
5973                                        NULL_RTX, VOIDmode, 0);
5974                   temp = expand_binop (mode, other_optab, op0, op1, target,
5975                                        unsignedp, OPTAB_LIB_WIDEN);
5976                   htem = expand_mult_highpart_adjust (innermode,
5977                                                       gen_highpart (innermode, temp),
5978                                                       op0, op1,
5979                                                       gen_highpart (innermode, temp),
5980                                                       unsignedp);
5981                   emit_move_insn (gen_highpart (innermode, temp), htem);
5982                   return temp;
5983                 }
5984             }
5985         }
5986       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
5987       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
5988       return expand_mult (mode, op0, op1, target, unsignedp);
5989
5990     case TRUNC_DIV_EXPR:
5991     case FLOOR_DIV_EXPR:
5992     case CEIL_DIV_EXPR:
5993     case ROUND_DIV_EXPR:
5994     case EXACT_DIV_EXPR:
5995       preexpand_calls (exp);
5996       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
5997         subtarget = 0;
5998       /* Possible optimization: compute the dividend with EXPAND_SUM
5999          then if the divisor is constant can optimize the case
6000          where some terms of the dividend have coeffs divisible by it.  */
6001       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
6002       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
6003       return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
6004
6005     case RDIV_EXPR:
6006       this_optab = flodiv_optab;
6007       goto binop;
6008
6009     case TRUNC_MOD_EXPR:
6010     case FLOOR_MOD_EXPR:
6011     case CEIL_MOD_EXPR:
6012     case ROUND_MOD_EXPR:
6013       preexpand_calls (exp);
6014       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
6015         subtarget = 0;
6016       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
6017       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
6018       return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
6019
6020     case FIX_ROUND_EXPR:
6021     case FIX_FLOOR_EXPR:
6022     case FIX_CEIL_EXPR:
6023       abort ();                 /* Not used for C.  */
6024
6025     case FIX_TRUNC_EXPR:
6026       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
6027       if (target == 0)
6028         target = gen_reg_rtx (mode);
6029       expand_fix (target, op0, unsignedp);
6030       return target;
6031
6032     case FLOAT_EXPR:
6033       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
6034       if (target == 0)
6035         target = gen_reg_rtx (mode);
6036       /* expand_float can't figure out what to do if FROM has VOIDmode.
6037          So give it the correct mode.  With -O, cse will optimize this.  */
6038       if (GET_MODE (op0) == VOIDmode)
6039         op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))),
6040                                 op0);
6041       expand_float (target, op0,
6042                     TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
6043       return target;
6044
6045     case NEGATE_EXPR:
6046       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
6047       temp = expand_unop (mode, neg_optab, op0, target, 0);
6048       if (temp == 0)
6049         abort ();
6050       return temp;
6051
6052     case ABS_EXPR:
6053       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
6054
6055       /* Handle complex values specially.  */
6056       if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
6057           || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
6058         return expand_complex_abs (mode, op0, target, unsignedp);
6059
6060       /* Unsigned abs is simply the operand.  Testing here means we don't
6061          risk generating incorrect code below.  */
6062       if (TREE_UNSIGNED (type))
6063         return op0;
6064
6065       return expand_abs (mode, op0, target, unsignedp,
6066                          safe_from_p (target, TREE_OPERAND (exp, 0)));
6067
6068     case MAX_EXPR:
6069     case MIN_EXPR:
6070       target = original_target;
6071       if (target == 0 || ! safe_from_p (target, TREE_OPERAND (exp, 1))
6072           || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
6073           || GET_MODE (target) != mode
6074           || (GET_CODE (target) == REG
6075               && REGNO (target) < FIRST_PSEUDO_REGISTER))
6076         target = gen_reg_rtx (mode);
6077       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
6078       op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
6079
6080       /* First try to do it with a special MIN or MAX instruction.
6081          If that does not win, use a conditional jump to select the proper
6082          value.  */
6083       this_optab = (TREE_UNSIGNED (type)
6084                     ? (code == MIN_EXPR ? umin_optab : umax_optab)
6085                     : (code == MIN_EXPR ? smin_optab : smax_optab));
6086
6087       temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
6088                            OPTAB_WIDEN);
6089       if (temp != 0)
6090         return temp;
6091
6092       /* At this point, a MEM target is no longer useful; we will get better
6093          code without it.  */
6094          
6095       if (GET_CODE (target) == MEM)
6096         target = gen_reg_rtx (mode);
6097
6098       if (target != op0)
6099         emit_move_insn (target, op0);
6100
6101       op0 = gen_label_rtx ();
6102
6103       /* If this mode is an integer too wide to compare properly,
6104          compare word by word.  Rely on cse to optimize constant cases.  */
6105       if (GET_MODE_CLASS (mode) == MODE_INT && !can_compare_p (mode))
6106         {
6107           if (code == MAX_EXPR)
6108             do_jump_by_parts_greater_rtx (mode, TREE_UNSIGNED (type),
6109                                           target, op1, NULL_RTX, op0);
6110           else
6111             do_jump_by_parts_greater_rtx (mode, TREE_UNSIGNED (type),
6112                                           op1, target, NULL_RTX, op0);
6113           emit_move_insn (target, op1);
6114         }
6115       else
6116         {
6117           if (code == MAX_EXPR)
6118             temp = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1)))
6119                     ? compare_from_rtx (target, op1, GEU, 1, mode, NULL_RTX, 0)
6120                     : compare_from_rtx (target, op1, GE, 0, mode, NULL_RTX, 0));
6121           else
6122             temp = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1)))
6123                     ? compare_from_rtx (target, op1, LEU, 1, mode, NULL_RTX, 0)
6124                     : compare_from_rtx (target, op1, LE, 0, mode, NULL_RTX, 0));
6125           if (temp == const0_rtx)
6126             emit_move_insn (target, op1);
6127           else if (temp != const_true_rtx)
6128             {
6129               if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
6130                 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op0));
6131               else
6132                 abort ();
6133               emit_move_insn (target, op1);
6134             }
6135         }
6136       emit_label (op0);
6137       return target;
6138
6139     case BIT_NOT_EXPR:
6140       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
6141       temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
6142       if (temp == 0)
6143         abort ();
6144       return temp;
6145
6146     case FFS_EXPR:
6147       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
6148       temp = expand_unop (mode, ffs_optab, op0, target, 1);
6149       if (temp == 0)
6150         abort ();
6151       return temp;
6152
6153       /* ??? Can optimize bitwise operations with one arg constant.
6154          Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
6155          and (a bitwise1 b) bitwise2 b (etc)
6156          but that is probably not worth while.  */
6157
6158       /* BIT_AND_EXPR is for bitwise anding.  TRUTH_AND_EXPR is for anding two
6159          boolean values when we want in all cases to compute both of them.  In
6160          general it is fastest to do TRUTH_AND_EXPR by computing both operands
6161          as actual zero-or-1 values and then bitwise anding.  In cases where
6162          there cannot be any side effects, better code would be made by
6163          treating TRUTH_AND_EXPR like TRUTH_ANDIF_EXPR; but the question is
6164          how to recognize those cases.  */
6165
6166     case TRUTH_AND_EXPR:
6167     case BIT_AND_EXPR:
6168       this_optab = and_optab;
6169       goto binop;
6170
6171     case TRUTH_OR_EXPR:
6172     case BIT_IOR_EXPR:
6173       this_optab = ior_optab;
6174       goto binop;
6175
6176     case TRUTH_XOR_EXPR:
6177     case BIT_XOR_EXPR:
6178       this_optab = xor_optab;
6179       goto binop;
6180
6181     case LSHIFT_EXPR:
6182     case RSHIFT_EXPR:
6183     case LROTATE_EXPR:
6184     case RROTATE_EXPR:
6185       preexpand_calls (exp);
6186       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
6187         subtarget = 0;
6188       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
6189       return expand_shift (code, mode, op0, TREE_OPERAND (exp, 1), target,
6190                            unsignedp);
6191
6192       /* Could determine the answer when only additive constants differ.  Also,
6193          the addition of one can be handled by changing the condition.  */
6194     case LT_EXPR:
6195     case LE_EXPR:
6196     case GT_EXPR:
6197     case GE_EXPR:
6198     case EQ_EXPR:
6199     case NE_EXPR:
6200       preexpand_calls (exp);
6201       temp = do_store_flag (exp, target, tmode != VOIDmode ? tmode : mode, 0);
6202       if (temp != 0)
6203         return temp;
6204
6205       /* For foo != 0, load foo, and if it is nonzero load 1 instead. */
6206       if (code == NE_EXPR && integer_zerop (TREE_OPERAND (exp, 1))
6207           && original_target
6208           && GET_CODE (original_target) == REG
6209           && (GET_MODE (original_target)
6210               == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
6211         {
6212           temp = expand_expr (TREE_OPERAND (exp, 0), original_target,
6213                               VOIDmode, 0);
6214
6215           if (temp != original_target)
6216             temp = copy_to_reg (temp);
6217
6218           op1 = gen_label_rtx ();
6219           emit_cmp_insn (temp, const0_rtx, EQ, NULL_RTX,
6220                          GET_MODE (temp), unsignedp, 0);
6221           emit_jump_insn (gen_beq (op1));
6222           emit_move_insn (temp, const1_rtx);
6223           emit_label (op1);
6224           return temp;
6225         }
6226
6227       /* If no set-flag instruction, must generate a conditional
6228          store into a temporary variable.  Drop through
6229          and handle this like && and ||.  */
6230
6231     case TRUTH_ANDIF_EXPR:
6232     case TRUTH_ORIF_EXPR:
6233       if (! ignore
6234           && (target == 0 || ! safe_from_p (target, exp)
6235               /* Make sure we don't have a hard reg (such as function's return
6236                  value) live across basic blocks, if not optimizing.  */
6237               || (!optimize && GET_CODE (target) == REG
6238                   && REGNO (target) < FIRST_PSEUDO_REGISTER)))
6239         target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
6240
6241       if (target)
6242         emit_clr_insn (target);
6243
6244       op1 = gen_label_rtx ();
6245       jumpifnot (exp, op1);
6246
6247       if (target)
6248         emit_0_to_1_insn (target);
6249
6250       emit_label (op1);
6251       return ignore ? const0_rtx : target;
6252
6253     case TRUTH_NOT_EXPR:
6254       op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
6255       /* The parser is careful to generate TRUTH_NOT_EXPR
6256          only with operands that are always zero or one.  */
6257       temp = expand_binop (mode, xor_optab, op0, const1_rtx,
6258                            target, 1, OPTAB_LIB_WIDEN);
6259       if (temp == 0)
6260         abort ();
6261       return temp;
6262
6263     case COMPOUND_EXPR:
6264       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
6265       emit_queue ();
6266       return expand_expr (TREE_OPERAND (exp, 1),
6267                           (ignore ? const0_rtx : target),
6268                           VOIDmode, 0);
6269
6270     case COND_EXPR:
6271       {
6272         rtx flag = NULL_RTX;
6273         tree left_cleanups = NULL_TREE;
6274         tree right_cleanups = NULL_TREE;
6275
6276         /* Used to save a pointer to the place to put the setting of
6277            the flag that indicates if this side of the conditional was
6278            taken.  We backpatch the code, if we find out later that we
6279            have any conditional cleanups that need to be performed. */
6280         rtx dest_right_flag = NULL_RTX;
6281         rtx dest_left_flag = NULL_RTX;
6282
6283         /* Note that COND_EXPRs whose type is a structure or union
6284            are required to be constructed to contain assignments of
6285            a temporary variable, so that we can evaluate them here
6286            for side effect only.  If type is void, we must do likewise.  */
6287
6288         /* If an arm of the branch requires a cleanup,
6289            only that cleanup is performed.  */
6290
6291         tree singleton = 0;
6292         tree binary_op = 0, unary_op = 0;
6293         tree old_cleanups = cleanups_this_call;
6294
6295         /* If this is (A ? 1 : 0) and A is a condition, just evaluate it and
6296            convert it to our mode, if necessary.  */
6297         if (integer_onep (TREE_OPERAND (exp, 1))
6298             && integer_zerop (TREE_OPERAND (exp, 2))
6299             && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
6300           {
6301             if (ignore)
6302               {
6303                 expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
6304                              modifier);
6305                 return const0_rtx;
6306               }
6307
6308             op0 = expand_expr (TREE_OPERAND (exp, 0), target, mode, modifier);
6309             if (GET_MODE (op0) == mode)
6310               return op0;
6311
6312             if (target == 0)
6313               target = gen_reg_rtx (mode);
6314             convert_move (target, op0, unsignedp);
6315             return target;
6316           }
6317
6318         /* If we are not to produce a result, we have no target.  Otherwise,
6319            if a target was specified use it; it will not be used as an
6320            intermediate target unless it is safe.  If no target, use a 
6321            temporary.  */
6322
6323         if (ignore)
6324           temp = 0;
6325         else if (original_target
6326                  && safe_from_p (original_target, TREE_OPERAND (exp, 0))
6327                  && GET_MODE (original_target) == mode
6328                  && ! (GET_CODE (original_target) == MEM
6329                        && MEM_VOLATILE_P (original_target)))
6330           temp = original_target;
6331         else
6332           temp = assign_temp (type, 0, 0, 1);
6333
6334         /* Check for X ? A + B : A.  If we have this, we can copy
6335            A to the output and conditionally add B.  Similarly for unary
6336            operations.  Don't do this if X has side-effects because
6337            those side effects might affect A or B and the "?" operation is
6338            a sequence point in ANSI.  (We test for side effects later.)  */
6339
6340         if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '2'
6341             && operand_equal_p (TREE_OPERAND (exp, 2),
6342                                 TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
6343           singleton = TREE_OPERAND (exp, 2), binary_op = TREE_OPERAND (exp, 1);
6344         else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '2'
6345                  && operand_equal_p (TREE_OPERAND (exp, 1),
6346                                      TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
6347           singleton = TREE_OPERAND (exp, 1), binary_op = TREE_OPERAND (exp, 2);
6348         else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '1'
6349                  && operand_equal_p (TREE_OPERAND (exp, 2),
6350                                      TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
6351           singleton = TREE_OPERAND (exp, 2), unary_op = TREE_OPERAND (exp, 1);
6352         else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '1'
6353                  && operand_equal_p (TREE_OPERAND (exp, 1),
6354                                      TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
6355           singleton = TREE_OPERAND (exp, 1), unary_op = TREE_OPERAND (exp, 2);
6356
6357         /* If we had X ? A + 1 : A and we can do the test of X as a store-flag
6358            operation, do this as A + (X != 0).  Similarly for other simple
6359            binary operators.  */
6360         if (temp && singleton && binary_op
6361             && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
6362             && (TREE_CODE (binary_op) == PLUS_EXPR
6363                 || TREE_CODE (binary_op) == MINUS_EXPR
6364                 || TREE_CODE (binary_op) == BIT_IOR_EXPR
6365                 || TREE_CODE (binary_op) == BIT_XOR_EXPR)
6366             && integer_onep (TREE_OPERAND (binary_op, 1))
6367             && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
6368           {
6369             rtx result;
6370             optab boptab = (TREE_CODE (binary_op) == PLUS_EXPR ? add_optab
6371                             : TREE_CODE (binary_op) == MINUS_EXPR ? sub_optab
6372                             : TREE_CODE (binary_op) == BIT_IOR_EXPR ? ior_optab
6373                             : xor_optab);
6374
6375             /* If we had X ? A : A + 1, do this as A + (X == 0).
6376
6377                We have to invert the truth value here and then put it
6378                back later if do_store_flag fails.  We cannot simply copy
6379                TREE_OPERAND (exp, 0) to another variable and modify that
6380                because invert_truthvalue can modify the tree pointed to
6381                by its argument.  */
6382             if (singleton == TREE_OPERAND (exp, 1))
6383               TREE_OPERAND (exp, 0)
6384                 = invert_truthvalue (TREE_OPERAND (exp, 0));
6385
6386             result = do_store_flag (TREE_OPERAND (exp, 0),
6387                                     (safe_from_p (temp, singleton)
6388                                      ? temp : NULL_RTX),
6389                                     mode, BRANCH_COST <= 1);
6390
6391             if (result)
6392               {
6393                 op1 = expand_expr (singleton, NULL_RTX, VOIDmode, 0);
6394                 return expand_binop (mode, boptab, op1, result, temp,
6395                                      unsignedp, OPTAB_LIB_WIDEN);
6396               }
6397             else if (singleton == TREE_OPERAND (exp, 1))
6398               TREE_OPERAND (exp, 0)
6399                 = invert_truthvalue (TREE_OPERAND (exp, 0));
6400           }
6401             
6402         do_pending_stack_adjust ();
6403         NO_DEFER_POP;
6404         op0 = gen_label_rtx ();
6405
6406         flag = gen_reg_rtx (word_mode);
6407         if (singleton && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0)))
6408           {
6409             if (temp != 0)
6410               {
6411                 /* If the target conflicts with the other operand of the
6412                    binary op, we can't use it.  Also, we can't use the target
6413                    if it is a hard register, because evaluating the condition
6414                    might clobber it.  */
6415                 if ((binary_op
6416                      && ! safe_from_p (temp, TREE_OPERAND (binary_op, 1)))
6417                     || (GET_CODE (temp) == REG
6418                         && REGNO (temp) < FIRST_PSEUDO_REGISTER))
6419                   temp = gen_reg_rtx (mode);
6420                 store_expr (singleton, temp, 0);
6421               }
6422             else
6423               expand_expr (singleton,
6424                            ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
6425             dest_left_flag = get_last_insn ();
6426             if (singleton == TREE_OPERAND (exp, 1))
6427               jumpif (TREE_OPERAND (exp, 0), op0);
6428             else
6429               jumpifnot (TREE_OPERAND (exp, 0), op0);
6430
6431             /* Allows cleanups up to here. */
6432             old_cleanups = cleanups_this_call;
6433             if (binary_op && temp == 0)
6434               /* Just touch the other operand.  */
6435               expand_expr (TREE_OPERAND (binary_op, 1),
6436                            ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
6437             else if (binary_op)
6438               store_expr (build (TREE_CODE (binary_op), type,
6439                                  make_tree (type, temp),
6440                                  TREE_OPERAND (binary_op, 1)),
6441                           temp, 0);
6442             else
6443               store_expr (build1 (TREE_CODE (unary_op), type,
6444                                   make_tree (type, temp)),
6445                           temp, 0);
6446             op1 = op0;
6447             dest_right_flag = get_last_insn ();
6448           }
6449 #if 0
6450         /* This is now done in jump.c and is better done there because it
6451            produces shorter register lifetimes.  */
6452            
6453         /* Check for both possibilities either constants or variables
6454            in registers (but not the same as the target!).  If so, can
6455            save branches by assigning one, branching, and assigning the
6456            other.  */
6457         else if (temp && GET_MODE (temp) != BLKmode
6458                  && (TREE_CONSTANT (TREE_OPERAND (exp, 1))
6459                      || ((TREE_CODE (TREE_OPERAND (exp, 1)) == PARM_DECL
6460                           || TREE_CODE (TREE_OPERAND (exp, 1)) == VAR_DECL)
6461                          && DECL_RTL (TREE_OPERAND (exp, 1))
6462                          && GET_CODE (DECL_RTL (TREE_OPERAND (exp, 1))) == REG
6463                          && DECL_RTL (TREE_OPERAND (exp, 1)) != temp))
6464                  && (TREE_CONSTANT (TREE_OPERAND (exp, 2))
6465                      || ((TREE_CODE (TREE_OPERAND (exp, 2)) == PARM_DECL
6466                           || TREE_CODE (TREE_OPERAND (exp, 2)) == VAR_DECL)
6467                          && DECL_RTL (TREE_OPERAND (exp, 2))
6468                          && GET_CODE (DECL_RTL (TREE_OPERAND (exp, 2))) == REG
6469                          && DECL_RTL (TREE_OPERAND (exp, 2)) != temp)))
6470           {
6471             if (GET_CODE (temp) == REG && REGNO (temp) < FIRST_PSEUDO_REGISTER)
6472               temp = gen_reg_rtx (mode);
6473             store_expr (TREE_OPERAND (exp, 2), temp, 0);
6474             dest_left_flag = get_last_insn ();
6475             jumpifnot (TREE_OPERAND (exp, 0), op0);
6476
6477             /* Allows cleanups up to here. */
6478             old_cleanups = cleanups_this_call;
6479             store_expr (TREE_OPERAND (exp, 1), temp, 0);
6480             op1 = op0;
6481             dest_right_flag = get_last_insn ();
6482           }
6483 #endif
6484         /* Check for A op 0 ? A : FOO and A op 0 ? FOO : A where OP is any
6485            comparison operator.  If we have one of these cases, set the
6486            output to A, branch on A (cse will merge these two references),
6487            then set the output to FOO.  */
6488         else if (temp
6489                  && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
6490                  && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
6491                  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
6492                                      TREE_OPERAND (exp, 1), 0)
6493                  && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
6494                  && safe_from_p (temp, TREE_OPERAND (exp, 2)))
6495           {
6496             if (GET_CODE (temp) == REG && REGNO (temp) < FIRST_PSEUDO_REGISTER)
6497               temp = gen_reg_rtx (mode);
6498             store_expr (TREE_OPERAND (exp, 1), temp, 0);
6499             dest_left_flag = get_last_insn ();
6500             jumpif (TREE_OPERAND (exp, 0), op0);
6501
6502             /* Allows cleanups up to here. */
6503             old_cleanups = cleanups_this_call;
6504             store_expr (TREE_OPERAND (exp, 2), temp, 0);
6505             op1 = op0;
6506             dest_right_flag = get_last_insn ();
6507           }
6508         else if (temp
6509                  && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
6510                  && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
6511                  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
6512                                      TREE_OPERAND (exp, 2), 0)
6513                  && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
6514                  && safe_from_p (temp, TREE_OPERAND (exp, 1)))
6515           {
6516             if (GET_CODE (temp) == REG && REGNO (temp) < FIRST_PSEUDO_REGISTER)
6517               temp = gen_reg_rtx (mode);
6518             store_expr (TREE_OPERAND (exp, 2), temp, 0);
6519             dest_left_flag = get_last_insn ();
6520             jumpifnot (TREE_OPERAND (exp, 0), op0);
6521
6522             /* Allows cleanups up to here. */
6523             old_cleanups = cleanups_this_call;
6524             store_expr (TREE_OPERAND (exp, 1), temp, 0);
6525             op1 = op0;
6526             dest_right_flag = get_last_insn ();
6527           }
6528         else
6529           {
6530             op1 = gen_label_rtx ();
6531             jumpifnot (TREE_OPERAND (exp, 0), op0);
6532
6533             /* Allows cleanups up to here. */
6534             old_cleanups = cleanups_this_call;
6535             if (temp != 0)
6536               store_expr (TREE_OPERAND (exp, 1), temp, 0);
6537             else
6538               expand_expr (TREE_OPERAND (exp, 1),
6539                            ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
6540             dest_left_flag = get_last_insn ();
6541
6542             /* Handle conditional cleanups, if any. */
6543             left_cleanups = defer_cleanups_to (old_cleanups);
6544
6545             emit_queue ();
6546             emit_jump_insn (gen_jump (op1));
6547             emit_barrier ();
6548             emit_label (op0);
6549             if (temp != 0)
6550               store_expr (TREE_OPERAND (exp, 2), temp, 0);
6551             else
6552               expand_expr (TREE_OPERAND (exp, 2),
6553                            ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
6554             dest_right_flag = get_last_insn ();
6555           }
6556
6557         /* Handle conditional cleanups, if any. */
6558         right_cleanups = defer_cleanups_to (old_cleanups);
6559
6560         emit_queue ();
6561         emit_label (op1);
6562         OK_DEFER_POP;
6563
6564         /* Add back in, any conditional cleanups. */
6565         if (left_cleanups || right_cleanups)
6566           {
6567             tree new_cleanups;
6568             tree cond;
6569             rtx last;
6570
6571             /* Now that we know that a flag is needed, go back and add in the
6572                setting of the flag. */
6573
6574             /* Do the left side flag. */
6575             last = get_last_insn ();
6576             /* Flag left cleanups as needed. */
6577             emit_move_insn (flag, const1_rtx);
6578             /* ??? deprecated, use sequences instead.  */
6579             reorder_insns (NEXT_INSN (last), get_last_insn (), dest_left_flag);
6580
6581             /* Do the right side flag. */
6582             last = get_last_insn ();
6583             /* Flag left cleanups as needed. */
6584             emit_move_insn (flag, const0_rtx);
6585             /* ??? deprecated, use sequences instead.  */
6586             reorder_insns (NEXT_INSN (last), get_last_insn (), dest_right_flag);
6587
6588             /* All cleanups must be on the function_obstack.  */
6589             push_obstacks_nochange ();
6590             resume_temporary_allocation ();
6591
6592             /* convert flag, which is an rtx, into a tree. */
6593             cond = make_node (RTL_EXPR);
6594             TREE_TYPE (cond) = integer_type_node;
6595             RTL_EXPR_RTL (cond) = flag;
6596             RTL_EXPR_SEQUENCE (cond) = NULL_RTX;
6597             cond = save_expr (cond);
6598
6599             if (! left_cleanups)
6600               left_cleanups = integer_zero_node;
6601             if (! right_cleanups)
6602               right_cleanups = integer_zero_node;
6603             new_cleanups = build (COND_EXPR, void_type_node,
6604                                   truthvalue_conversion (cond),
6605                                   left_cleanups, right_cleanups);
6606             new_cleanups = fold (new_cleanups);
6607
6608             pop_obstacks ();
6609
6610             /* Now add in the conditionalized cleanups. */
6611             cleanups_this_call
6612               = tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
6613             (*interim_eh_hook) (NULL_TREE);
6614           }
6615         return temp;
6616       }
6617
6618     case TARGET_EXPR:
6619       {
6620         /* Something needs to be initialized, but we didn't know
6621            where that thing was when building the tree.  For example,
6622            it could be the return value of a function, or a parameter
6623            to a function which lays down in the stack, or a temporary
6624            variable which must be passed by reference.
6625
6626            We guarantee that the expression will either be constructed
6627            or copied into our original target.  */
6628
6629         tree slot = TREE_OPERAND (exp, 0);
6630         tree cleanups = NULL_TREE;
6631         tree exp1;
6632         rtx temp;
6633
6634         if (TREE_CODE (slot) != VAR_DECL)
6635           abort ();
6636
6637         if (! ignore)
6638           target = original_target;
6639
6640         if (target == 0)
6641           {
6642             if (DECL_RTL (slot) != 0)
6643               {
6644                 target = DECL_RTL (slot);
6645                 /* If we have already expanded the slot, so don't do
6646                    it again.  (mrs)  */
6647                 if (TREE_OPERAND (exp, 1) == NULL_TREE)
6648                   return target;
6649               }
6650             else
6651               {
6652                 target = assign_temp (type, 2, 1, 1);
6653                 /* All temp slots at this level must not conflict.  */
6654                 preserve_temp_slots (target);
6655                 DECL_RTL (slot) = target;
6656
6657                 /* Since SLOT is not known to the called function
6658                    to belong to its stack frame, we must build an explicit
6659                    cleanup.  This case occurs when we must build up a reference
6660                    to pass the reference as an argument.  In this case,
6661                    it is very likely that such a reference need not be
6662                    built here.  */
6663
6664                 if (TREE_OPERAND (exp, 2) == 0)
6665                   TREE_OPERAND (exp, 2) = maybe_build_cleanup (slot);
6666                 cleanups = TREE_OPERAND (exp, 2);
6667               }
6668           }
6669         else
6670           {
6671             /* This case does occur, when expanding a parameter which
6672                needs to be constructed on the stack.  The target
6673                is the actual stack address that we want to initialize.
6674                The function we call will perform the cleanup in this case.  */
6675
6676             /* If we have already assigned it space, use that space,
6677                not target that we were passed in, as our target
6678                parameter is only a hint.  */
6679             if (DECL_RTL (slot) != 0)
6680               {
6681                 target = DECL_RTL (slot);
6682                 /* If we have already expanded the slot, so don't do
6683                    it again.  (mrs)  */
6684                 if (TREE_OPERAND (exp, 1) == NULL_TREE)
6685                   return target;
6686               }
6687
6688             DECL_RTL (slot) = target;
6689           }
6690
6691         exp1 = TREE_OPERAND (exp, 3) = TREE_OPERAND (exp, 1);
6692         /* Mark it as expanded.  */
6693         TREE_OPERAND (exp, 1) = NULL_TREE;
6694
6695         store_expr (exp1, target, 0);
6696
6697         if (cleanups)
6698           {
6699             cleanups_this_call = tree_cons (NULL_TREE,
6700                                             cleanups,
6701                                             cleanups_this_call);
6702             (*interim_eh_hook) (NULL_TREE);
6703           }
6704         
6705         return target;
6706       }
6707
6708     case INIT_EXPR:
6709       {
6710         tree lhs = TREE_OPERAND (exp, 0);
6711         tree rhs = TREE_OPERAND (exp, 1);
6712         tree noncopied_parts = 0;
6713         tree lhs_type = TREE_TYPE (lhs);
6714
6715         temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
6716         if (TYPE_NONCOPIED_PARTS (lhs_type) != 0 && !fixed_type_p (rhs))
6717           noncopied_parts = init_noncopied_parts (stabilize_reference (lhs),
6718                                                   TYPE_NONCOPIED_PARTS (lhs_type));
6719         while (noncopied_parts != 0)
6720           {
6721             expand_assignment (TREE_VALUE (noncopied_parts),
6722                                TREE_PURPOSE (noncopied_parts), 0, 0);
6723             noncopied_parts = TREE_CHAIN (noncopied_parts);
6724           }
6725         return temp;
6726       }
6727
6728     case MODIFY_EXPR:
6729       {
6730         /* If lhs is complex, expand calls in rhs before computing it.
6731            That's so we don't compute a pointer and save it over a call.
6732            If lhs is simple, compute it first so we can give it as a
6733            target if the rhs is just a call.  This avoids an extra temp and copy
6734            and that prevents a partial-subsumption which makes bad code.
6735            Actually we could treat component_ref's of vars like vars.  */
6736
6737         tree lhs = TREE_OPERAND (exp, 0);
6738         tree rhs = TREE_OPERAND (exp, 1);
6739         tree noncopied_parts = 0;
6740         tree lhs_type = TREE_TYPE (lhs);
6741
6742         temp = 0;
6743
6744         if (TREE_CODE (lhs) != VAR_DECL
6745             && TREE_CODE (lhs) != RESULT_DECL
6746             && TREE_CODE (lhs) != PARM_DECL)
6747           preexpand_calls (exp);
6748
6749         /* Check for |= or &= of a bitfield of size one into another bitfield
6750            of size 1.  In this case, (unless we need the result of the
6751            assignment) we can do this more efficiently with a
6752            test followed by an assignment, if necessary.
6753
6754            ??? At this point, we can't get a BIT_FIELD_REF here.  But if
6755            things change so we do, this code should be enhanced to
6756            support it.  */
6757         if (ignore
6758             && TREE_CODE (lhs) == COMPONENT_REF
6759             && (TREE_CODE (rhs) == BIT_IOR_EXPR
6760                 || TREE_CODE (rhs) == BIT_AND_EXPR)
6761             && TREE_OPERAND (rhs, 0) == lhs
6762             && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
6763             && TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (lhs, 1))) == 1
6764             && TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))) == 1)
6765           {
6766             rtx label = gen_label_rtx ();
6767
6768             do_jump (TREE_OPERAND (rhs, 1),
6769                      TREE_CODE (rhs) == BIT_IOR_EXPR ? label : 0,
6770                      TREE_CODE (rhs) == BIT_AND_EXPR ? label : 0);
6771             expand_assignment (lhs, convert (TREE_TYPE (rhs),
6772                                              (TREE_CODE (rhs) == BIT_IOR_EXPR
6773                                               ? integer_one_node
6774                                               : integer_zero_node)),
6775                                0, 0);
6776             do_pending_stack_adjust ();
6777             emit_label (label);
6778             return const0_rtx;
6779           }
6780
6781         if (TYPE_NONCOPIED_PARTS (lhs_type) != 0
6782             && ! (fixed_type_p (lhs) && fixed_type_p (rhs)))
6783           noncopied_parts = save_noncopied_parts (stabilize_reference (lhs),
6784                                                   TYPE_NONCOPIED_PARTS (lhs_type));
6785
6786         temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
6787         while (noncopied_parts != 0)
6788           {
6789             expand_assignment (TREE_PURPOSE (noncopied_parts),
6790                                TREE_VALUE (noncopied_parts), 0, 0);
6791             noncopied_parts = TREE_CHAIN (noncopied_parts);
6792           }
6793         return temp;
6794       }
6795
6796     case PREINCREMENT_EXPR:
6797     case PREDECREMENT_EXPR:
6798       return expand_increment (exp, 0, ignore);
6799
6800     case POSTINCREMENT_EXPR:
6801     case POSTDECREMENT_EXPR:
6802       /* Faster to treat as pre-increment if result is not used.  */
6803       return expand_increment (exp, ! ignore, ignore);
6804
6805     case ADDR_EXPR:
6806       /* If nonzero, TEMP will be set to the address of something that might
6807          be a MEM corresponding to a stack slot. */
6808       temp = 0;
6809
6810       /* Are we taking the address of a nested function?  */
6811       if (TREE_CODE (TREE_OPERAND (exp, 0)) == FUNCTION_DECL
6812           && decl_function_context (TREE_OPERAND (exp, 0)) != 0
6813           && ! DECL_NO_STATIC_CHAIN (TREE_OPERAND (exp, 0)))
6814         {
6815           op0 = trampoline_address (TREE_OPERAND (exp, 0));
6816           op0 = force_operand (op0, target);
6817         }
6818       /* If we are taking the address of something erroneous, just
6819          return a zero.  */
6820       else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
6821         return const0_rtx;
6822       else
6823         {
6824           /* We make sure to pass const0_rtx down if we came in with
6825              ignore set, to avoid doing the cleanups twice for something.  */
6826           op0 = expand_expr (TREE_OPERAND (exp, 0),
6827                              ignore ? const0_rtx : NULL_RTX, VOIDmode,
6828                              (modifier == EXPAND_INITIALIZER
6829                               ? modifier : EXPAND_CONST_ADDRESS));
6830
6831           /* If we are going to ignore the result, OP0 will have been set
6832              to const0_rtx, so just return it.  Don't get confused and
6833              think we are taking the address of the constant.  */
6834           if (ignore)
6835             return op0;
6836
6837           op0 = protect_from_queue (op0, 0);
6838
6839           /* We would like the object in memory.  If it is a constant,
6840              we can have it be statically allocated into memory.  For
6841              a non-constant (REG, SUBREG or CONCAT), we need to allocate some
6842              memory and store the value into it.  */
6843
6844           if (CONSTANT_P (op0))
6845             op0 = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))),
6846                                    op0);
6847           else if (GET_CODE (op0) == MEM)
6848             {
6849               mark_temp_addr_taken (op0);
6850               temp = XEXP (op0, 0);
6851             }
6852
6853           else if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
6854                    || GET_CODE (op0) == CONCAT)
6855             {
6856               /* If this object is in a register, it must be not
6857                  be BLKmode. */
6858               tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
6859               rtx memloc = assign_temp (inner_type, 1, 1, 1);
6860
6861               mark_temp_addr_taken (memloc);
6862               emit_move_insn (memloc, op0);
6863               op0 = memloc;
6864             }
6865
6866           if (GET_CODE (op0) != MEM)
6867             abort ();
6868   
6869           if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
6870             {
6871               temp = XEXP (op0, 0);
6872 #ifdef POINTERS_EXTEND_UNSIGNED
6873               if (GET_MODE (temp) == Pmode && GET_MODE (temp) != mode
6874                   && mode == ptr_mode)
6875                 temp = convert_memory_address (ptr_mode, temp);
6876 #endif
6877               return temp;
6878             }
6879
6880           op0 = force_operand (XEXP (op0, 0), target);
6881         }
6882
6883       if (flag_force_addr && GET_CODE (op0) != REG)
6884         op0 = force_reg (Pmode, op0);
6885
6886       if (GET_CODE (op0) == REG
6887           && ! REG_USERVAR_P (op0))
6888         mark_reg_pointer (op0, TYPE_ALIGN (TREE_TYPE (type)) / BITS_PER_UNIT);
6889
6890       /* If we might have had a temp slot, add an equivalent address
6891          for it.  */
6892       if (temp != 0)
6893         update_temp_slot_address (temp, op0);
6894
6895 #ifdef POINTERS_EXTEND_UNSIGNED
6896       if (GET_MODE (op0) == Pmode && GET_MODE (op0) != mode
6897           && mode == ptr_mode)
6898         op0 = convert_memory_address (ptr_mode, op0);
6899 #endif
6900
6901       return op0;
6902
6903     case ENTRY_VALUE_EXPR:
6904       abort ();
6905
6906     /* COMPLEX type for Extended Pascal & Fortran  */
6907     case COMPLEX_EXPR:
6908       {
6909         enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
6910         rtx insns;
6911
6912         /* Get the rtx code of the operands.  */
6913         op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
6914         op1 = expand_expr (TREE_OPERAND (exp, 1), 0, VOIDmode, 0);
6915
6916         if (! target)
6917           target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
6918
6919         start_sequence ();
6920
6921         /* Move the real (op0) and imaginary (op1) parts to their location.  */
6922         emit_move_insn (gen_realpart (mode, target), op0);
6923         emit_move_insn (gen_imagpart (mode, target), op1);
6924
6925         insns = get_insns ();
6926         end_sequence ();
6927
6928         /* Complex construction should appear as a single unit.  */
6929         /* If TARGET is a CONCAT, we got insns like RD = RS, ID = IS,
6930            each with a separate pseudo as destination.
6931            It's not correct for flow to treat them as a unit.  */
6932         if (GET_CODE (target) != CONCAT)
6933           emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
6934         else
6935           emit_insns (insns);
6936
6937         return target;
6938       }
6939
6940     case REALPART_EXPR:
6941       op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
6942       return gen_realpart (mode, op0);
6943       
6944     case IMAGPART_EXPR:
6945       op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
6946       return gen_imagpart (mode, op0);
6947
6948     case CONJ_EXPR:
6949       {
6950         enum machine_mode partmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
6951         rtx imag_t;
6952         rtx insns;
6953         
6954         op0  = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
6955
6956         if (! target)
6957           target = gen_reg_rtx (mode);
6958                                                                     
6959         start_sequence ();
6960
6961         /* Store the realpart and the negated imagpart to target.  */
6962         emit_move_insn (gen_realpart (partmode, target),
6963                         gen_realpart (partmode, op0));
6964
6965         imag_t = gen_imagpart (partmode, target);
6966         temp = expand_unop (partmode, neg_optab,
6967                                gen_imagpart (partmode, op0), imag_t, 0);
6968         if (temp != imag_t)
6969           emit_move_insn (imag_t, temp);
6970
6971         insns = get_insns ();
6972         end_sequence ();
6973
6974         /* Conjugate should appear as a single unit 
6975            If TARGET is a CONCAT, we got insns like RD = RS, ID = - IS,
6976            each with a separate pseudo as destination.
6977            It's not correct for flow to treat them as a unit.  */
6978         if (GET_CODE (target) != CONCAT)
6979           emit_no_conflict_block (insns, target, op0, NULL_RTX, NULL_RTX);
6980         else
6981           emit_insns (insns);
6982
6983         return target;
6984       }
6985
6986     case ERROR_MARK:
6987       op0 = CONST0_RTX (tmode);
6988       if (op0 != 0)
6989         return op0;
6990       return const0_rtx;
6991
6992     default:
6993       return (*lang_expand_expr) (exp, original_target, tmode, modifier);
6994     }
6995
6996   /* Here to do an ordinary binary operator, generating an instruction
6997      from the optab already placed in `this_optab'.  */
6998  binop:
6999   preexpand_calls (exp);
7000   if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
7001     subtarget = 0;
7002   op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
7003   op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
7004  binop2:
7005   temp = expand_binop (mode, this_optab, op0, op1, target,
7006                        unsignedp, OPTAB_LIB_WIDEN);
7007   if (temp == 0)
7008     abort ();
7009   return temp;
7010 }
7011
7012
7013 /* Emit bytecode to evaluate the given expression EXP to the stack. */
7014 void
7015 bc_expand_expr (exp)
7016     tree exp;
7017 {
7018   enum tree_code code;
7019   tree type, arg0;
7020   rtx r;
7021   struct binary_operator *binoptab;
7022   struct unary_operator *unoptab;
7023   struct increment_operator *incroptab;
7024   struct bc_label *lab, *lab1;
7025   enum bytecode_opcode opcode;
7026   
7027   
7028   code = TREE_CODE (exp);
7029   
7030   switch (code)
7031     {
7032     case PARM_DECL:
7033       
7034       if (DECL_RTL (exp) == 0)
7035         {
7036           error_with_decl (exp, "prior parameter's size depends on `%s'");
7037           return;
7038         }
7039       
7040       bc_load_parmaddr (DECL_RTL (exp));
7041       bc_load_memory (TREE_TYPE (exp), exp);
7042       
7043       return;
7044       
7045     case VAR_DECL:
7046       
7047       if (DECL_RTL (exp) == 0)
7048         abort ();
7049       
7050 #if 0
7051       if (BYTECODE_LABEL (DECL_RTL (exp)))
7052         bc_load_externaddr (DECL_RTL (exp));
7053       else
7054         bc_load_localaddr (DECL_RTL (exp));
7055 #endif
7056       if (TREE_PUBLIC (exp))
7057         bc_load_externaddr_id (DECL_ASSEMBLER_NAME (exp),
7058                                BYTECODE_BC_LABEL (DECL_RTL (exp))->offset);
7059       else
7060         bc_load_localaddr (DECL_RTL (exp));
7061       
7062       bc_load_memory (TREE_TYPE (exp), exp);
7063       return;
7064       
7065     case INTEGER_CST:
7066       
7067 #ifdef DEBUG_PRINT_CODE
7068       fprintf (stderr, " [%x]\n", TREE_INT_CST_LOW (exp));
7069 #endif
7070       bc_emit_instruction (mode_to_const_map[(int) (DECL_BIT_FIELD (exp)
7071                                              ? SImode
7072                                              : TYPE_MODE (TREE_TYPE (exp)))],
7073                            (HOST_WIDE_INT) TREE_INT_CST_LOW (exp));
7074       return;
7075       
7076     case REAL_CST:
7077       
7078 #if 0
7079 #ifdef DEBUG_PRINT_CODE
7080       fprintf (stderr, " [%g]\n", (double) TREE_INT_CST_LOW (exp));
7081 #endif
7082       /* FIX THIS: find a better way to pass real_cst's. -bson */
7083       bc_emit_instruction (mode_to_const_map[TYPE_MODE (TREE_TYPE (exp))],
7084                            (double) TREE_REAL_CST (exp));
7085 #else
7086       abort ();
7087 #endif
7088
7089       return;
7090       
7091     case CALL_EXPR:
7092       
7093       /* We build a call description vector describing the type of
7094          the return value and of the arguments; this call vector,
7095          together with a pointer to a location for the return value
7096          and the base of the argument list, is passed to the low
7097          level machine dependent call subroutine, which is responsible
7098          for putting the arguments wherever real functions expect
7099          them, as well as getting the return value back.  */
7100       {
7101         tree calldesc = 0, arg;
7102         int nargs = 0, i;
7103         rtx retval;
7104         
7105         /* Push the evaluated args on the evaluation stack in reverse
7106            order.  Also make an entry for each arg in the calldesc
7107            vector while we're at it.  */
7108         
7109         TREE_OPERAND (exp, 1) = nreverse (TREE_OPERAND (exp, 1));
7110         
7111         for (arg = TREE_OPERAND (exp, 1); arg; arg = TREE_CHAIN (arg))
7112           {
7113             ++nargs;
7114             bc_expand_expr (TREE_VALUE (arg));
7115             
7116             calldesc = tree_cons ((tree) 0,
7117                                   size_in_bytes (TREE_TYPE (TREE_VALUE (arg))),
7118                                   calldesc);
7119             calldesc = tree_cons ((tree) 0,
7120                                   bc_runtime_type_code (TREE_TYPE (TREE_VALUE (arg))),
7121                                   calldesc);
7122           }
7123         
7124         TREE_OPERAND (exp, 1) = nreverse (TREE_OPERAND (exp, 1));
7125         
7126         /* Allocate a location for the return value and push its
7127            address on the evaluation stack.  Also make an entry
7128            at the front of the calldesc for the return value type. */
7129         
7130         type = TREE_TYPE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
7131         retval = bc_allocate_local (int_size_in_bytes (type), TYPE_ALIGN (type));
7132         bc_load_localaddr (retval);
7133         
7134         calldesc = tree_cons ((tree) 0, size_in_bytes (type), calldesc);
7135         calldesc = tree_cons ((tree) 0, bc_runtime_type_code (type), calldesc);
7136         
7137         /* Prepend the argument count.  */
7138         calldesc = tree_cons ((tree) 0,
7139                               build_int_2 (nargs, 0),
7140                               calldesc);
7141         
7142         /* Push the address of the call description vector on the stack.  */
7143         calldesc = build_nt (CONSTRUCTOR, (tree) 0, calldesc);
7144         TREE_TYPE (calldesc) = build_array_type (integer_type_node,
7145                                                  build_index_type (build_int_2 (nargs * 2, 0)));
7146         r = output_constant_def (calldesc);
7147         bc_load_externaddr (r);
7148         
7149         /* Push the address of the function to be called. */
7150         bc_expand_expr (TREE_OPERAND (exp, 0));
7151         
7152         /* Call the function, popping its address and the calldesc vector
7153            address off the evaluation stack in the process.  */
7154         bc_emit_instruction (call);
7155         
7156         /* Pop the arguments off the stack.  */
7157         bc_adjust_stack (nargs);
7158         
7159         /* Load the return value onto the stack.  */
7160         bc_load_localaddr (retval);
7161         bc_load_memory (type, TREE_OPERAND (exp, 0));
7162       }
7163       return;
7164       
7165     case SAVE_EXPR:
7166       
7167       if (!SAVE_EXPR_RTL (exp))
7168         {
7169           /* First time around: copy to local variable */
7170           SAVE_EXPR_RTL (exp) = bc_allocate_local (int_size_in_bytes (TREE_TYPE (exp)),
7171                                                    TYPE_ALIGN (TREE_TYPE(exp)));
7172           bc_expand_expr (TREE_OPERAND (exp, 0));
7173           bc_emit_instruction (duplicate);
7174           
7175           bc_load_localaddr (SAVE_EXPR_RTL (exp));
7176           bc_store_memory (TREE_TYPE (exp), TREE_OPERAND (exp, 0));
7177         }
7178       else
7179         {
7180           /* Consecutive reference: use saved copy */
7181           bc_load_localaddr (SAVE_EXPR_RTL (exp));
7182           bc_load_memory (TREE_TYPE (exp), TREE_OPERAND (exp, 0));
7183         }
7184       return;
7185       
7186 #if 0
7187       /* FIXME: the XXXX_STMT codes have been removed in GCC2, but
7188          how are they handled instead? */
7189     case LET_STMT:
7190       
7191       TREE_USED (exp) = 1;
7192       bc_expand_expr (STMT_BODY (exp));
7193       return;
7194 #endif
7195       
7196     case NOP_EXPR:
7197     case CONVERT_EXPR:
7198       
7199       bc_expand_expr (TREE_OPERAND (exp, 0));
7200       bc_expand_conversion (TREE_TYPE (TREE_OPERAND (exp, 0)), TREE_TYPE (exp));
7201       return;
7202       
7203     case MODIFY_EXPR:
7204       
7205       expand_assignment (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), 0, 0);
7206       return;
7207       
7208     case ADDR_EXPR:
7209       
7210       bc_expand_address (TREE_OPERAND (exp, 0));
7211       return;
7212       
7213     case INDIRECT_REF:
7214       
7215       bc_expand_expr (TREE_OPERAND (exp, 0));
7216       bc_load_memory (TREE_TYPE (exp), TREE_OPERAND (exp, 0));
7217       return;
7218       
7219     case ARRAY_REF:
7220       
7221       bc_expand_expr (bc_canonicalize_array_ref (exp));
7222       return;
7223       
7224     case COMPONENT_REF:
7225       
7226       bc_expand_component_address (exp);
7227       
7228       /* If we have a bitfield, generate a proper load */
7229       bc_load_memory (TREE_TYPE (TREE_OPERAND (exp, 1)), TREE_OPERAND (exp, 1));
7230       return;
7231       
7232     case COMPOUND_EXPR:
7233       
7234       bc_expand_expr (TREE_OPERAND (exp, 0));
7235       bc_emit_instruction (drop);
7236       bc_expand_expr (TREE_OPERAND (exp, 1));
7237       return;
7238       
7239     case COND_EXPR:
7240       
7241       bc_expand_expr (TREE_OPERAND (exp, 0));
7242       bc_expand_truth_conversion (TREE_TYPE (TREE_OPERAND (exp, 0)));
7243       lab = bc_get_bytecode_label ();
7244       bc_emit_bytecode (xjumpifnot);
7245       bc_emit_bytecode_labelref (lab);
7246       
7247 #ifdef DEBUG_PRINT_CODE
7248       fputc ('\n', stderr);
7249 #endif
7250       bc_expand_expr (TREE_OPERAND (exp, 1));
7251       lab1 = bc_get_bytecode_label ();
7252       bc_emit_bytecode (jump);
7253       bc_emit_bytecode_labelref (lab1);
7254       
7255 #ifdef DEBUG_PRINT_CODE
7256       fputc ('\n', stderr);
7257 #endif
7258       
7259       bc_emit_bytecode_labeldef (lab);
7260       bc_expand_expr (TREE_OPERAND (exp, 2));
7261       bc_emit_bytecode_labeldef (lab1);
7262       return;
7263       
7264     case TRUTH_ANDIF_EXPR:
7265       
7266       opcode = xjumpifnot;
7267       goto andorif;
7268       
7269     case TRUTH_ORIF_EXPR:
7270       
7271       opcode = xjumpif;
7272       goto andorif;
7273       
7274     case PLUS_EXPR:
7275       
7276       binoptab = optab_plus_expr;
7277       goto binop;
7278       
7279     case MINUS_EXPR:
7280       
7281       binoptab = optab_minus_expr;
7282       goto binop;
7283       
7284     case MULT_EXPR:
7285       
7286       binoptab = optab_mult_expr;
7287       goto binop;
7288       
7289     case TRUNC_DIV_EXPR:
7290     case FLOOR_DIV_EXPR:
7291     case CEIL_DIV_EXPR:
7292     case ROUND_DIV_EXPR:
7293     case EXACT_DIV_EXPR:
7294       
7295       binoptab = optab_trunc_div_expr;
7296       goto binop;
7297       
7298     case TRUNC_MOD_EXPR:
7299     case FLOOR_MOD_EXPR:
7300     case CEIL_MOD_EXPR:
7301     case ROUND_MOD_EXPR:
7302       
7303       binoptab = optab_trunc_mod_expr;
7304       goto binop;
7305       
7306     case FIX_ROUND_EXPR:
7307     case FIX_FLOOR_EXPR:
7308     case FIX_CEIL_EXPR:
7309       abort ();                 /* Not used for C.  */
7310       
7311     case FIX_TRUNC_EXPR:
7312     case FLOAT_EXPR:
7313     case MAX_EXPR:
7314     case MIN_EXPR:
7315     case FFS_EXPR:
7316     case LROTATE_EXPR:
7317     case RROTATE_EXPR:
7318       abort ();                 /* FIXME */
7319       
7320     case RDIV_EXPR:
7321       
7322       binoptab = optab_rdiv_expr;
7323       goto binop;
7324       
7325     case BIT_AND_EXPR:
7326       
7327       binoptab = optab_bit_and_expr;
7328       goto binop;
7329       
7330     case BIT_IOR_EXPR:
7331       
7332       binoptab = optab_bit_ior_expr;
7333       goto binop;
7334       
7335     case BIT_XOR_EXPR:
7336       
7337       binoptab = optab_bit_xor_expr;
7338       goto binop;
7339       
7340     case LSHIFT_EXPR:
7341       
7342       binoptab = optab_lshift_expr;
7343       goto binop;
7344       
7345     case RSHIFT_EXPR:
7346       
7347       binoptab = optab_rshift_expr;
7348       goto binop;
7349       
7350     case TRUTH_AND_EXPR:
7351       
7352       binoptab = optab_truth_and_expr;
7353       goto binop;
7354       
7355     case TRUTH_OR_EXPR:
7356       
7357       binoptab = optab_truth_or_expr;
7358       goto binop;
7359       
7360     case LT_EXPR:
7361       
7362       binoptab = optab_lt_expr;
7363       goto binop;
7364       
7365     case LE_EXPR:
7366       
7367       binoptab = optab_le_expr;
7368       goto binop;
7369       
7370     case GE_EXPR:
7371       
7372       binoptab = optab_ge_expr;
7373       goto binop;
7374       
7375     case GT_EXPR:
7376       
7377       binoptab = optab_gt_expr;
7378       goto binop;
7379       
7380     case EQ_EXPR:
7381       
7382       binoptab = optab_eq_expr;
7383       goto binop;
7384       
7385     case NE_EXPR:
7386       
7387       binoptab = optab_ne_expr;
7388       goto binop;
7389       
7390     case NEGATE_EXPR:
7391       
7392       unoptab = optab_negate_expr;
7393       goto unop;
7394       
7395     case BIT_NOT_EXPR:
7396       
7397       unoptab = optab_bit_not_expr;
7398       goto unop;
7399       
7400     case TRUTH_NOT_EXPR:
7401       
7402       unoptab = optab_truth_not_expr;
7403       goto unop;
7404       
7405     case PREDECREMENT_EXPR:
7406       
7407       incroptab = optab_predecrement_expr;
7408       goto increment;
7409       
7410     case PREINCREMENT_EXPR:
7411       
7412       incroptab = optab_preincrement_expr;
7413       goto increment;
7414       
7415     case POSTDECREMENT_EXPR:
7416       
7417       incroptab = optab_postdecrement_expr;
7418       goto increment;
7419       
7420     case POSTINCREMENT_EXPR:
7421       
7422       incroptab = optab_postincrement_expr;
7423       goto increment;
7424       
7425     case CONSTRUCTOR:
7426       
7427       bc_expand_constructor (exp);
7428       return;
7429       
7430     case ERROR_MARK:
7431     case RTL_EXPR:
7432       
7433       return;
7434       
7435     case BIND_EXPR:
7436       {
7437         tree vars = TREE_OPERAND (exp, 0);
7438         int vars_need_expansion = 0;
7439         
7440         /* Need to open a binding contour here because
7441            if there are any cleanups they most be contained here.  */
7442         expand_start_bindings (0);
7443         
7444         /* Mark the corresponding BLOCK for output.  */
7445         if (TREE_OPERAND (exp, 2) != 0)
7446           TREE_USED (TREE_OPERAND (exp, 2)) = 1;
7447         
7448         /* If VARS have not yet been expanded, expand them now.  */
7449         while (vars)
7450           {
7451             if (DECL_RTL (vars) == 0)
7452               {
7453                 vars_need_expansion = 1;
7454                 expand_decl (vars);
7455               }
7456             expand_decl_init (vars);
7457             vars = TREE_CHAIN (vars);
7458           }
7459         
7460         bc_expand_expr (TREE_OPERAND (exp, 1));
7461         
7462         expand_end_bindings (TREE_OPERAND (exp, 0), 0, 0);
7463         
7464         return;
7465       }
7466     }
7467   
7468   abort ();
7469   
7470  binop:
7471   
7472   bc_expand_binary_operation (binoptab, TREE_TYPE (exp),
7473                               TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1));
7474   return;
7475   
7476   
7477  unop:
7478   
7479   bc_expand_unary_operation (unoptab, TREE_TYPE (exp), TREE_OPERAND (exp, 0));
7480   return;
7481   
7482   
7483  andorif:
7484   
7485   bc_expand_expr (TREE_OPERAND (exp, 0));
7486   bc_expand_truth_conversion (TREE_TYPE (TREE_OPERAND (exp, 0)));
7487   lab = bc_get_bytecode_label ();
7488   
7489   bc_emit_instruction (duplicate);
7490   bc_emit_bytecode (opcode);
7491   bc_emit_bytecode_labelref (lab);
7492   
7493 #ifdef DEBUG_PRINT_CODE
7494   fputc ('\n', stderr);
7495 #endif
7496   
7497   bc_emit_instruction (drop);
7498   
7499   bc_expand_expr (TREE_OPERAND (exp, 1));
7500   bc_expand_truth_conversion (TREE_TYPE (TREE_OPERAND (exp, 1)));
7501   bc_emit_bytecode_labeldef (lab);
7502   return;
7503   
7504   
7505  increment:
7506   
7507   type = TREE_TYPE (TREE_OPERAND (exp, 0));
7508   
7509   /* Push the quantum.  */
7510   bc_expand_expr (TREE_OPERAND (exp, 1));
7511   
7512   /* Convert it to the lvalue's type.  */
7513   bc_expand_conversion (TREE_TYPE (TREE_OPERAND (exp, 1)), type);
7514   
7515   /* Push the address of the lvalue */
7516   bc_expand_expr (build1 (ADDR_EXPR, TYPE_POINTER_TO (type), TREE_OPERAND (exp, 0)));
7517   
7518   /* Perform actual increment */
7519   bc_expand_increment (incroptab, type);
7520   return;
7521 }
7522 \f
7523 /* Return the alignment in bits of EXP, a pointer valued expression.
7524    But don't return more than MAX_ALIGN no matter what.
7525    The alignment returned is, by default, the alignment of the thing that
7526    EXP points to (if it is not a POINTER_TYPE, 0 is returned).
7527
7528    Otherwise, look at the expression to see if we can do better, i.e., if the
7529    expression is actually pointing at an object whose alignment is tighter.  */
7530
7531 static int
7532 get_pointer_alignment (exp, max_align)
7533      tree exp;
7534      unsigned max_align;
7535 {
7536   unsigned align, inner;
7537
7538   if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
7539     return 0;
7540
7541   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
7542   align = MIN (align, max_align);
7543
7544   while (1)
7545     {
7546       switch (TREE_CODE (exp))
7547         {
7548         case NOP_EXPR:
7549         case CONVERT_EXPR:
7550         case NON_LVALUE_EXPR:
7551           exp = TREE_OPERAND (exp, 0);
7552           if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
7553             return align;
7554           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
7555           align = MIN (inner, max_align);
7556           break;
7557
7558         case PLUS_EXPR:
7559           /* If sum of pointer + int, restrict our maximum alignment to that
7560              imposed by the integer.  If not, we can't do any better than
7561              ALIGN.  */
7562           if (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST)
7563             return align;
7564
7565           while (((TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)) * BITS_PER_UNIT)
7566                   & (max_align - 1))
7567                  != 0)
7568             max_align >>= 1;
7569
7570           exp = TREE_OPERAND (exp, 0);
7571           break;
7572
7573         case ADDR_EXPR:
7574           /* See what we are pointing at and look at its alignment.  */
7575           exp = TREE_OPERAND (exp, 0);
7576           if (TREE_CODE (exp) == FUNCTION_DECL)
7577             align = FUNCTION_BOUNDARY;
7578           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
7579             align = DECL_ALIGN (exp);
7580 #ifdef CONSTANT_ALIGNMENT
7581           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
7582             align = CONSTANT_ALIGNMENT (exp, align);
7583 #endif
7584           return MIN (align, max_align);
7585
7586         default:
7587           return align;
7588         }
7589     }
7590 }
7591 \f
7592 /* Return the tree node and offset if a given argument corresponds to
7593    a string constant.  */
7594
7595 static tree
7596 string_constant (arg, ptr_offset)
7597      tree arg;
7598      tree *ptr_offset;
7599 {
7600   STRIP_NOPS (arg);
7601
7602   if (TREE_CODE (arg) == ADDR_EXPR
7603       && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST)
7604     {
7605       *ptr_offset = integer_zero_node;
7606       return TREE_OPERAND (arg, 0);
7607     }
7608   else if (TREE_CODE (arg) == PLUS_EXPR)
7609     {
7610       tree arg0 = TREE_OPERAND (arg, 0);
7611       tree arg1 = TREE_OPERAND (arg, 1);
7612
7613       STRIP_NOPS (arg0);
7614       STRIP_NOPS (arg1);
7615
7616       if (TREE_CODE (arg0) == ADDR_EXPR
7617           && TREE_CODE (TREE_OPERAND (arg0, 0)) == STRING_CST)
7618         {
7619           *ptr_offset = arg1;
7620           return TREE_OPERAND (arg0, 0);
7621         }
7622       else if (TREE_CODE (arg1) == ADDR_EXPR
7623                && TREE_CODE (TREE_OPERAND (arg1, 0)) == STRING_CST)
7624         {
7625           *ptr_offset = arg0;
7626           return TREE_OPERAND (arg1, 0);
7627         }
7628     }
7629
7630   return 0;
7631 }
7632
7633 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
7634    way, because it could contain a zero byte in the middle.
7635    TREE_STRING_LENGTH is the size of the character array, not the string.
7636
7637    Unfortunately, string_constant can't access the values of const char
7638    arrays with initializers, so neither can we do so here.  */
7639
7640 static tree
7641 c_strlen (src)
7642      tree src;
7643 {
7644   tree offset_node;
7645   int offset, max;
7646   char *ptr;
7647
7648   src = string_constant (src, &offset_node);
7649   if (src == 0)
7650     return 0;
7651   max = TREE_STRING_LENGTH (src);
7652   ptr = TREE_STRING_POINTER (src);
7653   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
7654     {
7655       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
7656          compute the offset to the following null if we don't know where to
7657          start searching for it.  */
7658       int i;
7659       for (i = 0; i < max; i++)
7660         if (ptr[i] == 0)
7661           return 0;
7662       /* We don't know the starting offset, but we do know that the string
7663          has no internal zero bytes.  We can assume that the offset falls
7664          within the bounds of the string; otherwise, the programmer deserves
7665          what he gets.  Subtract the offset from the length of the string,
7666          and return that.  */
7667       /* This would perhaps not be valid if we were dealing with named
7668          arrays in addition to literal string constants.  */
7669       return size_binop (MINUS_EXPR, size_int (max), offset_node);
7670     }
7671
7672   /* We have a known offset into the string.  Start searching there for
7673      a null character.  */
7674   if (offset_node == 0)
7675     offset = 0;
7676   else
7677     {
7678       /* Did we get a long long offset?  If so, punt.  */
7679       if (TREE_INT_CST_HIGH (offset_node) != 0)
7680         return 0;
7681       offset = TREE_INT_CST_LOW (offset_node);
7682     }
7683   /* If the offset is known to be out of bounds, warn, and call strlen at
7684      runtime.  */
7685   if (offset < 0 || offset > max)
7686     {
7687       warning ("offset outside bounds of constant string");
7688       return 0;
7689     }
7690   /* Use strlen to search for the first zero byte.  Since any strings
7691      constructed with build_string will have nulls appended, we win even
7692      if we get handed something like (char[4])"abcd".
7693
7694      Since OFFSET is our starting index into the string, no further
7695      calculation is needed.  */
7696   return size_int (strlen (ptr + offset));
7697 }
7698
7699 rtx
7700 expand_builtin_return_addr (fndecl_code, count, tem)
7701      enum built_in_function fndecl_code;
7702      rtx tem;
7703      int count;
7704 {
7705   int i;
7706
7707   /* Some machines need special handling before we can access
7708      arbitrary frames.  For example, on the sparc, we must first flush
7709      all register windows to the stack.  */
7710 #ifdef SETUP_FRAME_ADDRESSES
7711   SETUP_FRAME_ADDRESSES ();
7712 #endif
7713
7714   /* On the sparc, the return address is not in the frame, it is in a
7715      register.  There is no way to access it off of the current frame
7716      pointer, but it can be accessed off the previous frame pointer by
7717      reading the value from the register window save area.  */
7718 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
7719   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
7720     count--;
7721 #endif
7722
7723   /* Scan back COUNT frames to the specified frame.  */
7724   for (i = 0; i < count; i++)
7725     {
7726       /* Assume the dynamic chain pointer is in the word that the
7727          frame address points to, unless otherwise specified.  */
7728 #ifdef DYNAMIC_CHAIN_ADDRESS
7729       tem = DYNAMIC_CHAIN_ADDRESS (tem);
7730 #endif
7731       tem = memory_address (Pmode, tem);
7732       tem = copy_to_reg (gen_rtx (MEM, Pmode, tem));
7733     }
7734
7735   /* For __builtin_frame_address, return what we've got.  */
7736   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
7737     return tem;
7738
7739   /* For __builtin_return_address, Get the return address from that
7740      frame.  */
7741 #ifdef RETURN_ADDR_RTX
7742   tem = RETURN_ADDR_RTX (count, tem);
7743 #else
7744   tem = memory_address (Pmode,
7745                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
7746   tem = gen_rtx (MEM, Pmode, tem);
7747 #endif
7748   return tem;
7749 }
7750 \f
7751 /* Expand an expression EXP that calls a built-in function,
7752    with result going to TARGET if that's convenient
7753    (and in mode MODE if that's convenient).
7754    SUBTARGET may be used as the target for computing one of EXP's operands.
7755    IGNORE is nonzero if the value is to be ignored.  */
7756
7757 #define CALLED_AS_BUILT_IN(NODE) \
7758    (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
7759
7760 static rtx
7761 expand_builtin (exp, target, subtarget, mode, ignore)
7762      tree exp;
7763      rtx target;
7764      rtx subtarget;
7765      enum machine_mode mode;
7766      int ignore;
7767 {
7768   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7769   tree arglist = TREE_OPERAND (exp, 1);
7770   rtx op0;
7771   rtx lab1, insns;
7772   enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
7773   optab builtin_optab;
7774
7775   switch (DECL_FUNCTION_CODE (fndecl))
7776     {
7777     case BUILT_IN_ABS:
7778     case BUILT_IN_LABS:
7779     case BUILT_IN_FABS:
7780       /* build_function_call changes these into ABS_EXPR.  */
7781       abort ();
7782
7783     case BUILT_IN_SIN:
7784     case BUILT_IN_COS:
7785       /* Treat these like sqrt, but only if the user asks for them. */
7786       if (! flag_fast_math)
7787         break;
7788     case BUILT_IN_FSQRT:
7789       /* If not optimizing, call the library function.  */
7790       if (! optimize)
7791         break;
7792
7793       if (arglist == 0
7794           /* Arg could be wrong type if user redeclared this fcn wrong.  */
7795           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
7796         break;
7797
7798       /* Stabilize and compute the argument.  */
7799       if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
7800           && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
7801         {
7802           exp = copy_node (exp);
7803           arglist = copy_node (arglist);
7804           TREE_OPERAND (exp, 1) = arglist;
7805           TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
7806         }
7807       op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
7808
7809       /* Make a suitable register to place result in.  */
7810       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
7811
7812       emit_queue ();
7813       start_sequence ();
7814
7815       switch (DECL_FUNCTION_CODE (fndecl))
7816         {
7817         case BUILT_IN_SIN:
7818           builtin_optab = sin_optab; break;
7819         case BUILT_IN_COS:
7820           builtin_optab = cos_optab; break;
7821         case BUILT_IN_FSQRT:
7822           builtin_optab = sqrt_optab; break;
7823         default:
7824           abort ();
7825         }
7826
7827       /* Compute into TARGET.
7828          Set TARGET to wherever the result comes back.  */
7829       target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
7830                             builtin_optab, op0, target, 0);
7831
7832       /* If we were unable to expand via the builtin, stop the
7833          sequence (without outputting the insns) and break, causing
7834          a call the the library function.  */
7835       if (target == 0)
7836         {
7837           end_sequence ();
7838           break;
7839         }
7840
7841       /* Check the results by default.  But if flag_fast_math is turned on,
7842          then assume sqrt will always be called with valid arguments.  */
7843
7844       if (! flag_fast_math)
7845         {
7846           /* Don't define the builtin FP instructions
7847              if your machine is not IEEE.  */
7848           if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
7849             abort ();
7850
7851           lab1 = gen_label_rtx ();
7852
7853           /* Test the result; if it is NaN, set errno=EDOM because
7854              the argument was not in the domain.  */
7855           emit_cmp_insn (target, target, EQ, 0, GET_MODE (target), 0, 0);
7856           emit_jump_insn (gen_beq (lab1));
7857
7858 #ifdef TARGET_EDOM
7859           {
7860 #ifdef GEN_ERRNO_RTX
7861             rtx errno_rtx = GEN_ERRNO_RTX;
7862 #else
7863             rtx errno_rtx
7864               = gen_rtx (MEM, word_mode, gen_rtx (SYMBOL_REF, Pmode, "errno"));
7865 #endif
7866
7867             emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
7868           }
7869 #else
7870           /* We can't set errno=EDOM directly; let the library call do it.
7871              Pop the arguments right away in case the call gets deleted. */
7872           NO_DEFER_POP;
7873           expand_call (exp, target, 0);
7874           OK_DEFER_POP;
7875 #endif
7876
7877           emit_label (lab1);
7878         }
7879
7880       /* Output the entire sequence. */
7881       insns = get_insns ();
7882       end_sequence ();
7883       emit_insns (insns);
7884  
7885       return target;
7886
7887       /* __builtin_apply_args returns block of memory allocated on
7888          the stack into which is stored the arg pointer, structure
7889          value address, static chain, and all the registers that might
7890          possibly be used in performing a function call.  The code is
7891          moved to the start of the function so the incoming values are
7892          saved.  */
7893     case BUILT_IN_APPLY_ARGS:
7894       /* Don't do __builtin_apply_args more than once in a function.
7895          Save the result of the first call and reuse it.  */
7896       if (apply_args_value != 0)
7897         return apply_args_value;
7898       {
7899         /* When this function is called, it means that registers must be
7900            saved on entry to this function.  So we migrate the
7901            call to the first insn of this function.  */
7902         rtx temp;
7903         rtx seq;
7904
7905         start_sequence ();
7906         temp = expand_builtin_apply_args ();
7907         seq = get_insns ();
7908         end_sequence ();
7909
7910         apply_args_value = temp;
7911
7912         /* Put the sequence after the NOTE that starts the function.
7913            If this is inside a SEQUENCE, make the outer-level insn
7914            chain current, so the code is placed at the start of the
7915            function.  */
7916         push_topmost_sequence ();
7917         emit_insns_before (seq, NEXT_INSN (get_insns ()));
7918         pop_topmost_sequence ();
7919         return temp;
7920       }
7921
7922       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
7923          FUNCTION with a copy of the parameters described by
7924          ARGUMENTS, and ARGSIZE.  It returns a block of memory
7925          allocated on the stack into which is stored all the registers
7926          that might possibly be used for returning the result of a
7927          function.  ARGUMENTS is the value returned by
7928          __builtin_apply_args.  ARGSIZE is the number of bytes of
7929          arguments that must be copied.  ??? How should this value be
7930          computed?  We'll also need a safe worst case value for varargs
7931          functions.  */
7932     case BUILT_IN_APPLY:
7933       if (arglist == 0
7934           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
7935           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
7936           || TREE_CHAIN (arglist) == 0
7937           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
7938           || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
7939           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
7940         return const0_rtx;
7941       else
7942         {
7943           int i;
7944           tree t;
7945           rtx ops[3];
7946
7947           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
7948             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
7949
7950           return expand_builtin_apply (ops[0], ops[1], ops[2]);
7951         }
7952
7953       /* __builtin_return (RESULT) causes the function to return the
7954          value described by RESULT.  RESULT is address of the block of
7955          memory returned by __builtin_apply.  */
7956     case BUILT_IN_RETURN:
7957       if (arglist
7958           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
7959           && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
7960         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
7961                                             NULL_RTX, VOIDmode, 0));
7962       return const0_rtx;
7963
7964     case BUILT_IN_SAVEREGS:
7965       /* Don't do __builtin_saveregs more than once in a function.
7966          Save the result of the first call and reuse it.  */
7967       if (saveregs_value != 0)
7968         return saveregs_value;
7969       {
7970         /* When this function is called, it means that registers must be
7971            saved on entry to this function.  So we migrate the
7972            call to the first insn of this function.  */
7973         rtx temp;
7974         rtx seq;
7975
7976         /* Now really call the function.  `expand_call' does not call
7977            expand_builtin, so there is no danger of infinite recursion here.  */
7978         start_sequence ();
7979
7980 #ifdef EXPAND_BUILTIN_SAVEREGS
7981         /* Do whatever the machine needs done in this case.  */
7982         temp = EXPAND_BUILTIN_SAVEREGS (arglist);
7983 #else
7984         /* The register where the function returns its value
7985            is likely to have something else in it, such as an argument.
7986            So preserve that register around the call.  */
7987
7988         if (value_mode != VOIDmode)
7989           {
7990             rtx valreg = hard_libcall_value (value_mode);
7991             rtx saved_valreg = gen_reg_rtx (value_mode);
7992
7993             emit_move_insn (saved_valreg, valreg);
7994             temp = expand_call (exp, target, ignore);
7995             emit_move_insn (valreg, saved_valreg);
7996           }
7997         else
7998           /* Generate the call, putting the value in a pseudo.  */
7999           temp = expand_call (exp, target, ignore);
8000 #endif
8001
8002         seq = get_insns ();
8003         end_sequence ();
8004
8005         saveregs_value = temp;
8006
8007         /* Put the sequence after the NOTE that starts the function.
8008            If this is inside a SEQUENCE, make the outer-level insn
8009            chain current, so the code is placed at the start of the
8010            function.  */
8011         push_topmost_sequence ();
8012         emit_insns_before (seq, NEXT_INSN (get_insns ()));
8013         pop_topmost_sequence ();
8014         return temp;
8015       }
8016
8017       /* __builtin_args_info (N) returns word N of the arg space info
8018          for the current function.  The number and meanings of words
8019          is controlled by the definition of CUMULATIVE_ARGS.  */
8020     case BUILT_IN_ARGS_INFO:
8021       {
8022         int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
8023         int i;
8024         int *word_ptr = (int *) &current_function_args_info;
8025         tree type, elts, result;
8026
8027         if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
8028           fatal ("CUMULATIVE_ARGS type defined badly; see %s, line %d",
8029                  __FILE__, __LINE__);
8030
8031         if (arglist != 0)
8032           {
8033             tree arg = TREE_VALUE (arglist);
8034             if (TREE_CODE (arg) != INTEGER_CST)
8035               error ("argument of `__builtin_args_info' must be constant");
8036             else
8037               {
8038                 int wordnum = TREE_INT_CST_LOW (arg);
8039
8040                 if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
8041                   error ("argument of `__builtin_args_info' out of range");
8042                 else
8043                   return GEN_INT (word_ptr[wordnum]);
8044               }
8045           }
8046         else
8047           error ("missing argument in `__builtin_args_info'");
8048
8049         return const0_rtx;
8050
8051 #if 0
8052         for (i = 0; i < nwords; i++)
8053           elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
8054
8055         type = build_array_type (integer_type_node,
8056                                  build_index_type (build_int_2 (nwords, 0)));
8057         result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
8058         TREE_CONSTANT (result) = 1;
8059         TREE_STATIC (result) = 1;
8060         result = build (INDIRECT_REF, build_pointer_type (type), result);
8061         TREE_CONSTANT (result) = 1;
8062         return expand_expr (result, NULL_RTX, VOIDmode, 0);
8063 #endif
8064       }
8065
8066       /* Return the address of the first anonymous stack arg.  */
8067     case BUILT_IN_NEXT_ARG:
8068       {
8069         tree fntype = TREE_TYPE (current_function_decl);
8070
8071         if ((TYPE_ARG_TYPES (fntype) == 0
8072              || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8073                  == void_type_node))
8074             && ! current_function_varargs)
8075           {
8076             error ("`va_start' used in function with fixed args");
8077             return const0_rtx;
8078           }
8079
8080         if (arglist)
8081           {
8082             tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8083             tree arg = TREE_VALUE (arglist);
8084
8085             /* Strip off all nops for the sake of the comparison.  This
8086                is not quite the same as STRIP_NOPS.  It does more.  
8087                We must also strip off INDIRECT_EXPR for C++ reference
8088                parameters.  */
8089             while (TREE_CODE (arg) == NOP_EXPR
8090                    || TREE_CODE (arg) == CONVERT_EXPR
8091                    || TREE_CODE (arg) == NON_LVALUE_EXPR
8092                    || TREE_CODE (arg) == INDIRECT_REF)
8093               arg = TREE_OPERAND (arg, 0);
8094             if (arg != last_parm)
8095               warning ("second parameter of `va_start' not last named argument");
8096           }
8097         else if (! current_function_varargs)
8098           /* Evidently an out of date version of <stdarg.h>; can't validate
8099              va_start's second argument, but can still work as intended.  */
8100           warning ("`__builtin_next_arg' called without an argument");
8101       }
8102
8103       return expand_binop (Pmode, add_optab,
8104                            current_function_internal_arg_pointer,
8105                            current_function_arg_offset_rtx,
8106                            NULL_RTX, 0, OPTAB_LIB_WIDEN);
8107
8108     case BUILT_IN_CLASSIFY_TYPE:
8109       if (arglist != 0)
8110         {
8111           tree type = TREE_TYPE (TREE_VALUE (arglist));
8112           enum tree_code code = TREE_CODE (type);
8113           if (code == VOID_TYPE)
8114             return GEN_INT (void_type_class);
8115           if (code == INTEGER_TYPE)
8116             return GEN_INT (integer_type_class);
8117           if (code == CHAR_TYPE)
8118             return GEN_INT (char_type_class);
8119           if (code == ENUMERAL_TYPE)
8120             return GEN_INT (enumeral_type_class);
8121           if (code == BOOLEAN_TYPE)
8122             return GEN_INT (boolean_type_class);
8123           if (code == POINTER_TYPE)
8124             return GEN_INT (pointer_type_class);
8125           if (code == REFERENCE_TYPE)
8126             return GEN_INT (reference_type_class);
8127           if (code == OFFSET_TYPE)
8128             return GEN_INT (offset_type_class);
8129           if (code == REAL_TYPE)
8130             return GEN_INT (real_type_class);
8131           if (code == COMPLEX_TYPE)
8132             return GEN_INT (complex_type_class);
8133           if (code == FUNCTION_TYPE)
8134             return GEN_INT (function_type_class);
8135           if (code == METHOD_TYPE)
8136             return GEN_INT (method_type_class);
8137           if (code == RECORD_TYPE)
8138             return GEN_INT (record_type_class);
8139           if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
8140             return GEN_INT (union_type_class);
8141           if (code == ARRAY_TYPE)
8142             {
8143               if (TYPE_STRING_FLAG (type))
8144                 return GEN_INT (string_type_class);
8145               else
8146                 return GEN_INT (array_type_class);
8147             }
8148           if (code == SET_TYPE)
8149             return GEN_INT (set_type_class);
8150           if (code == FILE_TYPE)
8151             return GEN_INT (file_type_class);
8152           if (code == LANG_TYPE)
8153             return GEN_INT (lang_type_class);
8154         }
8155       return GEN_INT (no_type_class);
8156
8157     case BUILT_IN_CONSTANT_P:
8158       if (arglist == 0)
8159         return const0_rtx;
8160       else
8161         {
8162           tree arg = TREE_VALUE (arglist);
8163
8164           STRIP_NOPS (arg);
8165           return (TREE_CODE_CLASS (TREE_CODE (arg)) == 'c'
8166                   || (TREE_CODE (arg) == ADDR_EXPR
8167                       && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST)
8168                   ? const1_rtx : const0_rtx);
8169         }
8170
8171     case BUILT_IN_FRAME_ADDRESS:
8172       /* The argument must be a nonnegative integer constant.
8173          It counts the number of frames to scan up the stack.
8174          The value is the address of that frame.  */
8175     case BUILT_IN_RETURN_ADDRESS:
8176       /* The argument must be a nonnegative integer constant.
8177          It counts the number of frames to scan up the stack.
8178          The value is the return address saved in that frame.  */
8179       if (arglist == 0)
8180         /* Warning about missing arg was already issued.  */
8181         return const0_rtx;
8182       else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST)
8183         {
8184           error ("invalid arg to `__builtin_return_address'");
8185           return const0_rtx;
8186         }
8187       else if (tree_int_cst_sgn (TREE_VALUE (arglist)) < 0)
8188         {
8189           error ("invalid arg to `__builtin_return_address'");
8190           return const0_rtx;
8191         }
8192       else
8193         {
8194           rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
8195                                                 TREE_INT_CST_LOW (TREE_VALUE (arglist)),
8196                                                 hard_frame_pointer_rtx);
8197
8198           /* For __builtin_frame_address, return what we've got.  */
8199           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
8200             return tem;
8201
8202           if (GET_CODE (tem) != REG)
8203             tem = copy_to_reg (tem);
8204           return tem;
8205         }
8206
8207     case BUILT_IN_ALLOCA:
8208       if (arglist == 0
8209           /* Arg could be non-integer if user redeclared this fcn wrong.  */
8210           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
8211         break;
8212
8213       /* Compute the argument.  */
8214       op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
8215
8216       /* Allocate the desired space.  */
8217       return allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
8218
8219     case BUILT_IN_FFS:
8220       /* If not optimizing, call the library function.  */
8221       if (!optimize && ! CALLED_AS_BUILT_IN (fndecl))
8222         break;
8223
8224       if (arglist == 0
8225           /* Arg could be non-integer if user redeclared this fcn wrong.  */
8226           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
8227         break;
8228
8229       /* Compute the argument.  */
8230       op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
8231       /* Compute ffs, into TARGET if possible.
8232          Set TARGET to wherever the result comes back.  */
8233       target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
8234                             ffs_optab, op0, target, 1);
8235       if (target == 0)
8236         abort ();
8237       return target;
8238
8239     case BUILT_IN_STRLEN:
8240       /* If not optimizing, call the library function.  */
8241       if (!optimize && ! CALLED_AS_BUILT_IN (fndecl))
8242         break;
8243
8244       if (arglist == 0
8245           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
8246           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
8247         break;
8248       else
8249         {
8250           tree src = TREE_VALUE (arglist);
8251           tree len = c_strlen (src);
8252
8253           int align
8254             = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
8255
8256           rtx result, src_rtx, char_rtx;
8257           enum machine_mode insn_mode = value_mode, char_mode;
8258           enum insn_code icode;
8259
8260           /* If the length is known, just return it. */
8261           if (len != 0)
8262             return expand_expr (len, target, mode, 0);
8263
8264           /* If SRC is not a pointer type, don't do this operation inline. */
8265           if (align == 0)
8266             break;
8267
8268           /* Call a function if we can't compute strlen in the right mode. */
8269
8270           while (insn_mode != VOIDmode)
8271             {
8272               icode = strlen_optab->handlers[(int) insn_mode].insn_code;
8273               if (icode != CODE_FOR_nothing)
8274                 break;
8275
8276               insn_mode = GET_MODE_WIDER_MODE (insn_mode);
8277             }
8278           if (insn_mode == VOIDmode)
8279             break;
8280
8281           /* Make a place to write the result of the instruction.  */
8282           result = target;
8283           if (! (result != 0
8284                  && GET_CODE (result) == REG
8285                  && GET_MODE (result) == insn_mode
8286                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
8287             result = gen_reg_rtx (insn_mode);
8288
8289           /* Make sure the operands are acceptable to the predicates.  */
8290
8291           if (! (*insn_operand_predicate[(int)icode][0]) (result, insn_mode))
8292             result = gen_reg_rtx (insn_mode);
8293
8294           src_rtx = memory_address (BLKmode,
8295                                     expand_expr (src, NULL_RTX, ptr_mode,
8296                                                  EXPAND_NORMAL));
8297           if (! (*insn_operand_predicate[(int)icode][1]) (src_rtx, Pmode))
8298             src_rtx = copy_to_mode_reg (Pmode, src_rtx);
8299
8300           char_rtx = const0_rtx;
8301           char_mode = insn_operand_mode[(int)icode][2];
8302           if (! (*insn_operand_predicate[(int)icode][2]) (char_rtx, char_mode))
8303             char_rtx = copy_to_mode_reg (char_mode, char_rtx);
8304
8305           emit_insn (GEN_FCN (icode) (result,
8306                                       gen_rtx (MEM, BLKmode, src_rtx),
8307                                       char_rtx, GEN_INT (align)));
8308
8309           /* Return the value in the proper mode for this function.  */
8310           if (GET_MODE (result) == value_mode)
8311             return result;
8312           else if (target != 0)
8313             {
8314               convert_move (target, result, 0);
8315               return target;
8316             }
8317           else
8318             return convert_to_mode (value_mode, result, 0);
8319         }
8320
8321     case BUILT_IN_STRCPY:
8322       /* If not optimizing, call the library function.  */
8323       if (!optimize && ! CALLED_AS_BUILT_IN (fndecl))
8324         break;
8325
8326       if (arglist == 0
8327           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
8328           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
8329           || TREE_CHAIN (arglist) == 0
8330           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
8331         break;
8332       else
8333         {
8334           tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
8335
8336           if (len == 0)
8337             break;
8338
8339           len = size_binop (PLUS_EXPR, len, integer_one_node);
8340
8341           chainon (arglist, build_tree_list (NULL_TREE, len));
8342         }
8343
8344       /* Drops in.  */
8345     case BUILT_IN_MEMCPY:
8346       /* If not optimizing, call the library function.  */
8347       if (!optimize && ! CALLED_AS_BUILT_IN (fndecl))
8348         break;
8349
8350       if (arglist == 0
8351           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
8352           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
8353           || TREE_CHAIN (arglist) == 0
8354           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
8355           || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
8356           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
8357         break;
8358       else
8359         {
8360           tree dest = TREE_VALUE (arglist);
8361           tree src = TREE_VALUE (TREE_CHAIN (arglist));
8362           tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8363           tree type;
8364
8365           int src_align
8366             = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
8367           int dest_align
8368             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
8369           rtx dest_rtx, dest_mem, src_mem;
8370
8371           /* If either SRC or DEST is not a pointer type, don't do
8372              this operation in-line.  */
8373           if (src_align == 0 || dest_align == 0)
8374             {
8375               if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRCPY)
8376                 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
8377               break;
8378             }
8379
8380           dest_rtx = expand_expr (dest, NULL_RTX, ptr_mode, EXPAND_SUM);
8381           dest_mem = gen_rtx (MEM, BLKmode,
8382                               memory_address (BLKmode, dest_rtx));
8383           /* There could be a void* cast on top of the object.  */
8384           while (TREE_CODE (dest) == NOP_EXPR)
8385             dest = TREE_OPERAND (dest, 0);
8386           type = TREE_TYPE (TREE_TYPE (dest));
8387           MEM_IN_STRUCT_P (dest_mem) = AGGREGATE_TYPE_P (type);
8388           src_mem = gen_rtx (MEM, BLKmode,
8389                              memory_address (BLKmode,
8390                                              expand_expr (src, NULL_RTX,
8391                                                           ptr_mode,
8392                                                           EXPAND_SUM)));
8393           /* There could be a void* cast on top of the object.  */
8394           while (TREE_CODE (src) == NOP_EXPR)
8395             src = TREE_OPERAND (src, 0);
8396           type = TREE_TYPE (TREE_TYPE (src));
8397           MEM_IN_STRUCT_P (src_mem) = AGGREGATE_TYPE_P (type);
8398
8399           /* Copy word part most expediently.  */
8400           emit_block_move (dest_mem, src_mem,
8401                            expand_expr (len, NULL_RTX, VOIDmode, 0),
8402                            MIN (src_align, dest_align));
8403           return force_operand (dest_rtx, NULL_RTX);
8404         }
8405
8406 /* These comparison functions need an instruction that returns an actual
8407    index.  An ordinary compare that just sets the condition codes
8408    is not enough.  */
8409 #ifdef HAVE_cmpstrsi
8410     case BUILT_IN_STRCMP:
8411       /* If not optimizing, call the library function.  */
8412       if (!optimize && ! CALLED_AS_BUILT_IN (fndecl))
8413         break;
8414
8415       if (arglist == 0
8416           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
8417           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
8418           || TREE_CHAIN (arglist) == 0
8419           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
8420         break;
8421       else if (!HAVE_cmpstrsi)
8422         break;
8423       {
8424         tree arg1 = TREE_VALUE (arglist);
8425         tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8426         tree offset;
8427         tree len, len2;
8428
8429         len = c_strlen (arg1);
8430         if (len)
8431           len = size_binop (PLUS_EXPR, integer_one_node, len);
8432         len2 = c_strlen (arg2);
8433         if (len2)
8434           len2 = size_binop (PLUS_EXPR, integer_one_node, len2);
8435
8436         /* If we don't have a constant length for the first, use the length
8437            of the second, if we know it.  We don't require a constant for
8438            this case; some cost analysis could be done if both are available
8439            but neither is constant.  For now, assume they're equally cheap.
8440
8441            If both strings have constant lengths, use the smaller.  This
8442            could arise if optimization results in strcpy being called with
8443            two fixed strings, or if the code was machine-generated.  We should
8444            add some code to the `memcmp' handler below to deal with such
8445            situations, someday.  */
8446         if (!len || TREE_CODE (len) != INTEGER_CST)
8447           {
8448             if (len2)
8449               len = len2;
8450             else if (len == 0)
8451               break;
8452           }
8453         else if (len2 && TREE_CODE (len2) == INTEGER_CST)
8454           {
8455             if (tree_int_cst_lt (len2, len))
8456               len = len2;
8457           }
8458
8459         chainon (arglist, build_tree_list (NULL_TREE, len));
8460       }
8461
8462       /* Drops in.  */
8463     case BUILT_IN_MEMCMP:
8464       /* If not optimizing, call the library function.  */
8465       if (!optimize && ! CALLED_AS_BUILT_IN (fndecl))
8466         break;
8467
8468       if (arglist == 0
8469           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
8470           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
8471           || TREE_CHAIN (arglist) == 0
8472           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
8473           || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
8474           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
8475         break;
8476       else if (!HAVE_cmpstrsi)
8477         break;
8478       {
8479         tree arg1 = TREE_VALUE (arglist);
8480         tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8481         tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8482         rtx result;
8483
8484         int arg1_align
8485           = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
8486         int arg2_align
8487           = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
8488         enum machine_mode insn_mode
8489           = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
8490
8491         /* If we don't have POINTER_TYPE, call the function.  */
8492         if (arg1_align == 0 || arg2_align == 0)
8493           {
8494             if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRCMP)
8495               TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
8496             break;
8497           }
8498
8499         /* Make a place to write the result of the instruction.  */
8500         result = target;
8501         if (! (result != 0
8502                && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
8503                && REGNO (result) >= FIRST_PSEUDO_REGISTER))
8504           result = gen_reg_rtx (insn_mode);
8505
8506         emit_insn (gen_cmpstrsi (result,
8507                                  gen_rtx (MEM, BLKmode,
8508                                           expand_expr (arg1, NULL_RTX,
8509                                                        ptr_mode,
8510                                                        EXPAND_NORMAL)),
8511                                  gen_rtx (MEM, BLKmode,
8512                                           expand_expr (arg2, NULL_RTX,
8513                                                        ptr_mode,
8514                                                        EXPAND_NORMAL)),
8515                                  expand_expr (len, NULL_RTX, VOIDmode, 0),
8516                                  GEN_INT (MIN (arg1_align, arg2_align))));
8517
8518         /* Return the value in the proper mode for this function.  */
8519         mode = TYPE_MODE (TREE_TYPE (exp));
8520         if (GET_MODE (result) == mode)
8521           return result;
8522         else if (target != 0)
8523           {
8524             convert_move (target, result, 0);
8525             return target;
8526           }
8527         else
8528           return convert_to_mode (mode, result, 0);
8529       } 
8530 #else
8531     case BUILT_IN_STRCMP:
8532     case BUILT_IN_MEMCMP:
8533       break;
8534 #endif
8535
8536       /* __builtin_setjmp is passed a pointer to an array of five words
8537          (not all will be used on all machines).  It operates similarly to
8538          the C library function of the same name, but is more efficient.
8539          Much of the code below (and for longjmp) is copied from the handling
8540          of non-local gotos.
8541
8542          NOTE: This is intended for use by GNAT and will only work in
8543          the method used by it.  This code will likely NOT survive to 
8544          the GCC 2.8.0 release.  */
8545     case BUILT_IN_SETJMP:
8546       if (arglist == 0
8547           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
8548         break;
8549
8550       {
8551         rtx buf_addr
8552           = force_reg (Pmode,
8553                        convert_modes (Pmode, ptr_mode,
8554                                       expand_expr (TREE_VALUE (arglist),
8555                                                    subtarget,
8556                                                    VOIDmode, 0),
8557                                       1));
8558         rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
8559         enum machine_mode sa_mode = Pmode;
8560         rtx stack_save;
8561         int old_inhibit_defer_pop = inhibit_defer_pop;
8562         int return_pops = RETURN_POPS_ARGS (get_identifier ("__dummy"),
8563                                             get_identifier ("__dummy"), 0);
8564         rtx next_arg_reg;
8565         CUMULATIVE_ARGS args_so_far;
8566         int i;
8567
8568         if (target == 0 || GET_CODE (target) != REG
8569             || REGNO (target) < FIRST_PSEUDO_REGISTER)
8570           target = gen_reg_rtx (value_mode);
8571
8572         emit_queue ();
8573
8574         CONST_CALL_P (emit_note (NULL_PTR, NOTE_INSN_SETJMP)) = 1;
8575         current_function_calls_setjmp = 1;
8576
8577         /* We store the frame pointer and the address of lab1 in the buffer
8578            and use the rest of it for the stack save area, which is
8579            machine-dependent.  */
8580         emit_move_insn (gen_rtx (MEM, Pmode, buf_addr),
8581                         virtual_stack_vars_rtx);
8582         emit_move_insn
8583           (validize_mem (gen_rtx (MEM, Pmode,
8584                                   plus_constant (buf_addr,
8585                                                  GET_MODE_SIZE (Pmode)))),
8586            gen_rtx (LABEL_REF, Pmode, lab1));
8587
8588 #ifdef HAVE_save_stack_nonlocal
8589         if (HAVE_save_stack_nonlocal)
8590           sa_mode = insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0];
8591 #endif
8592
8593         stack_save = gen_rtx (MEM, sa_mode,
8594                               plus_constant (buf_addr,
8595                                              2 * GET_MODE_SIZE (Pmode)));
8596         emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
8597
8598 #ifdef HAVE_setjmp
8599         if (HAVE_setjmp)
8600           emit_insn (gen_setjmp ());
8601 #endif
8602
8603         /* Set TARGET to zero and branch around the other case.  */
8604         emit_move_insn (target, const0_rtx);
8605         emit_jump_insn (gen_jump (lab2));
8606         emit_barrier ();
8607         emit_label (lab1);
8608
8609         /* Note that setjmp clobbers FP when we get here, so we have to
8610            make sure it's marked as used by this function.   */
8611         emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx));
8612
8613         /* Mark the static chain as clobbered here so life information
8614            doesn't get messed up for it.  */
8615         emit_insn (gen_rtx (CLOBBER, VOIDmode, static_chain_rtx));
8616
8617         /* Now put in the code to restore the frame pointer, and argument
8618            pointer, if needed.  The code below is from expand_end_bindings
8619            in stmt.c; see detailed documentation there.  */
8620 #ifdef HAVE_nonlocal_goto
8621         if (! HAVE_nonlocal_goto)
8622 #endif
8623           emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
8624
8625         current_function_has_nonlocal_goto = 1;
8626
8627 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
8628         if (fixed_regs[ARG_POINTER_REGNUM])
8629           {
8630 #ifdef ELIMINABLE_REGS
8631             static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
8632
8633             for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
8634               if (elim_regs[i].from == ARG_POINTER_REGNUM
8635                   && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
8636                 break;
8637
8638             if (i == sizeof elim_regs / sizeof elim_regs [0])
8639 #endif
8640               {
8641                 /* Now restore our arg pointer from the address at which it
8642                    was saved in our stack frame.
8643                    If there hasn't be space allocated for it yet, make
8644                    some now.  */
8645                 if (arg_pointer_save_area == 0)
8646                   arg_pointer_save_area
8647                     = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
8648                 emit_move_insn (virtual_incoming_args_rtx,
8649                                 copy_to_reg (arg_pointer_save_area));
8650               }
8651           }
8652 #endif
8653
8654         /* The static chain pointer contains the address of dummy function.
8655            We need to call it here to handle some PIC cases of restoring
8656            a global pointer.  Then return 1.  */
8657         op0 = copy_to_mode_reg (Pmode, static_chain_rtx);
8658
8659         /* We can't actually call emit_library_call here, so do everything
8660            it does, which isn't much for a libfunc with no args.  */
8661         op0 = memory_address (FUNCTION_MODE, op0);
8662
8663         INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE,
8664                               gen_rtx (SYMBOL_REF, Pmode, "__dummy"), 1);
8665         next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
8666
8667 #ifndef ACCUMULATE_OUTGOING_ARGS
8668 #ifdef HAVE_call_pop
8669         if (HAVE_call_pop)
8670           emit_call_insn (gen_call_pop (gen_rtx (MEM, FUNCTION_MODE, op0),
8671                                         const0_rtx, next_arg_reg,
8672                                         GEN_INT (return_pops)));
8673         else
8674 #endif
8675 #endif
8676
8677 #ifdef HAVE_call
8678         if (HAVE_call)
8679           emit_call_insn (gen_call (gen_rtx (MEM, FUNCTION_MODE, op0),
8680                                     const0_rtx, next_arg_reg, const0_rtx));
8681         else
8682 #endif
8683             abort ();
8684
8685         emit_move_insn (target, const1_rtx);
8686         emit_label (lab2);
8687         return target;
8688       }
8689
8690       /* __builtin_longjmp is passed a pointer to an array of five words
8691          and a value, which is a dummy.  It's similar to the C library longjmp
8692          function but works with __builtin_setjmp above.  */
8693     case BUILT_IN_LONGJMP:
8694       if (arglist == 0 || TREE_CHAIN (arglist) == 0
8695           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
8696         break;
8697
8698       {
8699         tree dummy_id = get_identifier ("__dummy");
8700         tree dummy_type = build_function_type (void_type_node, NULL_TREE);
8701         tree dummy_decl = build_decl (FUNCTION_DECL, dummy_id, dummy_type); 
8702         rtx buf_addr
8703           = force_reg (Pmode,
8704                        convert_modes (Pmode, ptr_mode,
8705                                       expand_expr (TREE_VALUE (arglist),
8706                                                    NULL_RTX,
8707                                                    VOIDmode, 0),
8708                                       1));
8709         rtx fp = gen_rtx (MEM, Pmode, buf_addr);
8710         rtx lab = gen_rtx (MEM, Pmode,
8711                            plus_constant (buf_addr, GET_MODE_SIZE (Pmode)));
8712         enum machine_mode sa_mode
8713 #ifdef HAVE_save_stack_nonlocal
8714           = (HAVE_save_stack_nonlocal
8715              ? insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0]
8716              : Pmode);
8717 #else
8718         = Pmode;
8719 #endif
8720         rtx stack = gen_rtx (MEM, sa_mode,
8721                              plus_constant (buf_addr,
8722                                             2 * GET_MODE_SIZE (Pmode)));
8723
8724         DECL_EXTERNAL (dummy_decl) = 1;
8725         TREE_PUBLIC (dummy_decl) = 1;
8726         make_decl_rtl (dummy_decl, NULL_PTR, 1);
8727
8728         /* Expand the second expression just for side-effects.  */
8729         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
8730                      const0_rtx, VOIDmode, 0);
8731
8732         assemble_external (dummy_decl);
8733
8734         /* Pick up FP, label, and SP from the block and jump.  This code is
8735            from expand_goto in stmt.c; see there for detailed comments.  */
8736 #if HAVE_nonlocal_goto
8737         if (HAVE_nonlocal_goto)
8738           emit_insn (gen_nonlocal_goto (fp, lab, stack,
8739                                         XEXP (DECL_RTL (dummy_decl), 0)));
8740       else
8741 #endif
8742         {
8743           lab = copy_to_reg (lab);
8744           emit_move_insn (hard_frame_pointer_rtx, fp);
8745           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
8746
8747           /* Put in the static chain register the address of the dummy
8748              function.  */
8749           emit_move_insn (static_chain_rtx, XEXP (DECL_RTL (dummy_decl), 0));
8750           emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx));
8751           emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
8752           emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
8753           emit_indirect_jump (lab);
8754         }
8755
8756         return const0_rtx;
8757       }
8758
8759     default:                    /* just do library call, if unknown builtin */
8760       error ("built-in function `%s' not currently supported",
8761              IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8762     }
8763
8764   /* The switch statement above can drop through to cause the function
8765      to be called normally.  */
8766
8767   return expand_call (exp, target, ignore);
8768 }
8769 \f
8770 /* Built-in functions to perform an untyped call and return.  */
8771
8772 /* For each register that may be used for calling a function, this
8773    gives a mode used to copy the register's value.  VOIDmode indicates
8774    the register is not used for calling a function.  If the machine
8775    has register windows, this gives only the outbound registers.
8776    INCOMING_REGNO gives the corresponding inbound register.  */
8777 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
8778
8779 /* For each register that may be used for returning values, this gives
8780    a mode used to copy the register's value.  VOIDmode indicates the
8781    register is not used for returning values.  If the machine has
8782    register windows, this gives only the outbound registers.
8783    INCOMING_REGNO gives the corresponding inbound register.  */
8784 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
8785
8786 /* For each register that may be used for calling a function, this
8787    gives the offset of that register into the block returned by
8788    __builtin_apply_args.  0 indicates that the register is not
8789    used for calling a function. */
8790 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
8791
8792 /* Return the offset of register REGNO into the block returned by 
8793    __builtin_apply_args.  This is not declared static, since it is
8794    needed in objc-act.c. */
8795
8796 int 
8797 apply_args_register_offset (regno)
8798      int regno;
8799 {
8800   apply_args_size ();
8801
8802   /* Arguments are always put in outgoing registers (in the argument
8803      block) if such make sense. */
8804 #ifdef OUTGOING_REGNO
8805   regno = OUTGOING_REGNO(regno);
8806 #endif
8807   return apply_args_reg_offset[regno];
8808 }
8809
8810 /* Return the size required for the block returned by __builtin_apply_args,
8811    and initialize apply_args_mode.  */
8812
8813 static int
8814 apply_args_size ()
8815 {
8816   static int size = -1;
8817   int align, regno;
8818   enum machine_mode mode;
8819
8820   /* The values computed by this function never change.  */
8821   if (size < 0)
8822     {
8823       /* The first value is the incoming arg-pointer.  */
8824       size = GET_MODE_SIZE (Pmode);
8825
8826       /* The second value is the structure value address unless this is
8827          passed as an "invisible" first argument.  */
8828       if (struct_value_rtx)
8829         size += GET_MODE_SIZE (Pmode);
8830
8831       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
8832         if (FUNCTION_ARG_REGNO_P (regno))
8833           {
8834             /* Search for the proper mode for copying this register's
8835                value.  I'm not sure this is right, but it works so far.  */
8836             enum machine_mode best_mode = VOIDmode;
8837
8838             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
8839                  mode != VOIDmode;
8840                  mode = GET_MODE_WIDER_MODE (mode))
8841               if (HARD_REGNO_MODE_OK (regno, mode)
8842                   && HARD_REGNO_NREGS (regno, mode) == 1)
8843                 best_mode = mode;
8844
8845             if (best_mode == VOIDmode)
8846               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
8847                    mode != VOIDmode;
8848                    mode = GET_MODE_WIDER_MODE (mode))
8849                 if (HARD_REGNO_MODE_OK (regno, mode)
8850                     && (mov_optab->handlers[(int) mode].insn_code
8851                         != CODE_FOR_nothing))
8852                   best_mode = mode;
8853
8854             mode = best_mode;
8855             if (mode == VOIDmode)
8856               abort ();
8857
8858             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
8859             if (size % align != 0)
8860               size = CEIL (size, align) * align;
8861             apply_args_reg_offset[regno] = size;
8862             size += GET_MODE_SIZE (mode);
8863             apply_args_mode[regno] = mode;
8864           }
8865         else
8866           {
8867             apply_args_mode[regno] = VOIDmode;
8868             apply_args_reg_offset[regno] = 0;
8869           }
8870     }
8871   return size;
8872 }
8873
8874 /* Return the size required for the block returned by __builtin_apply,
8875    and initialize apply_result_mode.  */
8876
8877 static int
8878 apply_result_size ()
8879 {
8880   static int size = -1;
8881   int align, regno;
8882   enum machine_mode mode;
8883
8884   /* The values computed by this function never change.  */
8885   if (size < 0)
8886     {
8887       size = 0;
8888
8889       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
8890         if (FUNCTION_VALUE_REGNO_P (regno))
8891           {
8892             /* Search for the proper mode for copying this register's
8893                value.  I'm not sure this is right, but it works so far.  */
8894             enum machine_mode best_mode = VOIDmode;
8895
8896             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
8897                  mode != TImode;
8898                  mode = GET_MODE_WIDER_MODE (mode))
8899               if (HARD_REGNO_MODE_OK (regno, mode))
8900                 best_mode = mode;
8901
8902             if (best_mode == VOIDmode)
8903               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
8904                    mode != VOIDmode;
8905                    mode = GET_MODE_WIDER_MODE (mode))
8906                 if (HARD_REGNO_MODE_OK (regno, mode)
8907                     && (mov_optab->handlers[(int) mode].insn_code
8908                         != CODE_FOR_nothing))
8909                   best_mode = mode;
8910
8911             mode = best_mode;
8912             if (mode == VOIDmode)
8913               abort ();
8914
8915             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
8916             if (size % align != 0)
8917               size = CEIL (size, align) * align;
8918             size += GET_MODE_SIZE (mode);
8919             apply_result_mode[regno] = mode;
8920           }
8921         else
8922           apply_result_mode[regno] = VOIDmode;
8923
8924       /* Allow targets that use untyped_call and untyped_return to override
8925          the size so that machine-specific information can be stored here.  */
8926 #ifdef APPLY_RESULT_SIZE
8927       size = APPLY_RESULT_SIZE;
8928 #endif
8929     }
8930   return size;
8931 }
8932
8933 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
8934 /* Create a vector describing the result block RESULT.  If SAVEP is true,
8935    the result block is used to save the values; otherwise it is used to
8936    restore the values.  */
8937
8938 static rtx
8939 result_vector (savep, result)
8940      int savep;
8941      rtx result;
8942 {
8943   int regno, size, align, nelts;
8944   enum machine_mode mode;
8945   rtx reg, mem;
8946   rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
8947   
8948   size = nelts = 0;
8949   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
8950     if ((mode = apply_result_mode[regno]) != VOIDmode)
8951       {
8952         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
8953         if (size % align != 0)
8954           size = CEIL (size, align) * align;
8955         reg = gen_rtx (REG, mode, savep ? regno : INCOMING_REGNO (regno));
8956         mem = change_address (result, mode,
8957                               plus_constant (XEXP (result, 0), size));
8958         savevec[nelts++] = (savep
8959                             ? gen_rtx (SET, VOIDmode, mem, reg)
8960                             : gen_rtx (SET, VOIDmode, reg, mem));
8961         size += GET_MODE_SIZE (mode);
8962       }
8963   return gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (nelts, savevec));
8964 }
8965 #endif /* HAVE_untyped_call or HAVE_untyped_return */
8966
8967 /* Save the state required to perform an untyped call with the same
8968    arguments as were passed to the current function.  */
8969
8970 static rtx
8971 expand_builtin_apply_args ()
8972 {
8973   rtx registers;
8974   int size, align, regno;
8975   enum machine_mode mode;
8976
8977   /* Create a block where the arg-pointer, structure value address,
8978      and argument registers can be saved.  */
8979   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
8980
8981   /* Walk past the arg-pointer and structure value address.  */
8982   size = GET_MODE_SIZE (Pmode);
8983   if (struct_value_rtx)
8984     size += GET_MODE_SIZE (Pmode);
8985
8986   /* Save each register used in calling a function to the block.  */
8987   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
8988     if ((mode = apply_args_mode[regno]) != VOIDmode)
8989       {
8990         rtx tem;
8991
8992         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
8993         if (size % align != 0)
8994           size = CEIL (size, align) * align;
8995
8996         tem = gen_rtx (REG, mode, INCOMING_REGNO (regno));
8997
8998 #ifdef STACK_REGS
8999         /* For reg-stack.c's stack register household.
9000            Compare with a similar piece of code in function.c.  */
9001
9002         emit_insn (gen_rtx (USE, mode, tem));
9003 #endif
9004
9005         emit_move_insn (change_address (registers, mode,
9006                                         plus_constant (XEXP (registers, 0),
9007                                                        size)),
9008                         tem);
9009         size += GET_MODE_SIZE (mode);
9010       }
9011
9012   /* Save the arg pointer to the block.  */
9013   emit_move_insn (change_address (registers, Pmode, XEXP (registers, 0)),
9014                   copy_to_reg (virtual_incoming_args_rtx));
9015   size = GET_MODE_SIZE (Pmode);
9016
9017   /* Save the structure value address unless this is passed as an
9018      "invisible" first argument.  */
9019   if (struct_value_incoming_rtx)
9020     {
9021       emit_move_insn (change_address (registers, Pmode,
9022                                       plus_constant (XEXP (registers, 0),
9023                                                      size)),
9024                       copy_to_reg (struct_value_incoming_rtx));
9025       size += GET_MODE_SIZE (Pmode);
9026     }
9027
9028   /* Return the address of the block.  */
9029   return copy_addr_to_reg (XEXP (registers, 0));
9030 }
9031
9032 /* Perform an untyped call and save the state required to perform an
9033    untyped return of whatever value was returned by the given function.  */
9034
9035 static rtx
9036 expand_builtin_apply (function, arguments, argsize)
9037      rtx function, arguments, argsize;
9038 {
9039   int size, align, regno;
9040   enum machine_mode mode;
9041   rtx incoming_args, result, reg, dest, call_insn;
9042   rtx old_stack_level = 0;
9043   rtx call_fusage = 0;
9044
9045   /* Create a block where the return registers can be saved.  */
9046   result = assign_stack_local (BLKmode, apply_result_size (), -1);
9047
9048   /* ??? The argsize value should be adjusted here.  */
9049
9050   /* Fetch the arg pointer from the ARGUMENTS block.  */
9051   incoming_args = gen_reg_rtx (Pmode);
9052   emit_move_insn (incoming_args,
9053                   gen_rtx (MEM, Pmode, arguments));
9054 #ifndef STACK_GROWS_DOWNWARD
9055   incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize,
9056                                 incoming_args, 0, OPTAB_LIB_WIDEN);
9057 #endif
9058
9059   /* Perform postincrements before actually calling the function.  */
9060   emit_queue ();
9061
9062   /* Push a new argument block and copy the arguments.  */
9063   do_pending_stack_adjust ();
9064   emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
9065
9066   /* Push a block of memory onto the stack to store the memory arguments.
9067      Save the address in a register, and copy the memory arguments.  ??? I
9068      haven't figured out how the calling convention macros effect this,
9069      but it's likely that the source and/or destination addresses in
9070      the block copy will need updating in machine specific ways.  */
9071   dest = copy_addr_to_reg (push_block (argsize, 0, 0));
9072   emit_block_move (gen_rtx (MEM, BLKmode, dest),
9073                    gen_rtx (MEM, BLKmode, incoming_args),
9074                    argsize,
9075                    PARM_BOUNDARY / BITS_PER_UNIT);
9076
9077   /* Refer to the argument block.  */
9078   apply_args_size ();
9079   arguments = gen_rtx (MEM, BLKmode, arguments);
9080
9081   /* Walk past the arg-pointer and structure value address.  */
9082   size = GET_MODE_SIZE (Pmode);
9083   if (struct_value_rtx)
9084     size += GET_MODE_SIZE (Pmode);
9085
9086   /* Restore each of the registers previously saved.  Make USE insns
9087      for each of these registers for use in making the call.  */
9088   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9089     if ((mode = apply_args_mode[regno]) != VOIDmode)
9090       {
9091         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
9092         if (size % align != 0)
9093           size = CEIL (size, align) * align;
9094         reg = gen_rtx (REG, mode, regno);
9095         emit_move_insn (reg,
9096                         change_address (arguments, mode,
9097                                         plus_constant (XEXP (arguments, 0),
9098                                                        size)));
9099
9100         use_reg (&call_fusage, reg);
9101         size += GET_MODE_SIZE (mode);
9102       }
9103
9104   /* Restore the structure value address unless this is passed as an
9105      "invisible" first argument.  */
9106   size = GET_MODE_SIZE (Pmode);
9107   if (struct_value_rtx)
9108     {
9109       rtx value = gen_reg_rtx (Pmode);
9110       emit_move_insn (value,
9111                       change_address (arguments, Pmode,
9112                                       plus_constant (XEXP (arguments, 0),
9113                                                      size)));
9114       emit_move_insn (struct_value_rtx, value);
9115       if (GET_CODE (struct_value_rtx) == REG)
9116           use_reg (&call_fusage, struct_value_rtx);
9117       size += GET_MODE_SIZE (Pmode);
9118     }
9119
9120   /* All arguments and registers used for the call are set up by now!  */
9121   function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
9122
9123   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
9124      and we don't want to load it into a register as an optimization,
9125      because prepare_call_address already did it if it should be done.  */
9126   if (GET_CODE (function) != SYMBOL_REF)
9127     function = memory_address (FUNCTION_MODE, function);
9128
9129   /* Generate the actual call instruction and save the return value.  */
9130 #ifdef HAVE_untyped_call
9131   if (HAVE_untyped_call)
9132     emit_call_insn (gen_untyped_call (gen_rtx (MEM, FUNCTION_MODE, function),
9133                                       result, result_vector (1, result)));
9134   else
9135 #endif
9136 #ifdef HAVE_call_value
9137   if (HAVE_call_value)
9138     {
9139       rtx valreg = 0;
9140
9141       /* Locate the unique return register.  It is not possible to
9142          express a call that sets more than one return register using
9143          call_value; use untyped_call for that.  In fact, untyped_call
9144          only needs to save the return registers in the given block.  */
9145       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9146         if ((mode = apply_result_mode[regno]) != VOIDmode)
9147           {
9148             if (valreg)
9149               abort (); /* HAVE_untyped_call required.  */
9150             valreg = gen_rtx (REG, mode, regno);
9151           }
9152
9153       emit_call_insn (gen_call_value (valreg,
9154                                       gen_rtx (MEM, FUNCTION_MODE, function),
9155                                       const0_rtx, NULL_RTX, const0_rtx));
9156
9157       emit_move_insn (change_address (result, GET_MODE (valreg),
9158                                       XEXP (result, 0)),
9159                       valreg);
9160     }
9161   else
9162 #endif
9163     abort ();
9164
9165   /* Find the CALL insn we just emitted.  */
9166   for (call_insn = get_last_insn ();
9167        call_insn && GET_CODE (call_insn) != CALL_INSN;
9168        call_insn = PREV_INSN (call_insn))
9169     ;
9170
9171   if (! call_insn)
9172     abort ();
9173
9174   /* Put the register usage information on the CALL.  If there is already
9175      some usage information, put ours at the end.  */
9176   if (CALL_INSN_FUNCTION_USAGE (call_insn))
9177     {
9178       rtx link;
9179
9180       for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
9181            link = XEXP (link, 1))
9182         ;
9183
9184       XEXP (link, 1) = call_fusage;
9185     }
9186   else
9187     CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
9188
9189   /* Restore the stack.  */
9190   emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
9191
9192   /* Return the address of the result block.  */
9193   return copy_addr_to_reg (XEXP (result, 0));
9194 }
9195
9196 /* Perform an untyped return.  */
9197
9198 static void
9199 expand_builtin_return (result)
9200      rtx result;
9201 {
9202   int size, align, regno;
9203   enum machine_mode mode;
9204   rtx reg;
9205   rtx call_fusage = 0;
9206
9207   apply_result_size ();
9208   result = gen_rtx (MEM, BLKmode, result);
9209
9210 #ifdef HAVE_untyped_return
9211   if (HAVE_untyped_return)
9212     {
9213       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
9214       emit_barrier ();
9215       return;
9216     }
9217 #endif
9218
9219   /* Restore the return value and note that each value is used.  */
9220   size = 0;
9221   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9222     if ((mode = apply_result_mode[regno]) != VOIDmode)
9223       {
9224         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
9225         if (size % align != 0)
9226           size = CEIL (size, align) * align;
9227         reg = gen_rtx (REG, mode, INCOMING_REGNO (regno));
9228         emit_move_insn (reg,
9229                         change_address (result, mode,
9230                                         plus_constant (XEXP (result, 0),
9231                                                        size)));
9232
9233         push_to_sequence (call_fusage);
9234         emit_insn (gen_rtx (USE, VOIDmode, reg));
9235         call_fusage = get_insns ();
9236         end_sequence ();
9237         size += GET_MODE_SIZE (mode);
9238       }
9239
9240   /* Put the USE insns before the return.  */
9241   emit_insns (call_fusage);
9242
9243   /* Return whatever values was restored by jumping directly to the end
9244      of the function.  */
9245   expand_null_return ();
9246 }
9247 \f
9248 /* Expand code for a post- or pre- increment or decrement
9249    and return the RTX for the result.
9250    POST is 1 for postinc/decrements and 0 for preinc/decrements.  */
9251
9252 static rtx
9253 expand_increment (exp, post, ignore)
9254      register tree exp;
9255      int post, ignore;
9256 {
9257   register rtx op0, op1;
9258   register rtx temp, value;
9259   register tree incremented = TREE_OPERAND (exp, 0);
9260   optab this_optab = add_optab;
9261   int icode;
9262   enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
9263   int op0_is_copy = 0;
9264   int single_insn = 0;
9265   /* 1 means we can't store into OP0 directly,
9266      because it is a subreg narrower than a word,
9267      and we don't dare clobber the rest of the word.  */
9268   int bad_subreg = 0;
9269
9270   if (output_bytecode)
9271     {
9272       bc_expand_expr (exp);
9273       return NULL_RTX;
9274     }
9275
9276   /* Stabilize any component ref that might need to be
9277      evaluated more than once below.  */
9278   if (!post
9279       || TREE_CODE (incremented) == BIT_FIELD_REF
9280       || (TREE_CODE (incremented) == COMPONENT_REF
9281           && (TREE_CODE (TREE_OPERAND (incremented, 0)) != INDIRECT_REF
9282               || DECL_BIT_FIELD (TREE_OPERAND (incremented, 1)))))
9283     incremented = stabilize_reference (incremented);
9284   /* Nested *INCREMENT_EXPRs can happen in C++.  We must force innermost
9285      ones into save exprs so that they don't accidentally get evaluated
9286      more than once by the code below.  */
9287   if (TREE_CODE (incremented) == PREINCREMENT_EXPR
9288       || TREE_CODE (incremented) == PREDECREMENT_EXPR)
9289     incremented = save_expr (incremented);
9290
9291   /* Compute the operands as RTX.
9292      Note whether OP0 is the actual lvalue or a copy of it:
9293      I believe it is a copy iff it is a register or subreg
9294      and insns were generated in computing it.   */
9295
9296   temp = get_last_insn ();
9297   op0 = expand_expr (incremented, NULL_RTX, VOIDmode, 0);
9298
9299   /* If OP0 is a SUBREG made for a promoted variable, we cannot increment
9300      in place but instead must do sign- or zero-extension during assignment,
9301      so we copy it into a new register and let the code below use it as
9302      a copy.
9303
9304      Note that we can safely modify this SUBREG since it is know not to be
9305      shared (it was made by the expand_expr call above).  */
9306
9307   if (GET_CODE (op0) == SUBREG && SUBREG_PROMOTED_VAR_P (op0))
9308     {
9309       if (post)
9310         SUBREG_REG (op0) = copy_to_reg (SUBREG_REG (op0));
9311       else
9312         bad_subreg = 1;
9313     }
9314   else if (GET_CODE (op0) == SUBREG
9315            && GET_MODE_BITSIZE (GET_MODE (op0)) < BITS_PER_WORD)
9316     {
9317       /* We cannot increment this SUBREG in place.  If we are
9318          post-incrementing, get a copy of the old value.  Otherwise,
9319          just mark that we cannot increment in place.  */
9320       if (post)
9321         op0 = copy_to_reg (op0);
9322       else
9323         bad_subreg = 1;
9324     }
9325
9326   op0_is_copy = ((GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
9327                  && temp != get_last_insn ());
9328   op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
9329
9330   /* Decide whether incrementing or decrementing.  */
9331   if (TREE_CODE (exp) == POSTDECREMENT_EXPR
9332       || TREE_CODE (exp) == PREDECREMENT_EXPR)
9333     this_optab = sub_optab;
9334
9335   /* Convert decrement by a constant into a negative increment.  */
9336   if (this_optab == sub_optab
9337       && GET_CODE (op1) == CONST_INT)
9338     {
9339       op1 = GEN_INT (- INTVAL (op1));
9340       this_optab = add_optab;
9341     }
9342
9343   /* For a preincrement, see if we can do this with a single instruction.  */
9344   if (!post)
9345     {
9346       icode = (int) this_optab->handlers[(int) mode].insn_code;
9347       if (icode != (int) CODE_FOR_nothing
9348           /* Make sure that OP0 is valid for operands 0 and 1
9349              of the insn we want to queue.  */
9350           && (*insn_operand_predicate[icode][0]) (op0, mode)
9351           && (*insn_operand_predicate[icode][1]) (op0, mode)
9352           && (*insn_operand_predicate[icode][2]) (op1, mode))
9353         single_insn = 1;
9354     }
9355
9356   /* If OP0 is not the actual lvalue, but rather a copy in a register,
9357      then we cannot just increment OP0.  We must therefore contrive to
9358      increment the original value.  Then, for postincrement, we can return
9359      OP0 since it is a copy of the old value.  For preincrement, expand here
9360      unless we can do it with a single insn.
9361
9362      Likewise if storing directly into OP0 would clobber high bits
9363      we need to preserve (bad_subreg).  */
9364   if (op0_is_copy || (!post && !single_insn) || bad_subreg)
9365     {
9366       /* This is the easiest way to increment the value wherever it is.
9367          Problems with multiple evaluation of INCREMENTED are prevented
9368          because either (1) it is a component_ref or preincrement,
9369          in which case it was stabilized above, or (2) it is an array_ref
9370          with constant index in an array in a register, which is
9371          safe to reevaluate.  */
9372       tree newexp = build (((TREE_CODE (exp) == POSTDECREMENT_EXPR
9373                              || TREE_CODE (exp) == PREDECREMENT_EXPR)
9374                             ? MINUS_EXPR : PLUS_EXPR),
9375                            TREE_TYPE (exp),
9376                            incremented,
9377                            TREE_OPERAND (exp, 1));
9378
9379       while (TREE_CODE (incremented) == NOP_EXPR
9380              || TREE_CODE (incremented) == CONVERT_EXPR)
9381         {
9382           newexp = convert (TREE_TYPE (incremented), newexp);
9383           incremented = TREE_OPERAND (incremented, 0);
9384         }
9385
9386       temp = expand_assignment (incremented, newexp, ! post && ! ignore , 0);
9387       return post ? op0 : temp;
9388     }
9389
9390   if (post)
9391     {
9392       /* We have a true reference to the value in OP0.
9393          If there is an insn to add or subtract in this mode, queue it.
9394          Queueing the increment insn avoids the register shuffling
9395          that often results if we must increment now and first save
9396          the old value for subsequent use.  */
9397
9398 #if 0  /* Turned off to avoid making extra insn for indexed memref.  */
9399       op0 = stabilize (op0);
9400 #endif
9401
9402       icode = (int) this_optab->handlers[(int) mode].insn_code;
9403       if (icode != (int) CODE_FOR_nothing
9404           /* Make sure that OP0 is valid for operands 0 and 1
9405              of the insn we want to queue.  */
9406           && (*insn_operand_predicate[icode][0]) (op0, mode)
9407           && (*insn_operand_predicate[icode][1]) (op0, mode))
9408         {
9409           if (! (*insn_operand_predicate[icode][2]) (op1, mode))
9410             op1 = force_reg (mode, op1);
9411
9412           return enqueue_insn (op0, GEN_FCN (icode) (op0, op0, op1));
9413         }
9414     }
9415
9416   /* Preincrement, or we can't increment with one simple insn.  */
9417   if (post)
9418     /* Save a copy of the value before inc or dec, to return it later.  */
9419     temp = value = copy_to_reg (op0);
9420   else
9421     /* Arrange to return the incremented value.  */
9422     /* Copy the rtx because expand_binop will protect from the queue,
9423        and the results of that would be invalid for us to return
9424        if our caller does emit_queue before using our result.  */
9425     temp = copy_rtx (value = op0);
9426
9427   /* Increment however we can.  */
9428   op1 = expand_binop (mode, this_optab, value, op1, op0,
9429                       TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
9430   /* Make sure the value is stored into OP0.  */
9431   if (op1 != op0)
9432     emit_move_insn (op0, op1);
9433
9434   return temp;
9435 }
9436 \f
9437 /* Expand all function calls contained within EXP, innermost ones first.
9438    But don't look within expressions that have sequence points.
9439    For each CALL_EXPR, record the rtx for its value
9440    in the CALL_EXPR_RTL field.  */
9441
9442 static void
9443 preexpand_calls (exp)
9444      tree exp;
9445 {
9446   register int nops, i;
9447   int type = TREE_CODE_CLASS (TREE_CODE (exp));
9448
9449   if (! do_preexpand_calls)
9450     return;
9451
9452   /* Only expressions and references can contain calls.  */
9453
9454   if (type != 'e' && type != '<' && type != '1' && type != '2' && type != 'r')
9455     return;
9456
9457   switch (TREE_CODE (exp))
9458     {
9459     case CALL_EXPR:
9460       /* Do nothing if already expanded.  */
9461       if (CALL_EXPR_RTL (exp) != 0
9462           /* Do nothing if the call returns a variable-sized object.  */
9463           || TREE_CODE (TYPE_SIZE (TREE_TYPE(exp))) != INTEGER_CST
9464           /* Do nothing to built-in functions.  */
9465           || (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
9466               && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
9467                   == FUNCTION_DECL)
9468               && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))))
9469         return;
9470
9471       CALL_EXPR_RTL (exp) = expand_call (exp, NULL_RTX, 0);
9472       return;
9473
9474     case COMPOUND_EXPR:
9475     case COND_EXPR:
9476     case TRUTH_ANDIF_EXPR:
9477     case TRUTH_ORIF_EXPR:
9478       /* If we find one of these, then we can be sure
9479          the adjust will be done for it (since it makes jumps).
9480          Do it now, so that if this is inside an argument
9481          of a function, we don't get the stack adjustment
9482          after some other args have already been pushed.  */
9483       do_pending_stack_adjust ();
9484       return;
9485
9486     case BLOCK:
9487     case RTL_EXPR:
9488     case WITH_CLEANUP_EXPR:
9489     case CLEANUP_POINT_EXPR:
9490       return;
9491
9492     case SAVE_EXPR:
9493       if (SAVE_EXPR_RTL (exp) != 0)
9494         return;
9495     }
9496
9497   nops = tree_code_length[(int) TREE_CODE (exp)];
9498   for (i = 0; i < nops; i++)
9499     if (TREE_OPERAND (exp, i) != 0)
9500       {
9501         type = TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, i)));
9502         if (type == 'e' || type == '<' || type == '1' || type == '2'
9503             || type == 'r')
9504           preexpand_calls (TREE_OPERAND (exp, i));
9505       }
9506 }
9507 \f
9508 /* At the start of a function, record that we have no previously-pushed
9509    arguments waiting to be popped.  */
9510
9511 void
9512 init_pending_stack_adjust ()
9513 {
9514   pending_stack_adjust = 0;
9515 }
9516
9517 /* When exiting from function, if safe, clear out any pending stack adjust
9518    so the adjustment won't get done.  */
9519
9520 void
9521 clear_pending_stack_adjust ()
9522 {
9523 #ifdef EXIT_IGNORE_STACK
9524   if (optimize > 0
9525       && ! flag_omit_frame_pointer && EXIT_IGNORE_STACK
9526       && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
9527       && ! flag_inline_functions)
9528     pending_stack_adjust = 0;
9529 #endif
9530 }
9531
9532 /* Pop any previously-pushed arguments that have not been popped yet.  */
9533
9534 void
9535 do_pending_stack_adjust ()
9536 {
9537   if (inhibit_defer_pop == 0)
9538     {
9539       if (pending_stack_adjust != 0)
9540         adjust_stack (GEN_INT (pending_stack_adjust));
9541       pending_stack_adjust = 0;
9542     }
9543 }
9544
9545 /* Defer the expansion all cleanups up to OLD_CLEANUPS.
9546    Returns the cleanups to be performed.  */
9547
9548 static tree
9549 defer_cleanups_to (old_cleanups)
9550      tree old_cleanups;
9551 {
9552   tree new_cleanups = NULL_TREE;
9553   tree cleanups = cleanups_this_call;
9554   tree last = NULL_TREE;
9555
9556   while (cleanups_this_call != old_cleanups)
9557     {
9558       (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
9559       last = cleanups_this_call;
9560       cleanups_this_call = TREE_CHAIN (cleanups_this_call);
9561     }      
9562
9563   if (last)
9564     {
9565       /* Remove the list from the chain of cleanups.  */
9566       TREE_CHAIN (last) = NULL_TREE;
9567
9568       /* reverse them so that we can build them in the right order.  */
9569       cleanups = nreverse (cleanups);
9570
9571       /* All cleanups must be on the function_obstack.  */
9572       push_obstacks_nochange ();
9573       resume_temporary_allocation ();
9574
9575       while (cleanups)
9576         {
9577           if (new_cleanups)
9578             new_cleanups = build (COMPOUND_EXPR, TREE_TYPE (new_cleanups),
9579                                   TREE_VALUE (cleanups), new_cleanups);
9580           else
9581             new_cleanups = TREE_VALUE (cleanups);
9582
9583           cleanups = TREE_CHAIN (cleanups);
9584         }
9585
9586       pop_obstacks ();
9587     }
9588
9589   return new_cleanups;
9590 }
9591
9592 /* Expand all cleanups up to OLD_CLEANUPS.
9593    Needed here, and also for language-dependent calls.  */
9594
9595 void
9596 expand_cleanups_to (old_cleanups)
9597      tree old_cleanups;
9598 {
9599   while (cleanups_this_call != old_cleanups)
9600     {
9601       (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
9602       expand_expr (TREE_VALUE (cleanups_this_call), const0_rtx, VOIDmode, 0);
9603       cleanups_this_call = TREE_CHAIN (cleanups_this_call);
9604     }
9605 }
9606 \f
9607 /* Expand conditional expressions.  */
9608
9609 /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
9610    LABEL is an rtx of code CODE_LABEL, in this function and all the
9611    functions here.  */
9612
9613 void
9614 jumpifnot (exp, label)
9615      tree exp;
9616      rtx label;
9617 {
9618   do_jump (exp, label, NULL_RTX);
9619 }
9620
9621 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
9622
9623 void
9624 jumpif (exp, label)
9625      tree exp;
9626      rtx label;
9627 {
9628   do_jump (exp, NULL_RTX, label);
9629 }
9630
9631 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
9632    the result is zero, or IF_TRUE_LABEL if the result is one.
9633    Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
9634    meaning fall through in that case.
9635
9636    do_jump always does any pending stack adjust except when it does not
9637    actually perform a jump.  An example where there is no jump
9638    is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
9639
9640    This function is responsible for optimizing cases such as
9641    &&, || and comparison operators in EXP.  */
9642
9643 void
9644 do_jump (exp, if_false_label, if_true_label)
9645      tree exp;
9646      rtx if_false_label, if_true_label;
9647 {
9648   register enum tree_code code = TREE_CODE (exp);
9649   /* Some cases need to create a label to jump to
9650      in order to properly fall through.
9651      These cases set DROP_THROUGH_LABEL nonzero.  */
9652   rtx drop_through_label = 0;
9653   rtx temp;
9654   rtx comparison = 0;
9655   int i;
9656   tree type;
9657   enum machine_mode mode;
9658
9659   emit_queue ();
9660
9661   switch (code)
9662     {
9663     case ERROR_MARK:
9664       break;
9665
9666     case INTEGER_CST:
9667       temp = integer_zerop (exp) ? if_false_label : if_true_label;
9668       if (temp)
9669         emit_jump (temp);
9670       break;
9671
9672 #if 0
9673       /* This is not true with #pragma weak  */
9674     case ADDR_EXPR:
9675       /* The address of something can never be zero.  */
9676       if (if_true_label)
9677         emit_jump (if_true_label);
9678       break;
9679 #endif
9680
9681     case NOP_EXPR:
9682       if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
9683           || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
9684           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF)
9685         goto normal;
9686     case CONVERT_EXPR:
9687       /* If we are narrowing the operand, we have to do the compare in the
9688          narrower mode.  */
9689       if ((TYPE_PRECISION (TREE_TYPE (exp))
9690            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
9691         goto normal;
9692     case NON_LVALUE_EXPR:
9693     case REFERENCE_EXPR:
9694     case ABS_EXPR:
9695     case NEGATE_EXPR:
9696     case LROTATE_EXPR:
9697     case RROTATE_EXPR:
9698       /* These cannot change zero->non-zero or vice versa.  */
9699       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
9700       break;
9701
9702 #if 0
9703       /* This is never less insns than evaluating the PLUS_EXPR followed by
9704          a test and can be longer if the test is eliminated.  */
9705     case PLUS_EXPR:
9706       /* Reduce to minus.  */
9707       exp = build (MINUS_EXPR, TREE_TYPE (exp),
9708                    TREE_OPERAND (exp, 0),
9709                    fold (build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (exp, 1)),
9710                                  TREE_OPERAND (exp, 1))));
9711       /* Process as MINUS.  */
9712 #endif
9713
9714     case MINUS_EXPR:
9715       /* Non-zero iff operands of minus differ.  */
9716       comparison = compare (build (NE_EXPR, TREE_TYPE (exp),
9717                                    TREE_OPERAND (exp, 0),
9718                                    TREE_OPERAND (exp, 1)),
9719                             NE, NE);
9720       break;
9721
9722     case BIT_AND_EXPR:
9723       /* If we are AND'ing with a small constant, do this comparison in the
9724          smallest type that fits.  If the machine doesn't have comparisons
9725          that small, it will be converted back to the wider comparison.
9726          This helps if we are testing the sign bit of a narrower object.
9727          combine can't do this for us because it can't know whether a
9728          ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
9729
9730       if (! SLOW_BYTE_ACCESS
9731           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
9732           && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
9733           && (i = floor_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))) >= 0
9734           && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
9735           && (type = type_for_mode (mode, 1)) != 0
9736           && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
9737           && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
9738               != CODE_FOR_nothing))
9739         {
9740           do_jump (convert (type, exp), if_false_label, if_true_label);
9741           break;
9742         }
9743       goto normal;
9744
9745     case TRUTH_NOT_EXPR:
9746       do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
9747       break;
9748
9749     case TRUTH_ANDIF_EXPR:
9750       {
9751         rtx seq1, seq2;
9752         tree cleanups, old_cleanups;
9753
9754         if (if_false_label == 0)
9755           if_false_label = drop_through_label = gen_label_rtx ();
9756         start_sequence ();
9757         do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
9758         seq1 = get_insns ();
9759         end_sequence ();
9760
9761         old_cleanups = cleanups_this_call;
9762         start_sequence ();
9763         do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
9764         seq2 = get_insns ();
9765         end_sequence ();
9766
9767         cleanups = defer_cleanups_to (old_cleanups);
9768         if (cleanups)
9769           {
9770             rtx flag = gen_reg_rtx (word_mode);
9771             tree new_cleanups;
9772             tree cond;
9773
9774             /* Flag cleanups as not needed. */
9775             emit_move_insn (flag, const0_rtx);
9776             emit_insns (seq1);
9777
9778             /* Flag cleanups as needed. */
9779             emit_move_insn (flag, const1_rtx);
9780             emit_insns (seq2);
9781
9782             /* All cleanups must be on the function_obstack.  */
9783             push_obstacks_nochange ();
9784             resume_temporary_allocation ();
9785
9786             /* convert flag, which is an rtx, into a tree. */
9787             cond = make_node (RTL_EXPR);
9788             TREE_TYPE (cond) = integer_type_node;
9789             RTL_EXPR_RTL (cond) = flag;
9790             RTL_EXPR_SEQUENCE (cond) = NULL_RTX;
9791             cond = save_expr (cond);
9792
9793             new_cleanups = build (COND_EXPR, void_type_node,
9794                                   truthvalue_conversion (cond),
9795                                   cleanups, integer_zero_node);
9796             new_cleanups = fold (new_cleanups);
9797
9798             pop_obstacks ();
9799
9800             /* Now add in the conditionalized cleanups. */
9801             cleanups_this_call
9802               = tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
9803             (*interim_eh_hook) (NULL_TREE);
9804           }
9805         else
9806           {
9807             emit_insns (seq1);
9808             emit_insns (seq2);
9809           }
9810       }
9811       break;
9812
9813     case TRUTH_ORIF_EXPR:
9814       {
9815         rtx seq1, seq2;
9816         tree cleanups, old_cleanups;
9817
9818         if (if_true_label == 0)
9819           if_true_label = drop_through_label = gen_label_rtx ();
9820         start_sequence ();
9821         do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
9822         seq1 = get_insns ();
9823         end_sequence ();
9824
9825         old_cleanups = cleanups_this_call;
9826         start_sequence ();
9827         do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
9828         seq2 = get_insns ();
9829         end_sequence ();
9830
9831         cleanups = defer_cleanups_to (old_cleanups);
9832         if (cleanups)
9833           {
9834             rtx flag = gen_reg_rtx (word_mode);
9835             tree new_cleanups;
9836             tree cond;
9837
9838             /* Flag cleanups as not needed. */
9839             emit_move_insn (flag, const0_rtx);
9840             emit_insns (seq1);
9841
9842             /* Flag cleanups as needed. */
9843             emit_move_insn (flag, const1_rtx);
9844             emit_insns (seq2);
9845
9846             /* All cleanups must be on the function_obstack.  */
9847             push_obstacks_nochange ();
9848             resume_temporary_allocation ();
9849
9850             /* convert flag, which is an rtx, into a tree. */
9851             cond = make_node (RTL_EXPR);
9852             TREE_TYPE (cond) = integer_type_node;
9853             RTL_EXPR_RTL (cond) = flag;
9854             RTL_EXPR_SEQUENCE (cond) = NULL_RTX;
9855             cond = save_expr (cond);
9856
9857             new_cleanups = build (COND_EXPR, void_type_node,
9858                                   truthvalue_conversion (cond),
9859                                   cleanups, integer_zero_node);
9860             new_cleanups = fold (new_cleanups);
9861
9862             pop_obstacks ();
9863
9864             /* Now add in the conditionalized cleanups. */
9865             cleanups_this_call
9866               = tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
9867             (*interim_eh_hook) (NULL_TREE);
9868           }
9869         else
9870           {
9871             emit_insns (seq1);
9872             emit_insns (seq2);
9873           }
9874       }
9875       break;
9876
9877     case COMPOUND_EXPR:
9878       push_temp_slots ();
9879       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
9880       preserve_temp_slots (NULL_RTX);
9881       free_temp_slots ();
9882       pop_temp_slots ();
9883       emit_queue ();
9884       do_pending_stack_adjust ();
9885       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
9886       break;
9887
9888     case COMPONENT_REF:
9889     case BIT_FIELD_REF:
9890     case ARRAY_REF:
9891       {
9892         int bitsize, bitpos, unsignedp;
9893         enum machine_mode mode;
9894         tree type;
9895         tree offset;
9896         int volatilep = 0;
9897
9898         /* Get description of this reference.  We don't actually care
9899            about the underlying object here.  */
9900         get_inner_reference (exp, &bitsize, &bitpos, &offset,
9901                              &mode, &unsignedp, &volatilep);
9902
9903         type = type_for_size (bitsize, unsignedp);
9904         if (! SLOW_BYTE_ACCESS
9905             && type != 0 && bitsize >= 0
9906             && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
9907             && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
9908                 != CODE_FOR_nothing))
9909           {
9910             do_jump (convert (type, exp), if_false_label, if_true_label);
9911             break;
9912           }
9913         goto normal;
9914       }
9915
9916     case COND_EXPR:
9917       /* Do (a ? 1 : 0) and (a ? 0 : 1) as special cases.  */
9918       if (integer_onep (TREE_OPERAND (exp, 1))
9919           && integer_zerop (TREE_OPERAND (exp, 2)))
9920         do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
9921
9922       else if (integer_zerop (TREE_OPERAND (exp, 1))
9923                && integer_onep (TREE_OPERAND (exp, 2)))
9924         do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
9925
9926       else
9927         {
9928           register rtx label1 = gen_label_rtx ();
9929           drop_through_label = gen_label_rtx ();
9930           do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
9931           /* Now the THEN-expression.  */
9932           do_jump (TREE_OPERAND (exp, 1),
9933                    if_false_label ? if_false_label : drop_through_label,
9934                    if_true_label ? if_true_label : drop_through_label);
9935           /* In case the do_jump just above never jumps.  */
9936           do_pending_stack_adjust ();
9937           emit_label (label1);
9938           /* Now the ELSE-expression.  */
9939           do_jump (TREE_OPERAND (exp, 2),
9940                    if_false_label ? if_false_label : drop_through_label,
9941                    if_true_label ? if_true_label : drop_through_label);
9942         }
9943       break;
9944
9945     case EQ_EXPR:
9946       {
9947         tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
9948
9949         if (integer_zerop (TREE_OPERAND (exp, 1)))
9950           do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
9951         else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
9952                  || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
9953           do_jump
9954             (fold
9955              (build (TRUTH_ANDIF_EXPR, TREE_TYPE (exp),
9956                      fold (build (EQ_EXPR, TREE_TYPE (exp),
9957                                   fold (build1 (REALPART_EXPR,
9958                                                 TREE_TYPE (inner_type),
9959                                                 TREE_OPERAND (exp, 0))),
9960                                   fold (build1 (REALPART_EXPR,
9961                                                 TREE_TYPE (inner_type),
9962                                                 TREE_OPERAND (exp, 1))))),
9963                      fold (build (EQ_EXPR, TREE_TYPE (exp),
9964                                   fold (build1 (IMAGPART_EXPR,
9965                                                 TREE_TYPE (inner_type),
9966                                                 TREE_OPERAND (exp, 0))),
9967                                   fold (build1 (IMAGPART_EXPR,
9968                                                 TREE_TYPE (inner_type),
9969                                                 TREE_OPERAND (exp, 1))))))),
9970              if_false_label, if_true_label);
9971         else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
9972                  && !can_compare_p (TYPE_MODE (inner_type)))
9973           do_jump_by_parts_equality (exp, if_false_label, if_true_label);
9974         else
9975           comparison = compare (exp, EQ, EQ);
9976         break;
9977       }
9978
9979     case NE_EXPR:
9980       {
9981         tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
9982
9983         if (integer_zerop (TREE_OPERAND (exp, 1)))
9984           do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
9985         else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
9986                  || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
9987           do_jump
9988             (fold
9989              (build (TRUTH_ORIF_EXPR, TREE_TYPE (exp),
9990                      fold (build (NE_EXPR, TREE_TYPE (exp),
9991                                   fold (build1 (REALPART_EXPR,
9992                                                 TREE_TYPE (inner_type),
9993                                                 TREE_OPERAND (exp, 0))),
9994                                   fold (build1 (REALPART_EXPR,
9995                                                 TREE_TYPE (inner_type),
9996                                                 TREE_OPERAND (exp, 1))))),
9997                      fold (build (NE_EXPR, TREE_TYPE (exp),
9998                                   fold (build1 (IMAGPART_EXPR,
9999                                                 TREE_TYPE (inner_type),
10000                                                 TREE_OPERAND (exp, 0))),
10001                                   fold (build1 (IMAGPART_EXPR,
10002                                                 TREE_TYPE (inner_type),
10003                                                 TREE_OPERAND (exp, 1))))))),
10004              if_false_label, if_true_label);
10005         else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
10006                  && !can_compare_p (TYPE_MODE (inner_type)))
10007           do_jump_by_parts_equality (exp, if_true_label, if_false_label);
10008         else
10009           comparison = compare (exp, NE, NE);
10010         break;
10011       }
10012
10013     case LT_EXPR:
10014       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
10015            == MODE_INT)
10016           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
10017         do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label);
10018       else
10019         comparison = compare (exp, LT, LTU);
10020       break;
10021
10022     case LE_EXPR:
10023       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
10024            == MODE_INT)
10025           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
10026         do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label);
10027       else
10028         comparison = compare (exp, LE, LEU);
10029       break;
10030
10031     case GT_EXPR:
10032       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
10033            == MODE_INT)
10034           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
10035         do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label);
10036       else
10037         comparison = compare (exp, GT, GTU);
10038       break;
10039
10040     case GE_EXPR:
10041       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
10042            == MODE_INT)
10043           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
10044         do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label);
10045       else
10046         comparison = compare (exp, GE, GEU);
10047       break;
10048
10049     default:
10050     normal:
10051       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
10052 #if 0
10053       /* This is not needed any more and causes poor code since it causes
10054          comparisons and tests from non-SI objects to have different code
10055          sequences.  */
10056       /* Copy to register to avoid generating bad insns by cse
10057          from (set (mem ...) (arithop))  (set (cc0) (mem ...)).  */
10058       if (!cse_not_expected && GET_CODE (temp) == MEM)
10059         temp = copy_to_reg (temp);
10060 #endif
10061       do_pending_stack_adjust ();
10062       if (GET_CODE (temp) == CONST_INT)
10063         comparison = (temp == const0_rtx ? const0_rtx : const_true_rtx);
10064       else if (GET_CODE (temp) == LABEL_REF)
10065         comparison = const_true_rtx;
10066       else if (GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
10067                && !can_compare_p (GET_MODE (temp)))
10068         /* Note swapping the labels gives us not-equal.  */
10069         do_jump_by_parts_equality_rtx (temp, if_true_label, if_false_label);
10070       else if (GET_MODE (temp) != VOIDmode)
10071         comparison = compare_from_rtx (temp, CONST0_RTX (GET_MODE (temp)),
10072                                        NE, TREE_UNSIGNED (TREE_TYPE (exp)),
10073                                        GET_MODE (temp), NULL_RTX, 0);
10074       else
10075         abort ();
10076     }
10077
10078   /* Do any postincrements in the expression that was tested.  */
10079   emit_queue ();
10080
10081   /* If COMPARISON is nonzero here, it is an rtx that can be substituted
10082      straight into a conditional jump instruction as the jump condition.
10083      Otherwise, all the work has been done already.  */
10084
10085   if (comparison == const_true_rtx)
10086     {
10087       if (if_true_label)
10088         emit_jump (if_true_label);
10089     }
10090   else if (comparison == const0_rtx)
10091     {
10092       if (if_false_label)
10093         emit_jump (if_false_label);
10094     }
10095   else if (comparison)
10096     do_jump_for_compare (comparison, if_false_label, if_true_label);
10097
10098   if (drop_through_label)
10099     {
10100       /* If do_jump produces code that might be jumped around,
10101          do any stack adjusts from that code, before the place
10102          where control merges in.  */
10103       do_pending_stack_adjust ();
10104       emit_label (drop_through_label);
10105     }
10106 }
10107 \f
10108 /* Given a comparison expression EXP for values too wide to be compared
10109    with one insn, test the comparison and jump to the appropriate label.
10110    The code of EXP is ignored; we always test GT if SWAP is 0,
10111    and LT if SWAP is 1.  */
10112
10113 static void
10114 do_jump_by_parts_greater (exp, swap, if_false_label, if_true_label)
10115      tree exp;
10116      int swap;
10117      rtx if_false_label, if_true_label;
10118 {
10119   rtx op0 = expand_expr (TREE_OPERAND (exp, swap), NULL_RTX, VOIDmode, 0);
10120   rtx op1 = expand_expr (TREE_OPERAND (exp, !swap), NULL_RTX, VOIDmode, 0);
10121   enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
10122   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
10123   rtx drop_through_label = 0;
10124   int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)));
10125   int i;
10126
10127   if (! if_true_label || ! if_false_label)
10128     drop_through_label = gen_label_rtx ();
10129   if (! if_true_label)
10130     if_true_label = drop_through_label;
10131   if (! if_false_label)
10132     if_false_label = drop_through_label;
10133
10134   /* Compare a word at a time, high order first.  */
10135   for (i = 0; i < nwords; i++)
10136     {
10137       rtx comp;
10138       rtx op0_word, op1_word;
10139
10140       if (WORDS_BIG_ENDIAN)
10141         {
10142           op0_word = operand_subword_force (op0, i, mode);
10143           op1_word = operand_subword_force (op1, i, mode);
10144         }
10145       else
10146         {
10147           op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
10148           op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
10149         }
10150
10151       /* All but high-order word must be compared as unsigned.  */
10152       comp = compare_from_rtx (op0_word, op1_word,
10153                                (unsignedp || i > 0) ? GTU : GT,
10154                                unsignedp, word_mode, NULL_RTX, 0);
10155       if (comp == const_true_rtx)
10156         emit_jump (if_true_label);
10157       else if (comp != const0_rtx)
10158         do_jump_for_compare (comp, NULL_RTX, if_true_label);
10159
10160       /* Consider lower words only if these are equal.  */
10161       comp = compare_from_rtx (op0_word, op1_word, NE, unsignedp, word_mode,
10162                                NULL_RTX, 0);
10163       if (comp == const_true_rtx)
10164         emit_jump (if_false_label);
10165       else if (comp != const0_rtx)
10166         do_jump_for_compare (comp, NULL_RTX, if_false_label);
10167     }
10168
10169   if (if_false_label)
10170     emit_jump (if_false_label);
10171   if (drop_through_label)
10172     emit_label (drop_through_label);
10173 }
10174
10175 /* Compare OP0 with OP1, word at a time, in mode MODE.
10176    UNSIGNEDP says to do unsigned comparison.
10177    Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise.  */
10178
10179 void
10180 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label)
10181      enum machine_mode mode;
10182      int unsignedp;
10183      rtx op0, op1;
10184      rtx if_false_label, if_true_label;
10185 {
10186   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
10187   rtx drop_through_label = 0;
10188   int i;
10189
10190   if (! if_true_label || ! if_false_label)
10191     drop_through_label = gen_label_rtx ();
10192   if (! if_true_label)
10193     if_true_label = drop_through_label;
10194   if (! if_false_label)
10195     if_false_label = drop_through_label;
10196
10197   /* Compare a word at a time, high order first.  */
10198   for (i = 0; i < nwords; i++)
10199     {
10200       rtx comp;
10201       rtx op0_word, op1_word;
10202
10203       if (WORDS_BIG_ENDIAN)
10204         {
10205           op0_word = operand_subword_force (op0, i, mode);
10206           op1_word = operand_subword_force (op1, i, mode);
10207         }
10208       else
10209         {
10210           op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
10211           op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
10212         }
10213
10214       /* All but high-order word must be compared as unsigned.  */
10215       comp = compare_from_rtx (op0_word, op1_word,
10216                                (unsignedp || i > 0) ? GTU : GT,
10217                                unsignedp, word_mode, NULL_RTX, 0);
10218       if (comp == const_true_rtx)
10219         emit_jump (if_true_label);
10220       else if (comp != const0_rtx)
10221         do_jump_for_compare (comp, NULL_RTX, if_true_label);
10222
10223       /* Consider lower words only if these are equal.  */
10224       comp = compare_from_rtx (op0_word, op1_word, NE, unsignedp, word_mode,
10225                                NULL_RTX, 0);
10226       if (comp == const_true_rtx)
10227         emit_jump (if_false_label);
10228       else if (comp != const0_rtx)
10229         do_jump_for_compare (comp, NULL_RTX, if_false_label);
10230     }
10231
10232   if (if_false_label)
10233     emit_jump (if_false_label);
10234   if (drop_through_label)
10235     emit_label (drop_through_label);
10236 }
10237
10238 /* Given an EQ_EXPR expression EXP for values too wide to be compared
10239    with one insn, test the comparison and jump to the appropriate label.  */
10240
10241 static void
10242 do_jump_by_parts_equality (exp, if_false_label, if_true_label)
10243      tree exp;
10244      rtx if_false_label, if_true_label;
10245 {
10246   rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
10247   rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
10248   enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
10249   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
10250   int i;
10251   rtx drop_through_label = 0;
10252
10253   if (! if_false_label)
10254     drop_through_label = if_false_label = gen_label_rtx ();
10255
10256   for (i = 0; i < nwords; i++)
10257     {
10258       rtx comp = compare_from_rtx (operand_subword_force (op0, i, mode),
10259                                    operand_subword_force (op1, i, mode),
10260                                    EQ, TREE_UNSIGNED (TREE_TYPE (exp)),
10261                                    word_mode, NULL_RTX, 0);
10262       if (comp == const_true_rtx)
10263         emit_jump (if_false_label);
10264       else if (comp != const0_rtx)
10265         do_jump_for_compare (comp, if_false_label, NULL_RTX);
10266     }
10267
10268   if (if_true_label)
10269     emit_jump (if_true_label);
10270   if (drop_through_label)
10271     emit_label (drop_through_label);
10272 }
10273 \f
10274 /* Jump according to whether OP0 is 0.
10275    We assume that OP0 has an integer mode that is too wide
10276    for the available compare insns.  */
10277
10278 static void
10279 do_jump_by_parts_equality_rtx (op0, if_false_label, if_true_label)
10280      rtx op0;
10281      rtx if_false_label, if_true_label;
10282 {
10283   int nwords = GET_MODE_SIZE (GET_MODE (op0)) / UNITS_PER_WORD;
10284   int i;
10285   rtx drop_through_label = 0;
10286
10287   if (! if_false_label)
10288     drop_through_label = if_false_label = gen_label_rtx ();
10289
10290   for (i = 0; i < nwords; i++)
10291     {
10292       rtx comp = compare_from_rtx (operand_subword_force (op0, i,
10293                                                           GET_MODE (op0)),
10294                                    const0_rtx, EQ, 1, word_mode, NULL_RTX, 0);
10295       if (comp == const_true_rtx)
10296         emit_jump (if_false_label);
10297       else if (comp != const0_rtx)
10298         do_jump_for_compare (comp, if_false_label, NULL_RTX);
10299     }
10300
10301   if (if_true_label)
10302     emit_jump (if_true_label);
10303   if (drop_through_label)
10304     emit_label (drop_through_label);
10305 }
10306
10307 /* Given a comparison expression in rtl form, output conditional branches to
10308    IF_TRUE_LABEL, IF_FALSE_LABEL, or both.  */
10309
10310 static void
10311 do_jump_for_compare (comparison, if_false_label, if_true_label)
10312      rtx comparison, if_false_label, if_true_label;
10313 {
10314   if (if_true_label)
10315     {
10316       if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
10317         emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_true_label));
10318       else
10319         abort ();
10320
10321       if (if_false_label)
10322         emit_jump (if_false_label);
10323     }
10324   else if (if_false_label)
10325     {
10326       rtx insn;
10327       rtx prev = get_last_insn ();
10328       rtx branch = 0;
10329
10330       /* Output the branch with the opposite condition.  Then try to invert
10331          what is generated.  If more than one insn is a branch, or if the
10332          branch is not the last insn written, abort. If we can't invert
10333          the branch, emit make a true label, redirect this jump to that,
10334          emit a jump to the false label and define the true label.  */
10335
10336       if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
10337         emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)])(if_false_label));
10338       else
10339         abort ();
10340
10341       /* Here we get the first insn that was just emitted.  It used to be  the
10342          case that, on some machines, emitting the branch would discard
10343          the previous compare insn and emit a replacement.  This isn't
10344          done anymore, but abort if we see that PREV is deleted.  */
10345
10346       if (prev == 0)
10347         insn = get_insns ();
10348       else if (INSN_DELETED_P (prev))
10349         abort ();
10350       else
10351         insn = NEXT_INSN (prev);
10352
10353       for (; insn; insn = NEXT_INSN (insn))
10354         if (GET_CODE (insn) == JUMP_INSN)
10355           {
10356             if (branch)
10357               abort ();
10358             branch = insn;
10359           }
10360
10361       if (branch != get_last_insn ())
10362         abort ();
10363
10364       JUMP_LABEL (branch) = if_false_label;
10365       if (! invert_jump (branch, if_false_label))
10366         {
10367           if_true_label = gen_label_rtx ();
10368           redirect_jump (branch, if_true_label);
10369           emit_jump (if_false_label);
10370           emit_label (if_true_label);
10371         }
10372     }
10373 }
10374 \f
10375 /* Generate code for a comparison expression EXP
10376    (including code to compute the values to be compared)
10377    and set (CC0) according to the result.
10378    SIGNED_CODE should be the rtx operation for this comparison for
10379    signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
10380
10381    We force a stack adjustment unless there are currently
10382    things pushed on the stack that aren't yet used.  */
10383
10384 static rtx
10385 compare (exp, signed_code, unsigned_code)
10386      register tree exp;
10387      enum rtx_code signed_code, unsigned_code;
10388 {
10389   register rtx op0
10390     = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
10391   register rtx op1
10392     = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
10393   register tree type = TREE_TYPE (TREE_OPERAND (exp, 0));
10394   register enum machine_mode mode = TYPE_MODE (type);
10395   int unsignedp = TREE_UNSIGNED (type);
10396   enum rtx_code code = unsignedp ? unsigned_code : signed_code;
10397
10398   return compare_from_rtx (op0, op1, code, unsignedp, mode,
10399                            ((mode == BLKmode)
10400                             ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
10401                            TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
10402 }
10403
10404 /* Like compare but expects the values to compare as two rtx's.
10405    The decision as to signed or unsigned comparison must be made by the caller.
10406
10407    If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
10408    compared.
10409
10410    If ALIGN is non-zero, it is the alignment of this type; if zero, the
10411    size of MODE should be used.  */
10412
10413 rtx
10414 compare_from_rtx (op0, op1, code, unsignedp, mode, size, align)
10415      register rtx op0, op1;
10416      enum rtx_code code;
10417      int unsignedp;
10418      enum machine_mode mode;
10419      rtx size;
10420      int align;
10421 {
10422   rtx tem;
10423
10424   /* If one operand is constant, make it the second one.  Only do this
10425      if the other operand is not constant as well.  */
10426
10427   if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
10428       || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
10429     {
10430       tem = op0;
10431       op0 = op1;
10432       op1 = tem;
10433       code = swap_condition (code);
10434     }
10435
10436   if (flag_force_mem)
10437     {
10438       op0 = force_not_mem (op0);
10439       op1 = force_not_mem (op1);
10440     }
10441
10442   do_pending_stack_adjust ();
10443
10444   if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT
10445       && (tem = simplify_relational_operation (code, mode, op0, op1)) != 0)
10446     return tem;
10447
10448 #if 0
10449   /* There's no need to do this now that combine.c can eliminate lots of
10450      sign extensions.  This can be less efficient in certain cases on other
10451      machines. */
10452
10453   /* If this is a signed equality comparison, we can do it as an
10454      unsigned comparison since zero-extension is cheaper than sign
10455      extension and comparisons with zero are done as unsigned.  This is
10456      the case even on machines that can do fast sign extension, since
10457      zero-extension is easier to combine with other operations than
10458      sign-extension is.  If we are comparing against a constant, we must
10459      convert it to what it would look like unsigned.  */
10460   if ((code == EQ || code == NE) && ! unsignedp
10461       && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
10462     {
10463       if (GET_CODE (op1) == CONST_INT
10464           && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
10465         op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
10466       unsignedp = 1;
10467     }
10468 #endif
10469         
10470   emit_cmp_insn (op0, op1, code, size, mode, unsignedp, align);
10471
10472   return gen_rtx (code, VOIDmode, cc0_rtx, const0_rtx);
10473 }
10474 \f
10475 /* Generate code to calculate EXP using a store-flag instruction
10476    and return an rtx for the result.  EXP is either a comparison
10477    or a TRUTH_NOT_EXPR whose operand is a comparison.
10478
10479    If TARGET is nonzero, store the result there if convenient.
10480
10481    If ONLY_CHEAP is non-zero, only do this if it is likely to be very
10482    cheap.
10483
10484    Return zero if there is no suitable set-flag instruction
10485    available on this machine.
10486
10487    Once expand_expr has been called on the arguments of the comparison,
10488    we are committed to doing the store flag, since it is not safe to
10489    re-evaluate the expression.  We emit the store-flag insn by calling
10490    emit_store_flag, but only expand the arguments if we have a reason
10491    to believe that emit_store_flag will be successful.  If we think that
10492    it will, but it isn't, we have to simulate the store-flag with a
10493    set/jump/set sequence.  */
10494
10495 static rtx
10496 do_store_flag (exp, target, mode, only_cheap)
10497      tree exp;
10498      rtx target;
10499      enum machine_mode mode;
10500      int only_cheap;
10501 {
10502   enum rtx_code code;
10503   tree arg0, arg1, type;
10504   tree tem;
10505   enum machine_mode operand_mode;
10506   int invert = 0;
10507   int unsignedp;
10508   rtx op0, op1;
10509   enum insn_code icode;
10510   rtx subtarget = target;
10511   rtx result, label, pattern, jump_pat;
10512
10513   /* If this is a TRUTH_NOT_EXPR, set a flag indicating we must invert the
10514      result at the end.  We can't simply invert the test since it would
10515      have already been inverted if it were valid.  This case occurs for
10516      some floating-point comparisons.  */
10517
10518   if (TREE_CODE (exp) == TRUTH_NOT_EXPR)
10519     invert = 1, exp = TREE_OPERAND (exp, 0);
10520
10521   arg0 = TREE_OPERAND (exp, 0);
10522   arg1 = TREE_OPERAND (exp, 1);
10523   type = TREE_TYPE (arg0);
10524   operand_mode = TYPE_MODE (type);
10525   unsignedp = TREE_UNSIGNED (type);
10526
10527   /* We won't bother with BLKmode store-flag operations because it would mean
10528      passing a lot of information to emit_store_flag.  */
10529   if (operand_mode == BLKmode)
10530     return 0;
10531
10532   STRIP_NOPS (arg0);
10533   STRIP_NOPS (arg1);
10534
10535   /* Get the rtx comparison code to use.  We know that EXP is a comparison
10536      operation of some type.  Some comparisons against 1 and -1 can be
10537      converted to comparisons with zero.  Do so here so that the tests
10538      below will be aware that we have a comparison with zero.   These
10539      tests will not catch constants in the first operand, but constants
10540      are rarely passed as the first operand.  */
10541
10542   switch (TREE_CODE (exp))
10543     {
10544     case EQ_EXPR:
10545       code = EQ;
10546       break;
10547     case NE_EXPR:
10548       code = NE;
10549       break;
10550     case LT_EXPR:
10551       if (integer_onep (arg1))
10552         arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
10553       else
10554         code = unsignedp ? LTU : LT;
10555       break;
10556     case LE_EXPR:
10557       if (! unsignedp && integer_all_onesp (arg1))
10558         arg1 = integer_zero_node, code = LT;
10559       else
10560         code = unsignedp ? LEU : LE;
10561       break;
10562     case GT_EXPR:
10563       if (! unsignedp && integer_all_onesp (arg1))
10564         arg1 = integer_zero_node, code = GE;
10565       else
10566         code = unsignedp ? GTU : GT;
10567       break;
10568     case GE_EXPR:
10569       if (integer_onep (arg1))
10570         arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
10571       else
10572         code = unsignedp ? GEU : GE;
10573       break;
10574     default:
10575       abort ();
10576     }
10577
10578   /* Put a constant second.  */
10579   if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST)
10580     {
10581       tem = arg0; arg0 = arg1; arg1 = tem;
10582       code = swap_condition (code);
10583     }
10584
10585   /* If this is an equality or inequality test of a single bit, we can
10586      do this by shifting the bit being tested to the low-order bit and
10587      masking the result with the constant 1.  If the condition was EQ,
10588      we xor it with 1.  This does not require an scc insn and is faster
10589      than an scc insn even if we have it.  */
10590
10591   if ((code == NE || code == EQ)
10592       && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
10593       && integer_pow2p (TREE_OPERAND (arg0, 1))
10594       && TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT)
10595     {
10596       tree inner = TREE_OPERAND (arg0, 0);
10597       HOST_WIDE_INT tem;
10598       int bitnum;
10599       int ops_unsignedp;
10600
10601       tem = INTVAL (expand_expr (TREE_OPERAND (arg0, 1),
10602                                  NULL_RTX, VOIDmode, 0));
10603       /* In this case, immed_double_const will sign extend the value to make
10604          it look the same on the host and target.  We must remove the
10605          sign-extension before calling exact_log2, since exact_log2 will
10606          fail for negative values.  */
10607       if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT
10608           && BITS_PER_WORD == GET_MODE_BITSIZE (TYPE_MODE (type)))
10609         /* We don't use the obvious constant shift to generate the mask,
10610            because that generates compiler warnings when BITS_PER_WORD is
10611            greater than or equal to HOST_BITS_PER_WIDE_INT, even though this
10612            code is unreachable in that case.  */
10613         tem = tem & GET_MODE_MASK (word_mode);
10614       bitnum = exact_log2 (tem);
10615
10616       /* If INNER is a right shift of a constant and it plus BITNUM does
10617          not overflow, adjust BITNUM and INNER.  */
10618
10619       if (TREE_CODE (inner) == RSHIFT_EXPR
10620           && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
10621           && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
10622           && (bitnum + TREE_INT_CST_LOW (TREE_OPERAND (inner, 1))
10623               < TYPE_PRECISION (type)))
10624         {
10625           bitnum +=TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
10626           inner = TREE_OPERAND (inner, 0);
10627         }
10628
10629       /* If we are going to be able to omit the AND below, we must do our
10630          operations as unsigned.  If we must use the AND, we have a choice.
10631          Normally unsigned is faster, but for some machines signed is.  */
10632       ops_unsignedp = (bitnum == TYPE_PRECISION (type) - 1 ? 1
10633 #ifdef LOAD_EXTEND_OP
10634                        : (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND ? 0 : 1)
10635 #else
10636                        : 1
10637 #endif
10638                        );
10639
10640       if (subtarget == 0 || GET_CODE (subtarget) != REG
10641           || GET_MODE (subtarget) != operand_mode
10642           || ! safe_from_p (subtarget, inner))
10643         subtarget = 0;
10644
10645       op0 = expand_expr (inner, subtarget, VOIDmode, 0);
10646
10647       if (bitnum != 0)
10648         op0 = expand_shift (RSHIFT_EXPR, GET_MODE (op0), op0,
10649                             size_int (bitnum), subtarget, ops_unsignedp);
10650
10651       if (GET_MODE (op0) != mode)
10652         op0 = convert_to_mode (mode, op0, ops_unsignedp);
10653
10654       if ((code == EQ && ! invert) || (code == NE && invert))
10655         op0 = expand_binop (mode, xor_optab, op0, const1_rtx, subtarget,
10656                             ops_unsignedp, OPTAB_LIB_WIDEN);
10657
10658       /* Put the AND last so it can combine with more things.  */
10659       if (bitnum != TYPE_PRECISION (type) - 1)
10660         op0 = expand_and (op0, const1_rtx, subtarget);
10661
10662       return op0;
10663     }
10664
10665   /* Now see if we are likely to be able to do this.  Return if not.  */
10666   if (! can_compare_p (operand_mode))
10667     return 0;
10668   icode = setcc_gen_code[(int) code];
10669   if (icode == CODE_FOR_nothing
10670       || (only_cheap && insn_operand_mode[(int) icode][0] != mode))
10671     {
10672       /* We can only do this if it is one of the special cases that
10673          can be handled without an scc insn.  */
10674       if ((code == LT && integer_zerop (arg1))
10675           || (! only_cheap && code == GE && integer_zerop (arg1)))
10676         ;
10677       else if (BRANCH_COST >= 0
10678                && ! only_cheap && (code == NE || code == EQ)
10679                && TREE_CODE (type) != REAL_TYPE
10680                && ((abs_optab->handlers[(int) operand_mode].insn_code
10681                     != CODE_FOR_nothing)
10682                    || (ffs_optab->handlers[(int) operand_mode].insn_code
10683                        != CODE_FOR_nothing)))
10684         ;
10685       else
10686         return 0;
10687     }
10688       
10689   preexpand_calls (exp);
10690   if (subtarget == 0 || GET_CODE (subtarget) != REG
10691       || GET_MODE (subtarget) != operand_mode
10692       || ! safe_from_p (subtarget, arg1))
10693     subtarget = 0;
10694
10695   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
10696   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
10697
10698   if (target == 0)
10699     target = gen_reg_rtx (mode);
10700
10701   /* Pass copies of OP0 and OP1 in case they contain a QUEUED.  This is safe
10702      because, if the emit_store_flag does anything it will succeed and
10703      OP0 and OP1 will not be used subsequently.  */
10704
10705   result = emit_store_flag (target, code,
10706                             queued_subexp_p (op0) ? copy_rtx (op0) : op0,
10707                             queued_subexp_p (op1) ? copy_rtx (op1) : op1,
10708                             operand_mode, unsignedp, 1);
10709
10710   if (result)
10711     {
10712       if (invert)
10713         result = expand_binop (mode, xor_optab, result, const1_rtx,
10714                                result, 0, OPTAB_LIB_WIDEN);
10715       return result;
10716     }
10717
10718   /* If this failed, we have to do this with set/compare/jump/set code.  */
10719   if (target == 0 || GET_CODE (target) != REG
10720       || reg_mentioned_p (target, op0) || reg_mentioned_p (target, op1))
10721     target = gen_reg_rtx (GET_MODE (target));
10722
10723   emit_move_insn (target, invert ? const0_rtx : const1_rtx);
10724   result = compare_from_rtx (op0, op1, code, unsignedp,
10725                              operand_mode, NULL_RTX, 0);
10726   if (GET_CODE (result) == CONST_INT)
10727     return (((result == const0_rtx && ! invert)
10728              || (result != const0_rtx && invert))
10729             ? const0_rtx : const1_rtx);
10730
10731   label = gen_label_rtx ();
10732   if (bcc_gen_fctn[(int) code] == 0)
10733     abort ();
10734
10735   emit_jump_insn ((*bcc_gen_fctn[(int) code]) (label));
10736   emit_move_insn (target, invert ? const1_rtx : const0_rtx);
10737   emit_label (label);
10738
10739   return target;
10740 }
10741 \f
10742 /* Generate a tablejump instruction (used for switch statements).  */
10743
10744 #ifdef HAVE_tablejump
10745
10746 /* INDEX is the value being switched on, with the lowest value
10747    in the table already subtracted.
10748    MODE is its expected mode (needed if INDEX is constant).
10749    RANGE is the length of the jump table.
10750    TABLE_LABEL is a CODE_LABEL rtx for the table itself.
10751
10752    DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
10753    index value is out of range.  */
10754
10755 void
10756 do_tablejump (index, mode, range, table_label, default_label)
10757      rtx index, range, table_label, default_label;
10758      enum machine_mode mode;
10759 {
10760   register rtx temp, vector;
10761
10762   /* Do an unsigned comparison (in the proper mode) between the index
10763      expression and the value which represents the length of the range.
10764      Since we just finished subtracting the lower bound of the range
10765      from the index expression, this comparison allows us to simultaneously
10766      check that the original index expression value is both greater than
10767      or equal to the minimum value of the range and less than or equal to
10768      the maximum value of the range.  */
10769
10770   emit_cmp_insn (index, range, GTU, NULL_RTX, mode, 1, 0);
10771   emit_jump_insn (gen_bgtu (default_label));
10772
10773   /* If index is in range, it must fit in Pmode.
10774      Convert to Pmode so we can index with it.  */
10775   if (mode != Pmode)
10776     index = convert_to_mode (Pmode, index, 1);
10777
10778   /* Don't let a MEM slip thru, because then INDEX that comes
10779      out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
10780      and break_out_memory_refs will go to work on it and mess it up.  */
10781 #ifdef PIC_CASE_VECTOR_ADDRESS
10782   if (flag_pic && GET_CODE (index) != REG)
10783     index = copy_to_mode_reg (Pmode, index);
10784 #endif
10785
10786   /* If flag_force_addr were to affect this address
10787      it could interfere with the tricky assumptions made
10788      about addresses that contain label-refs,
10789      which may be valid only very near the tablejump itself.  */
10790   /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
10791      GET_MODE_SIZE, because this indicates how large insns are.  The other
10792      uses should all be Pmode, because they are addresses.  This code
10793      could fail if addresses and insns are not the same size.  */
10794   index = gen_rtx (PLUS, Pmode,
10795                    gen_rtx (MULT, Pmode, index,
10796                             GEN_INT (GET_MODE_SIZE (CASE_VECTOR_MODE))),
10797                    gen_rtx (LABEL_REF, Pmode, table_label));
10798 #ifdef PIC_CASE_VECTOR_ADDRESS
10799   if (flag_pic)
10800     index = PIC_CASE_VECTOR_ADDRESS (index);
10801   else
10802 #endif
10803     index = memory_address_noforce (CASE_VECTOR_MODE, index);
10804   temp = gen_reg_rtx (CASE_VECTOR_MODE);
10805   vector = gen_rtx (MEM, CASE_VECTOR_MODE, index);
10806   RTX_UNCHANGING_P (vector) = 1;
10807   convert_move (temp, vector, 0);
10808
10809   emit_jump_insn (gen_tablejump (temp, table_label));
10810
10811 #ifndef CASE_VECTOR_PC_RELATIVE
10812   /* If we are generating PIC code or if the table is PC-relative, the
10813      table and JUMP_INSN must be adjacent, so don't output a BARRIER.  */
10814   if (! flag_pic)
10815     emit_barrier ();
10816 #endif
10817 }
10818
10819 #endif /* HAVE_tablejump */
10820
10821
10822 /* Emit a suitable bytecode to load a value from memory, assuming a pointer
10823    to that value is on the top of the stack. The resulting type is TYPE, and
10824    the source declaration is DECL. */
10825
10826 void
10827 bc_load_memory (type, decl)
10828      tree type, decl;
10829 {
10830   enum bytecode_opcode opcode;
10831   
10832   
10833   /* Bit fields are special.  We only know about signed and
10834      unsigned ints, and enums.  The latter are treated as
10835      signed integers. */
10836   
10837   if (DECL_BIT_FIELD (decl))
10838     if (TREE_CODE (type) == ENUMERAL_TYPE
10839         || TREE_CODE (type) == INTEGER_TYPE)
10840       opcode = TREE_UNSIGNED (type) ? zxloadBI : sxloadBI;
10841     else
10842       abort ();
10843   else
10844     /* See corresponding comment in bc_store_memory(). */
10845     if (TYPE_MODE (type) == BLKmode
10846         || TYPE_MODE (type) == VOIDmode)
10847       return;
10848     else
10849       opcode = mode_to_load_map [(int) TYPE_MODE (type)];
10850
10851   if (opcode == neverneverland)
10852     abort ();
10853   
10854   bc_emit_bytecode (opcode);
10855   
10856 #ifdef DEBUG_PRINT_CODE
10857   fputc ('\n', stderr);
10858 #endif
10859 }
10860
10861
10862 /* Store the contents of the second stack slot to the address in the
10863    top stack slot.  DECL is the declaration of the destination and is used
10864    to determine whether we're dealing with a bitfield. */
10865
10866 void
10867 bc_store_memory (type, decl)
10868      tree type, decl;
10869 {
10870   enum bytecode_opcode opcode;
10871   
10872   
10873   if (DECL_BIT_FIELD (decl))
10874     {
10875       if (TREE_CODE (type) == ENUMERAL_TYPE
10876           || TREE_CODE (type) == INTEGER_TYPE)
10877         opcode = sstoreBI;
10878       else
10879         abort ();
10880     }
10881   else
10882     if (TYPE_MODE (type) == BLKmode)
10883       {
10884         /* Copy structure.  This expands to a block copy instruction, storeBLK.
10885            In addition to the arguments expected by the other store instructions,
10886            it also expects a type size (SImode) on top of the stack, which is the
10887            structure size in size units (usually bytes).  The two first arguments
10888            are already on the stack; so we just put the size on level 1.  For some
10889            other languages, the size may be variable, this is why we don't encode
10890            it as a storeBLK literal, but rather treat it as a full-fledged expression. */
10891         
10892         bc_expand_expr (TYPE_SIZE (type));
10893         opcode = storeBLK;
10894       }
10895     else
10896       opcode = mode_to_store_map [(int) TYPE_MODE (type)];
10897
10898   if (opcode == neverneverland)
10899     abort ();
10900
10901   bc_emit_bytecode (opcode);
10902   
10903 #ifdef DEBUG_PRINT_CODE
10904   fputc ('\n', stderr);
10905 #endif
10906 }
10907
10908
10909 /* Allocate local stack space sufficient to hold a value of the given
10910    SIZE at alignment boundary ALIGNMENT bits.  ALIGNMENT must be an
10911    integral power of 2.  A special case is locals of type VOID, which
10912    have size 0 and alignment 1 - any "voidish" SIZE or ALIGNMENT is
10913    remapped into the corresponding attribute of SI.  */
10914
10915 rtx
10916 bc_allocate_local (size, alignment)
10917      int size, alignment;
10918 {
10919   rtx retval;
10920   int byte_alignment;
10921
10922   if (size < 0)
10923     abort ();
10924
10925   /* Normalize size and alignment  */
10926   if (!size)
10927     size = UNITS_PER_WORD;
10928
10929   if (alignment < BITS_PER_UNIT)
10930     byte_alignment = 1 << (INT_ALIGN - 1);
10931   else
10932     /* Align */
10933     byte_alignment = alignment / BITS_PER_UNIT;
10934
10935   if (local_vars_size & (byte_alignment - 1))
10936     local_vars_size += byte_alignment - (local_vars_size & (byte_alignment - 1));
10937
10938   retval = bc_gen_rtx ((char *) 0, local_vars_size, (struct bc_label *) 0);
10939   local_vars_size += size;
10940
10941   return retval;
10942 }
10943
10944
10945 /* Allocate variable-sized local array. Variable-sized arrays are
10946    actually pointers to the address in memory where they are stored. */
10947
10948 rtx
10949 bc_allocate_variable_array (size)
10950      tree size;
10951 {
10952   rtx retval;
10953   const int ptralign = (1 << (PTR_ALIGN - 1));
10954
10955   /* Align pointer */
10956   if (local_vars_size & ptralign)
10957     local_vars_size +=  ptralign - (local_vars_size & ptralign);
10958
10959   /* Note down local space needed: pointer to block; also return
10960      dummy rtx */
10961
10962   retval = bc_gen_rtx ((char *) 0, local_vars_size, (struct bc_label *) 0);
10963   local_vars_size += POINTER_SIZE / BITS_PER_UNIT;
10964   return retval;
10965 }
10966
10967
10968 /* Push the machine address for the given external variable offset.  */
10969 void
10970 bc_load_externaddr (externaddr)
10971      rtx externaddr;
10972 {
10973   bc_emit_bytecode (constP);
10974   bc_emit_code_labelref (BYTECODE_LABEL (externaddr),
10975                          BYTECODE_BC_LABEL (externaddr)->offset);
10976
10977 #ifdef DEBUG_PRINT_CODE
10978   fputc ('\n', stderr);
10979 #endif
10980 }
10981
10982
10983 /* Like above, but expects an IDENTIFIER.  */
10984 void
10985 bc_load_externaddr_id (id, offset)
10986      tree id;
10987      int offset;
10988 {
10989   if (!IDENTIFIER_POINTER (id))
10990     abort ();
10991
10992   bc_emit_bytecode (constP);
10993   bc_emit_code_labelref (xstrdup (IDENTIFIER_POINTER (id)), offset);
10994
10995 #ifdef DEBUG_PRINT_CODE
10996   fputc ('\n', stderr);
10997 #endif
10998 }
10999
11000
11001 /* Push the machine address for the given local variable offset.  */
11002 void
11003 bc_load_localaddr (localaddr)
11004      rtx localaddr;
11005 {
11006   bc_emit_instruction (localP, (HOST_WIDE_INT) BYTECODE_BC_LABEL (localaddr)->offset);
11007 }
11008
11009
11010 /* Push the machine address for the given parameter offset.
11011    NOTE: offset is in bits. */
11012 void
11013 bc_load_parmaddr (parmaddr)
11014      rtx parmaddr;
11015 {
11016   bc_emit_instruction (argP, ((HOST_WIDE_INT) BYTECODE_BC_LABEL (parmaddr)->offset
11017                               / BITS_PER_UNIT));
11018 }
11019
11020
11021 /* Convert a[i] into *(a + i).  */
11022 tree
11023 bc_canonicalize_array_ref (exp)
11024      tree exp;
11025 {
11026   tree type = TREE_TYPE (exp);
11027   tree array_adr = build1 (ADDR_EXPR, TYPE_POINTER_TO (type),
11028                            TREE_OPERAND (exp, 0));
11029   tree index = TREE_OPERAND (exp, 1);
11030
11031
11032   /* Convert the integer argument to a type the same size as a pointer
11033      so the multiply won't overflow spuriously.  */
11034
11035   if (TYPE_PRECISION (TREE_TYPE (index)) != POINTER_SIZE)
11036     index = convert (type_for_size (POINTER_SIZE, 0), index);
11037
11038   /* The array address isn't volatile even if the array is.
11039      (Of course this isn't terribly relevant since the bytecode
11040      translator treats nearly everything as volatile anyway.)  */
11041   TREE_THIS_VOLATILE (array_adr) = 0;
11042
11043   return build1 (INDIRECT_REF, type,
11044                  fold (build (PLUS_EXPR,
11045                               TYPE_POINTER_TO (type),
11046                               array_adr,
11047                               fold (build (MULT_EXPR,
11048                                            TYPE_POINTER_TO (type),
11049                                            index,
11050                                            size_in_bytes (type))))));
11051 }
11052
11053
11054 /* Load the address of the component referenced by the given
11055    COMPONENT_REF expression.
11056
11057    Returns innermost lvalue. */
11058
11059 tree
11060 bc_expand_component_address (exp)
11061      tree exp;
11062 {
11063   tree tem, chain;
11064   enum machine_mode mode;
11065   int bitpos = 0;
11066   HOST_WIDE_INT SIval;
11067
11068
11069   tem = TREE_OPERAND (exp, 1);
11070   mode = DECL_MODE (tem);
11071
11072
11073   /* Compute cumulative bit offset for nested component refs
11074      and array refs, and find the ultimate containing object.  */
11075
11076   for (tem = exp;; tem = TREE_OPERAND (tem, 0))
11077     {
11078       if (TREE_CODE (tem) == COMPONENT_REF)
11079         bitpos += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (TREE_OPERAND (tem, 1)));
11080       else
11081         if (TREE_CODE (tem) == ARRAY_REF
11082             && TREE_CODE (TREE_OPERAND (tem, 1)) == INTEGER_CST
11083             && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) == INTEGER_CST)
11084
11085           bitpos += (TREE_INT_CST_LOW (TREE_OPERAND (tem, 1))
11086                      * TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tem)))
11087                      /* * TYPE_SIZE_UNIT (TREE_TYPE (tem)) */);
11088         else
11089           break;
11090     }
11091
11092   bc_expand_expr (tem);
11093
11094
11095   /* For bitfields also push their offset and size */
11096   if (DECL_BIT_FIELD (TREE_OPERAND (exp, 1)))
11097     bc_push_offset_and_size (bitpos, /* DECL_SIZE_UNIT */ (TREE_OPERAND (exp, 1)));
11098   else
11099     if (SIval = bitpos / BITS_PER_UNIT)
11100       bc_emit_instruction (addconstPSI, SIval);
11101
11102   return (TREE_OPERAND (exp, 1));
11103 }
11104
11105
11106 /* Emit code to push two SI constants */
11107 void
11108 bc_push_offset_and_size (offset, size)
11109      HOST_WIDE_INT offset, size;
11110 {
11111   bc_emit_instruction (constSI, offset);
11112   bc_emit_instruction (constSI, size);
11113 }
11114
11115
11116 /* Emit byte code to push the address of the given lvalue expression to
11117    the stack.  If it's a bit field, we also push offset and size info.
11118
11119    Returns innermost component, which allows us to determine not only
11120    its type, but also whether it's a bitfield. */
11121
11122 tree
11123 bc_expand_address (exp)
11124      tree exp;
11125 {
11126   /* Safeguard */
11127   if (!exp || TREE_CODE (exp) == ERROR_MARK)
11128     return (exp);
11129
11130
11131   switch (TREE_CODE (exp))
11132     {
11133     case ARRAY_REF:
11134
11135       return (bc_expand_address (bc_canonicalize_array_ref (exp)));
11136
11137     case COMPONENT_REF:
11138
11139       return (bc_expand_component_address (exp));
11140
11141     case INDIRECT_REF:
11142
11143       bc_expand_expr (TREE_OPERAND (exp, 0));
11144
11145       /* For variable-sized types: retrieve pointer.  Sometimes the
11146          TYPE_SIZE tree is NULL.  Is this a bug or a feature?  Let's
11147          also make sure we have an operand, just in case... */
11148
11149       if (TREE_OPERAND (exp, 0)
11150           && TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)))
11151           && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)))) != INTEGER_CST)
11152         bc_emit_instruction (loadP);
11153
11154       /* If packed, also return offset and size */
11155       if (DECL_BIT_FIELD (TREE_OPERAND (exp, 0)))
11156         
11157         bc_push_offset_and_size (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (TREE_OPERAND (exp, 0))),
11158                                  TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (exp, 0))));
11159
11160       return (TREE_OPERAND (exp, 0));
11161
11162     case FUNCTION_DECL:
11163
11164       bc_load_externaddr_id (DECL_ASSEMBLER_NAME (exp),
11165                              BYTECODE_BC_LABEL (DECL_RTL (exp))->offset);
11166       break;
11167
11168     case PARM_DECL:
11169
11170       bc_load_parmaddr (DECL_RTL (exp));
11171
11172       /* For variable-sized types: retrieve pointer */
11173       if (TYPE_SIZE (TREE_TYPE (exp))
11174           && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST)
11175         bc_emit_instruction (loadP);
11176
11177       /* If packed, also return offset and size */
11178       if (DECL_BIT_FIELD (exp))
11179         bc_push_offset_and_size (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (exp)),
11180                                  TREE_INT_CST_LOW (DECL_SIZE (exp)));
11181
11182       break;
11183
11184     case RESULT_DECL:
11185
11186       bc_emit_instruction (returnP);
11187       break;
11188
11189     case VAR_DECL:
11190
11191 #if 0
11192       if (BYTECODE_LABEL (DECL_RTL (exp)))
11193         bc_load_externaddr (DECL_RTL (exp));
11194 #endif
11195
11196       if (DECL_EXTERNAL (exp))
11197         bc_load_externaddr_id (DECL_ASSEMBLER_NAME (exp),
11198                                (BYTECODE_BC_LABEL (DECL_RTL (exp)))->offset);
11199       else
11200         bc_load_localaddr (DECL_RTL (exp));
11201
11202       /* For variable-sized types: retrieve pointer */
11203       if (TYPE_SIZE (TREE_TYPE (exp))
11204           && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST)
11205         bc_emit_instruction (loadP);
11206
11207       /* If packed, also return offset and size */
11208       if (DECL_BIT_FIELD (exp))
11209         bc_push_offset_and_size (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (exp)),
11210                                  TREE_INT_CST_LOW (DECL_SIZE (exp)));
11211       
11212       break;
11213
11214     case STRING_CST:
11215       {
11216         rtx r;
11217         
11218         bc_emit_bytecode (constP);
11219         r = output_constant_def (exp);
11220         bc_emit_code_labelref (BYTECODE_LABEL (r), BYTECODE_BC_LABEL (r)->offset);
11221
11222 #ifdef DEBUG_PRINT_CODE
11223         fputc ('\n', stderr);
11224 #endif
11225       }
11226       break;
11227
11228     default:
11229
11230       abort();
11231       break;
11232     }
11233
11234   /* Most lvalues don't have components. */
11235   return (exp);
11236 }
11237
11238
11239 /* Emit a type code to be used by the runtime support in handling
11240    parameter passing.   The type code consists of the machine mode
11241    plus the minimal alignment shifted left 8 bits.  */
11242
11243 tree
11244 bc_runtime_type_code (type)
11245      tree type;
11246 {
11247   int val;
11248
11249   switch (TREE_CODE (type))
11250     {
11251     case VOID_TYPE:
11252     case INTEGER_TYPE:
11253     case REAL_TYPE:
11254     case COMPLEX_TYPE:
11255     case ENUMERAL_TYPE:
11256     case POINTER_TYPE:
11257     case RECORD_TYPE:
11258
11259       val = (int) TYPE_MODE (type) | TYPE_ALIGN (type) << 8;
11260       break;
11261
11262     case ERROR_MARK:
11263
11264       val = 0;
11265       break;
11266
11267     default:
11268
11269       abort ();
11270     }
11271   return build_int_2 (val, 0);
11272 }
11273
11274
11275 /* Generate constructor label */
11276 char *
11277 bc_gen_constr_label ()
11278 {
11279   static int label_counter;
11280   static char label[20];
11281
11282   sprintf (label, "*LR%d", label_counter++);
11283
11284   return (obstack_copy0 (&permanent_obstack, label, strlen (label)));
11285 }
11286
11287
11288 /* Evaluate constructor CONSTR and return pointer to it on level one.  We
11289    expand the constructor data as static data, and push a pointer to it.
11290    The pointer is put in the pointer table and is retrieved by a constP
11291    bytecode instruction.  We then loop and store each constructor member in
11292    the corresponding component.  Finally, we return the original pointer on
11293    the stack. */
11294
11295 void
11296 bc_expand_constructor (constr)
11297      tree constr;
11298 {
11299   char *l;
11300   HOST_WIDE_INT ptroffs;
11301   rtx constr_rtx;
11302
11303   
11304   /* Literal constructors are handled as constants, whereas
11305      non-literals are evaluated and stored element by element
11306      into the data segment. */
11307   
11308   /* Allocate space in proper segment and push pointer to space on stack.
11309    */
11310
11311   l = bc_gen_constr_label ();
11312
11313   if (TREE_CONSTANT (constr))
11314     {
11315       text_section ();
11316
11317       bc_emit_const_labeldef (l);
11318       bc_output_constructor (constr, int_size_in_bytes (TREE_TYPE (constr)));
11319     }
11320   else
11321     {
11322       data_section ();
11323
11324       bc_emit_data_labeldef (l);
11325       bc_output_data_constructor (constr);
11326     }
11327
11328   
11329   /* Add reference to pointer table and recall pointer to stack;
11330      this code is common for both types of constructors: literals
11331      and non-literals. */
11332
11333   ptroffs = bc_define_pointer (l);
11334   bc_emit_instruction (constP, ptroffs);
11335
11336   /* This is all that has to be done if it's a literal. */
11337   if (TREE_CONSTANT (constr))
11338     return;
11339
11340
11341   /* At this point, we have the pointer to the structure on top of the stack.
11342      Generate sequences of store_memory calls for the constructor. */
11343   
11344   /* constructor type is structure */
11345   if (TREE_CODE (TREE_TYPE (constr)) == RECORD_TYPE)
11346     {
11347       register tree elt;
11348       
11349       /* If the constructor has fewer fields than the structure,
11350          clear the whole structure first.  */
11351       
11352       if (list_length (CONSTRUCTOR_ELTS (constr))
11353           != list_length (TYPE_FIELDS (TREE_TYPE (constr))))
11354         {
11355           bc_emit_instruction (duplicate);
11356           bc_emit_instruction (constSI, (HOST_WIDE_INT) int_size_in_bytes (TREE_TYPE (constr)));
11357           bc_emit_instruction (clearBLK);
11358         }
11359       
11360       /* Store each element of the constructor into the corresponding
11361          field of TARGET.  */
11362       
11363       for (elt = CONSTRUCTOR_ELTS (constr); elt; elt = TREE_CHAIN (elt))
11364         {
11365           register tree field = TREE_PURPOSE (elt);
11366           register enum machine_mode mode;
11367           int bitsize;
11368           int bitpos;
11369           int unsignedp;
11370           
11371           bitsize = TREE_INT_CST_LOW (DECL_SIZE (field)) /* * DECL_SIZE_UNIT (field) */;
11372           mode = DECL_MODE (field);
11373           unsignedp = TREE_UNSIGNED (field);
11374
11375           bitpos = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
11376           
11377           bc_store_field (elt, bitsize, bitpos, mode, TREE_VALUE (elt), TREE_TYPE (TREE_VALUE (elt)),
11378                           /* The alignment of TARGET is
11379                              at least what its type requires.  */
11380                           VOIDmode, 0,
11381                           TYPE_ALIGN (TREE_TYPE (constr)) / BITS_PER_UNIT,
11382                           int_size_in_bytes (TREE_TYPE (constr)));
11383         }
11384     }
11385   else
11386     
11387     /* Constructor type is array */
11388     if (TREE_CODE (TREE_TYPE (constr)) == ARRAY_TYPE)
11389       {
11390         register tree elt;
11391         register int i;
11392         tree domain = TYPE_DOMAIN (TREE_TYPE (constr));
11393         int minelt = TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain));
11394         int maxelt = TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain));
11395         tree elttype = TREE_TYPE (TREE_TYPE (constr));
11396         
11397         /* If the constructor has fewer fields than the structure,
11398            clear the whole structure first.  */
11399         
11400         if (list_length (CONSTRUCTOR_ELTS (constr)) < maxelt - minelt + 1)
11401           {
11402             bc_emit_instruction (duplicate);
11403             bc_emit_instruction (constSI, (HOST_WIDE_INT) int_size_in_bytes (TREE_TYPE (constr)));
11404             bc_emit_instruction (clearBLK);
11405           }
11406         
11407         
11408         /* Store each element of the constructor into the corresponding
11409            element of TARGET, determined by counting the elements. */
11410         
11411         for (elt = CONSTRUCTOR_ELTS (constr), i = 0;
11412              elt;
11413              elt = TREE_CHAIN (elt), i++)
11414           {
11415             register enum machine_mode mode;
11416             int bitsize;
11417             int bitpos;
11418             int unsignedp;
11419             
11420             mode = TYPE_MODE (elttype);
11421             bitsize = GET_MODE_BITSIZE (mode);
11422             unsignedp = TREE_UNSIGNED (elttype);
11423             
11424             bitpos = (i * TREE_INT_CST_LOW (TYPE_SIZE (elttype))
11425                       /* * TYPE_SIZE_UNIT (elttype) */ );
11426             
11427             bc_store_field (elt, bitsize, bitpos, mode,
11428                             TREE_VALUE (elt), TREE_TYPE (TREE_VALUE (elt)),
11429                             /* The alignment of TARGET is
11430                                at least what its type requires.  */
11431                             VOIDmode, 0,
11432                             TYPE_ALIGN (TREE_TYPE (constr)) / BITS_PER_UNIT,
11433                             int_size_in_bytes (TREE_TYPE (constr)));
11434           }
11435   
11436       }
11437 }
11438
11439
11440 /* Store the value of EXP (an expression tree) into member FIELD of
11441    structure at address on stack, which has type TYPE, mode MODE and
11442    occupies BITSIZE bits, starting BITPOS bits from the beginning of the
11443    structure.
11444
11445    ALIGN is the alignment that TARGET is known to have, measured in bytes.
11446    TOTAL_SIZE is its size in bytes, or -1 if variable.  */
11447
11448 void
11449 bc_store_field (field, bitsize, bitpos, mode, exp, type,
11450                 value_mode, unsignedp, align, total_size)
11451      int bitsize, bitpos;
11452      enum machine_mode mode;
11453      tree field, exp, type;
11454      enum machine_mode value_mode;
11455      int unsignedp;
11456      int align;
11457      int total_size;
11458 {
11459
11460   /* Expand expression and copy pointer */
11461   bc_expand_expr (exp);
11462   bc_emit_instruction (over);
11463
11464
11465   /* If the component is a bit field, we cannot use addressing to access
11466      it.  Use bit-field techniques to store in it.  */
11467
11468   if (DECL_BIT_FIELD (field))
11469     {
11470       bc_store_bit_field (bitpos, bitsize, unsignedp);
11471       return;
11472     }
11473   else
11474     /* Not bit field */
11475     {
11476       HOST_WIDE_INT offset = bitpos / BITS_PER_UNIT;
11477
11478       /* Advance pointer to the desired member */
11479       if (offset)
11480         bc_emit_instruction (addconstPSI, offset);
11481
11482       /* Store */
11483       bc_store_memory (type, field);
11484     }
11485 }
11486
11487
11488 /* Store SI/SU in bitfield */
11489 void
11490 bc_store_bit_field (offset, size, unsignedp)
11491      int offset, size, unsignedp;
11492 {
11493   /* Push bitfield offset and size */
11494   bc_push_offset_and_size (offset, size);
11495
11496   /* Store */
11497   bc_emit_instruction (sstoreBI);
11498 }
11499
11500
11501 /* Load SI/SU from bitfield */
11502 void
11503 bc_load_bit_field (offset, size, unsignedp)
11504      int offset, size, unsignedp;
11505 {
11506   /* Push bitfield offset and size */
11507   bc_push_offset_and_size (offset, size);
11508
11509   /* Load: sign-extend if signed, else zero-extend */
11510   bc_emit_instruction (unsignedp ? zxloadBI : sxloadBI);
11511 }  
11512
11513
11514 /* Adjust interpreter stack by NLEVELS.  Positive means drop NLEVELS
11515    (adjust stack pointer upwards), negative means add that number of
11516    levels (adjust the stack pointer downwards).  Only positive values
11517    normally make sense. */
11518
11519 void
11520 bc_adjust_stack (nlevels)
11521      int nlevels;
11522 {
11523   switch (nlevels)
11524     {
11525     case 0:
11526       break;
11527       
11528     case 2:
11529       bc_emit_instruction (drop);
11530       
11531     case 1:
11532       bc_emit_instruction (drop);
11533       break;
11534       
11535     default:
11536       
11537       bc_emit_instruction (adjstackSI, (HOST_WIDE_INT) nlevels);
11538       stack_depth -= nlevels;
11539     }
11540
11541 #if defined (VALIDATE_STACK_FOR_BC)
11542   VALIDATE_STACK_FOR_BC ();
11543 #endif
11544 }