OSDN Git Service

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