OSDN Git Service

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