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