OSDN Git Service

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