OSDN Git Service

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