OSDN Git Service

*** empty log message ***
[pf3gnuchains/gcc-fork.git] / gcc / expr.c
1 /* Convert tree expression to rtl instructions, for GNU compiler.
2    Copyright (C) 1988, 1992 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 #include "config.h"
22 #include "rtl.h"
23 #include "tree.h"
24 #include "flags.h"
25 #include "function.h"
26 #include "insn-flags.h"
27 #include "insn-codes.h"
28 #include "expr.h"
29 #include "insn-config.h"
30 #include "recog.h"
31 #include "output.h"
32 #include "gvarargs.h"
33 #include "typeclass.h"
34
35 #define CEIL(x,y) (((x) + (y) - 1) / (y))
36
37 /* Decide whether a function's arguments should be processed
38    from first to last or from last to first.  */
39
40 #ifdef STACK_GROWS_DOWNWARD
41 #ifdef PUSH_ROUNDING
42 #define PUSH_ARGS_REVERSED      /* If it's last to first */
43 #endif
44 #endif
45
46 #ifndef STACK_PUSH_CODE
47 #ifdef STACK_GROWS_DOWNWARD
48 #define STACK_PUSH_CODE PRE_DEC
49 #else
50 #define STACK_PUSH_CODE PRE_INC
51 #endif
52 #endif
53
54 /* Like STACK_BOUNDARY but in units of bytes, not bits.  */
55 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
56
57 /* If this is nonzero, we do not bother generating VOLATILE
58    around volatile memory references, and we are willing to
59    output indirect addresses.  If cse is to follow, we reject
60    indirect addresses so a useful potential cse is generated;
61    if it is used only once, instruction combination will produce
62    the same indirect address eventually.  */
63 int cse_not_expected;
64
65 /* Nonzero to generate code for all the subroutines within an
66    expression before generating the upper levels of the expression.
67    Nowadays this is never zero.  */
68 int do_preexpand_calls = 1;
69
70 /* Number of units that we should eventually pop off the stack.
71    These are the arguments to function calls that have already returned.  */
72 int pending_stack_adjust;
73
74 /* Nonzero means stack pops must not be deferred, and deferred stack
75    pops must not be output.  It is nonzero inside a function call,
76    inside a conditional expression, inside a statement expression,
77    and in other cases as well.  */
78 int inhibit_defer_pop;
79
80 /* A list of all cleanups which belong to the arguments of
81    function calls being expanded by expand_call.  */
82 tree cleanups_this_call;
83
84 /* Nonzero means __builtin_saveregs has already been done in this function.
85    The value is the pseudoreg containing the value __builtin_saveregs
86    returned.  */
87 static rtx saveregs_value;
88
89 rtx store_expr ();
90 static void store_constructor ();
91 static rtx store_field ();
92 static rtx expand_builtin ();
93 static rtx compare ();
94 static rtx do_store_flag ();
95 static void preexpand_calls ();
96 static rtx expand_increment ();
97 static void init_queue ();
98
99 void do_pending_stack_adjust ();
100 static void do_jump_for_compare ();
101 static void do_jump_by_parts_equality ();
102 static void do_jump_by_parts_equality_rtx ();
103 static void do_jump_by_parts_greater ();
104
105 /* Record for each mode whether we can move a register directly to or
106    from an object of that mode in memory.  If we can't, we won't try
107    to use that mode directly when accessing a field of that mode.  */
108
109 static char direct_load[NUM_MACHINE_MODES];
110 static char direct_store[NUM_MACHINE_MODES];
111
112 /* MOVE_RATIO is the number of move instructions that is better than
113    a block move.  */
114
115 #ifndef MOVE_RATIO
116 #if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi)
117 #define MOVE_RATIO 2
118 #else
119 /* A value of around 6 would minimize code size; infinity would minimize
120    execution time.  */
121 #define MOVE_RATIO 15
122 #endif
123 #endif
124
125 /* SLOW_UNALIGNED_ACCESS is non-zero if unaligned accesses are very slow. */
126
127 #ifndef SLOW_UNALIGNED_ACCESS
128 #define SLOW_UNALIGNED_ACCESS 0
129 #endif
130 \f
131 /* This is run once per compilation to set up which modes can be used
132    directly in memory.  */
133
134 void
135 init_expr_once ()
136 {
137   rtx insn, pat;
138   enum machine_mode mode;
139   rtx mem = gen_rtx (MEM, VOIDmode, stack_pointer_rtx);
140
141   start_sequence ();
142   insn = emit_insn (gen_rtx (SET, 0, 0));
143   pat = PATTERN (insn);
144
145   for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
146        mode = (enum machine_mode) ((int) mode + 1))
147     {
148       int regno;
149       rtx reg;
150       int num_clobbers;
151
152       direct_load[(int) mode] = direct_store[(int) mode] = 0;
153       PUT_MODE (mem, mode);
154
155       /* Find a register that can be used in this mode, if any.  */
156       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
157         if (HARD_REGNO_MODE_OK (regno, mode))
158           break;
159
160       if (regno == FIRST_PSEUDO_REGISTER)
161         continue;
162
163       reg = gen_rtx (REG, mode, regno);
164
165       SET_SRC (pat) = mem;
166       SET_DEST (pat) = reg;
167       direct_load[(int) mode] = (recog (pat, insn, &num_clobbers)) >= 0;
168
169       SET_SRC (pat) = reg;
170       SET_DEST (pat) = mem;
171       direct_store[(int) mode] = (recog (pat, insn, &num_clobbers)) >= 0;
172     }
173
174   end_sequence ();
175 }
176       
177 /* This is run at the start of compiling a function.  */
178
179 void
180 init_expr ()
181 {
182   init_queue ();
183
184   pending_stack_adjust = 0;
185   inhibit_defer_pop = 0;
186   cleanups_this_call = 0;
187   saveregs_value = 0;
188   forced_labels = 0;
189 }
190
191 /* Save all variables describing the current status into the structure *P.
192    This is used before starting a nested function.  */
193
194 void
195 save_expr_status (p)
196      struct function *p;
197 {
198   /* Instead of saving the postincrement queue, empty it.  */
199   emit_queue ();
200
201   p->pending_stack_adjust = pending_stack_adjust;
202   p->inhibit_defer_pop = inhibit_defer_pop;
203   p->cleanups_this_call = cleanups_this_call;
204   p->saveregs_value = saveregs_value;
205   p->forced_labels = forced_labels;
206
207   pending_stack_adjust = 0;
208   inhibit_defer_pop = 0;
209   cleanups_this_call = 0;
210   saveregs_value = 0;
211   forced_labels = 0;
212 }
213
214 /* Restore all variables describing the current status from the structure *P.
215    This is used after a nested function.  */
216
217 void
218 restore_expr_status (p)
219      struct function *p;
220 {
221   pending_stack_adjust = p->pending_stack_adjust;
222   inhibit_defer_pop = p->inhibit_defer_pop;
223   cleanups_this_call = p->cleanups_this_call;
224   saveregs_value = p->saveregs_value;
225   forced_labels = p->forced_labels;
226 }
227 \f
228 /* Manage the queue of increment instructions to be output
229    for POSTINCREMENT_EXPR expressions, etc.  */
230
231 static rtx pending_chain;
232
233 /* Queue up to increment (or change) VAR later.  BODY says how:
234    BODY should be the same thing you would pass to emit_insn
235    to increment right away.  It will go to emit_insn later on.
236
237    The value is a QUEUED expression to be used in place of VAR
238    where you want to guarantee the pre-incrementation value of VAR.  */
239
240 static rtx
241 enqueue_insn (var, body)
242      rtx var, body;
243 {
244   pending_chain = gen_rtx (QUEUED, GET_MODE (var),
245                            var, NULL_RTX, NULL_RTX, body, pending_chain);
246   return pending_chain;
247 }
248
249 /* Use protect_from_queue to convert a QUEUED expression
250    into something that you can put immediately into an instruction.
251    If the queued incrementation has not happened yet,
252    protect_from_queue returns the variable itself.
253    If the incrementation has happened, protect_from_queue returns a temp
254    that contains a copy of the old value of the variable.
255
256    Any time an rtx which might possibly be a QUEUED is to be put
257    into an instruction, it must be passed through protect_from_queue first.
258    QUEUED expressions are not meaningful in instructions.
259
260    Do not pass a value through protect_from_queue and then hold
261    on to it for a while before putting it in an instruction!
262    If the queue is flushed in between, incorrect code will result.  */
263
264 rtx
265 protect_from_queue (x, modify)
266      register rtx x;
267      int modify;
268 {
269   register RTX_CODE code = GET_CODE (x);
270
271 #if 0  /* A QUEUED can hang around after the queue is forced out.  */
272   /* Shortcut for most common case.  */
273   if (pending_chain == 0)
274     return x;
275 #endif
276
277   if (code != QUEUED)
278     {
279       /* A special hack for read access to (MEM (QUEUED ...))
280          to facilitate use of autoincrement.
281          Make a copy of the contents of the memory location
282          rather than a copy of the address, but not
283          if the value is of mode BLKmode.  */
284       if (code == MEM && GET_MODE (x) != BLKmode
285           && GET_CODE (XEXP (x, 0)) == QUEUED && !modify)
286         {
287           register rtx y = XEXP (x, 0);
288           XEXP (x, 0) = QUEUED_VAR (y);
289           if (QUEUED_INSN (y))
290             {
291               register rtx temp = gen_reg_rtx (GET_MODE (x));
292               emit_insn_before (gen_move_insn (temp, x),
293                                 QUEUED_INSN (y));
294               return temp;
295             }
296           return x;
297         }
298       /* Otherwise, recursively protect the subexpressions of all
299          the kinds of rtx's that can contain a QUEUED.  */
300       if (code == MEM)
301         XEXP (x, 0) = protect_from_queue (XEXP (x, 0), 0);
302       else if (code == PLUS || code == MULT)
303         {
304           XEXP (x, 0) = protect_from_queue (XEXP (x, 0), 0);
305           XEXP (x, 1) = protect_from_queue (XEXP (x, 1), 0);
306         }
307       return x;
308     }
309   /* If the increment has not happened, use the variable itself.  */
310   if (QUEUED_INSN (x) == 0)
311     return QUEUED_VAR (x);
312   /* If the increment has happened and a pre-increment copy exists,
313      use that copy.  */
314   if (QUEUED_COPY (x) != 0)
315     return QUEUED_COPY (x);
316   /* The increment has happened but we haven't set up a pre-increment copy.
317      Set one up now, and use it.  */
318   QUEUED_COPY (x) = gen_reg_rtx (GET_MODE (QUEUED_VAR (x)));
319   emit_insn_before (gen_move_insn (QUEUED_COPY (x), QUEUED_VAR (x)),
320                     QUEUED_INSN (x));
321   return QUEUED_COPY (x);
322 }
323
324 /* Return nonzero if X contains a QUEUED expression:
325    if it contains anything that will be altered by a queued increment.
326    We handle only combinations of MEM, PLUS, MINUS and MULT operators
327    since memory addresses generally contain only those.  */
328
329 static int
330 queued_subexp_p (x)
331      rtx x;
332 {
333   register enum rtx_code code = GET_CODE (x);
334   switch (code)
335     {
336     case QUEUED:
337       return 1;
338     case MEM:
339       return queued_subexp_p (XEXP (x, 0));
340     case MULT:
341     case PLUS:
342     case MINUS:
343       return queued_subexp_p (XEXP (x, 0))
344         || queued_subexp_p (XEXP (x, 1));
345     }
346   return 0;
347 }
348
349 /* Perform all the pending incrementations.  */
350
351 void
352 emit_queue ()
353 {
354   register rtx p;
355   while (p = pending_chain)
356     {
357       QUEUED_INSN (p) = emit_insn (QUEUED_BODY (p));
358       pending_chain = QUEUED_NEXT (p);
359     }
360 }
361
362 static void
363 init_queue ()
364 {
365   if (pending_chain)
366     abort ();
367 }
368 \f
369 /* Copy data from FROM to TO, where the machine modes are not the same.
370    Both modes may be integer, or both may be floating.
371    UNSIGNEDP should be nonzero if FROM is an unsigned type.
372    This causes zero-extension instead of sign-extension.  */
373
374 void
375 convert_move (to, from, unsignedp)
376      register rtx to, from;
377      int unsignedp;
378 {
379   enum machine_mode to_mode = GET_MODE (to);
380   enum machine_mode from_mode = GET_MODE (from);
381   int to_real = GET_MODE_CLASS (to_mode) == MODE_FLOAT;
382   int from_real = GET_MODE_CLASS (from_mode) == MODE_FLOAT;
383   enum insn_code code;
384   rtx libcall;
385
386   /* rtx code for making an equivalent value.  */
387   enum rtx_code equiv_code = (unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
388
389   to = protect_from_queue (to, 1);
390   from = protect_from_queue (from, 0);
391
392   if (to_real != from_real)
393     abort ();
394
395   if (to_mode == from_mode
396       || (from_mode == VOIDmode && CONSTANT_P (from)))
397     {
398       emit_move_insn (to, from);
399       return;
400     }
401
402   if (to_real)
403     {
404 #ifdef HAVE_extendsfdf2
405       if (HAVE_extendsfdf2 && from_mode == SFmode && to_mode == DFmode)
406         {
407           emit_unop_insn (CODE_FOR_extendsfdf2, to, from, UNKNOWN);
408           return;
409         }
410 #endif
411 #ifdef HAVE_extendsfxf2
412       if (HAVE_extendsfxf2 && from_mode == SFmode && to_mode == XFmode)
413         {
414           emit_unop_insn (CODE_FOR_extendsfxf2, to, from, UNKNOWN);
415           return;
416         }
417 #endif
418 #ifdef HAVE_extendsftf2
419       if (HAVE_extendsftf2 && from_mode == SFmode && to_mode == TFmode)
420         {
421           emit_unop_insn (CODE_FOR_extendsftf2, to, from, UNKNOWN);
422           return;
423         }
424 #endif
425 #ifdef HAVE_extenddfxf2
426       if (HAVE_extenddfxf2 && from_mode == DFmode && to_mode == XFmode)
427         {
428           emit_unop_insn (CODE_FOR_extenddfxf2, to, from, UNKNOWN);
429           return;
430         }
431 #endif
432 #ifdef HAVE_extenddftf2
433       if (HAVE_extenddftf2 && from_mode == DFmode && to_mode == TFmode)
434         {
435           emit_unop_insn (CODE_FOR_extenddftf2, to, from, UNKNOWN);
436           return;
437         }
438 #endif
439 #ifdef HAVE_truncdfsf2
440       if (HAVE_truncdfsf2 && from_mode == DFmode && to_mode == SFmode)
441         {
442           emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
443           return;
444         }
445 #endif
446 #ifdef HAVE_truncxfsf2
447       if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)
448         {
449           emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);
450           return;
451         }
452 #endif
453 #ifdef HAVE_trunctfsf2
454       if (HAVE_trunctfsf2 && from_mode == TFmode && to_mode == SFmode)
455         {
456           emit_unop_insn (CODE_FOR_trunctfsf2, to, from, UNKNOWN);
457           return;
458         }
459 #endif
460 #ifdef HAVE_truncxfdf2
461       if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)
462         {
463           emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);
464           return;
465         }
466 #endif
467 #ifdef HAVE_trunctfdf2
468       if (HAVE_trunctfdf2 && from_mode == TFmode && to_mode == DFmode)
469         {
470           emit_unop_insn (CODE_FOR_trunctfdf2, to, from, UNKNOWN);
471           return;
472         }
473 #endif
474
475       libcall = (rtx) 0;
476       switch (from_mode)
477         {
478         case SFmode:
479           switch (to_mode)
480             {
481             case DFmode:
482               libcall = extendsfdf2_libfunc;
483               break;
484
485             case XFmode:
486               libcall = extendsfxf2_libfunc;
487               break;
488
489             case TFmode:
490               libcall = extendsftf2_libfunc;
491               break;
492             }
493           break;
494
495         case DFmode:
496           switch (to_mode)
497             {
498             case SFmode:
499               libcall = truncdfsf2_libfunc;
500               break;
501
502             case XFmode:
503               libcall = extenddfxf2_libfunc;
504               break;
505
506             case TFmode:
507               libcall = extenddftf2_libfunc;
508               break;
509             }
510           break;
511
512         case XFmode:
513           switch (to_mode)
514             {
515             case SFmode:
516               libcall = truncxfsf2_libfunc;
517               break;
518
519             case DFmode:
520               libcall = truncxfdf2_libfunc;
521               break;
522             }
523           break;
524
525         case TFmode:
526           switch (to_mode)
527             {
528             case SFmode:
529               libcall = trunctfsf2_libfunc;
530               break;
531
532             case DFmode:
533               libcall = trunctfdf2_libfunc;
534               break;
535             }
536           break;
537         }
538
539       if (libcall == (rtx) 0)
540         /* This conversion is not implemented yet.  */
541         abort ();
542
543       emit_library_call (libcall, 1, to_mode, 1, from, from_mode);
544       emit_move_insn (to, hard_libcall_value (to_mode));
545       return;
546     }
547
548   /* Now both modes are integers.  */
549
550   /* Handle expanding beyond a word.  */
551   if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode)
552       && GET_MODE_BITSIZE (to_mode) > BITS_PER_WORD)
553     {
554       rtx insns;
555       rtx lowpart;
556       rtx fill_value;
557       rtx lowfrom;
558       int i;
559       enum machine_mode lowpart_mode;
560       int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
561
562       /* Try converting directly if the insn is supported.  */
563       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
564           != CODE_FOR_nothing)
565         {
566           emit_unop_insn (code, to, from, equiv_code);
567           return;
568         }
569       /* Next, try converting via full word.  */
570       else if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD
571                && ((code = can_extend_p (to_mode, word_mode, unsignedp))
572                    != CODE_FOR_nothing))
573         {
574           convert_move (gen_lowpart (word_mode, to), from, unsignedp);
575           emit_unop_insn (code, to,
576                           gen_lowpart (word_mode, to), equiv_code);
577           return;
578         }
579
580       /* No special multiword conversion insn; do it by hand.  */
581       start_sequence ();
582
583       /* Get a copy of FROM widened to a word, if necessary.  */
584       if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD)
585         lowpart_mode = word_mode;
586       else
587         lowpart_mode = from_mode;
588
589       lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
590
591       lowpart = gen_lowpart (lowpart_mode, to);
592       emit_move_insn (lowpart, lowfrom);
593
594       /* Compute the value to put in each remaining word.  */
595       if (unsignedp)
596         fill_value = const0_rtx;
597       else
598         {
599 #ifdef HAVE_slt
600           if (HAVE_slt
601               && insn_operand_mode[(int) CODE_FOR_slt][0] == word_mode
602               && STORE_FLAG_VALUE == -1)
603             {
604               emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,
605                              lowpart_mode, 0, 0);
606               fill_value = gen_reg_rtx (word_mode);
607               emit_insn (gen_slt (fill_value));
608             }
609           else
610 #endif
611             {
612               fill_value
613                 = expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom,
614                                 size_int (GET_MODE_BITSIZE (lowpart_mode) - 1),
615                                 NULL_RTX, 0);
616               fill_value = convert_to_mode (word_mode, fill_value, 1);
617             }
618         }
619
620       /* Fill the remaining words.  */
621       for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
622         {
623           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
624           rtx subword = operand_subword (to, index, 1, to_mode);
625
626           if (subword == 0)
627             abort ();
628
629           if (fill_value != subword)
630             emit_move_insn (subword, fill_value);
631         }
632
633       insns = get_insns ();
634       end_sequence ();
635
636       emit_no_conflict_block (insns, to, from, NULL_RTX,
637                               gen_rtx (equiv_code, to_mode, from));
638       return;
639     }
640
641   if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD)
642     {
643       convert_move (to, gen_lowpart (word_mode, from), 0);
644       return;
645     }
646
647   /* Handle pointer conversion */                       /* SPEE 900220 */
648   if (to_mode == PSImode)
649     {
650       if (from_mode != SImode)
651         from = convert_to_mode (SImode, from, unsignedp);
652
653 #ifdef HAVE_truncsipsi
654       if (HAVE_truncsipsi)
655         {
656           emit_unop_insn (CODE_FOR_truncsipsi, to, from, UNKNOWN);
657           return;
658         }
659 #endif /* HAVE_truncsipsi */
660       abort ();
661     }
662
663   if (from_mode == PSImode)
664     {
665       if (to_mode != SImode)
666         {
667           from = convert_to_mode (SImode, from, unsignedp);
668           from_mode = SImode;
669         }
670       else
671         {
672 #ifdef HAVE_extendpsisi
673           if (HAVE_extendpsisi)
674             {
675               emit_unop_insn (CODE_FOR_extendpsisi, to, from, UNKNOWN);
676               return;
677             }
678 #endif /* HAVE_extendpsisi */
679           abort ();
680         }
681     }
682
683   /* Now follow all the conversions between integers
684      no more than a word long.  */
685
686   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
687   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
688       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
689                                 GET_MODE_BITSIZE (from_mode))
690       && ((GET_CODE (from) == MEM
691            && ! MEM_VOLATILE_P (from)
692            && direct_load[(int) to_mode]
693            && ! mode_dependent_address_p (XEXP (from, 0)))
694           || GET_CODE (from) == REG
695           || GET_CODE (from) == SUBREG))
696     {
697       emit_move_insn (to, gen_lowpart (to_mode, from));
698       return;
699     }
700
701   /* For truncation, usually we can just refer to FROM in a narrower mode.  */
702   if (GET_MODE_BITSIZE (to_mode) > GET_MODE_BITSIZE (from_mode))
703     {
704       /* Convert directly if that works.  */
705       if ((code = can_extend_p (to_mode, from_mode, unsignedp))
706           != CODE_FOR_nothing)
707         {
708           emit_unop_insn (code, to, from, equiv_code);
709           return;
710         }
711       else
712         {
713           enum machine_mode intermediate;
714
715           /* Search for a mode to convert via.  */
716           for (intermediate = from_mode; intermediate != VOIDmode;
717                intermediate = GET_MODE_WIDER_MODE (intermediate))
718             if ((can_extend_p (to_mode, intermediate, unsignedp)
719                  != CODE_FOR_nothing)
720                 && (can_extend_p (intermediate, from_mode, unsignedp)
721                     != CODE_FOR_nothing))
722               {
723                 convert_move (to, convert_to_mode (intermediate, from,
724                                                    unsignedp), unsignedp);
725                 return;
726               }
727
728           /* No suitable intermediate mode.  */
729           abort ();
730         }
731     }
732
733   /* Support special truncate insns for certain modes.  */ 
734
735   if (from_mode == DImode && to_mode == SImode)
736     {
737 #ifdef HAVE_truncdisi2
738       if (HAVE_truncdisi2)
739         {
740           emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);
741           return;
742         }
743 #endif
744       convert_move (to, force_reg (from_mode, from), unsignedp);
745       return;
746     }
747
748   if (from_mode == DImode && to_mode == HImode)
749     {
750 #ifdef HAVE_truncdihi2
751       if (HAVE_truncdihi2)
752         {
753           emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);
754           return;
755         }
756 #endif
757       convert_move (to, force_reg (from_mode, from), unsignedp);
758       return;
759     }
760
761   if (from_mode == DImode && to_mode == QImode)
762     {
763 #ifdef HAVE_truncdiqi2
764       if (HAVE_truncdiqi2)
765         {
766           emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);
767           return;
768         }
769 #endif
770       convert_move (to, force_reg (from_mode, from), unsignedp);
771       return;
772     }
773
774   if (from_mode == SImode && to_mode == HImode)
775     {
776 #ifdef HAVE_truncsihi2
777       if (HAVE_truncsihi2)
778         {
779           emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);
780           return;
781         }
782 #endif
783       convert_move (to, force_reg (from_mode, from), unsignedp);
784       return;
785     }
786
787   if (from_mode == SImode && to_mode == QImode)
788     {
789 #ifdef HAVE_truncsiqi2
790       if (HAVE_truncsiqi2)
791         {
792           emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);
793           return;
794         }
795 #endif
796       convert_move (to, force_reg (from_mode, from), unsignedp);
797       return;
798     }
799
800   if (from_mode == HImode && to_mode == QImode)
801     {
802 #ifdef HAVE_trunchiqi2
803       if (HAVE_trunchiqi2)
804         {
805           emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);
806           return;
807         }
808 #endif
809       convert_move (to, force_reg (from_mode, from), unsignedp);
810       return;
811     }
812
813   /* Handle truncation of volatile memrefs, and so on;
814      the things that couldn't be truncated directly,
815      and for which there was no special instruction.  */
816   if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))
817     {
818       rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
819       emit_move_insn (to, temp);
820       return;
821     }
822
823   /* Mode combination is not recognized.  */
824   abort ();
825 }
826
827 /* Return an rtx for a value that would result
828    from converting X to mode MODE.
829    Both X and MODE may be floating, or both integer.
830    UNSIGNEDP is nonzero if X is an unsigned value.
831    This can be done by referring to a part of X in place
832    or by copying to a new temporary with conversion.  */
833
834 rtx
835 convert_to_mode (mode, x, unsignedp)
836      enum machine_mode mode;
837      rtx x;
838      int unsignedp;
839 {
840   register rtx temp;
841
842   x = protect_from_queue (x, 0);
843
844   if (mode == GET_MODE (x))
845     return x;
846
847   /* There is one case that we must handle specially: If we are converting
848      a CONST_INT into a mode whose size is twice HOST_BITS_PER_WIDE_INT and
849      we are to interpret the constant as unsigned, gen_lowpart will do
850      the wrong if the constant appears negative.  What we want to do is
851      make the high-order word of the constant zero, not all ones.  */
852
853   if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
854       && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
855       && GET_CODE (x) == CONST_INT && INTVAL (x) < 0)
856     return immed_double_const (INTVAL (x), (HOST_WIDE_INT) 0, mode);
857
858   /* We can do this with a gen_lowpart if both desired and current modes
859      are integer, and this is either a constant integer, a register, or a
860      non-volatile MEM.  Except for the constant case, we must be narrowing
861      the operand.  */
862
863   if (GET_CODE (x) == CONST_INT
864       || (GET_MODE_CLASS (mode) == MODE_INT
865           && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
866           && (GET_CODE (x) == CONST_DOUBLE
867               || (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (x))
868                   && ((GET_CODE (x) == MEM && ! MEM_VOLATILE_P (x))
869                       && direct_load[(int) mode]
870                       || GET_CODE (x) == REG)))))
871     return gen_lowpart (mode, x);
872
873   temp = gen_reg_rtx (mode);
874   convert_move (temp, x, unsignedp);
875   return temp;
876 }
877 \f
878 /* Generate several move instructions to copy LEN bytes
879    from block FROM to block TO.  (These are MEM rtx's with BLKmode).
880    The caller must pass FROM and TO
881     through protect_from_queue before calling.
882    ALIGN (in bytes) is maximum alignment we can assume.  */
883
884 struct move_by_pieces
885 {
886   rtx to;
887   rtx to_addr;
888   int autinc_to;
889   int explicit_inc_to;
890   rtx from;
891   rtx from_addr;
892   int autinc_from;
893   int explicit_inc_from;
894   int len;
895   int offset;
896   int reverse;
897 };
898
899 static void move_by_pieces_1 ();
900 static int move_by_pieces_ninsns ();
901
902 static void
903 move_by_pieces (to, from, len, align)
904      rtx to, from;
905      int len, align;
906 {
907   struct move_by_pieces data;
908   rtx to_addr = XEXP (to, 0), from_addr = XEXP (from, 0);
909   int max_size = MOVE_MAX + 1;
910
911   data.offset = 0;
912   data.to_addr = to_addr;
913   data.from_addr = from_addr;
914   data.to = to;
915   data.from = from;
916   data.autinc_to
917     = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
918        || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
919   data.autinc_from
920     = (GET_CODE (from_addr) == PRE_INC || GET_CODE (from_addr) == PRE_DEC
921        || GET_CODE (from_addr) == POST_INC
922        || GET_CODE (from_addr) == POST_DEC);
923
924   data.explicit_inc_from = 0;
925   data.explicit_inc_to = 0;
926   data.reverse
927     = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
928   if (data.reverse) data.offset = len;
929   data.len = len;
930
931   /* If copying requires more than two move insns,
932      copy addresses to registers (to make displacements shorter)
933      and use post-increment if available.  */
934   if (!(data.autinc_from && data.autinc_to)
935       && move_by_pieces_ninsns (len, align) > 2)
936     {
937 #ifdef HAVE_PRE_DECREMENT
938       if (data.reverse && ! data.autinc_from)
939         {
940           data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
941           data.autinc_from = 1;
942           data.explicit_inc_from = -1;
943         }
944 #endif
945 #ifdef HAVE_POST_INCREMENT
946       if (! data.autinc_from)
947         {
948           data.from_addr = copy_addr_to_reg (from_addr);
949           data.autinc_from = 1;
950           data.explicit_inc_from = 1;
951         }
952 #endif
953       if (!data.autinc_from && CONSTANT_P (from_addr))
954         data.from_addr = copy_addr_to_reg (from_addr);
955 #ifdef HAVE_PRE_DECREMENT
956       if (data.reverse && ! data.autinc_to)
957         {
958           data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
959           data.autinc_to = 1;
960           data.explicit_inc_to = -1;
961         }
962 #endif
963 #ifdef HAVE_POST_INCREMENT
964       if (! data.reverse && ! data.autinc_to)
965         {
966           data.to_addr = copy_addr_to_reg (to_addr);
967           data.autinc_to = 1;
968           data.explicit_inc_to = 1;
969         }
970 #endif
971       if (!data.autinc_to && CONSTANT_P (to_addr))
972         data.to_addr = copy_addr_to_reg (to_addr);
973     }
974
975   if (! (STRICT_ALIGNMENT || SLOW_UNALIGNED_ACCESS)
976       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
977     align = MOVE_MAX;
978
979   /* First move what we can in the largest integer mode, then go to
980      successively smaller modes.  */
981
982   while (max_size > 1)
983     {
984       enum machine_mode mode = VOIDmode, tmode;
985       enum insn_code icode;
986
987       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
988            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
989         if (GET_MODE_SIZE (tmode) < max_size)
990           mode = tmode;
991
992       if (mode == VOIDmode)
993         break;
994
995       icode = mov_optab->handlers[(int) mode].insn_code;
996       if (icode != CODE_FOR_nothing
997           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
998                            GET_MODE_SIZE (mode)))
999         move_by_pieces_1 (GEN_FCN (icode), mode, &data);
1000
1001       max_size = GET_MODE_SIZE (mode);
1002     }
1003
1004   /* The code above should have handled everything.  */
1005   if (data.len != 0)
1006     abort ();
1007 }
1008
1009 /* Return number of insns required to move L bytes by pieces.
1010    ALIGN (in bytes) is maximum alignment we can assume.  */
1011
1012 static int
1013 move_by_pieces_ninsns (l, align)
1014      unsigned int l;
1015      int align;
1016 {
1017   register int n_insns = 0;
1018   int max_size = MOVE_MAX + 1;
1019
1020   if (! (STRICT_ALIGNMENT || SLOW_UNALIGNED_ACCESS)
1021       || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1022     align = MOVE_MAX;
1023
1024   while (max_size > 1)
1025     {
1026       enum machine_mode mode = VOIDmode, tmode;
1027       enum insn_code icode;
1028
1029       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1030            tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
1031         if (GET_MODE_SIZE (tmode) < max_size)
1032           mode = tmode;
1033
1034       if (mode == VOIDmode)
1035         break;
1036
1037       icode = mov_optab->handlers[(int) mode].insn_code;
1038       if (icode != CODE_FOR_nothing
1039           && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
1040                            GET_MODE_SIZE (mode)))
1041         n_insns += l / GET_MODE_SIZE (mode), l %= GET_MODE_SIZE (mode);
1042
1043       max_size = GET_MODE_SIZE (mode);
1044     }
1045
1046   return n_insns;
1047 }
1048
1049 /* Subroutine of move_by_pieces.  Move as many bytes as appropriate
1050    with move instructions for mode MODE.  GENFUN is the gen_... function
1051    to make a move insn for that mode.  DATA has all the other info.  */
1052
1053 static void
1054 move_by_pieces_1 (genfun, mode, data)
1055      rtx (*genfun) ();
1056      enum machine_mode mode;
1057      struct move_by_pieces *data;
1058 {
1059   register int size = GET_MODE_SIZE (mode);
1060   register rtx to1, from1;
1061
1062   while (data->len >= size)
1063     {
1064       if (data->reverse) data->offset -= size;
1065
1066       to1 = (data->autinc_to
1067              ? gen_rtx (MEM, mode, data->to_addr)
1068              : change_address (data->to, mode,
1069                                plus_constant (data->to_addr, data->offset)));
1070       from1 =
1071         (data->autinc_from
1072          ? gen_rtx (MEM, mode, data->from_addr)
1073          : change_address (data->from, mode,
1074                            plus_constant (data->from_addr, data->offset)));
1075
1076 #ifdef HAVE_PRE_DECREMENT
1077       if (data->explicit_inc_to < 0)
1078         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
1079       if (data->explicit_inc_from < 0)
1080         emit_insn (gen_add2_insn (data->from_addr, GEN_INT (-size)));
1081 #endif
1082
1083       emit_insn ((*genfun) (to1, from1));
1084 #ifdef HAVE_POST_INCREMENT
1085       if (data->explicit_inc_to > 0)
1086         emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
1087       if (data->explicit_inc_from > 0)
1088         emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size)));
1089 #endif
1090
1091       if (! data->reverse) data->offset += size;
1092
1093       data->len -= size;
1094     }
1095 }
1096 \f
1097 /* Emit code to move a block Y to a block X.
1098    This may be done with string-move instructions,
1099    with multiple scalar move instructions, or with a library call.
1100
1101    Both X and Y must be MEM rtx's (perhaps inside VOLATILE)
1102    with mode BLKmode.
1103    SIZE is an rtx that says how long they are.
1104    ALIGN is the maximum alignment we can assume they have,
1105    measured in bytes.  */
1106
1107 void
1108 emit_block_move (x, y, size, align)
1109      rtx x, y;
1110      rtx size;
1111      int align;
1112 {
1113   if (GET_MODE (x) != BLKmode)
1114     abort ();
1115
1116   if (GET_MODE (y) != BLKmode)
1117     abort ();
1118
1119   x = protect_from_queue (x, 1);
1120   y = protect_from_queue (y, 0);
1121
1122   if (GET_CODE (x) != MEM)
1123     abort ();
1124   if (GET_CODE (y) != MEM)
1125     abort ();
1126   if (size == 0)
1127     abort ();
1128
1129   if (GET_CODE (size) == CONST_INT
1130       && (move_by_pieces_ninsns (INTVAL (size), align) < MOVE_RATIO))
1131     move_by_pieces (x, y, INTVAL (size), align);
1132   else
1133     {
1134       /* Try the most limited insn first, because there's no point
1135          including more than one in the machine description unless
1136          the more limited one has some advantage.  */
1137 #ifdef HAVE_movstrqi
1138       if (HAVE_movstrqi
1139           && GET_CODE (size) == CONST_INT
1140           && ((unsigned) INTVAL (size)
1141               < (1 << (GET_MODE_BITSIZE (QImode) - 1))))
1142         {
1143           rtx insn = gen_movstrqi (x, y, size, GEN_INT (align));
1144           if (insn)
1145             {
1146               emit_insn (insn);
1147               return;
1148             }
1149         }
1150 #endif
1151 #ifdef HAVE_movstrhi
1152       if (HAVE_movstrhi
1153           && GET_CODE (size) == CONST_INT
1154           && ((unsigned) INTVAL (size)
1155               < (1 << (GET_MODE_BITSIZE (HImode) - 1))))
1156         {
1157           rtx insn = gen_movstrhi (x, y, size, GEN_INT (align));
1158           if (insn)
1159             {
1160               emit_insn (insn);
1161               return;
1162             }
1163         }
1164 #endif
1165 #ifdef HAVE_movstrsi
1166       if (HAVE_movstrsi)
1167         {
1168           rtx insn = gen_movstrsi (x, y, size, GEN_INT (align));
1169           if (insn)
1170             {
1171               emit_insn (insn);
1172               return;
1173             }
1174         }
1175 #endif
1176 #ifdef HAVE_movstrdi
1177       if (HAVE_movstrdi)
1178         {
1179           rtx insn = gen_movstrdi (x, y, size, GEN_INT (align));
1180           if (insn)
1181             {
1182               emit_insn (insn);
1183               return;
1184             }
1185         }
1186 #endif
1187
1188 #ifdef TARGET_MEM_FUNCTIONS
1189       emit_library_call (memcpy_libfunc, 1,
1190                          VOIDmode, 3, XEXP (x, 0), Pmode,
1191                          XEXP (y, 0), Pmode,
1192                          convert_to_mode (Pmode, size, 1), Pmode);
1193 #else
1194       emit_library_call (bcopy_libfunc, 1,
1195                          VOIDmode, 3, XEXP (y, 0), Pmode,
1196                          XEXP (x, 0), Pmode,
1197                          convert_to_mode (Pmode, size, 1), Pmode);
1198 #endif
1199     }
1200 }
1201 \f
1202 /* Copy all or part of a value X into registers starting at REGNO.
1203    The number of registers to be filled is NREGS.  */
1204
1205 void
1206 move_block_to_reg (regno, x, nregs, mode)
1207      int regno;
1208      rtx x;
1209      int nregs;
1210      enum machine_mode mode;
1211 {
1212   int i;
1213   rtx pat, last;
1214
1215   if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
1216     x = validize_mem (force_const_mem (mode, x));
1217
1218   /* See if the machine can do this with a load multiple insn.  */
1219 #ifdef HAVE_load_multiple
1220   last = get_last_insn ();
1221   pat = gen_load_multiple (gen_rtx (REG, word_mode, regno), x,
1222                            GEN_INT (nregs));
1223   if (pat)
1224     {
1225       emit_insn (pat);
1226       return;
1227     }
1228   else
1229     delete_insns_since (last);
1230 #endif
1231
1232   for (i = 0; i < nregs; i++)
1233     emit_move_insn (gen_rtx (REG, word_mode, regno + i),
1234                     operand_subword_force (x, i, mode));
1235 }
1236
1237 /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
1238    The number of registers to be filled is NREGS.  */
1239
1240 void
1241 move_block_from_reg (regno, x, nregs)
1242      int regno;
1243      rtx x;
1244      int nregs;
1245 {
1246   int i;
1247   rtx pat, last;
1248
1249   /* See if the machine can do this with a store multiple insn.  */
1250 #ifdef HAVE_store_multiple
1251   last = get_last_insn ();
1252   pat = gen_store_multiple (x, gen_rtx (REG, word_mode, regno),
1253                             GEN_INT (nregs));
1254   if (pat)
1255     {
1256       emit_insn (pat);
1257       return;
1258     }
1259   else
1260     delete_insns_since (last);
1261 #endif
1262
1263   for (i = 0; i < nregs; i++)
1264     {
1265       rtx tem = operand_subword (x, i, 1, BLKmode);
1266
1267       if (tem == 0)
1268         abort ();
1269
1270       emit_move_insn (tem, gen_rtx (REG, word_mode, regno + i));
1271     }
1272 }
1273
1274 /* Mark NREGS consecutive regs, starting at REGNO, as being live now.  */
1275
1276 void
1277 use_regs (regno, nregs)
1278      int regno;
1279      int nregs;
1280 {
1281   int i;
1282
1283   for (i = 0; i < nregs; i++)
1284     emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, word_mode, regno + i)));
1285 }
1286 \f
1287 /* Write zeros through the storage of OBJECT.
1288    If OBJECT has BLKmode, SIZE is its length in bytes.  */
1289
1290 void
1291 clear_storage (object, size)
1292      rtx object;
1293      int size;
1294 {
1295   if (GET_MODE (object) == BLKmode)
1296     {
1297 #ifdef TARGET_MEM_FUNCTIONS
1298       emit_library_call (memset_libfunc, 1,
1299                          VOIDmode, 3,
1300                          XEXP (object, 0), Pmode, const0_rtx, Pmode,
1301                          GEN_INT (size), Pmode);
1302 #else
1303       emit_library_call (bzero_libfunc, 1,
1304                          VOIDmode, 2,
1305                          XEXP (object, 0), Pmode,
1306                          GEN_INT (size), Pmode);
1307 #endif
1308     }
1309   else
1310     emit_move_insn (object, const0_rtx);
1311 }
1312
1313 /* Generate code to copy Y into X.
1314    Both Y and X must have the same mode, except that
1315    Y can be a constant with VOIDmode.
1316    This mode cannot be BLKmode; use emit_block_move for that.
1317
1318    Return the last instruction emitted.  */
1319
1320 rtx
1321 emit_move_insn (x, y)
1322      rtx x, y;
1323 {
1324   enum machine_mode mode = GET_MODE (x);
1325   int i;
1326
1327   x = protect_from_queue (x, 1);
1328   y = protect_from_queue (y, 0);
1329
1330   if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
1331     abort ();
1332
1333   if (CONSTANT_P (y) && ! LEGITIMATE_CONSTANT_P (y))
1334     y = force_const_mem (mode, y);
1335
1336   /* If X or Y are memory references, verify that their addresses are valid
1337      for the machine.  */
1338   if (GET_CODE (x) == MEM
1339       && ((! memory_address_p (GET_MODE (x), XEXP (x, 0))
1340            && ! push_operand (x, GET_MODE (x)))
1341           || (flag_force_addr
1342               && CONSTANT_ADDRESS_P (XEXP (x, 0)))))
1343     x = change_address (x, VOIDmode, XEXP (x, 0));
1344
1345   if (GET_CODE (y) == MEM
1346       && (! memory_address_p (GET_MODE (y), XEXP (y, 0))
1347           || (flag_force_addr
1348               && CONSTANT_ADDRESS_P (XEXP (y, 0)))))
1349     y = change_address (y, VOIDmode, XEXP (y, 0));
1350
1351   if (mode == BLKmode)
1352     abort ();
1353
1354   if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1355     return
1356       emit_insn (GEN_FCN (mov_optab->handlers[(int) mode].insn_code) (x, y));
1357
1358   /* This will handle any multi-word mode that lacks a move_insn pattern.
1359      However, you will get better code if you define such patterns,
1360      even if they must turn into multiple assembler instructions.  */
1361   else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
1362     {
1363       rtx last_insn = 0;
1364
1365       for (i = 0;
1366            i < (GET_MODE_SIZE (mode)  + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
1367            i++)
1368         {
1369           rtx xpart = operand_subword (x, i, 1, mode);
1370           rtx ypart = operand_subword (y, i, 1, mode);
1371
1372           /* If we can't get a part of Y, put Y into memory if it is a
1373              constant.  Otherwise, force it into a register.  If we still
1374              can't get a part of Y, abort.  */
1375           if (ypart == 0 && CONSTANT_P (y))
1376             {
1377               y = force_const_mem (mode, y);
1378               ypart = operand_subword (y, i, 1, mode);
1379             }
1380           else if (ypart == 0)
1381             ypart = operand_subword_force (y, i, mode);
1382
1383           if (xpart == 0 || ypart == 0)
1384             abort ();
1385
1386           last_insn = emit_move_insn (xpart, ypart);
1387         }
1388       return last_insn;
1389     }
1390   else
1391     abort ();
1392 }
1393 \f
1394 /* Pushing data onto the stack.  */
1395
1396 /* Push a block of length SIZE (perhaps variable)
1397    and return an rtx to address the beginning of the block.
1398    Note that it is not possible for the value returned to be a QUEUED.
1399    The value may be virtual_outgoing_args_rtx.
1400
1401    EXTRA is the number of bytes of padding to push in addition to SIZE.
1402    BELOW nonzero means this padding comes at low addresses;
1403    otherwise, the padding comes at high addresses.  */
1404
1405 rtx
1406 push_block (size, extra, below)
1407      rtx size;
1408      int extra, below;
1409 {
1410   register rtx temp;
1411   if (CONSTANT_P (size))
1412     anti_adjust_stack (plus_constant (size, extra));
1413   else if (GET_CODE (size) == REG && extra == 0)
1414     anti_adjust_stack (size);
1415   else
1416     {
1417       rtx temp = copy_to_mode_reg (Pmode, size);
1418       if (extra != 0)
1419         temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra),
1420                              temp, 0, OPTAB_LIB_WIDEN);
1421       anti_adjust_stack (temp);
1422     }
1423
1424 #ifdef STACK_GROWS_DOWNWARD
1425   temp = virtual_outgoing_args_rtx;
1426   if (extra != 0 && below)
1427     temp = plus_constant (temp, extra);
1428 #else
1429   if (GET_CODE (size) == CONST_INT)
1430     temp = plus_constant (virtual_outgoing_args_rtx,
1431                           - INTVAL (size) - (below ? 0 : extra));
1432   else if (extra != 0 && !below)
1433     temp = gen_rtx (PLUS, Pmode, virtual_outgoing_args_rtx,
1434                     negate_rtx (Pmode, plus_constant (size, extra)));
1435   else
1436     temp = gen_rtx (PLUS, Pmode, virtual_outgoing_args_rtx,
1437                     negate_rtx (Pmode, size));
1438 #endif
1439
1440   return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
1441 }
1442
1443 static rtx
1444 gen_push_operand ()
1445 {
1446   return gen_rtx (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
1447 }
1448
1449 /* Generate code to push X onto the stack, assuming it has mode MODE and
1450    type TYPE.
1451    MODE is redundant except when X is a CONST_INT (since they don't
1452    carry mode info).
1453    SIZE is an rtx for the size of data to be copied (in bytes),
1454    needed only if X is BLKmode.
1455
1456    ALIGN (in bytes) is maximum alignment we can assume.
1457
1458    If PARTIAL is nonzero, then copy that many of the first words
1459    of X into registers starting with REG, and push the rest of X.
1460    The amount of space pushed is decreased by PARTIAL words,
1461    rounded *down* to a multiple of PARM_BOUNDARY.
1462    REG must be a hard register in this case.
1463
1464    EXTRA is the amount in bytes of extra space to leave next to this arg.
1465    This is ignored if an argument block has already been allocated.
1466
1467    On a machine that lacks real push insns, ARGS_ADDR is the address of
1468    the bottom of the argument block for this call.  We use indexing off there
1469    to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
1470    argument block has not been preallocated.
1471
1472    ARGS_SO_FAR is the size of args previously pushed for this call.  */
1473
1474 void
1475 emit_push_insn (x, mode, type, size, align, partial, reg, extra,
1476                 args_addr, args_so_far)
1477      register rtx x;
1478      enum machine_mode mode;
1479      tree type;
1480      rtx size;
1481      int align;
1482      int partial;
1483      rtx reg;
1484      int extra;
1485      rtx args_addr;
1486      rtx args_so_far;
1487 {
1488   rtx xinner;
1489   enum direction stack_direction
1490 #ifdef STACK_GROWS_DOWNWARD
1491     = downward;
1492 #else
1493     = upward;
1494 #endif
1495
1496   /* Decide where to pad the argument: `downward' for below,
1497      `upward' for above, or `none' for don't pad it.
1498      Default is below for small data on big-endian machines; else above.  */
1499   enum direction where_pad = FUNCTION_ARG_PADDING (mode, type);
1500
1501   /* Invert direction if stack is post-update.  */
1502   if (STACK_PUSH_CODE == POST_INC || STACK_PUSH_CODE == POST_DEC)
1503     if (where_pad != none)
1504       where_pad = (where_pad == downward ? upward : downward);
1505
1506   xinner = x = protect_from_queue (x, 0);
1507
1508   if (mode == BLKmode)
1509     {
1510       /* Copy a block into the stack, entirely or partially.  */
1511
1512       register rtx temp;
1513       int used = partial * UNITS_PER_WORD;
1514       int offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
1515       int skip;
1516       
1517       if (size == 0)
1518         abort ();
1519
1520       used -= offset;
1521
1522       /* USED is now the # of bytes we need not copy to the stack
1523          because registers will take care of them.  */
1524
1525       if (partial != 0)
1526         xinner = change_address (xinner, BLKmode,
1527                                  plus_constant (XEXP (xinner, 0), used));
1528
1529       /* If the partial register-part of the arg counts in its stack size,
1530          skip the part of stack space corresponding to the registers.
1531          Otherwise, start copying to the beginning of the stack space,
1532          by setting SKIP to 0.  */
1533 #ifndef REG_PARM_STACK_SPACE
1534       skip = 0;
1535 #else
1536       skip = used;
1537 #endif
1538
1539 #ifdef PUSH_ROUNDING
1540       /* Do it with several push insns if that doesn't take lots of insns
1541          and if there is no difficulty with push insns that skip bytes
1542          on the stack for alignment purposes.  */
1543       if (args_addr == 0
1544           && GET_CODE (size) == CONST_INT
1545           && skip == 0
1546           && (move_by_pieces_ninsns ((unsigned) INTVAL (size) - used, align)
1547               < MOVE_RATIO)
1548           /* Here we avoid the case of a structure whose weak alignment
1549              forces many pushes of a small amount of data,
1550              and such small pushes do rounding that causes trouble.  */
1551           && ((! STRICT_ALIGNMENT && ! SLOW_UNALIGNED_ACCESS)
1552               || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT
1553               || PUSH_ROUNDING (align) == align)
1554           && PUSH_ROUNDING (INTVAL (size)) == INTVAL (size))
1555         {
1556           /* Push padding now if padding above and stack grows down,
1557              or if padding below and stack grows up.
1558              But if space already allocated, this has already been done.  */
1559           if (extra && args_addr == 0
1560               && where_pad != none && where_pad != stack_direction)
1561             anti_adjust_stack (GEN_INT (extra));
1562
1563           move_by_pieces (gen_rtx (MEM, BLKmode, gen_push_operand ()), xinner,
1564                           INTVAL (size) - used, align);
1565         }
1566       else
1567 #endif /* PUSH_ROUNDING */
1568         {
1569           /* Otherwise make space on the stack and copy the data
1570              to the address of that space.  */
1571
1572           /* Deduct words put into registers from the size we must copy.  */
1573           if (partial != 0)
1574             {
1575               if (GET_CODE (size) == CONST_INT)
1576                 size = GEN_INT (INTVAL (size) - used);
1577               else
1578                 size = expand_binop (GET_MODE (size), sub_optab, size,
1579                                      GEN_INT (used), NULL_RTX, 0,
1580                                      OPTAB_LIB_WIDEN);
1581             }
1582
1583           /* Get the address of the stack space.
1584              In this case, we do not deal with EXTRA separately.
1585              A single stack adjust will do.  */
1586           if (! args_addr)
1587             {
1588               temp = push_block (size, extra, where_pad == downward);
1589               extra = 0;
1590             }
1591           else if (GET_CODE (args_so_far) == CONST_INT)
1592             temp = memory_address (BLKmode,
1593                                    plus_constant (args_addr,
1594                                                   skip + INTVAL (args_so_far)));
1595           else
1596             temp = memory_address (BLKmode,
1597                                    plus_constant (gen_rtx (PLUS, Pmode,
1598                                                            args_addr, args_so_far),
1599                                                   skip));
1600
1601           /* TEMP is the address of the block.  Copy the data there.  */
1602           if (GET_CODE (size) == CONST_INT
1603               && (move_by_pieces_ninsns ((unsigned) INTVAL (size), align)
1604                   < MOVE_RATIO))
1605             {
1606               move_by_pieces (gen_rtx (MEM, BLKmode, temp), xinner,
1607                               INTVAL (size), align);
1608               goto ret;
1609             }
1610           /* Try the most limited insn first, because there's no point
1611              including more than one in the machine description unless
1612              the more limited one has some advantage.  */
1613 #ifdef HAVE_movstrqi
1614           if (HAVE_movstrqi
1615               && GET_CODE (size) == CONST_INT
1616               && ((unsigned) INTVAL (size)
1617                   < (1 << (GET_MODE_BITSIZE (QImode) - 1))))
1618             {
1619               emit_insn (gen_movstrqi (gen_rtx (MEM, BLKmode, temp),
1620                                        xinner, size, GEN_INT (align)));
1621               goto ret;
1622             }
1623 #endif
1624 #ifdef HAVE_movstrhi
1625           if (HAVE_movstrhi
1626               && GET_CODE (size) == CONST_INT
1627               && ((unsigned) INTVAL (size)
1628                   < (1 << (GET_MODE_BITSIZE (HImode) - 1))))
1629             {
1630               emit_insn (gen_movstrhi (gen_rtx (MEM, BLKmode, temp),
1631                                        xinner, size, GEN_INT (align)));
1632               goto ret;
1633             }
1634 #endif
1635 #ifdef HAVE_movstrsi
1636           if (HAVE_movstrsi)
1637             {
1638               emit_insn (gen_movstrsi (gen_rtx (MEM, BLKmode, temp),
1639                                        xinner, size, GEN_INT (align)));
1640               goto ret;
1641             }
1642 #endif
1643 #ifdef HAVE_movstrdi
1644           if (HAVE_movstrdi)
1645             {
1646               emit_insn (gen_movstrdi (gen_rtx (MEM, BLKmode, temp),
1647                                        xinner, size, GEN_INT (align)));
1648               goto ret;
1649             }
1650 #endif
1651
1652 #ifndef ACCUMULATE_OUTGOING_ARGS
1653           /* If the source is referenced relative to the stack pointer,
1654              copy it to another register to stabilize it.  We do not need
1655              to do this if we know that we won't be changing sp.  */
1656
1657           if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
1658               || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
1659             temp = copy_to_reg (temp);
1660 #endif
1661
1662           /* Make inhibit_defer_pop nonzero around the library call
1663              to force it to pop the bcopy-arguments right away.  */
1664           NO_DEFER_POP;
1665 #ifdef TARGET_MEM_FUNCTIONS
1666           emit_library_call (memcpy_libfunc, 1,
1667                              VOIDmode, 3, temp, Pmode, XEXP (xinner, 0), Pmode,
1668                              size, Pmode);
1669 #else
1670           emit_library_call (bcopy_libfunc, 1,
1671                              VOIDmode, 3, XEXP (xinner, 0), Pmode, temp, Pmode,
1672                              size, Pmode);
1673 #endif
1674           OK_DEFER_POP;
1675         }
1676     }
1677   else if (partial > 0)
1678     {
1679       /* Scalar partly in registers.  */
1680
1681       int size = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
1682       int i;
1683       int not_stack;
1684       /* # words of start of argument
1685          that we must make space for but need not store.  */
1686       int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
1687       int args_offset = INTVAL (args_so_far);
1688       int skip;
1689
1690       /* Push padding now if padding above and stack grows down,
1691          or if padding below and stack grows up.
1692          But if space already allocated, this has already been done.  */
1693       if (extra && args_addr == 0
1694           && where_pad != none && where_pad != stack_direction)
1695         anti_adjust_stack (GEN_INT (extra));
1696
1697       /* If we make space by pushing it, we might as well push
1698          the real data.  Otherwise, we can leave OFFSET nonzero
1699          and leave the space uninitialized.  */
1700       if (args_addr == 0)
1701         offset = 0;
1702
1703       /* Now NOT_STACK gets the number of words that we don't need to
1704          allocate on the stack.  */
1705       not_stack = partial - offset;
1706
1707       /* If the partial register-part of the arg counts in its stack size,
1708          skip the part of stack space corresponding to the registers.
1709          Otherwise, start copying to the beginning of the stack space,
1710          by setting SKIP to 0.  */
1711 #ifndef REG_PARM_STACK_SPACE
1712       skip = 0;
1713 #else
1714       skip = not_stack;
1715 #endif
1716
1717       if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
1718         x = validize_mem (force_const_mem (mode, x));
1719
1720       /* If X is a hard register in a non-integer mode, copy it into a pseudo;
1721          SUBREGs of such registers are not allowed.  */
1722       if ((GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER
1723            && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
1724         x = copy_to_reg (x);
1725
1726       /* Loop over all the words allocated on the stack for this arg.  */
1727       /* We can do it by words, because any scalar bigger than a word
1728          has a size a multiple of a word.  */
1729 #ifndef PUSH_ARGS_REVERSED
1730       for (i = not_stack; i < size; i++)
1731 #else
1732       for (i = size - 1; i >= not_stack; i--)
1733 #endif
1734         if (i >= not_stack + offset)
1735           emit_push_insn (operand_subword_force (x, i, mode),
1736                           word_mode, NULL_TREE, NULL_RTX, align, 0, NULL_RTX,
1737                           0, args_addr,
1738                           GEN_INT (args_offset + ((i - not_stack + skip)
1739                                                   * UNITS_PER_WORD)));
1740     }
1741   else
1742     {
1743       rtx addr;
1744
1745       /* Push padding now if padding above and stack grows down,
1746          or if padding below and stack grows up.
1747          But if space already allocated, this has already been done.  */
1748       if (extra && args_addr == 0
1749           && where_pad != none && where_pad != stack_direction)
1750         anti_adjust_stack (GEN_INT (extra));
1751
1752 #ifdef PUSH_ROUNDING
1753       if (args_addr == 0)
1754         addr = gen_push_operand ();
1755       else
1756 #endif
1757         if (GET_CODE (args_so_far) == CONST_INT)
1758           addr
1759             = memory_address (mode,
1760                               plus_constant (args_addr, INTVAL (args_so_far)));
1761       else
1762         addr = memory_address (mode, gen_rtx (PLUS, Pmode, args_addr,
1763                                               args_so_far));
1764
1765       emit_move_insn (gen_rtx (MEM, mode, addr), x);
1766     }
1767
1768  ret:
1769   /* If part should go in registers, copy that part
1770      into the appropriate registers.  Do this now, at the end,
1771      since mem-to-mem copies above may do function calls.  */
1772   if (partial > 0)
1773     move_block_to_reg (REGNO (reg), x, partial, mode);
1774
1775   if (extra && args_addr == 0 && where_pad == stack_direction)
1776     anti_adjust_stack (GEN_INT (extra));
1777 }
1778 \f
1779 /* Output a library call to function FUN (a SYMBOL_REF rtx)
1780    (emitting the queue unless NO_QUEUE is nonzero),
1781    for a value of mode OUTMODE,
1782    with NARGS different arguments, passed as alternating rtx values
1783    and machine_modes to convert them to.
1784    The rtx values should have been passed through protect_from_queue already.
1785
1786    NO_QUEUE will be true if and only if the library call is a `const' call
1787    which will be enclosed in REG_LIBCALL/REG_RETVAL notes; it is equivalent
1788    to the variable is_const in expand_call.  */
1789
1790 void
1791 emit_library_call (va_alist)
1792      va_dcl
1793 {
1794   va_list p;
1795   struct args_size args_size;
1796   register int argnum;
1797   enum machine_mode outmode;
1798   int nargs;
1799   rtx fun;
1800   rtx orgfun;
1801   int inc;
1802   int count;
1803   rtx argblock = 0;
1804   CUMULATIVE_ARGS args_so_far;
1805   struct arg { rtx value; enum machine_mode mode; rtx reg; int partial;
1806                struct args_size offset; struct args_size size; };
1807   struct arg *argvec;
1808   int old_inhibit_defer_pop = inhibit_defer_pop;
1809   int no_queue = 0;
1810   rtx use_insns;
1811
1812   va_start (p);
1813   orgfun = fun = va_arg (p, rtx);
1814   no_queue = va_arg (p, int);
1815   outmode = va_arg (p, enum machine_mode);
1816   nargs = va_arg (p, int);
1817
1818   /* Copy all the libcall-arguments out of the varargs data
1819      and into a vector ARGVEC.
1820
1821      Compute how to pass each argument.  We only support a very small subset
1822      of the full argument passing conventions to limit complexity here since
1823      library functions shouldn't have many args.  */
1824
1825   argvec = (struct arg *) alloca (nargs * sizeof (struct arg));
1826
1827   INIT_CUMULATIVE_ARGS (args_so_far, (tree)0, fun);
1828
1829   args_size.constant = 0;
1830   args_size.var = 0;
1831
1832   for (count = 0; count < nargs; count++)
1833     {
1834       rtx val = va_arg (p, rtx);
1835       enum machine_mode mode = va_arg (p, enum machine_mode);
1836
1837       /* We cannot convert the arg value to the mode the library wants here;
1838          must do it earlier where we know the signedness of the arg.  */
1839       if (mode == BLKmode
1840           || (GET_MODE (val) != mode && GET_MODE (val) != VOIDmode))
1841         abort ();
1842
1843       /* On some machines, there's no way to pass a float to a library fcn.
1844          Pass it as a double instead.  */
1845 #ifdef LIBGCC_NEEDS_DOUBLE
1846       if (LIBGCC_NEEDS_DOUBLE && mode == SFmode)
1847         val = convert_to_mode (DFmode, val), mode = DFmode;
1848 #endif
1849
1850       /* Make sure it is a reasonable operand for a move or push insn.  */
1851       if (GET_CODE (val) != REG && GET_CODE (val) != MEM
1852           && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
1853         val = force_operand (val, NULL_RTX);
1854
1855       argvec[count].value = val;
1856       argvec[count].mode = mode;
1857
1858 #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
1859       if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
1860         abort ();
1861 #endif
1862
1863       argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
1864       if (argvec[count].reg && GET_CODE (argvec[count].reg) == EXPR_LIST)
1865         abort ();
1866 #ifdef FUNCTION_ARG_PARTIAL_NREGS
1867       argvec[count].partial
1868         = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, NULL_TREE, 1);
1869 #else
1870       argvec[count].partial = 0;
1871 #endif
1872
1873       locate_and_pad_parm (mode, NULL_TREE,
1874                            argvec[count].reg && argvec[count].partial == 0,
1875                            NULL_TREE, &args_size, &argvec[count].offset,
1876                            &argvec[count].size);
1877
1878       if (argvec[count].size.var)
1879         abort ();
1880
1881 #ifndef REG_PARM_STACK_SPACE
1882       if (argvec[count].partial)
1883         argvec[count].size.constant -= argvec[count].partial * UNITS_PER_WORD;
1884 #endif
1885
1886       if (argvec[count].reg == 0 || argvec[count].partial != 0
1887 #ifdef REG_PARM_STACK_SPACE
1888           || 1
1889 #endif
1890           )
1891         args_size.constant += argvec[count].size.constant;
1892
1893 #ifdef ACCUMULATE_OUTGOING_ARGS
1894       /* If this arg is actually passed on the stack, it might be
1895          clobbering something we already put there (this library call might
1896          be inside the evaluation of an argument to a function whose call
1897          requires the stack).  This will only occur when the library call
1898          has sufficient args to run out of argument registers.  Abort in
1899          this case; if this ever occurs, code must be added to save and
1900          restore the arg slot.  */
1901
1902       if (argvec[count].reg == 0 || argvec[count].partial != 0)
1903         abort ();
1904 #endif
1905
1906       FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree)0, 1);
1907     }
1908   va_end (p);
1909
1910   /* If this machine requires an external definition for library
1911      functions, write one out.  */
1912   assemble_external_libcall (fun);
1913
1914 #ifdef STACK_BOUNDARY
1915   args_size.constant = (((args_size.constant + (STACK_BYTES - 1))
1916                          / STACK_BYTES) * STACK_BYTES);
1917 #endif
1918
1919 #ifdef REG_PARM_STACK_SPACE
1920   args_size.constant = MAX (args_size.constant,
1921                             REG_PARM_STACK_SPACE ((tree) 0));
1922 #endif
1923
1924 #ifdef ACCUMULATE_OUTGOING_ARGS
1925   if (args_size.constant > current_function_outgoing_args_size)
1926     current_function_outgoing_args_size = args_size.constant;
1927   args_size.constant = 0;
1928 #endif
1929
1930 #ifndef PUSH_ROUNDING
1931   argblock = push_block (GEN_INT (args_size.constant), 0, 0);
1932 #endif
1933
1934 #ifdef PUSH_ARGS_REVERSED
1935   inc = -1;
1936   argnum = nargs - 1;
1937 #else
1938   inc = 1;
1939   argnum = 0;
1940 #endif
1941
1942   /* Push the args that need to be pushed.  */
1943
1944   for (count = 0; count < nargs; count++, argnum += inc)
1945     {
1946       register enum machine_mode mode = argvec[argnum].mode;
1947       register rtx val = argvec[argnum].value;
1948       rtx reg = argvec[argnum].reg;
1949       int partial = argvec[argnum].partial;
1950
1951       if (! (reg != 0 && partial == 0))
1952         emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
1953                         argblock, GEN_INT (argvec[count].offset.constant));
1954       NO_DEFER_POP;
1955     }
1956
1957 #ifdef PUSH_ARGS_REVERSED
1958   argnum = nargs - 1;
1959 #else
1960   argnum = 0;
1961 #endif
1962
1963   /* Now load any reg parms into their regs.  */
1964
1965   for (count = 0; count < nargs; count++, argnum += inc)
1966     {
1967       register enum machine_mode mode = argvec[argnum].mode;
1968       register rtx val = argvec[argnum].value;
1969       rtx reg = argvec[argnum].reg;
1970       int partial = argvec[argnum].partial;
1971
1972       if (reg != 0 && partial == 0)
1973         emit_move_insn (reg, val);
1974       NO_DEFER_POP;
1975     }
1976
1977   /* For version 1.37, try deleting this entirely.  */
1978   if (! no_queue)
1979     emit_queue ();
1980
1981   /* Any regs containing parms remain in use through the call.  */
1982   start_sequence ();
1983   for (count = 0; count < nargs; count++)
1984     if (argvec[count].reg != 0)
1985       emit_insn (gen_rtx (USE, VOIDmode, argvec[count].reg));
1986
1987   use_insns = get_insns ();
1988   end_sequence ();
1989
1990   fun = prepare_call_address (fun, NULL_TREE, &use_insns);
1991
1992   /* Don't allow popping to be deferred, since then
1993      cse'ing of library calls could delete a call and leave the pop.  */
1994   NO_DEFER_POP;
1995
1996   /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
1997      will set inhibit_defer_pop to that value.  */
1998
1999   emit_call_1 (fun, get_identifier (XSTR (orgfun, 0)), args_size.constant, 0,
2000                FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
2001                outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
2002                old_inhibit_defer_pop + 1, use_insns, no_queue);
2003
2004   /* Now restore inhibit_defer_pop to its actual original value.  */
2005   OK_DEFER_POP;
2006 }
2007 \f
2008 /* Expand an assignment that stores the value of FROM into TO.
2009    If WANT_VALUE is nonzero, return an rtx for the value of TO.
2010    (This may contain a QUEUED rtx.)
2011    Otherwise, the returned value is not meaningful.
2012
2013    SUGGEST_REG is no longer actually used.
2014    It used to mean, copy the value through a register
2015    and return that register, if that is possible.
2016    But now we do this if WANT_VALUE.
2017
2018    If the value stored is a constant, we return the constant.  */
2019
2020 rtx
2021 expand_assignment (to, from, want_value, suggest_reg)
2022      tree to, from;
2023      int want_value;
2024      int suggest_reg;
2025 {
2026   register rtx to_rtx = 0;
2027   rtx result;
2028
2029   /* Don't crash if the lhs of the assignment was erroneous.  */
2030
2031   if (TREE_CODE (to) == ERROR_MARK)
2032     return expand_expr (from, NULL_RTX, VOIDmode, 0);
2033
2034   /* Assignment of a structure component needs special treatment
2035      if the structure component's rtx is not simply a MEM.
2036      Assignment of an array element at a constant index
2037      has the same problem.  */
2038
2039   if (TREE_CODE (to) == COMPONENT_REF
2040       || TREE_CODE (to) == BIT_FIELD_REF
2041       || (TREE_CODE (to) == ARRAY_REF
2042           && TREE_CODE (TREE_OPERAND (to, 1)) == INTEGER_CST
2043           && TREE_CODE (TYPE_SIZE (TREE_TYPE (to))) == INTEGER_CST))
2044     {
2045       enum machine_mode mode1;
2046       int bitsize;
2047       int bitpos;
2048       tree offset;
2049       int unsignedp;
2050       int volatilep = 0;
2051       tree tem = get_inner_reference (to, &bitsize, &bitpos, &offset,
2052                                       &mode1, &unsignedp, &volatilep);
2053
2054       /* If we are going to use store_bit_field and extract_bit_field,
2055          make sure to_rtx will be safe for multiple use.  */
2056
2057       if (mode1 == VOIDmode && want_value)
2058         tem = stabilize_reference (tem);
2059
2060       to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
2061       if (offset != 0)
2062         {
2063           rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
2064
2065           if (GET_CODE (to_rtx) != MEM)
2066             abort ();
2067           to_rtx = change_address (to_rtx, VOIDmode,
2068                                    gen_rtx (PLUS, Pmode, XEXP (to_rtx, 0),
2069                                             force_reg (Pmode, offset_rtx)));
2070         }
2071       if (volatilep)
2072         {
2073           if (GET_CODE (to_rtx) == MEM)
2074             MEM_VOLATILE_P (to_rtx) = 1;
2075 #if 0  /* This was turned off because, when a field is volatile
2076           in an object which is not volatile, the object may be in a register,
2077           and then we would abort over here.  */
2078           else
2079             abort ();
2080 #endif
2081         }
2082
2083       result = store_field (to_rtx, bitsize, bitpos, mode1, from,
2084                             (want_value
2085                              /* Spurious cast makes HPUX compiler happy.  */
2086                              ? (enum machine_mode) TYPE_MODE (TREE_TYPE (to))
2087                              : VOIDmode),
2088                             unsignedp,
2089                             /* Required alignment of containing datum.  */
2090                             TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT,
2091                             int_size_in_bytes (TREE_TYPE (tem)));
2092       preserve_temp_slots (result);
2093       free_temp_slots ();
2094
2095       return result;
2096     }
2097
2098   /* Ordinary treatment.  Expand TO to get a REG or MEM rtx.
2099      Don't re-expand if it was expanded already (in COMPONENT_REF case).  */
2100
2101   if (to_rtx == 0)
2102     to_rtx = expand_expr (to, NULL_RTX, VOIDmode, 0);
2103
2104   /* In case we are returning the contents of an object which overlaps
2105      the place the value is being stored, use a safe function when copying
2106      a value through a pointer into a structure value return block.  */
2107   if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF
2108       && current_function_returns_struct
2109       && !current_function_returns_pcc_struct)
2110     {
2111       rtx from_rtx = expand_expr (from, NULL_RTX, VOIDmode, 0);
2112       rtx size = expr_size (from);
2113
2114 #ifdef TARGET_MEM_FUNCTIONS
2115       emit_library_call (memcpy_libfunc, 1,
2116                          VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
2117                          XEXP (from_rtx, 0), Pmode,
2118                          size, Pmode);
2119 #else
2120       emit_library_call (bcopy_libfunc, 1,
2121                          VOIDmode, 3, XEXP (from_rtx, 0), Pmode,
2122                          XEXP (to_rtx, 0), Pmode,
2123                          size, Pmode);
2124 #endif
2125
2126       preserve_temp_slots (to_rtx);
2127       free_temp_slots ();
2128       return to_rtx;
2129     }
2130
2131   /* Compute FROM and store the value in the rtx we got.  */
2132
2133   result = store_expr (from, to_rtx, want_value);
2134   preserve_temp_slots (result);
2135   free_temp_slots ();
2136   return result;
2137 }
2138
2139 /* Generate code for computing expression EXP,
2140    and storing the value into TARGET.
2141    Returns TARGET or an equivalent value.
2142    TARGET may contain a QUEUED rtx.
2143
2144    If SUGGEST_REG is nonzero, copy the value through a register
2145    and return that register, if that is possible.
2146
2147    If the value stored is a constant, we return the constant.  */
2148
2149 rtx
2150 store_expr (exp, target, suggest_reg)
2151      register tree exp;
2152      register rtx target;
2153      int suggest_reg;
2154 {
2155   register rtx temp;
2156   int dont_return_target = 0;
2157
2158   if (TREE_CODE (exp) == COMPOUND_EXPR)
2159     {
2160       /* Perform first part of compound expression, then assign from second
2161          part.  */
2162       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
2163       emit_queue ();
2164       return store_expr (TREE_OPERAND (exp, 1), target, suggest_reg);
2165     }
2166   else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
2167     {
2168       /* For conditional expression, get safe form of the target.  Then
2169          test the condition, doing the appropriate assignment on either
2170          side.  This avoids the creation of unnecessary temporaries.
2171          For non-BLKmode, it is more efficient not to do this.  */
2172
2173       rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
2174
2175       emit_queue ();
2176       target = protect_from_queue (target, 1);
2177
2178       NO_DEFER_POP;
2179       jumpifnot (TREE_OPERAND (exp, 0), lab1);
2180       store_expr (TREE_OPERAND (exp, 1), target, suggest_reg);
2181       emit_queue ();
2182       emit_jump_insn (gen_jump (lab2));
2183       emit_barrier ();
2184       emit_label (lab1);
2185       store_expr (TREE_OPERAND (exp, 2), target, suggest_reg);
2186       emit_queue ();
2187       emit_label (lab2);
2188       OK_DEFER_POP;
2189       return target;
2190     }
2191   else if (suggest_reg && GET_CODE (target) == MEM
2192            && GET_MODE (target) != BLKmode)
2193     /* If target is in memory and caller wants value in a register instead,
2194        arrange that.  Pass TARGET as target for expand_expr so that,
2195        if EXP is another assignment, SUGGEST_REG will be nonzero for it.
2196        We know expand_expr will not use the target in that case.  */
2197     {
2198       temp = expand_expr (exp, cse_not_expected ? NULL_RTX : target,
2199                           GET_MODE (target), 0);
2200       if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
2201         temp = copy_to_reg (temp);
2202       dont_return_target = 1;
2203     }
2204   else if (queued_subexp_p (target))
2205     /* If target contains a postincrement, it is not safe
2206        to use as the returned value.  It would access the wrong
2207        place by the time the queued increment gets output.
2208        So copy the value through a temporary and use that temp
2209        as the result.  */
2210     {
2211       if (GET_MODE (target) != BLKmode && GET_MODE (target) != VOIDmode)
2212         {
2213           /* Expand EXP into a new pseudo.  */
2214           temp = gen_reg_rtx (GET_MODE (target));
2215           temp = expand_expr (exp, temp, GET_MODE (target), 0);
2216         }
2217       else
2218         temp = expand_expr (exp, NULL_RTX, GET_MODE (target), 0);
2219       dont_return_target = 1;
2220     }
2221   else
2222     {
2223       temp = expand_expr (exp, target, GET_MODE (target), 0);
2224       /* DO return TARGET if it's a specified hardware register.
2225          expand_return relies on this.  */
2226       if (!(target && GET_CODE (target) == REG
2227             && REGNO (target) < FIRST_PSEUDO_REGISTER)
2228           && CONSTANT_P (temp))
2229         dont_return_target = 1;
2230     }
2231
2232   /* If value was not generated in the target, store it there.
2233      Convert the value to TARGET's type first if nec.  */
2234
2235   if (temp != target && TREE_CODE (exp) != ERROR_MARK)
2236     {
2237       target = protect_from_queue (target, 1);
2238       if (GET_MODE (temp) != GET_MODE (target)
2239           && GET_MODE (temp) != VOIDmode)
2240         {
2241           int unsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
2242           if (dont_return_target)
2243             {
2244               /* In this case, we will return TEMP,
2245                  so make sure it has the proper mode.
2246                  But don't forget to store the value into TARGET.  */
2247               temp = convert_to_mode (GET_MODE (target), temp, unsignedp);
2248               emit_move_insn (target, temp);
2249             }
2250           else
2251             convert_move (target, temp, unsignedp);
2252         }
2253
2254       else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
2255         {
2256           /* Handle copying a string constant into an array.
2257              The string constant may be shorter than the array.
2258              So copy just the string's actual length, and clear the rest.  */
2259           rtx size;
2260
2261           /* Get the size of the data type of the string,
2262              which is actually the size of the target.  */
2263           size = expr_size (exp);
2264           if (GET_CODE (size) == CONST_INT
2265               && INTVAL (size) < TREE_STRING_LENGTH (exp))
2266             emit_block_move (target, temp, size,
2267                              TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
2268           else
2269             {
2270               /* Compute the size of the data to copy from the string.  */
2271               tree copy_size
2272                 = fold (build (MIN_EXPR, sizetype,
2273                                size_binop (CEIL_DIV_EXPR,
2274                                            TYPE_SIZE (TREE_TYPE (exp)),
2275                                            size_int (BITS_PER_UNIT)),
2276                                convert (sizetype,
2277                                         build_int_2 (TREE_STRING_LENGTH (exp), 0))));
2278               rtx copy_size_rtx = expand_expr (copy_size, NULL_RTX,
2279                                                VOIDmode, 0);
2280               rtx label = 0;
2281
2282               /* Copy that much.  */
2283               emit_block_move (target, temp, copy_size_rtx,
2284                                TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
2285
2286               /* Figure out how much is left in TARGET
2287                  that we have to clear.  */
2288               if (GET_CODE (copy_size_rtx) == CONST_INT)
2289                 {
2290                   temp = plus_constant (XEXP (target, 0),
2291                                         TREE_STRING_LENGTH (exp));
2292                   size = plus_constant (size,
2293                                         - TREE_STRING_LENGTH (exp));
2294                 }
2295               else
2296                 {
2297                   enum machine_mode size_mode = Pmode;
2298
2299                   temp = force_reg (Pmode, XEXP (target, 0));
2300                   temp = expand_binop (size_mode, add_optab, temp,
2301                                        copy_size_rtx, NULL_RTX, 0,
2302                                        OPTAB_LIB_WIDEN);
2303
2304                   size = expand_binop (size_mode, sub_optab, size,
2305                                        copy_size_rtx, NULL_RTX, 0,
2306                                        OPTAB_LIB_WIDEN);
2307
2308                   emit_cmp_insn (size, const0_rtx, LT, NULL_RTX,
2309                                  GET_MODE (size), 0, 0);
2310                   label = gen_label_rtx ();
2311                   emit_jump_insn (gen_blt (label));
2312                 }
2313
2314               if (size != const0_rtx)
2315                 {
2316 #ifdef TARGET_MEM_FUNCTIONS
2317                   emit_library_call (memset_libfunc, 1, VOIDmode, 3,
2318                                      temp, Pmode, const0_rtx, Pmode, size, Pmode);
2319 #else
2320                   emit_library_call (bzero_libfunc, 1, VOIDmode, 2,
2321                                      temp, Pmode, size, Pmode);
2322 #endif
2323                 }
2324               if (label)
2325                 emit_label (label);
2326             }
2327         }
2328       else if (GET_MODE (temp) == BLKmode)
2329         emit_block_move (target, temp, expr_size (exp),
2330                          TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
2331       else
2332         emit_move_insn (target, temp);
2333     }
2334   if (dont_return_target)
2335     return temp;
2336   return target;
2337 }
2338 \f
2339 /* Store the value of constructor EXP into the rtx TARGET.
2340    TARGET is either a REG or a MEM.  */
2341
2342 static void
2343 store_constructor (exp, target)
2344      tree exp;
2345      rtx target;
2346 {
2347   tree type = TREE_TYPE (exp);
2348
2349   /* We know our target cannot conflict, since safe_from_p has been called.  */
2350 #if 0
2351   /* Don't try copying piece by piece into a hard register
2352      since that is vulnerable to being clobbered by EXP.
2353      Instead, construct in a pseudo register and then copy it all.  */
2354   if (GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)
2355     {
2356       rtx temp = gen_reg_rtx (GET_MODE (target));
2357       store_constructor (exp, temp);
2358       emit_move_insn (target, temp);
2359       return;
2360     }
2361 #endif
2362
2363   if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)
2364     {
2365       register tree elt;
2366
2367       /* Inform later passes that the whole union value is dead.  */
2368       if (TREE_CODE (type) == UNION_TYPE)
2369         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2370
2371       /* If we are building a static constructor into a register,
2372          set the initial value as zero so we can fold the value into
2373          a constant.  */
2374       else if (GET_CODE (target) == REG && TREE_STATIC (exp))
2375         emit_move_insn (target, const0_rtx);
2376
2377       /* If the constructor has fewer fields than the structure,
2378          clear the whole structure first.  */
2379       else if (list_length (CONSTRUCTOR_ELTS (exp))
2380                != list_length (TYPE_FIELDS (type)))
2381         clear_storage (target, int_size_in_bytes (type));
2382       else
2383         /* Inform later passes that the old value is dead.  */
2384         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2385
2386       /* Store each element of the constructor into
2387          the corresponding field of TARGET.  */
2388
2389       for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
2390         {
2391           register tree field = TREE_PURPOSE (elt);
2392           register enum machine_mode mode;
2393           int bitsize;
2394           int bitpos;
2395           int unsignedp;
2396
2397           /* Just ignore missing fields.
2398              We cleared the whole structure, above,
2399              if any fields are missing.  */
2400           if (field == 0)
2401             continue;
2402
2403           bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
2404           unsignedp = TREE_UNSIGNED (field);
2405           mode = DECL_MODE (field);
2406           if (DECL_BIT_FIELD (field))
2407             mode = VOIDmode;
2408
2409           if (TREE_CODE (DECL_FIELD_BITPOS (field)) != INTEGER_CST)
2410             /* ??? This case remains to be written.  */
2411             abort ();
2412
2413           bitpos = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
2414
2415           store_field (target, bitsize, bitpos, mode, TREE_VALUE (elt),
2416                        /* The alignment of TARGET is
2417                           at least what its type requires.  */
2418                        VOIDmode, 0,
2419                        TYPE_ALIGN (type) / BITS_PER_UNIT,
2420                        int_size_in_bytes (type));
2421         }
2422     }
2423   else if (TREE_CODE (type) == ARRAY_TYPE)
2424     {
2425       register tree elt;
2426       register int i;
2427       tree domain = TYPE_DOMAIN (type);
2428       HOST_WIDE_INT minelt = TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain));
2429       HOST_WIDE_INT maxelt = TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain));
2430       tree elttype = TREE_TYPE (type);
2431
2432       /* If the constructor has fewer fields than the structure,
2433          clear the whole structure first.  Similarly if this this is
2434          static constructor of a non-BLKmode object.  */
2435
2436       if (list_length (CONSTRUCTOR_ELTS (exp)) < maxelt - minelt + 1
2437           || (GET_CODE (target) == REG && TREE_STATIC (exp)))
2438         clear_storage (target, maxelt - minelt + 1);
2439       else
2440         /* Inform later passes that the old value is dead.  */
2441         emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2442
2443       /* Store each element of the constructor into
2444          the corresponding element of TARGET, determined
2445          by counting the elements.  */
2446       for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
2447            elt;
2448            elt = TREE_CHAIN (elt), i++)
2449         {
2450           register enum machine_mode mode;
2451           int bitsize;
2452           int bitpos;
2453           int unsignedp;
2454
2455           mode = TYPE_MODE (elttype);
2456           bitsize = GET_MODE_BITSIZE (mode);
2457           unsignedp = TREE_UNSIGNED (elttype);
2458
2459           bitpos = (i * TREE_INT_CST_LOW (TYPE_SIZE (elttype)));
2460
2461           store_field (target, bitsize, bitpos, mode, TREE_VALUE (elt),
2462                        /* The alignment of TARGET is
2463                           at least what its type requires.  */
2464                        VOIDmode, 0,
2465                        TYPE_ALIGN (type) / BITS_PER_UNIT,
2466                        int_size_in_bytes (type));
2467         }
2468     }
2469
2470   else
2471     abort ();
2472 }
2473
2474 /* Store the value of EXP (an expression tree)
2475    into a subfield of TARGET which has mode MODE and occupies
2476    BITSIZE bits, starting BITPOS bits from the start of TARGET.
2477    If MODE is VOIDmode, it means that we are storing into a bit-field.
2478
2479    If VALUE_MODE is VOIDmode, return nothing in particular.
2480    UNSIGNEDP is not used in this case.
2481
2482    Otherwise, return an rtx for the value stored.  This rtx
2483    has mode VALUE_MODE if that is convenient to do.
2484    In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
2485
2486    ALIGN is the alignment that TARGET is known to have, measured in bytes.
2487    TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.  */
2488
2489 static rtx
2490 store_field (target, bitsize, bitpos, mode, exp, value_mode,
2491              unsignedp, align, total_size)
2492      rtx target;
2493      int bitsize, bitpos;
2494      enum machine_mode mode;
2495      tree exp;
2496      enum machine_mode value_mode;
2497      int unsignedp;
2498      int align;
2499      int total_size;
2500 {
2501   HOST_WIDE_INT width_mask = 0;
2502
2503   if (bitsize < HOST_BITS_PER_WIDE_INT)
2504     width_mask = ((HOST_WIDE_INT) 1 << bitsize) - 1;
2505
2506   /* If we are storing into an unaligned field of an aligned union that is
2507      in a register, we may have the mode of TARGET being an integer mode but
2508      MODE == BLKmode.  In that case, get an aligned object whose size and
2509      alignment are the same as TARGET and store TARGET into it (we can avoid
2510      the store if the field being stored is the entire width of TARGET).  Then
2511      call ourselves recursively to store the field into a BLKmode version of
2512      that object.  Finally, load from the object into TARGET.  This is not
2513      very efficient in general, but should only be slightly more expensive
2514      than the otherwise-required unaligned accesses.  Perhaps this can be
2515      cleaned up later.  */
2516
2517   if (mode == BLKmode
2518       && (GET_CODE (target) == REG || GET_CODE (target) == SUBREG))
2519     {
2520       rtx object = assign_stack_temp (GET_MODE (target),
2521                                       GET_MODE_SIZE (GET_MODE (target)), 0);
2522       rtx blk_object = copy_rtx (object);
2523
2524       PUT_MODE (blk_object, BLKmode);
2525
2526       if (bitsize != GET_MODE_BITSIZE (GET_MODE (target)))
2527         emit_move_insn (object, target);
2528
2529       store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0,
2530                    align, total_size);
2531
2532       emit_move_insn (target, object);
2533
2534       return target;
2535     }
2536
2537   /* If the structure is in a register or if the component
2538      is a bit field, we cannot use addressing to access it.
2539      Use bit-field techniques or SUBREG to store in it.  */
2540
2541   if (mode == VOIDmode
2542       || (mode != BLKmode && ! direct_store[(int) mode])
2543       || GET_CODE (target) == REG
2544       || GET_CODE (target) == SUBREG)
2545     {
2546       rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
2547       /* Store the value in the bitfield.  */
2548       store_bit_field (target, bitsize, bitpos, mode, temp, align, total_size);
2549       if (value_mode != VOIDmode)
2550         {
2551           /* The caller wants an rtx for the value.  */
2552           /* If possible, avoid refetching from the bitfield itself.  */
2553           if (width_mask != 0
2554               && ! (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)))
2555             return expand_and (temp, GEN_INT (width_mask), NULL_RTX);
2556           return extract_bit_field (target, bitsize, bitpos, unsignedp,
2557                                     NULL_RTX, value_mode, 0, align,
2558                                     total_size);
2559         }
2560       return const0_rtx;
2561     }
2562   else
2563     {
2564       rtx addr = XEXP (target, 0);
2565       rtx to_rtx;
2566
2567       /* If a value is wanted, it must be the lhs;
2568          so make the address stable for multiple use.  */
2569
2570       if (value_mode != VOIDmode && GET_CODE (addr) != REG
2571           && ! CONSTANT_ADDRESS_P (addr)
2572           /* A frame-pointer reference is already stable.  */
2573           && ! (GET_CODE (addr) == PLUS
2574                 && GET_CODE (XEXP (addr, 1)) == CONST_INT
2575                 && (XEXP (addr, 0) == virtual_incoming_args_rtx
2576                     || XEXP (addr, 0) == virtual_stack_vars_rtx)))
2577         addr = copy_to_reg (addr);
2578
2579       /* Now build a reference to just the desired component.  */
2580
2581       to_rtx = change_address (target, mode,
2582                                plus_constant (addr, (bitpos / BITS_PER_UNIT)));
2583       MEM_IN_STRUCT_P (to_rtx) = 1;
2584
2585       return store_expr (exp, to_rtx, value_mode != VOIDmode);
2586     }
2587 }
2588 \f
2589 /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
2590    or an ARRAY_REF, look for nested COMPONENT_REFs, BIT_FIELD_REFs, or
2591    ARRAY_REFs at constant positions and find the ultimate containing object,
2592    which we return.
2593
2594    We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
2595    bit position, and *PUNSIGNEDP to the signedness of the field.
2596    If the position of the field is variable, we store a tree
2597    giving the variable offset (in units) in *POFFSET.
2598    This offset is in addition to the bit position.
2599    If the position is not variable, we store 0 in *POFFSET.
2600
2601    If any of the extraction expressions is volatile,
2602    we store 1 in *PVOLATILEP.  Otherwise we don't change that.
2603
2604    If the field is a bit-field, *PMODE is set to VOIDmode.  Otherwise, it
2605    is a mode that can be used to access the field.  In that case, *PBITSIZE
2606    is redundant.
2607
2608    If the field describes a variable-sized object, *PMODE is set to
2609    VOIDmode and *PBITSIZE is set to -1.  An access cannot be made in
2610    this case, but the address of the object can be found.  */
2611
2612 tree
2613 get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, punsignedp, pvolatilep)
2614      tree exp;
2615      int *pbitsize;
2616      int *pbitpos;
2617      tree *poffset;
2618      enum machine_mode *pmode;
2619      int *punsignedp;
2620      int *pvolatilep;
2621 {
2622   tree size_tree = 0;
2623   enum machine_mode mode = VOIDmode;
2624   tree offset = 0;
2625
2626   if (TREE_CODE (exp) == COMPONENT_REF)
2627     {
2628       size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
2629       if (! DECL_BIT_FIELD (TREE_OPERAND (exp, 1)))
2630         mode = DECL_MODE (TREE_OPERAND (exp, 1));
2631       *punsignedp = TREE_UNSIGNED (TREE_OPERAND (exp, 1));
2632     }
2633   else if (TREE_CODE (exp) == BIT_FIELD_REF)
2634     {
2635       size_tree = TREE_OPERAND (exp, 1);
2636       *punsignedp = TREE_UNSIGNED (exp);
2637     }
2638   else
2639     {
2640       mode = TYPE_MODE (TREE_TYPE (exp));
2641       *pbitsize = GET_MODE_BITSIZE (mode);
2642       *punsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
2643     }
2644       
2645   if (size_tree)
2646     {
2647       if (TREE_CODE (size_tree) != INTEGER_CST)
2648         mode = BLKmode, *pbitsize = -1;
2649       else
2650         *pbitsize = TREE_INT_CST_LOW (size_tree);
2651     }
2652
2653   /* Compute cumulative bit-offset for nested component-refs and array-refs,
2654      and find the ultimate containing object.  */
2655
2656   *pbitpos = 0;
2657
2658   while (1)
2659     {
2660       if (TREE_CODE (exp) == COMPONENT_REF || TREE_CODE (exp) == BIT_FIELD_REF)
2661         {
2662           tree pos = (TREE_CODE (exp) == COMPONENT_REF
2663                       ? DECL_FIELD_BITPOS (TREE_OPERAND (exp, 1))
2664                       : TREE_OPERAND (exp, 2));
2665
2666           if (TREE_CODE (pos) == PLUS_EXPR)
2667             {
2668               tree constant, var;
2669               if (TREE_CODE (TREE_OPERAND (pos, 0)) == INTEGER_CST)
2670                 {
2671                   constant = TREE_OPERAND (pos, 0);
2672                   var = TREE_OPERAND (pos, 1);
2673                 }
2674               else if (TREE_CODE (TREE_OPERAND (pos, 1)) == INTEGER_CST)
2675                 {
2676                   constant = TREE_OPERAND (pos, 1);
2677                   var = TREE_OPERAND (pos, 0);
2678                 }
2679               else
2680                 abort ();
2681               *pbitpos += TREE_INT_CST_LOW (constant);
2682               if (offset)
2683                 offset = size_binop (PLUS_EXPR, offset,
2684                                      size_binop (FLOOR_DIV_EXPR, var,
2685                                                  size_int (BITS_PER_UNIT)));
2686               else
2687                 offset = size_binop (FLOOR_DIV_EXPR, var,
2688                                      size_int (BITS_PER_UNIT));
2689             }
2690           else if (TREE_CODE (pos) == INTEGER_CST)
2691             *pbitpos += TREE_INT_CST_LOW (pos);
2692           else
2693             {
2694               /* Assume here that the offset is a multiple of a unit.
2695                  If not, there should be an explicitly added constant.  */
2696               if (offset)
2697                 offset = size_binop (PLUS_EXPR, offset,
2698                                      size_binop (FLOOR_DIV_EXPR, pos,
2699                                                  size_int (BITS_PER_UNIT)));
2700               else
2701                 offset = size_binop (FLOOR_DIV_EXPR, pos,
2702                                      size_int (BITS_PER_UNIT));
2703             }
2704         }
2705
2706       else if (TREE_CODE (exp) == ARRAY_REF
2707                && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
2708                && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST)
2709         {
2710           *pbitpos += (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))
2711                        * TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))));
2712         }
2713       else if (TREE_CODE (exp) != NON_LVALUE_EXPR
2714                && ! ((TREE_CODE (exp) == NOP_EXPR
2715                       || TREE_CODE (exp) == CONVERT_EXPR)
2716                      && (TYPE_MODE (TREE_TYPE (exp))
2717                          == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))))
2718         break;
2719
2720       /* If any reference in the chain is volatile, the effect is volatile.  */
2721       if (TREE_THIS_VOLATILE (exp))
2722         *pvolatilep = 1;
2723       exp = TREE_OPERAND (exp, 0);
2724     }
2725
2726   /* If this was a bit-field, see if there is a mode that allows direct
2727      access in case EXP is in memory.  */
2728   if (mode == VOIDmode && *pbitpos % *pbitsize == 0)
2729     {
2730       mode = mode_for_size (*pbitsize, MODE_INT, 0);
2731       if (mode == BLKmode)
2732         mode = VOIDmode;
2733     }
2734
2735   *pmode = mode;
2736   *poffset = offset;
2737 #if 0
2738   /* We aren't finished fixing the callers to really handle nonzero offset.  */
2739   if (offset != 0)
2740     abort ();
2741 #endif
2742
2743   return exp;
2744 }
2745 \f
2746 /* Given an rtx VALUE that may contain additions and multiplications,
2747    return an equivalent value that just refers to a register or memory.
2748    This is done by generating instructions to perform the arithmetic
2749    and returning a pseudo-register containing the value.  */
2750
2751 rtx
2752 force_operand (value, target)
2753      rtx value, target;
2754 {
2755   register optab binoptab = 0;
2756   /* Use a temporary to force order of execution of calls to
2757      `force_operand'.  */
2758   rtx tmp;
2759   register rtx op2;
2760   /* Use subtarget as the target for operand 0 of a binary operation.  */
2761   register rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
2762
2763   if (GET_CODE (value) == PLUS)
2764     binoptab = add_optab;
2765   else if (GET_CODE (value) == MINUS)
2766     binoptab = sub_optab;
2767   else if (GET_CODE (value) == MULT)
2768     {
2769       op2 = XEXP (value, 1);
2770       if (!CONSTANT_P (op2)
2771           && !(GET_CODE (op2) == REG && op2 != subtarget))
2772         subtarget = 0;
2773       tmp = force_operand (XEXP (value, 0), subtarget);
2774       return expand_mult (GET_MODE (value), tmp,
2775                           force_operand (op2, NULL_RTX),
2776                           target, 0);
2777     }
2778
2779   if (binoptab)
2780     {
2781       op2 = XEXP (value, 1);
2782       if (!CONSTANT_P (op2)
2783           && !(GET_CODE (op2) == REG && op2 != subtarget))
2784         subtarget = 0;
2785       if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT)
2786         {
2787           binoptab = add_optab;
2788           op2 = negate_rtx (GET_MODE (value), op2);
2789         }
2790
2791       /* Check for an addition with OP2 a constant integer and our first
2792          operand a PLUS of a virtual register and something else.  In that
2793          case, we want to emit the sum of the virtual register and the
2794          constant first and then add the other value.  This allows virtual
2795          register instantiation to simply modify the constant rather than
2796          creating another one around this addition.  */
2797       if (binoptab == add_optab && GET_CODE (op2) == CONST_INT
2798           && GET_CODE (XEXP (value, 0)) == PLUS
2799           && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
2800           && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
2801           && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
2802         {
2803           rtx temp = expand_binop (GET_MODE (value), binoptab,
2804                                    XEXP (XEXP (value, 0), 0), op2,
2805                                    subtarget, 0, OPTAB_LIB_WIDEN);
2806           return expand_binop (GET_MODE (value), binoptab, temp,
2807                                force_operand (XEXP (XEXP (value, 0), 1), 0),
2808                                target, 0, OPTAB_LIB_WIDEN);
2809         }
2810                                    
2811       tmp = force_operand (XEXP (value, 0), subtarget);
2812       return expand_binop (GET_MODE (value), binoptab, tmp,
2813                            force_operand (op2, NULL_RTX),
2814                            target, 0, OPTAB_LIB_WIDEN);
2815       /* We give UNSIGNEP = 0 to expand_binop
2816          because the only operations we are expanding here are signed ones.  */
2817     }
2818   return value;
2819 }
2820 \f
2821 /* Subroutine of expand_expr:
2822    save the non-copied parts (LIST) of an expr (LHS), and return a list
2823    which can restore these values to their previous values,
2824    should something modify their storage.  */
2825
2826 static tree
2827 save_noncopied_parts (lhs, list)
2828      tree lhs;
2829      tree list;
2830 {
2831   tree tail;
2832   tree parts = 0;
2833
2834   for (tail = list; tail; tail = TREE_CHAIN (tail))
2835     if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
2836       parts = chainon (parts, save_noncopied_parts (lhs, TREE_VALUE (tail)));
2837     else
2838       {
2839         tree part = TREE_VALUE (tail);
2840         tree part_type = TREE_TYPE (part);
2841         tree to_be_saved = build (COMPONENT_REF, part_type, lhs, part);
2842         rtx target = assign_stack_temp (TYPE_MODE (part_type),
2843                                         int_size_in_bytes (part_type), 0);
2844         if (! memory_address_p (TYPE_MODE (part_type), XEXP (target, 0)))
2845           target = change_address (target, TYPE_MODE (part_type), NULL_RTX);
2846         parts = tree_cons (to_be_saved,
2847                            build (RTL_EXPR, part_type, NULL_TREE,
2848                                   (tree) target),
2849                            parts);
2850         store_expr (TREE_PURPOSE (parts), RTL_EXPR_RTL (TREE_VALUE (parts)), 0);
2851       }
2852   return parts;
2853 }
2854
2855 /* Subroutine of expand_expr:
2856    record the non-copied parts (LIST) of an expr (LHS), and return a list
2857    which specifies the initial values of these parts.  */
2858
2859 static tree
2860 init_noncopied_parts (lhs, list)
2861      tree lhs;
2862      tree list;
2863 {
2864   tree tail;
2865   tree parts = 0;
2866
2867   for (tail = list; tail; tail = TREE_CHAIN (tail))
2868     if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
2869       parts = chainon (parts, init_noncopied_parts (lhs, TREE_VALUE (tail)));
2870     else
2871       {
2872         tree part = TREE_VALUE (tail);
2873         tree part_type = TREE_TYPE (part);
2874         tree to_be_initialized = build (COMPONENT_REF, part_type, lhs, part);
2875         parts = tree_cons (TREE_PURPOSE (tail), to_be_initialized, parts);
2876       }
2877   return parts;
2878 }
2879
2880 /* Subroutine of expand_expr: return nonzero iff there is no way that
2881    EXP can reference X, which is being modified.  */
2882
2883 static int
2884 safe_from_p (x, exp)
2885      rtx x;
2886      tree exp;
2887 {
2888   rtx exp_rtl = 0;
2889   int i, nops;
2890
2891   if (x == 0)
2892     return 1;
2893
2894   /* If this is a subreg of a hard register, declare it unsafe, otherwise,
2895      find the underlying pseudo.  */
2896   if (GET_CODE (x) == SUBREG)
2897     {
2898       x = SUBREG_REG (x);
2899       if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
2900         return 0;
2901     }
2902
2903   /* If X is a location in the outgoing argument area, it is always safe.  */
2904   if (GET_CODE (x) == MEM
2905       && (XEXP (x, 0) == virtual_outgoing_args_rtx
2906           || (GET_CODE (XEXP (x, 0)) == PLUS
2907               && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx)))
2908     return 1;
2909
2910   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
2911     {
2912     case 'd':
2913       exp_rtl = DECL_RTL (exp);
2914       break;
2915
2916     case 'c':
2917       return 1;
2918
2919     case 'x':
2920       if (TREE_CODE (exp) == TREE_LIST)
2921         return ((TREE_VALUE (exp) == 0
2922                  || safe_from_p (x, TREE_VALUE (exp)))
2923                 && (TREE_CHAIN (exp) == 0
2924                     || safe_from_p (x, TREE_CHAIN (exp))));
2925       else
2926         return 0;
2927
2928     case '1':
2929       return safe_from_p (x, TREE_OPERAND (exp, 0));
2930
2931     case '2':
2932     case '<':
2933       return (safe_from_p (x, TREE_OPERAND (exp, 0))
2934               && safe_from_p (x, TREE_OPERAND (exp, 1)));
2935
2936     case 'e':
2937     case 'r':
2938       /* Now do code-specific tests.  EXP_RTL is set to any rtx we find in
2939          the expression.  If it is set, we conflict iff we are that rtx or
2940          both are in memory.  Otherwise, we check all operands of the
2941          expression recursively.  */
2942
2943       switch (TREE_CODE (exp))
2944         {
2945         case ADDR_EXPR:
2946           return staticp (TREE_OPERAND (exp, 0));
2947
2948         case INDIRECT_REF:
2949           if (GET_CODE (x) == MEM)
2950             return 0;
2951           break;
2952
2953         case CALL_EXPR:
2954           exp_rtl = CALL_EXPR_RTL (exp);
2955           if (exp_rtl == 0)
2956             {
2957               /* Assume that the call will clobber all hard registers and
2958                  all of memory.  */
2959               if ((GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
2960                   || GET_CODE (x) == MEM)
2961                 return 0;
2962             }
2963
2964           break;
2965
2966         case RTL_EXPR:
2967           exp_rtl = RTL_EXPR_RTL (exp);
2968           if (exp_rtl == 0)
2969             /* We don't know what this can modify.  */
2970             return 0;
2971
2972           break;
2973
2974         case WITH_CLEANUP_EXPR:
2975           exp_rtl = RTL_EXPR_RTL (exp);
2976           break;
2977
2978         case SAVE_EXPR:
2979           exp_rtl = SAVE_EXPR_RTL (exp);
2980           break;
2981
2982         case BIND_EXPR:
2983           /* The only operand we look at is operand 1.  The rest aren't
2984              part of the expression.  */
2985           return safe_from_p (x, TREE_OPERAND (exp, 1));
2986
2987         case METHOD_CALL_EXPR:
2988           /* This takes a rtx argument, but shouldn't appear here. */
2989           abort ();
2990         }
2991
2992       /* If we have an rtx, we do not need to scan our operands.  */
2993       if (exp_rtl)
2994         break;
2995
2996       nops = tree_code_length[(int) TREE_CODE (exp)];
2997       for (i = 0; i < nops; i++)
2998         if (TREE_OPERAND (exp, i) != 0
2999             && ! safe_from_p (x, TREE_OPERAND (exp, i)))
3000           return 0;
3001     }
3002
3003   /* If we have an rtl, find any enclosed object.  Then see if we conflict
3004      with it.  */
3005   if (exp_rtl)
3006     {
3007       if (GET_CODE (exp_rtl) == SUBREG)
3008         {
3009           exp_rtl = SUBREG_REG (exp_rtl);
3010           if (GET_CODE (exp_rtl) == REG
3011               && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
3012             return 0;
3013         }
3014
3015       /* If the rtl is X, then it is not safe.  Otherwise, it is unless both
3016          are memory and EXP is not readonly.  */
3017       return ! (rtx_equal_p (x, exp_rtl)
3018                 || (GET_CODE (x) == MEM && GET_CODE (exp_rtl) == MEM
3019                     && ! TREE_READONLY (exp)));
3020     }
3021
3022   /* If we reach here, it is safe.  */
3023   return 1;
3024 }
3025
3026 /* Subroutine of expand_expr: return nonzero iff EXP is an
3027    expression whose type is statically determinable.  */
3028
3029 static int
3030 fixed_type_p (exp)
3031      tree exp;
3032 {
3033   if (TREE_CODE (exp) == PARM_DECL
3034       || TREE_CODE (exp) == VAR_DECL
3035       || TREE_CODE (exp) == CALL_EXPR || TREE_CODE (exp) == TARGET_EXPR
3036       || TREE_CODE (exp) == COMPONENT_REF
3037       || TREE_CODE (exp) == ARRAY_REF)
3038     return 1;
3039   return 0;
3040 }
3041 \f
3042 /* expand_expr: generate code for computing expression EXP.
3043    An rtx for the computed value is returned.  The value is never null.
3044    In the case of a void EXP, const0_rtx is returned.
3045
3046    The value may be stored in TARGET if TARGET is nonzero.
3047    TARGET is just a suggestion; callers must assume that
3048    the rtx returned may not be the same as TARGET.
3049
3050    If TARGET is CONST0_RTX, it means that the value will be ignored.
3051
3052    If TMODE is not VOIDmode, it suggests generating the
3053    result in mode TMODE.  But this is done only when convenient.
3054    Otherwise, TMODE is ignored and the value generated in its natural mode.
3055    TMODE is just a suggestion; callers must assume that
3056    the rtx returned may not have mode TMODE.
3057
3058    EXPAND_CONST_ADDRESS says that it is okay to return a MEM
3059    with a constant address even if that address is not normally legitimate.
3060    EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
3061
3062    If MODIFIER is EXPAND_SUM then when EXP is an addition
3063    we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
3064    or a nest of (PLUS ...) and (MINUS ...) where the terms are
3065    products as above, or REG or MEM, or constant.
3066    Ordinarily in such cases we would output mul or add instructions
3067    and then return a pseudo reg containing the sum.
3068
3069    EXPAND_INITIALIZER is much like EXPAND_SUM except that
3070    it also marks a label as absolutely required (it can't be dead).
3071    This is used for outputting expressions used in initializers.  */
3072
3073 rtx
3074 expand_expr (exp, target, tmode, modifier)
3075      register tree exp;
3076      rtx target;
3077      enum machine_mode tmode;
3078      enum expand_modifier modifier;
3079 {
3080   register rtx op0, op1, temp;
3081   tree type = TREE_TYPE (exp);
3082   int unsignedp = TREE_UNSIGNED (type);
3083   register enum machine_mode mode = TYPE_MODE (type);
3084   register enum tree_code code = TREE_CODE (exp);
3085   optab this_optab;
3086   /* Use subtarget as the target for operand 0 of a binary operation.  */
3087   rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
3088   rtx original_target = target;
3089   int ignore = target == const0_rtx;
3090   tree context;
3091
3092   /* Don't use hard regs as subtargets, because the combiner
3093      can only handle pseudo regs.  */
3094   if (subtarget && REGNO (subtarget) < FIRST_PSEUDO_REGISTER)
3095     subtarget = 0;
3096   /* Avoid subtargets inside loops,
3097      since they hide some invariant expressions.  */
3098   if (preserve_subexpressions_p ())
3099     subtarget = 0;
3100
3101   if (ignore) target = 0, original_target = 0;
3102
3103   /* If will do cse, generate all results into pseudo registers
3104      since 1) that allows cse to find more things
3105      and 2) otherwise cse could produce an insn the machine
3106      cannot support.  */
3107
3108   if (! cse_not_expected && mode != BLKmode && target
3109       && (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER))
3110     target = subtarget;
3111
3112   /* Ensure we reference a volatile object even if value is ignored.  */
3113   if (ignore && TREE_THIS_VOLATILE (exp)
3114       && mode != VOIDmode && mode != BLKmode)
3115     {
3116       target = gen_reg_rtx (mode);
3117       temp = expand_expr (exp, target, VOIDmode, modifier);
3118       if (temp != target)
3119         emit_move_insn (target, temp);
3120       return target;
3121     }
3122
3123   switch (code)
3124     {
3125     case LABEL_DECL:
3126       {
3127         tree function = decl_function_context (exp);
3128         /* Handle using a label in a containing function.  */
3129         if (function != current_function_decl && function != 0)
3130           {
3131             struct function *p = find_function_data (function);
3132             /* Allocate in the memory associated with the function
3133                that the label is in.  */
3134             push_obstacks (p->function_obstack,
3135                            p->function_maybepermanent_obstack);
3136
3137             p->forced_labels = gen_rtx (EXPR_LIST, VOIDmode,
3138                                         label_rtx (exp), p->forced_labels);
3139             pop_obstacks ();
3140           }
3141         else if (modifier == EXPAND_INITIALIZER)
3142           forced_labels = gen_rtx (EXPR_LIST, VOIDmode,
3143                                    label_rtx (exp), forced_labels);
3144         return gen_rtx (MEM, FUNCTION_MODE,
3145                         gen_rtx (LABEL_REF, Pmode, label_rtx (exp)));
3146       }
3147
3148     case PARM_DECL:
3149       if (DECL_RTL (exp) == 0)
3150         {
3151           error_with_decl (exp, "prior parameter's size depends on `%s'");
3152           return CONST0_RTX (mode);
3153         }
3154
3155     case FUNCTION_DECL:
3156     case VAR_DECL:
3157     case RESULT_DECL:
3158       if (DECL_RTL (exp) == 0)
3159         abort ();
3160       /* Ensure variable marked as used
3161          even if it doesn't go through a parser.  */
3162       TREE_USED (exp) = 1;
3163       /* Handle variables inherited from containing functions.  */
3164       context = decl_function_context (exp);
3165
3166       /* We treat inline_function_decl as an alias for the current function
3167          because that is the inline function whose vars, types, etc.
3168          are being merged into the current function.
3169          See expand_inline_function.  */
3170       if (context != 0 && context != current_function_decl
3171           && context != inline_function_decl
3172           /* If var is static, we don't need a static chain to access it.  */
3173           && ! (GET_CODE (DECL_RTL (exp)) == MEM
3174                 && CONSTANT_P (XEXP (DECL_RTL (exp), 0))))
3175         {
3176           rtx addr;
3177
3178           /* Mark as non-local and addressable.  */
3179           TREE_NONLOCAL (exp) = 1;
3180           mark_addressable (exp);
3181           if (GET_CODE (DECL_RTL (exp)) != MEM)
3182             abort ();
3183           addr = XEXP (DECL_RTL (exp), 0);
3184           if (GET_CODE (addr) == MEM)
3185             addr = gen_rtx (MEM, Pmode, fix_lexical_addr (XEXP (addr, 0), exp));
3186           else
3187             addr = fix_lexical_addr (addr, exp);
3188           return change_address (DECL_RTL (exp), mode, addr);
3189         }
3190
3191       /* This is the case of an array whose size is to be determined
3192          from its initializer, while the initializer is still being parsed.
3193          See expand_decl.  */
3194       if (GET_CODE (DECL_RTL (exp)) == MEM
3195           && GET_CODE (XEXP (DECL_RTL (exp), 0)) == REG)
3196         return change_address (DECL_RTL (exp), GET_MODE (DECL_RTL (exp)),
3197                                XEXP (DECL_RTL (exp), 0));
3198       if (GET_CODE (DECL_RTL (exp)) == MEM
3199           && modifier != EXPAND_CONST_ADDRESS
3200           && modifier != EXPAND_SUM
3201           && modifier != EXPAND_INITIALIZER)
3202         {
3203           /* DECL_RTL probably contains a constant address.
3204              On RISC machines where a constant address isn't valid,
3205              make some insns to get that address into a register.  */
3206           if (!memory_address_p (DECL_MODE (exp), XEXP (DECL_RTL (exp), 0))
3207               || (flag_force_addr
3208                   && CONSTANT_ADDRESS_P (XEXP (DECL_RTL (exp), 0))))
3209             return change_address (DECL_RTL (exp), VOIDmode,
3210                                    copy_rtx (XEXP (DECL_RTL (exp), 0)));
3211         }
3212       return DECL_RTL (exp);
3213
3214     case INTEGER_CST:
3215       return immed_double_const (TREE_INT_CST_LOW (exp),
3216                                  TREE_INT_CST_HIGH (exp),
3217                                  mode);
3218
3219     case CONST_DECL:
3220       return expand_expr (DECL_INITIAL (exp), target, VOIDmode, 0);
3221
3222     case REAL_CST:
3223       /* If optimized, generate immediate CONST_DOUBLE
3224          which will be turned into memory by reload if necessary. 
3225      
3226          We used to force a register so that loop.c could see it.  But
3227          this does not allow gen_* patterns to perform optimizations with
3228          the constants.  It also produces two insns in cases like "x = 1.0;".
3229          On most machines, floating-point constants are not permitted in
3230          many insns, so we'd end up copying it to a register in any case.
3231
3232          Now, we do the copying in expand_binop, if appropriate.  */
3233       return immed_real_const (exp);
3234
3235     case COMPLEX_CST:
3236     case STRING_CST:
3237       if (! TREE_CST_RTL (exp))
3238         output_constant_def (exp);
3239
3240       /* TREE_CST_RTL probably contains a constant address.
3241          On RISC machines where a constant address isn't valid,
3242          make some insns to get that address into a register.  */
3243       if (GET_CODE (TREE_CST_RTL (exp)) == MEM
3244           && modifier != EXPAND_CONST_ADDRESS
3245           && modifier != EXPAND_INITIALIZER
3246           && modifier != EXPAND_SUM
3247           && !memory_address_p (mode, XEXP (TREE_CST_RTL (exp), 0)))
3248         return change_address (TREE_CST_RTL (exp), VOIDmode,
3249                                copy_rtx (XEXP (TREE_CST_RTL (exp), 0)));
3250       return TREE_CST_RTL (exp);
3251
3252     case SAVE_EXPR:
3253       context = decl_function_context (exp);
3254       /* We treat inline_function_decl as an alias for the current function
3255          because that is the inline function whose vars, types, etc.
3256          are being merged into the current function.
3257          See expand_inline_function.  */
3258       if (context == current_function_decl || context == inline_function_decl)
3259         context = 0;
3260
3261       /* If this is non-local, handle it.  */
3262       if (context)
3263         {
3264           temp = SAVE_EXPR_RTL (exp);
3265           if (temp && GET_CODE (temp) == REG)
3266             {
3267               put_var_into_stack (exp);
3268               temp = SAVE_EXPR_RTL (exp);
3269             }
3270           if (temp == 0 || GET_CODE (temp) != MEM)
3271             abort ();
3272           return change_address (temp, mode,
3273                                  fix_lexical_addr (XEXP (temp, 0), exp));
3274         }
3275       if (SAVE_EXPR_RTL (exp) == 0)
3276         {
3277           if (mode == BLKmode)
3278             temp
3279               = assign_stack_temp (mode,
3280                                    int_size_in_bytes (TREE_TYPE (exp)), 0);
3281           else
3282             temp = gen_reg_rtx (mode);
3283           SAVE_EXPR_RTL (exp) = temp;
3284           store_expr (TREE_OPERAND (exp, 0), temp, 0);
3285           if (!optimize && GET_CODE (temp) == REG)
3286             save_expr_regs = gen_rtx (EXPR_LIST, VOIDmode, temp,
3287                                       save_expr_regs);
3288         }
3289       return SAVE_EXPR_RTL (exp);
3290
3291     case EXIT_EXPR:
3292       /* Exit the current loop if the body-expression is true.  */
3293       {
3294         rtx label = gen_label_rtx ();
3295         do_jump (TREE_OPERAND (exp, 0), label, NULL_RTX);
3296         expand_exit_loop (NULL_PTR);
3297         emit_label (label);
3298       }
3299       return const0_rtx;
3300
3301     case LOOP_EXPR:
3302       expand_start_loop (1);
3303       expand_expr_stmt (TREE_OPERAND (exp, 0));
3304       expand_end_loop ();
3305
3306       return const0_rtx;
3307
3308     case BIND_EXPR:
3309       {
3310         tree vars = TREE_OPERAND (exp, 0);
3311         int vars_need_expansion = 0;
3312
3313         /* Need to open a binding contour here because
3314            if there are any cleanups they most be contained here.  */
3315         expand_start_bindings (0);
3316
3317         /* Mark the corresponding BLOCK for output.  */
3318         if (TREE_OPERAND (exp, 2) != 0)
3319           TREE_USED (TREE_OPERAND (exp, 2)) = 1;
3320
3321         /* If VARS have not yet been expanded, expand them now.  */
3322         while (vars)
3323           {
3324             if (DECL_RTL (vars) == 0)
3325               {
3326                 vars_need_expansion = 1;
3327                 expand_decl (vars);
3328               }
3329             expand_decl_init (vars);
3330             vars = TREE_CHAIN (vars);
3331           }
3332
3333         temp = expand_expr (TREE_OPERAND (exp, 1), target, tmode, modifier);
3334
3335         expand_end_bindings (TREE_OPERAND (exp, 0), 0, 0);
3336
3337         return temp;
3338       }
3339
3340     case RTL_EXPR:
3341       if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
3342         abort ();
3343       emit_insns (RTL_EXPR_SEQUENCE (exp));
3344       RTL_EXPR_SEQUENCE (exp) = const0_rtx;
3345       return RTL_EXPR_RTL (exp);
3346
3347     case CONSTRUCTOR:
3348       /* All elts simple constants => refer to a constant in memory.  But
3349          if this is a non-BLKmode mode, let it store a field at a time
3350          since that should make a CONST_INT or CONST_DOUBLE when we
3351          fold.  */
3352       if (TREE_STATIC (exp) && (mode == BLKmode || TREE_ADDRESSABLE (exp)))
3353         {
3354           rtx constructor = output_constant_def (exp);
3355           if (modifier != EXPAND_CONST_ADDRESS
3356               && modifier != EXPAND_INITIALIZER
3357               && modifier != EXPAND_SUM
3358               && !memory_address_p (GET_MODE (constructor),
3359                                     XEXP (constructor, 0)))
3360             constructor = change_address (constructor, VOIDmode,
3361                                           XEXP (constructor, 0));
3362           return constructor;
3363         }
3364
3365       if (ignore)
3366         {
3367           tree elt;
3368           for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
3369             expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
3370           return const0_rtx;
3371         }
3372       else
3373         {
3374           if (target == 0 || ! safe_from_p (target, exp))
3375             {
3376               if (mode != BLKmode && ! TREE_ADDRESSABLE (exp))
3377                 target = gen_reg_rtx (mode);
3378               else
3379                 {
3380                   rtx safe_target = assign_stack_temp (mode, int_size_in_bytes (type), 0);
3381                   if (target)
3382                     MEM_IN_STRUCT_P (safe_target) = MEM_IN_STRUCT_P (target);
3383                   target = safe_target;
3384                 }
3385             }
3386           store_constructor (exp, target);
3387           return target;
3388         }
3389
3390     case INDIRECT_REF:
3391       {
3392         tree exp1 = TREE_OPERAND (exp, 0);
3393         tree exp2;
3394
3395         /* A SAVE_EXPR as the address in an INDIRECT_EXPR is generated
3396            for  *PTR += ANYTHING  where PTR is put inside the SAVE_EXPR.
3397            This code has the same general effect as simply doing
3398            expand_expr on the save expr, except that the expression PTR
3399            is computed for use as a memory address.  This means different
3400            code, suitable for indexing, may be generated.  */
3401         if (TREE_CODE (exp1) == SAVE_EXPR
3402             && SAVE_EXPR_RTL (exp1) == 0
3403             && TREE_CODE (exp2 = TREE_OPERAND (exp1, 0)) != ERROR_MARK
3404             && TYPE_MODE (TREE_TYPE (exp1)) == Pmode
3405             && TYPE_MODE (TREE_TYPE (exp2)) == Pmode)
3406           {
3407             temp = expand_expr (TREE_OPERAND (exp1, 0), NULL_RTX,
3408                                 VOIDmode, EXPAND_SUM);
3409             op0 = memory_address (mode, temp);
3410             op0 = copy_all_regs (op0);
3411             SAVE_EXPR_RTL (exp1) = op0;
3412           }
3413         else
3414           {
3415             op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
3416             op0 = memory_address (mode, op0);
3417           }
3418
3419         temp = gen_rtx (MEM, mode, op0);
3420         /* If address was computed by addition,
3421            mark this as an element of an aggregate.  */
3422         if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
3423             || (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR
3424                 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == PLUS_EXPR)
3425             || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
3426             || TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
3427             || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE
3428             || (TREE_CODE (exp1) == ADDR_EXPR
3429                 && (exp2 = TREE_OPERAND (exp1, 0))
3430                 && (TREE_CODE (TREE_TYPE (exp2)) == ARRAY_TYPE
3431                     || TREE_CODE (TREE_TYPE (exp2)) == RECORD_TYPE
3432                     || TREE_CODE (TREE_TYPE (exp2)) == UNION_TYPE)))
3433           MEM_IN_STRUCT_P (temp) = 1;
3434         MEM_VOLATILE_P (temp) = TREE_THIS_VOLATILE (exp) || flag_volatile;
3435 #if 0 /* It is incorrectto set RTX_UNCHANGING_P here, because the fact that
3436          a location is accessed through a pointer to const does not mean
3437          that the value there can never change.  */
3438         RTX_UNCHANGING_P (temp) = TREE_READONLY (exp);
3439 #endif
3440         return temp;
3441       }
3442
3443     case ARRAY_REF:
3444       if (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST
3445           || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3446         {
3447           /* Nonconstant array index or nonconstant element size.
3448              Generate the tree for *(&array+index) and expand that,
3449              except do it in a language-independent way
3450              and don't complain about non-lvalue arrays.
3451              `mark_addressable' should already have been called
3452              for any array for which this case will be reached.  */
3453
3454           /* Don't forget the const or volatile flag from the array element. */
3455           tree variant_type = build_type_variant (type,
3456                                                   TREE_READONLY (exp),
3457                                                   TREE_THIS_VOLATILE (exp));
3458           tree array_adr = build1 (ADDR_EXPR, build_pointer_type (variant_type),
3459                                    TREE_OPERAND (exp, 0));
3460           tree index = TREE_OPERAND (exp, 1);
3461           tree elt;
3462
3463           /* Convert the integer argument to a type the same size as a pointer
3464              so the multiply won't overflow spuriously.  */
3465           if (TYPE_PRECISION (TREE_TYPE (index)) != POINTER_SIZE)
3466             index = convert (type_for_size (POINTER_SIZE, 0), index);
3467
3468           /* Don't think the address has side effects
3469              just because the array does.
3470              (In some cases the address might have side effects,
3471              and we fail to record that fact here.  However, it should not
3472              matter, since expand_expr should not care.)  */
3473           TREE_SIDE_EFFECTS (array_adr) = 0;
3474
3475           elt = build1 (INDIRECT_REF, type,
3476                         fold (build (PLUS_EXPR, TYPE_POINTER_TO (variant_type),
3477                                      array_adr,
3478                                      fold (build (MULT_EXPR,
3479                                                   TYPE_POINTER_TO (variant_type),
3480                                                   index, size_in_bytes (type))))));
3481
3482           /* Volatility, etc., of new expression is same as old expression.  */
3483           TREE_SIDE_EFFECTS (elt) = TREE_SIDE_EFFECTS (exp);
3484           TREE_THIS_VOLATILE (elt) = TREE_THIS_VOLATILE (exp);
3485           TREE_READONLY (elt) = TREE_READONLY (exp);
3486
3487           return expand_expr (elt, target, tmode, modifier);
3488         }
3489
3490       /* Fold an expression like: "foo"[2].
3491          This is not done in fold so it won't happen inside &.  */
3492       {
3493         int i;
3494         tree arg0 = TREE_OPERAND (exp, 0);
3495         tree arg1 = TREE_OPERAND (exp, 1);
3496
3497         if (TREE_CODE (arg0) == STRING_CST
3498             && TREE_CODE (arg1) == INTEGER_CST
3499             && !TREE_INT_CST_HIGH (arg1)
3500             && (i = TREE_INT_CST_LOW (arg1)) < TREE_STRING_LENGTH (arg0))
3501           {
3502             if (TREE_TYPE (TREE_TYPE (arg0)) == integer_type_node)
3503               {
3504                 exp = build_int_2 (((int *)TREE_STRING_POINTER (arg0))[i], 0);
3505                 TREE_TYPE (exp) = integer_type_node;
3506                 return expand_expr (exp, target, tmode, modifier);
3507               }
3508             if (TREE_TYPE (TREE_TYPE (arg0)) == char_type_node)
3509               {
3510                 exp = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0);
3511                 TREE_TYPE (exp) = integer_type_node;
3512                 return expand_expr (convert (TREE_TYPE (TREE_TYPE (arg0)), exp), target, tmode, modifier);
3513               }
3514           }
3515       }
3516
3517       /* If this is a constant index into a constant array,
3518          just get the value from the array.  Handle both the cases when
3519          we have an explicit constructor and when our operand is a variable
3520          that was declared const.  */
3521
3522       if (TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR
3523           && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0)))
3524         {
3525           tree index = fold (TREE_OPERAND (exp, 1));
3526           if (TREE_CODE (index) == INTEGER_CST
3527               && TREE_INT_CST_HIGH (index) == 0)
3528             {
3529               int i = TREE_INT_CST_LOW (index);
3530               tree elem = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
3531
3532               while (elem && i--)
3533                 elem = TREE_CHAIN (elem);
3534               if (elem)
3535                 return expand_expr (fold (TREE_VALUE (elem)), target,
3536                                     tmode, modifier);
3537             }
3538         }
3539           
3540       else if (TREE_READONLY (TREE_OPERAND (exp, 0))
3541                && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
3542                && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == ARRAY_TYPE
3543                && TREE_CODE (TREE_OPERAND (exp, 0)) == VAR_DECL
3544                && DECL_INITIAL (TREE_OPERAND (exp, 0))
3545                && optimize >= 1
3546                && (TREE_CODE (DECL_INITIAL (TREE_OPERAND (exp, 0)))
3547                    != ERROR_MARK))
3548         {
3549           tree index = fold (TREE_OPERAND (exp, 1));
3550           if (TREE_CODE (index) == INTEGER_CST
3551               && TREE_INT_CST_HIGH (index) == 0)
3552             {
3553               int i = TREE_INT_CST_LOW (index);
3554               tree init = DECL_INITIAL (TREE_OPERAND (exp, 0));
3555
3556               if (TREE_CODE (init) == CONSTRUCTOR)
3557                 {
3558                   tree elem = CONSTRUCTOR_ELTS (init);
3559
3560                   while (elem && i--)
3561                     elem = TREE_CHAIN (elem);
3562                   if (elem)
3563                     return expand_expr (fold (TREE_VALUE (elem)), target,
3564                                         tmode, modifier);
3565                 }
3566               else if (TREE_CODE (init) == STRING_CST
3567                        && i < TREE_STRING_LENGTH (init))
3568                 {
3569                   temp = GEN_INT (TREE_STRING_POINTER (init)[i]);
3570                   return convert_to_mode (mode, temp, 0);
3571                 }
3572             }
3573         }
3574       /* Treat array-ref with constant index as a component-ref.  */
3575
3576     case COMPONENT_REF:
3577     case BIT_FIELD_REF:
3578       /* If the operand is a CONSTRUCTOR, we can just extract the
3579          appropriate field if it is present.  */
3580       if (code != ARRAY_REF
3581           && TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR)
3582         {
3583           tree elt;
3584
3585           for (elt = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)); elt;
3586                elt = TREE_CHAIN (elt))
3587             if (TREE_PURPOSE (elt) == TREE_OPERAND (exp, 1))
3588               return expand_expr (TREE_VALUE (elt), target, tmode, modifier);
3589         }
3590
3591       {
3592         enum machine_mode mode1;
3593         int bitsize;
3594         int bitpos;
3595         tree offset;
3596         int volatilep = 0;
3597         tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
3598                                         &mode1, &unsignedp, &volatilep);
3599
3600         /* In some cases, we will be offsetting OP0's address by a constant.
3601            So get it as a sum, if possible.  If we will be using it
3602            directly in an insn, we validate it.  */
3603         op0 = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_SUM);
3604
3605         /* If this is a constant, put it into a register if it is a
3606            legimate constant and memory if it isn't.  */
3607         if (CONSTANT_P (op0))
3608           {
3609             enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem));
3610             if (LEGITIMATE_CONSTANT_P (op0))
3611               op0 = force_reg (mode, op0);
3612             else
3613               op0 = validize_mem (force_const_mem (mode, op0));
3614           }
3615
3616         if (offset != 0)
3617           {
3618             rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
3619
3620             if (GET_CODE (op0) != MEM)
3621               abort ();
3622             op0 = change_address (op0, VOIDmode,
3623                                   gen_rtx (PLUS, Pmode, XEXP (op0, 0),
3624                                            force_reg (Pmode, offset_rtx)));
3625           }
3626
3627         /* Don't forget about volatility even if this is a bitfield.  */
3628         if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0))
3629           {
3630             op0 = copy_rtx (op0);
3631             MEM_VOLATILE_P (op0) = 1;
3632           }
3633
3634         if (mode1 == VOIDmode
3635             || (mode1 != BLKmode && ! direct_load[(int) mode1])
3636             || GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
3637           {
3638             /* In cases where an aligned union has an unaligned object
3639                as a field, we might be extracting a BLKmode value from
3640                an integer-mode (e.g., SImode) object.  Handle this case
3641                by doing the extract into an object as wide as the field
3642                (which we know to be the width of a basic mode), then
3643                storing into memory, and changing the mode to BLKmode.  */
3644             enum machine_mode ext_mode = mode;
3645
3646             if (ext_mode == BLKmode)
3647               ext_mode = mode_for_size (bitsize, MODE_INT, 1);
3648
3649             if (ext_mode == BLKmode)
3650               abort ();
3651
3652             op0 = extract_bit_field (validize_mem (op0), bitsize, bitpos,
3653                                      unsignedp, target, ext_mode, ext_mode,
3654                                      TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT,
3655                                      int_size_in_bytes (TREE_TYPE (tem)));
3656             if (mode == BLKmode)
3657               {
3658                 rtx new = assign_stack_temp (ext_mode,
3659                                              bitsize / BITS_PER_UNIT, 0);
3660
3661                 emit_move_insn (new, op0);
3662                 op0 = copy_rtx (new);
3663                 PUT_MODE (op0, BLKmode);
3664               }
3665
3666             return op0;
3667           }
3668
3669         /* Get a reference to just this component.  */
3670         if (modifier == EXPAND_CONST_ADDRESS
3671             || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
3672           op0 = gen_rtx (MEM, mode1, plus_constant (XEXP (op0, 0),
3673                                                     (bitpos / BITS_PER_UNIT)));
3674         else
3675           op0 = change_address (op0, mode1,
3676                                 plus_constant (XEXP (op0, 0),
3677                                                (bitpos / BITS_PER_UNIT)));
3678         MEM_IN_STRUCT_P (op0) = 1;
3679         MEM_VOLATILE_P (op0) |= volatilep;
3680         if (mode == mode1 || mode1 == BLKmode || mode1 == tmode)
3681           return op0;
3682         if (target == 0)
3683           target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
3684         convert_move (target, op0, unsignedp);
3685         return target;
3686       }
3687
3688     case OFFSET_REF:
3689       {
3690         tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
3691         tree addr = build (PLUS_EXPR, type, base, TREE_OPERAND (exp, 1));
3692         op0 = expand_expr (addr, NULL_RTX, VOIDmode, EXPAND_SUM);
3693         temp = gen_rtx (MEM, mode, memory_address (mode, op0));
3694         MEM_IN_STRUCT_P (temp) = 1;
3695         MEM_VOLATILE_P (temp) = TREE_THIS_VOLATILE (exp) || flag_volatile;
3696 #if 0 /* It is incorrectto set RTX_UNCHANGING_P here, because the fact that
3697          a location is accessed through a pointer to const does not mean
3698          that the value there can never change.  */
3699         RTX_UNCHANGING_P (temp) = TREE_READONLY (exp);
3700 #endif
3701         return temp;
3702       }
3703
3704       /* Intended for a reference to a buffer of a file-object in Pascal.
3705          But it's not certain that a special tree code will really be
3706          necessary for these.  INDIRECT_REF might work for them.  */
3707     case BUFFER_REF:
3708       abort ();
3709
3710     case WITH_CLEANUP_EXPR:
3711       if (RTL_EXPR_RTL (exp) == 0)
3712         {
3713           RTL_EXPR_RTL (exp)
3714             = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
3715           cleanups_this_call
3716             = tree_cons (NULL_TREE, TREE_OPERAND (exp, 2), cleanups_this_call);
3717           /* That's it for this cleanup.  */
3718           TREE_OPERAND (exp, 2) = 0;
3719         }
3720       return RTL_EXPR_RTL (exp);
3721
3722     case CALL_EXPR:
3723       /* Check for a built-in function.  */
3724       if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
3725           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == FUNCTION_DECL
3726           && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
3727         return expand_builtin (exp, target, subtarget, tmode, ignore);
3728       /* If this call was expanded already by preexpand_calls,
3729          just return the result we got.  */
3730       if (CALL_EXPR_RTL (exp) != 0)
3731         return CALL_EXPR_RTL (exp);
3732       return expand_call (exp, target, ignore);
3733
3734     case NON_LVALUE_EXPR:
3735     case NOP_EXPR:
3736     case CONVERT_EXPR:
3737     case REFERENCE_EXPR:
3738       if (TREE_CODE (type) == VOID_TYPE || ignore)
3739         {
3740           expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
3741           return const0_rtx;
3742         }
3743       if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
3744         return expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, modifier);
3745       if (TREE_CODE (type) == UNION_TYPE)
3746         {
3747           tree valtype = TREE_TYPE (TREE_OPERAND (exp, 0));
3748           if (target == 0)
3749             {
3750               if (mode == BLKmode)
3751                 {
3752                   if (TYPE_SIZE (type) == 0
3753                       || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3754                     abort ();
3755                   target = assign_stack_temp (BLKmode,
3756                                               (TREE_INT_CST_LOW (TYPE_SIZE (type))
3757                                                + BITS_PER_UNIT - 1)
3758                                               / BITS_PER_UNIT, 0);
3759                 }
3760               else
3761                 target = gen_reg_rtx (mode);
3762             }
3763           if (GET_CODE (target) == MEM)
3764             /* Store data into beginning of memory target.  */
3765             store_expr (TREE_OPERAND (exp, 0),
3766                         change_address (target, TYPE_MODE (valtype), 0),
3767                         NULL_RTX);
3768           else if (GET_CODE (target) == REG)
3769             /* Store this field into a union of the proper type.  */
3770             store_field (target, GET_MODE_BITSIZE (TYPE_MODE (valtype)), 0,
3771                          TYPE_MODE (valtype), TREE_OPERAND (exp, 0),
3772                          VOIDmode, 0, 1,
3773                          int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0))));
3774           else
3775             abort ();
3776
3777           /* Return the entire union.  */
3778           return target;
3779         }
3780       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, 0);
3781       if (GET_MODE (op0) == mode || GET_MODE (op0) == VOIDmode)
3782         return op0;
3783       if (flag_force_mem && GET_CODE (op0) == MEM)
3784         op0 = copy_to_reg (op0);
3785
3786       if (target == 0)
3787         return convert_to_mode (mode, op0, TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
3788       else
3789         convert_move (target, op0, TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
3790       return target;
3791
3792     case PLUS_EXPR:
3793       /* We come here from MINUS_EXPR when the second operand is a constant. */
3794     plus_expr:
3795       this_optab = add_optab;
3796
3797       /* If we are adding a constant, an RTL_EXPR that is sp, fp, or ap, and
3798          something else, make sure we add the register to the constant and
3799          then to the other thing.  This case can occur during strength
3800          reduction and doing it this way will produce better code if the
3801          frame pointer or argument pointer is eliminated.
3802
3803          fold-const.c will ensure that the constant is always in the inner
3804          PLUS_EXPR, so the only case we need to do anything about is if
3805          sp, ap, or fp is our second argument, in which case we must swap
3806          the innermost first argument and our second argument.  */
3807
3808       if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
3809           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 1)) == INTEGER_CST
3810           && TREE_CODE (TREE_OPERAND (exp, 1)) == RTL_EXPR
3811           && (RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == frame_pointer_rtx
3812               || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == stack_pointer_rtx
3813               || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == arg_pointer_rtx))
3814         {
3815           tree t = TREE_OPERAND (exp, 1);
3816
3817           TREE_OPERAND (exp, 1) = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3818           TREE_OPERAND (TREE_OPERAND (exp, 0), 0) = t;
3819         }
3820
3821       /* If the result is to be Pmode and we are adding an integer to
3822          something, we might be forming a constant.  So try to use
3823          plus_constant.  If it produces a sum and we can't accept it,
3824          use force_operand.  This allows P = &ARR[const] to generate
3825          efficient code on machines where a SYMBOL_REF is not a valid
3826          address.
3827
3828          If this is an EXPAND_SUM call, always return the sum.  */
3829       if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
3830           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
3831           && (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
3832               || mode == Pmode))
3833         {
3834           op1 = expand_expr (TREE_OPERAND (exp, 1), subtarget, VOIDmode,
3835                              EXPAND_SUM);
3836           op1 = plus_constant (op1, TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)));
3837           if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
3838             op1 = force_operand (op1, target);
3839           return op1;
3840         }
3841
3842       else if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
3843                && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_INT
3844                && (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
3845                    || mode == Pmode))
3846         {
3847           op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
3848                              EXPAND_SUM);
3849           op0 = plus_constant (op0, TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)));
3850           if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
3851             op0 = force_operand (op0, target);
3852           return op0;
3853         }
3854
3855       /* No sense saving up arithmetic to be done
3856          if it's all in the wrong mode to form part of an address.
3857          And force_operand won't know whether to sign-extend or
3858          zero-extend.  */
3859       if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
3860           || mode != Pmode) goto binop;
3861
3862       preexpand_calls (exp);
3863       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
3864         subtarget = 0;
3865
3866       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
3867       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
3868
3869       /* Make sure any term that's a sum with a constant comes last.  */
3870       if (GET_CODE (op0) == PLUS
3871           && CONSTANT_P (XEXP (op0, 1)))
3872         {
3873           temp = op0;
3874           op0 = op1;
3875           op1 = temp;
3876         }
3877       /* If adding to a sum including a constant,
3878          associate it to put the constant outside.  */
3879       if (GET_CODE (op1) == PLUS
3880           && CONSTANT_P (XEXP (op1, 1)))
3881         {
3882           rtx constant_term = const0_rtx;
3883
3884           temp = simplify_binary_operation (PLUS, mode, XEXP (op1, 0), op0);
3885           if (temp != 0)
3886             op0 = temp;
3887           /* Ensure that MULT comes first if there is one.  */
3888           else if (GET_CODE (op0) == MULT)
3889             op0 = gen_rtx (PLUS, mode, op0, XEXP (op1, 0));
3890           else
3891             op0 = gen_rtx (PLUS, mode, XEXP (op1, 0), op0);
3892
3893           /* Let's also eliminate constants from op0 if possible.  */
3894           op0 = eliminate_constant_term (op0, &constant_term);
3895
3896           /* CONSTANT_TERM and XEXP (op1, 1) are known to be constant, so
3897              their sum should be a constant.  Form it into OP1, since the 
3898              result we want will then be OP0 + OP1.  */
3899
3900           temp = simplify_binary_operation (PLUS, mode, constant_term,
3901                                             XEXP (op1, 1));
3902           if (temp != 0)
3903             op1 = temp;
3904           else
3905             op1 = gen_rtx (PLUS, mode, constant_term, XEXP (op1, 1));
3906         }
3907
3908       /* Put a constant term last and put a multiplication first.  */
3909       if (CONSTANT_P (op0) || GET_CODE (op1) == MULT)
3910         temp = op1, op1 = op0, op0 = temp;
3911
3912       temp = simplify_binary_operation (PLUS, mode, op0, op1);
3913       return temp ? temp : gen_rtx (PLUS, mode, op0, op1);
3914
3915     case MINUS_EXPR:
3916       /* Handle difference of two symbolic constants,
3917          for the sake of an initializer.  */
3918       if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
3919           && really_constant_p (TREE_OPERAND (exp, 0))
3920           && really_constant_p (TREE_OPERAND (exp, 1)))
3921         {
3922           rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX,
3923                                  VOIDmode, modifier);
3924           rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
3925                                  VOIDmode, modifier);
3926           return gen_rtx (MINUS, mode, op0, op1);
3927         }
3928       /* Convert A - const to A + (-const).  */
3929       if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
3930         {
3931           exp = build (PLUS_EXPR, type, TREE_OPERAND (exp, 0),
3932                        fold (build1 (NEGATE_EXPR, type,
3933                                      TREE_OPERAND (exp, 1))));
3934           goto plus_expr;
3935         }
3936       this_optab = sub_optab;
3937       goto binop;
3938
3939     case MULT_EXPR:
3940       preexpand_calls (exp);
3941       /* If first operand is constant, swap them.
3942          Thus the following special case checks need only
3943          check the second operand.  */
3944       if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST)
3945         {
3946           register tree t1 = TREE_OPERAND (exp, 0);
3947           TREE_OPERAND (exp, 0) = TREE_OPERAND (exp, 1);
3948           TREE_OPERAND (exp, 1) = t1;
3949         }
3950
3951       /* Attempt to return something suitable for generating an
3952          indexed address, for machines that support that.  */
3953
3954       if (modifier == EXPAND_SUM && mode == Pmode
3955           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
3956           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
3957         {
3958           op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, EXPAND_SUM);
3959
3960           /* Apply distributive law if OP0 is x+c.  */
3961           if (GET_CODE (op0) == PLUS
3962               && GET_CODE (XEXP (op0, 1)) == CONST_INT)
3963             return gen_rtx (PLUS, mode,
3964                             gen_rtx (MULT, mode, XEXP (op0, 0),
3965                                      GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))),
3966                             GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))
3967                                      * INTVAL (XEXP (op0, 1))));
3968
3969           if (GET_CODE (op0) != REG)
3970             op0 = force_operand (op0, NULL_RTX);
3971           if (GET_CODE (op0) != REG)
3972             op0 = copy_to_mode_reg (mode, op0);
3973
3974           return gen_rtx (MULT, mode, op0,
3975                           GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))));
3976         }
3977
3978       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
3979         subtarget = 0;
3980
3981       /* Check for multiplying things that have been extended
3982          from a narrower type.  If this machine supports multiplying
3983          in that narrower type with a result in the desired type,
3984          do it that way, and avoid the explicit type-conversion.  */
3985       if (TREE_CODE (TREE_OPERAND (exp, 0)) == NOP_EXPR
3986           && TREE_CODE (type) == INTEGER_TYPE
3987           && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
3988               < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))
3989           && ((TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
3990                && int_fits_type_p (TREE_OPERAND (exp, 1),
3991                                    TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
3992                /* Don't use a widening multiply if a shift will do.  */
3993                && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1))))
3994                     > HOST_BITS_PER_WIDE_INT)
3995                    || exact_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))) < 0))
3996               ||
3997               (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
3998                && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
3999                    ==
4000                    TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))))
4001                /* If both operands are extended, they must either both
4002                   be zero-extended or both be sign-extended.  */
4003                && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
4004                    ==
4005                    TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))))))
4006         {
4007           enum machine_mode innermode
4008             = TYPE_MODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)));
4009           this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
4010                         ? umul_widen_optab : smul_widen_optab);
4011           if (mode == GET_MODE_WIDER_MODE (innermode)
4012               && this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4013             {
4014               op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
4015                                  NULL_RTX, VOIDmode, 0);
4016               if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
4017                 op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
4018                                    VOIDmode, 0);
4019               else
4020                 op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
4021                                    NULL_RTX, VOIDmode, 0);
4022               goto binop2;
4023             }
4024         }
4025       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4026       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
4027       return expand_mult (mode, op0, op1, target, unsignedp);
4028
4029     case TRUNC_DIV_EXPR:
4030     case FLOOR_DIV_EXPR:
4031     case CEIL_DIV_EXPR:
4032     case ROUND_DIV_EXPR:
4033     case EXACT_DIV_EXPR:
4034       preexpand_calls (exp);
4035       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
4036         subtarget = 0;
4037       /* Possible optimization: compute the dividend with EXPAND_SUM
4038          then if the divisor is constant can optimize the case
4039          where some terms of the dividend have coeffs divisible by it.  */
4040       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4041       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
4042       return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
4043
4044     case RDIV_EXPR:
4045       this_optab = flodiv_optab;
4046       goto binop;
4047
4048     case TRUNC_MOD_EXPR:
4049     case FLOOR_MOD_EXPR:
4050     case CEIL_MOD_EXPR:
4051     case ROUND_MOD_EXPR:
4052       preexpand_calls (exp);
4053       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
4054         subtarget = 0;
4055       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4056       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
4057       return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
4058
4059     case FIX_ROUND_EXPR:
4060     case FIX_FLOOR_EXPR:
4061     case FIX_CEIL_EXPR:
4062       abort ();                 /* Not used for C.  */
4063
4064     case FIX_TRUNC_EXPR:
4065       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
4066       if (target == 0)
4067         target = gen_reg_rtx (mode);
4068       expand_fix (target, op0, unsignedp);
4069       return target;
4070
4071     case FLOAT_EXPR:
4072       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
4073       if (target == 0)
4074         target = gen_reg_rtx (mode);
4075       /* expand_float can't figure out what to do if FROM has VOIDmode.
4076          So give it the correct mode.  With -O, cse will optimize this.  */
4077       if (GET_MODE (op0) == VOIDmode)
4078         op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))),
4079                                 op0);
4080       expand_float (target, op0,
4081                     TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
4082       return target;
4083
4084     case NEGATE_EXPR:
4085       op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
4086       temp = expand_unop (mode, neg_optab, op0, target, 0);
4087       if (temp == 0)
4088         abort ();
4089       return temp;
4090
4091     case ABS_EXPR:
4092       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4093
4094       /* Unsigned abs is simply the operand.  Testing here means we don't
4095          risk generating incorrect code below.  */
4096       if (TREE_UNSIGNED (type))
4097         return op0;
4098
4099       /* First try to do it with a special abs instruction.  */
4100       temp = expand_unop (mode, abs_optab, op0, target, 0);
4101       if (temp != 0)
4102         return temp;
4103
4104       /* If this machine has expensive jumps, we can do integer absolute
4105          value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
4106          where W is the width of MODE.  */
4107
4108       if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
4109         {
4110           rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
4111                                        size_int (GET_MODE_BITSIZE (mode) - 1),
4112                                        NULL_RTX, 0);
4113
4114           temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
4115                                OPTAB_LIB_WIDEN);
4116           if (temp != 0)
4117             temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
4118                                  OPTAB_LIB_WIDEN);
4119
4120           if (temp != 0)
4121             return temp;
4122         }
4123
4124       /* If that does not win, use conditional jump and negate.  */
4125       target = original_target;
4126       temp = gen_label_rtx ();
4127       if (target == 0 || ! safe_from_p (target, TREE_OPERAND (exp, 0))
4128           || (GET_CODE (target) == REG
4129               && REGNO (target) < FIRST_PSEUDO_REGISTER))
4130         target = gen_reg_rtx (mode);
4131       emit_move_insn (target, op0);
4132       emit_cmp_insn (target,
4133                      expand_expr (convert (type, integer_zero_node),
4134                                   NULL_RTX, VOIDmode, 0),
4135                      GE, NULL_RTX, mode, 0, 0);
4136       NO_DEFER_POP;
4137       emit_jump_insn (gen_bge (temp));
4138       op0 = expand_unop (mode, neg_optab, target, target, 0);
4139       if (op0 != target)
4140         emit_move_insn (target, op0);
4141       emit_label (temp);
4142       OK_DEFER_POP;
4143       return target;
4144
4145     case MAX_EXPR:
4146     case MIN_EXPR:
4147       target = original_target;
4148       if (target == 0 || ! safe_from_p (target, TREE_OPERAND (exp, 1))
4149           || (GET_CODE (target) == REG
4150               && REGNO (target) < FIRST_PSEUDO_REGISTER))
4151         target = gen_reg_rtx (mode);
4152       op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
4153       op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
4154
4155       /* First try to do it with a special MIN or MAX instruction.
4156          If that does not win, use a conditional jump to select the proper
4157          value.  */
4158       this_optab = (TREE_UNSIGNED (type)
4159                     ? (code == MIN_EXPR ? umin_optab : umax_optab)
4160                     : (code == MIN_EXPR ? smin_optab : smax_optab));
4161
4162       temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
4163                            OPTAB_WIDEN);
4164       if (temp != 0)
4165         return temp;
4166
4167       if (target != op0)
4168         emit_move_insn (target, op0);
4169       op0 = gen_label_rtx ();
4170       if (code == MAX_EXPR)
4171         temp = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1)))
4172                 ? compare_from_rtx (target, op1, GEU, 1, mode, NULL_RTX, 0)
4173                 : compare_from_rtx (target, op1, GE, 0, mode, NULL_RTX, 0));
4174       else
4175         temp = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1)))
4176                 ? compare_from_rtx (target, op1, LEU, 1, mode, NULL_RTX, 0)
4177                 : compare_from_rtx (target, op1, LE, 0, mode, NULL_RTX, 0));
4178       if (temp == const0_rtx)
4179         emit_move_insn (target, op1);
4180       else if (temp != const_true_rtx)
4181         {
4182           if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
4183             emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op0));
4184           else
4185             abort ();
4186           emit_move_insn (target, op1);
4187         }
4188       emit_label (op0);
4189       return target;
4190
4191 /* ??? Can optimize when the operand of this is a bitwise operation,
4192    by using a different bitwise operation.  */
4193     case BIT_NOT_EXPR:
4194       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4195       temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
4196       if (temp == 0)
4197         abort ();
4198       return temp;
4199
4200     case FFS_EXPR:
4201       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4202       temp = expand_unop (mode, ffs_optab, op0, target, 1);
4203       if (temp == 0)
4204         abort ();
4205       return temp;
4206
4207 /* ??? Can optimize bitwise operations with one arg constant.
4208    Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
4209    and (a bitwise1 b) bitwise2 b (etc)
4210    but that is probably not worth while.  */
4211
4212 /* BIT_AND_EXPR is for bitwise anding.
4213    TRUTH_AND_EXPR is for anding two boolean values
4214    when we want in all cases to compute both of them.
4215    In general it is fastest to do TRUTH_AND_EXPR by
4216    computing both operands as actual zero-or-1 values
4217    and then bitwise anding.  In cases where there cannot
4218    be any side effects, better code would be made by
4219    treating TRUTH_AND_EXPR like TRUTH_ANDIF_EXPR;
4220    but the question is how to recognize those cases.  */
4221
4222     case TRUTH_AND_EXPR:
4223     case BIT_AND_EXPR:
4224       this_optab = and_optab;
4225       goto binop;
4226
4227 /* See comment above about TRUTH_AND_EXPR; it applies here too.  */
4228     case TRUTH_OR_EXPR:
4229     case BIT_IOR_EXPR:
4230       this_optab = ior_optab;
4231       goto binop;
4232
4233     case BIT_XOR_EXPR:
4234       this_optab = xor_optab;
4235       goto binop;
4236
4237     case LSHIFT_EXPR:
4238     case RSHIFT_EXPR:
4239     case LROTATE_EXPR:
4240     case RROTATE_EXPR:
4241       preexpand_calls (exp);
4242       if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
4243         subtarget = 0;
4244       op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4245       return expand_shift (code, mode, op0, TREE_OPERAND (exp, 1), target,
4246                            unsignedp);
4247
4248 /* Could determine the answer when only additive constants differ.
4249    Also, the addition of one can be handled by changing the condition.  */
4250     case LT_EXPR:
4251     case LE_EXPR:
4252     case GT_EXPR:
4253     case GE_EXPR:
4254     case EQ_EXPR:
4255     case NE_EXPR:
4256       preexpand_calls (exp);
4257       temp = do_store_flag (exp, target, tmode != VOIDmode ? tmode : mode, 0);
4258       if (temp != 0)
4259         return temp;
4260       /* For foo != 0, load foo, and if it is nonzero load 1 instead. */
4261       if (code == NE_EXPR && integer_zerop (TREE_OPERAND (exp, 1))
4262           && original_target
4263           && GET_CODE (original_target) == REG
4264           && (GET_MODE (original_target)
4265               == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
4266         {
4267           temp = expand_expr (TREE_OPERAND (exp, 0), original_target, VOIDmode, 0);
4268           if (temp != original_target)
4269             temp = copy_to_reg (temp);
4270           op1 = gen_label_rtx ();
4271           emit_cmp_insn (temp, const0_rtx, EQ, NULL_RTX,
4272                          GET_MODE (temp), unsignedp, 0);
4273           emit_jump_insn (gen_beq (op1));
4274           emit_move_insn (temp, const1_rtx);
4275           emit_label (op1);
4276           return temp;
4277         }
4278       /* If no set-flag instruction, must generate a conditional
4279          store into a temporary variable.  Drop through
4280          and handle this like && and ||.  */
4281
4282     case TRUTH_ANDIF_EXPR:
4283     case TRUTH_ORIF_EXPR:
4284       if (target == 0 || ! safe_from_p (target, exp)
4285           /* Make sure we don't have a hard reg (such as function's return
4286              value) live across basic blocks, if not optimizing.  */
4287           || (!optimize && GET_CODE (target) == REG
4288               && REGNO (target) < FIRST_PSEUDO_REGISTER))
4289         target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
4290       emit_clr_insn (target);
4291       op1 = gen_label_rtx ();
4292       jumpifnot (exp, op1);
4293       emit_0_to_1_insn (target);
4294       emit_label (op1);
4295       return target;
4296
4297     case TRUTH_NOT_EXPR:
4298       op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
4299       /* The parser is careful to generate TRUTH_NOT_EXPR
4300          only with operands that are always zero or one.  */
4301       temp = expand_binop (mode, xor_optab, op0, const1_rtx,
4302                            target, 1, OPTAB_LIB_WIDEN);
4303       if (temp == 0)
4304         abort ();
4305       return temp;
4306
4307     case COMPOUND_EXPR:
4308       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
4309       emit_queue ();
4310       return expand_expr (TREE_OPERAND (exp, 1),
4311                           (ignore ? const0_rtx : target),
4312                           VOIDmode, 0);
4313
4314     case COND_EXPR:
4315       {
4316         /* Note that COND_EXPRs whose type is a structure or union
4317            are required to be constructed to contain assignments of
4318            a temporary variable, so that we can evaluate them here
4319            for side effect only.  If type is void, we must do likewise.  */
4320
4321         /* If an arm of the branch requires a cleanup,
4322            only that cleanup is performed.  */
4323
4324         tree singleton = 0;
4325         tree binary_op = 0, unary_op = 0;
4326         tree old_cleanups = cleanups_this_call;
4327         cleanups_this_call = 0;
4328
4329         /* If this is (A ? 1 : 0) and A is a condition, just evaluate it and
4330            convert it to our mode, if necessary.  */
4331         if (integer_onep (TREE_OPERAND (exp, 1))
4332             && integer_zerop (TREE_OPERAND (exp, 2))
4333             && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
4334           {
4335             op0 = expand_expr (TREE_OPERAND (exp, 0), target, mode, modifier);
4336             if (GET_MODE (op0) == mode)
4337               return op0;
4338             if (target == 0)
4339               target = gen_reg_rtx (mode);
4340             convert_move (target, op0, unsignedp);
4341             return target;
4342           }
4343
4344         /* If we are not to produce a result, we have no target.  Otherwise,
4345            if a target was specified use it; it will not be used as an
4346            intermediate target unless it is safe.  If no target, use a 
4347            temporary.  */
4348
4349         if (mode == VOIDmode || ignore)
4350           temp = 0;
4351         else if (original_target
4352                  && safe_from_p (original_target, TREE_OPERAND (exp, 0)))
4353           temp = original_target;
4354         else if (mode == BLKmode)
4355           {
4356             if (TYPE_SIZE (type) == 0
4357                 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
4358               abort ();
4359             temp = assign_stack_temp (BLKmode,
4360                                       (TREE_INT_CST_LOW (TYPE_SIZE (type))
4361                                        + BITS_PER_UNIT - 1)
4362                                       / BITS_PER_UNIT, 0);
4363           }
4364         else
4365           temp = gen_reg_rtx (mode);
4366
4367         /* Check for X ? A + B : A.  If we have this, we can copy
4368            A to the output and conditionally add B.  Similarly for unary
4369            operations.  Don't do this if X has side-effects because
4370            those side effects might affect A or B and the "?" operation is
4371            a sequence point in ANSI.  (We test for side effects later.)  */
4372
4373         if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '2'
4374             && operand_equal_p (TREE_OPERAND (exp, 2),
4375                                 TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
4376           singleton = TREE_OPERAND (exp, 2), binary_op = TREE_OPERAND (exp, 1);
4377         else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '2'
4378                  && operand_equal_p (TREE_OPERAND (exp, 1),
4379                                      TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
4380           singleton = TREE_OPERAND (exp, 1), binary_op = TREE_OPERAND (exp, 2);
4381         else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '1'
4382                  && operand_equal_p (TREE_OPERAND (exp, 2),
4383                                      TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
4384           singleton = TREE_OPERAND (exp, 2), unary_op = TREE_OPERAND (exp, 1);
4385         else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '1'
4386                  && operand_equal_p (TREE_OPERAND (exp, 1),
4387                                      TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
4388           singleton = TREE_OPERAND (exp, 1), unary_op = TREE_OPERAND (exp, 2);
4389
4390         /* If we had X ? A + 1 : A and we can do the test of X as a store-flag
4391            operation, do this as A + (X != 0).  Similarly for other simple
4392            binary operators.  */
4393         if (singleton && binary_op
4394             && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
4395             && (TREE_CODE (binary_op) == PLUS_EXPR
4396                 || TREE_CODE (binary_op) == MINUS_EXPR
4397                 || TREE_CODE (binary_op) == BIT_IOR_EXPR
4398                 || TREE_CODE (binary_op) == BIT_XOR_EXPR
4399                 || TREE_CODE (binary_op) == BIT_AND_EXPR)
4400             && integer_onep (TREE_OPERAND (binary_op, 1))
4401             && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
4402           {
4403             rtx result;
4404             optab boptab = (TREE_CODE (binary_op) == PLUS_EXPR ? add_optab
4405                             : TREE_CODE (binary_op) == MINUS_EXPR ? sub_optab
4406                             : TREE_CODE (binary_op) == BIT_IOR_EXPR ? ior_optab
4407                             : TREE_CODE (binary_op) == BIT_XOR_EXPR ? xor_optab
4408                             : and_optab);
4409
4410             /* If we had X ? A : A + 1, do this as A + (X == 0).
4411
4412                We have to invert the truth value here and then put it
4413                back later if do_store_flag fails.  We cannot simply copy
4414                TREE_OPERAND (exp, 0) to another variable and modify that
4415                because invert_truthvalue can modify the tree pointed to
4416                by its argument.  */
4417             if (singleton == TREE_OPERAND (exp, 1))
4418               TREE_OPERAND (exp, 0)
4419                 = invert_truthvalue (TREE_OPERAND (exp, 0));
4420
4421             result = do_store_flag (TREE_OPERAND (exp, 0),
4422                                     (safe_from_p (temp, singleton)
4423                                      ? temp : NULL_RTX),
4424                                     mode, BRANCH_COST <= 1);
4425
4426             if (result)
4427               {
4428                 op1 = expand_expr (singleton, NULL_RTX, VOIDmode, 0);
4429                 return expand_binop (mode, boptab, op1, result, temp,
4430                                      unsignedp, OPTAB_LIB_WIDEN);
4431               }
4432             else if (singleton == TREE_OPERAND (exp, 1))
4433               TREE_OPERAND (exp, 0)
4434                 = invert_truthvalue (TREE_OPERAND (exp, 0));
4435           }
4436             
4437         NO_DEFER_POP;
4438         op0 = gen_label_rtx ();
4439
4440         if (singleton && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0)))
4441           {
4442             if (temp != 0)
4443               {
4444                 /* If the target conflicts with the other operand of the
4445                    binary op, we can't use it.  Also, we can't use the target
4446                    if it is a hard register, because evaluating the condition
4447                    might clobber it.  */
4448                 if ((binary_op
4449                      && ! safe_from_p (temp, TREE_OPERAND (binary_op, 1)))
4450                     || (GET_CODE (temp) == REG
4451                         && REGNO (temp) < FIRST_PSEUDO_REGISTER))
4452                   temp = gen_reg_rtx (mode);
4453                 store_expr (singleton, temp, 0);
4454               }
4455             else
4456               expand_expr (singleton,
4457                            ignore ? const1_rtx : NULL_RTX, VOIDmode, 0);
4458             if (cleanups_this_call)
4459               {
4460                 sorry ("aggregate value in COND_EXPR");
4461                 cleanups_this_call = 0;
4462               }
4463             if (singleton == TREE_OPERAND (exp, 1))
4464               jumpif (TREE_OPERAND (exp, 0), op0);
4465             else
4466               jumpifnot (TREE_OPERAND (exp, 0), op0);
4467
4468             if (binary_op && temp == 0)
4469               /* Just touch the other operand.  */
4470               expand_expr (TREE_OPERAND (binary_op, 1),
4471                            ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
4472             else if (binary_op)
4473               store_expr (build (TREE_CODE (binary_op), type,
4474                                  make_tree (type, temp),
4475                                  TREE_OPERAND (binary_op, 1)),
4476                           temp, 0);
4477             else
4478               store_expr (build1 (TREE_CODE (unary_op), type,
4479                                   make_tree (type, temp)),
4480                           temp, 0);
4481             op1 = op0;
4482           }
4483 #if 0
4484         /* This is now done in jump.c and is better done there because it
4485            produces shorter register lifetimes.  */
4486            
4487         /* Check for both possibilities either constants or variables
4488            in registers (but not the same as the target!).  If so, can
4489            save branches by assigning one, branching, and assigning the
4490            other.  */
4491         else if (temp && GET_MODE (temp) != BLKmode
4492                  && (TREE_CONSTANT (TREE_OPERAND (exp, 1))
4493                      || ((TREE_CODE (TREE_OPERAND (exp, 1)) == PARM_DECL
4494                           || TREE_CODE (TREE_OPERAND (exp, 1)) == VAR_DECL)
4495                          && DECL_RTL (TREE_OPERAND (exp, 1))
4496                          && GET_CODE (DECL_RTL (TREE_OPERAND (exp, 1))) == REG
4497                          && DECL_RTL (TREE_OPERAND (exp, 1)) != temp))
4498                  && (TREE_CONSTANT (TREE_OPERAND (exp, 2))
4499                      || ((TREE_CODE (TREE_OPERAND (exp, 2)) == PARM_DECL
4500                           || TREE_CODE (TREE_OPERAND (exp, 2)) == VAR_DECL)
4501                          && DECL_RTL (TREE_OPERAND (exp, 2))
4502                          && GET_CODE (DECL_RTL (TREE_OPERAND (exp, 2))) == REG
4503                          && DECL_RTL (TREE_OPERAND (exp, 2)) != temp)))
4504           {
4505             if (GET_CODE (temp) == REG && REGNO (temp) < FIRST_PSEUDO_REGISTER)
4506               temp = gen_reg_rtx (mode);
4507             store_expr (TREE_OPERAND (exp, 2), temp, 0);
4508             jumpifnot (TREE_OPERAND (exp, 0), op0);
4509             store_expr (TREE_OPERAND (exp, 1), temp, 0);
4510             op1 = op0;
4511           }
4512 #endif
4513         /* Check for A op 0 ? A : FOO and A op 0 ? FOO : A where OP is any
4514            comparison operator.  If we have one of these cases, set the
4515            output to A, branch on A (cse will merge these two references),
4516            then set the output to FOO.  */
4517         else if (temp
4518                  && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
4519                  && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
4520                  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
4521                                      TREE_OPERAND (exp, 1), 0)
4522                  && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
4523                  && safe_from_p (temp, TREE_OPERAND (exp, 2)))
4524           {
4525             if (GET_CODE (temp) == REG && REGNO (temp) < FIRST_PSEUDO_REGISTER)
4526               temp = gen_reg_rtx (mode);
4527             store_expr (TREE_OPERAND (exp, 1), temp, 0);
4528             jumpif (TREE_OPERAND (exp, 0), op0);
4529             store_expr (TREE_OPERAND (exp, 2), temp, 0);
4530             op1 = op0;
4531           }
4532         else if (temp
4533                  && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
4534                  && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
4535                  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
4536                                      TREE_OPERAND (exp, 2), 0)
4537                  && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
4538                  && safe_from_p (temp, TREE_OPERAND (exp, 1)))
4539           {
4540             if (GET_CODE (temp) == REG && REGNO (temp) < FIRST_PSEUDO_REGISTER)
4541               temp = gen_reg_rtx (mode);
4542             store_expr (TREE_OPERAND (exp, 2), temp, 0);
4543             jumpifnot (TREE_OPERAND (exp, 0), op0);
4544             store_expr (TREE_OPERAND (exp, 1), temp, 0);
4545             op1 = op0;
4546           }
4547         else
4548           {
4549             op1 = gen_label_rtx ();
4550             jumpifnot (TREE_OPERAND (exp, 0), op0);
4551             if (temp != 0)
4552               store_expr (TREE_OPERAND (exp, 1), temp, 0);
4553             else
4554               expand_expr (TREE_OPERAND (exp, 1),
4555                            ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
4556             if (cleanups_this_call)
4557               {
4558                 sorry ("aggregate value in COND_EXPR");
4559                 cleanups_this_call = 0;
4560               }
4561
4562             emit_queue ();
4563             emit_jump_insn (gen_jump (op1));
4564             emit_barrier ();
4565             emit_label (op0);
4566             if (temp != 0)
4567               store_expr (TREE_OPERAND (exp, 2), temp, 0);
4568             else
4569               expand_expr (TREE_OPERAND (exp, 2),
4570                            ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
4571           }
4572
4573         if (cleanups_this_call)
4574           {
4575             sorry ("aggregate value in COND_EXPR");
4576             cleanups_this_call = 0;
4577           }
4578
4579         emit_queue ();
4580         emit_label (op1);
4581         OK_DEFER_POP;
4582         cleanups_this_call = old_cleanups;
4583         return temp;
4584       }
4585
4586     case TARGET_EXPR:
4587       {
4588         /* Something needs to be initialized, but we didn't know
4589            where that thing was when building the tree.  For example,
4590            it could be the return value of a function, or a parameter
4591            to a function which lays down in the stack, or a temporary
4592            variable which must be passed by reference.
4593
4594            We guarantee that the expression will either be constructed
4595            or copied into our original target.  */
4596
4597         tree slot = TREE_OPERAND (exp, 0);
4598
4599         if (TREE_CODE (slot) != VAR_DECL)
4600           abort ();
4601
4602         if (target == 0)
4603           {
4604             if (DECL_RTL (slot) != 0)
4605               target = DECL_RTL (slot);
4606             else
4607               {
4608                 target = assign_stack_temp (mode, int_size_in_bytes (type), 0);
4609                 /* All temp slots at this level must not conflict.  */
4610                 preserve_temp_slots (target);
4611                 DECL_RTL (slot) = target;
4612               }
4613
4614 #if 0
4615             /* Since SLOT is not known to the called function
4616                to belong to its stack frame, we must build an explicit
4617                cleanup.  This case occurs when we must build up a reference
4618                to pass the reference as an argument.  In this case,
4619                it is very likely that such a reference need not be
4620                built here.  */
4621
4622             if (TREE_OPERAND (exp, 2) == 0)
4623               TREE_OPERAND (exp, 2) = maybe_build_cleanup (slot);
4624             if (TREE_OPERAND (exp, 2))
4625               cleanups_this_call = tree_cons (NULL_TREE, TREE_OPERAND (exp, 2),
4626                                               cleanups_this_call);
4627 #endif
4628           }
4629         else
4630           {
4631             /* This case does occur, when expanding a parameter which
4632                needs to be constructed on the stack.  The target
4633                is the actual stack address that we want to initialize.
4634                The function we call will perform the cleanup in this case.  */
4635
4636             DECL_RTL (slot) = target;
4637           }
4638
4639         return expand_expr (TREE_OPERAND (exp, 1), target, tmode, modifier);
4640       }
4641
4642     case INIT_EXPR:
4643       {
4644         tree lhs = TREE_OPERAND (exp, 0);
4645         tree rhs = TREE_OPERAND (exp, 1);
4646         tree noncopied_parts = 0;
4647         tree lhs_type = TREE_TYPE (lhs);
4648
4649         temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
4650         if (TYPE_NONCOPIED_PARTS (lhs_type) != 0 && !fixed_type_p (rhs))
4651           noncopied_parts = init_noncopied_parts (stabilize_reference (lhs),
4652                                                   TYPE_NONCOPIED_PARTS (lhs_type));
4653         while (noncopied_parts != 0)
4654           {
4655             expand_assignment (TREE_VALUE (noncopied_parts),
4656                                TREE_PURPOSE (noncopied_parts), 0, 0);
4657             noncopied_parts = TREE_CHAIN (noncopied_parts);
4658           }
4659         return temp;
4660       }
4661
4662     case MODIFY_EXPR:
4663       {
4664         /* If lhs is complex, expand calls in rhs before computing it.
4665            That's so we don't compute a pointer and save it over a call.
4666            If lhs is simple, compute it first so we can give it as a
4667            target if the rhs is just a call.  This avoids an extra temp and copy
4668            and that prevents a partial-subsumption which makes bad code.
4669            Actually we could treat component_ref's of vars like vars.  */
4670
4671         tree lhs = TREE_OPERAND (exp, 0);
4672         tree rhs = TREE_OPERAND (exp, 1);
4673         tree noncopied_parts = 0;
4674         tree lhs_type = TREE_TYPE (lhs);
4675
4676         temp = 0;
4677
4678         if (TREE_CODE (lhs) != VAR_DECL
4679             && TREE_CODE (lhs) != RESULT_DECL
4680             && TREE_CODE (lhs) != PARM_DECL)
4681           preexpand_calls (exp);
4682
4683         /* Check for |= or &= of a bitfield of size one into another bitfield
4684            of size 1.  In this case, (unless we need the result of the
4685            assignment) we can do this more efficiently with a
4686            test followed by an assignment, if necessary.
4687
4688            ??? At this point, we can't get a BIT_FIELD_REF here.  But if
4689            things change so we do, this code should be enhanced to
4690            support it.  */
4691         if (ignore
4692             && TREE_CODE (lhs) == COMPONENT_REF
4693             && (TREE_CODE (rhs) == BIT_IOR_EXPR
4694                 || TREE_CODE (rhs) == BIT_AND_EXPR)
4695             && TREE_OPERAND (rhs, 0) == lhs
4696             && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
4697             && TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (lhs, 1))) == 1
4698             && TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))) == 1)
4699           {
4700             rtx label = gen_label_rtx ();
4701
4702             do_jump (TREE_OPERAND (rhs, 1),
4703                      TREE_CODE (rhs) == BIT_IOR_EXPR ? label : 0,
4704                      TREE_CODE (rhs) == BIT_AND_EXPR ? label : 0);
4705             expand_assignment (lhs, convert (TREE_TYPE (rhs),
4706                                              (TREE_CODE (rhs) == BIT_IOR_EXPR
4707                                               ? integer_one_node
4708                                               : integer_zero_node)),
4709                                0, 0);
4710             do_pending_stack_adjust ();
4711             emit_label (label);
4712             return const0_rtx;
4713           }
4714
4715         if (TYPE_NONCOPIED_PARTS (lhs_type) != 0
4716             && ! (fixed_type_p (lhs) && fixed_type_p (rhs)))
4717           noncopied_parts = save_noncopied_parts (stabilize_reference (lhs),
4718                                                   TYPE_NONCOPIED_PARTS (lhs_type));
4719
4720         temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
4721         while (noncopied_parts != 0)
4722           {
4723             expand_assignment (TREE_PURPOSE (noncopied_parts),
4724                                TREE_VALUE (noncopied_parts), 0, 0);
4725             noncopied_parts = TREE_CHAIN (noncopied_parts);
4726           }
4727         return temp;
4728       }
4729
4730     case PREINCREMENT_EXPR:
4731     case PREDECREMENT_EXPR:
4732       return expand_increment (exp, 0);
4733
4734     case POSTINCREMENT_EXPR:
4735     case POSTDECREMENT_EXPR:
4736       /* Faster to treat as pre-increment if result is not used.  */
4737       return expand_increment (exp, ! ignore);
4738
4739     case ADDR_EXPR:
4740       /* Are we taking the address of a nested function?  */
4741       if (TREE_CODE (TREE_OPERAND (exp, 0)) == FUNCTION_DECL
4742           && decl_function_context (TREE_OPERAND (exp, 0)) != 0)
4743         {
4744           op0 = trampoline_address (TREE_OPERAND (exp, 0));
4745           op0 = force_operand (op0, target);
4746         }
4747       else
4748         {
4749           op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode,
4750                              (modifier == EXPAND_INITIALIZER
4751                               ? modifier : EXPAND_CONST_ADDRESS));
4752           if (GET_CODE (op0) != MEM)
4753             abort ();
4754   
4755           if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
4756             return XEXP (op0, 0);
4757           op0 = force_operand (XEXP (op0, 0), target);
4758         }
4759       if (flag_force_addr && GET_CODE (op0) != REG)
4760         return force_reg (Pmode, op0);
4761       return op0;
4762
4763     case ENTRY_VALUE_EXPR:
4764       abort ();
4765
4766     case ERROR_MARK:
4767       return const0_rtx;
4768
4769     default:
4770       return (*lang_expand_expr) (exp, target, tmode, modifier);
4771     }
4772
4773   /* Here to do an ordinary binary operator, generating an instruction
4774      from the optab already placed in `this_optab'.  */
4775  binop:
4776   preexpand_calls (exp);
4777   if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
4778     subtarget = 0;
4779   op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
4780   op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
4781  binop2:
4782   temp = expand_binop (mode, this_optab, op0, op1, target,
4783                        unsignedp, OPTAB_LIB_WIDEN);
4784   if (temp == 0)
4785     abort ();
4786   return temp;
4787 }
4788 \f
4789 /* Return the alignment in bits of EXP, a pointer valued expression.
4790    But don't return more than MAX_ALIGN no matter what.
4791    The alignment returned is, by default, the alignment of the thing that
4792    EXP points to (if it is not a POINTER_TYPE, 0 is returned).
4793
4794    Otherwise, look at the expression to see if we can do better, i.e., if the
4795    expression is actually pointing at an object whose alignment is tighter.  */
4796
4797 static int
4798 get_pointer_alignment (exp, max_align)
4799      tree exp;
4800      unsigned max_align;
4801 {
4802   unsigned align, inner;
4803
4804   if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
4805     return 0;
4806
4807   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
4808   align = MIN (align, max_align);
4809
4810   while (1)
4811     {
4812       switch (TREE_CODE (exp))
4813         {
4814         case NOP_EXPR:
4815         case CONVERT_EXPR:
4816         case NON_LVALUE_EXPR:
4817           exp = TREE_OPERAND (exp, 0);
4818           if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
4819             return align;
4820           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
4821           inner = MIN (inner, max_align);
4822           align = MAX (align, inner);
4823           break;
4824
4825         case PLUS_EXPR:
4826           /* If sum of pointer + int, restrict our maximum alignment to that
4827              imposed by the integer.  If not, we can't do any better than
4828              ALIGN.  */
4829           if (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST)
4830             return align;
4831
4832           while (((TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)) * BITS_PER_UNIT)
4833                   & (max_align - 1))
4834                  != 0)
4835             max_align >>= 1;
4836
4837           exp = TREE_OPERAND (exp, 0);
4838           break;
4839
4840         case ADDR_EXPR:
4841           /* See what we are pointing at and look at its alignment.  */
4842           exp = TREE_OPERAND (exp, 0);
4843           if (TREE_CODE (exp) == FUNCTION_DECL)
4844             align = MAX (align, FUNCTION_BOUNDARY);
4845           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
4846             align = MAX (align, DECL_ALIGN (exp));
4847 #ifdef CONSTANT_ALIGNMENT
4848           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
4849             align = CONSTANT_ALIGNMENT (exp, align);
4850 #endif
4851           return MIN (align, max_align);
4852
4853         default:
4854           return align;
4855         }
4856     }
4857 }
4858 \f
4859 /* Return the tree node and offset if a given argument corresponds to
4860    a string constant.  */
4861
4862 static tree
4863 string_constant (arg, ptr_offset)
4864      tree arg;
4865      tree *ptr_offset;
4866 {
4867   STRIP_NOPS (arg);
4868
4869   if (TREE_CODE (arg) == ADDR_EXPR
4870       && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST)
4871     {
4872       *ptr_offset = integer_zero_node;
4873       return TREE_OPERAND (arg, 0);
4874     }
4875   else if (TREE_CODE (arg) == PLUS_EXPR)
4876     {
4877       tree arg0 = TREE_OPERAND (arg, 0);
4878       tree arg1 = TREE_OPERAND (arg, 1);
4879
4880       STRIP_NOPS (arg0);
4881       STRIP_NOPS (arg1);
4882
4883       if (TREE_CODE (arg0) == ADDR_EXPR
4884           && TREE_CODE (TREE_OPERAND (arg0, 0)) == STRING_CST)
4885         {
4886           *ptr_offset = arg1;
4887           return TREE_OPERAND (arg0, 0);
4888         }
4889       else if (TREE_CODE (arg1) == ADDR_EXPR
4890                && TREE_CODE (TREE_OPERAND (arg1, 0)) == STRING_CST)
4891         {
4892           *ptr_offset = arg0;
4893           return TREE_OPERAND (arg1, 0);
4894         }
4895     }
4896
4897   return 0;
4898 }
4899
4900 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
4901    way, because it could contain a zero byte in the middle.
4902    TREE_STRING_LENGTH is the size of the character array, not the string.
4903
4904    Unfortunately, string_constant can't access the values of const char
4905    arrays with initializers, so neither can we do so here.  */
4906
4907 static tree
4908 c_strlen (src)
4909      tree src;
4910 {
4911   tree offset_node;
4912   int offset, max;
4913   char *ptr;
4914
4915   src = string_constant (src, &offset_node);
4916   if (src == 0)
4917     return 0;
4918   max = TREE_STRING_LENGTH (src);
4919   ptr = TREE_STRING_POINTER (src);
4920   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
4921     {
4922       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
4923          compute the offset to the following null if we don't know where to
4924          start searching for it.  */
4925       int i;
4926       for (i = 0; i < max; i++)
4927         if (ptr[i] == 0)
4928           return 0;
4929       /* We don't know the starting offset, but we do know that the string
4930          has no internal zero bytes.  We can assume that the offset falls
4931          within the bounds of the string; otherwise, the programmer deserves
4932          what he gets.  Subtract the offset from the length of the string,
4933          and return that.  */
4934       /* This would perhaps not be valid if we were dealing with named
4935          arrays in addition to literal string constants.  */
4936       return size_binop (MINUS_EXPR, size_int (max), offset_node);
4937     }
4938
4939   /* We have a known offset into the string.  Start searching there for
4940      a null character.  */
4941   if (offset_node == 0)
4942     offset = 0;
4943   else
4944     {
4945       /* Did we get a long long offset?  If so, punt.  */
4946       if (TREE_INT_CST_HIGH (offset_node) != 0)
4947         return 0;
4948       offset = TREE_INT_CST_LOW (offset_node);
4949     }
4950   /* If the offset is known to be out of bounds, warn, and call strlen at
4951      runtime.  */
4952   if (offset < 0 || offset > max)
4953     {
4954       warning ("offset outside bounds of constant string");
4955       return 0;
4956     }
4957   /* Use strlen to search for the first zero byte.  Since any strings
4958      constructed with build_string will have nulls appended, we win even
4959      if we get handed something like (char[4])"abcd".
4960
4961      Since OFFSET is our starting index into the string, no further
4962      calculation is needed.  */
4963   return size_int (strlen (ptr + offset));
4964 }
4965 \f
4966 /* Expand an expression EXP that calls a built-in function,
4967    with result going to TARGET if that's convenient
4968    (and in mode MODE if that's convenient).
4969    SUBTARGET may be used as the target for computing one of EXP's operands.
4970    IGNORE is nonzero if the value is to be ignored.  */
4971
4972 static rtx
4973 expand_builtin (exp, target, subtarget, mode, ignore)
4974      tree exp;
4975      rtx target;
4976      rtx subtarget;
4977      enum machine_mode mode;
4978      int ignore;
4979 {
4980   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4981   tree arglist = TREE_OPERAND (exp, 1);
4982   rtx op0;
4983   rtx lab1, lab2, insns;
4984   enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
4985
4986   switch (DECL_FUNCTION_CODE (fndecl))
4987     {
4988     case BUILT_IN_ABS:
4989     case BUILT_IN_LABS:
4990     case BUILT_IN_FABS:
4991       /* build_function_call changes these into ABS_EXPR.  */
4992       abort ();
4993
4994     case BUILT_IN_FSQRT:
4995       /* If not optimizing, call the library function.  */
4996       if (! optimize)
4997         break;
4998
4999       if (arglist == 0
5000           /* Arg could be wrong type if user redeclared this fcn wrong.  */
5001           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
5002         return CONST0_RTX (TYPE_MODE (TREE_TYPE (exp)));
5003
5004       /* Stabilize and compute the argument.  */
5005       if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
5006           && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
5007         {
5008           exp = copy_node (exp);
5009           arglist = copy_node (arglist);
5010           TREE_OPERAND (exp, 1) = arglist;
5011           TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
5012         }
5013       op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
5014
5015       /* Make a suitable register to place result in.  */
5016       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
5017
5018       /* Test the argument to make sure it is in the proper domain for
5019          the sqrt function.  If it is not in the domain, branch to a 
5020          library call.  */
5021       emit_queue ();
5022       start_sequence ();
5023       lab1 = gen_label_rtx ();
5024       lab2 = gen_label_rtx ();
5025
5026       /* By default check the arguments.  If flag_fast_math is turned on,
5027          then assume sqrt will always be called with valid arguments. 
5028          Note changing the test below from "> 0" to ">= 0" would cause
5029          incorrect results when computing sqrt(-0.0).  */
5030
5031       if (! flag_fast_math) 
5032         {
5033           /* By checking op > 0 we are able to catch all of the
5034              IEEE special cases with a single if conditional.  */
5035           emit_cmp_insn (op0, CONST0_RTX (GET_MODE (op0)), GT, NULL_RTX,
5036                          GET_MODE (op0), 0, 0);
5037           emit_jump_insn (gen_bgt (lab1));
5038
5039           /* The argument was not in the domain; do this via library call.
5040              Pop the arguments right away in case the call gets deleted. */
5041           NO_DEFER_POP;
5042           expand_call (exp, target, 0);
5043           OK_DEFER_POP;
5044
5045           /* Branch around open coded version */
5046           emit_jump_insn (gen_jump (lab2));
5047         }
5048
5049       emit_label (lab1);
5050       /* Arg is in the domain, compute sqrt, into TARGET. 
5051          Set TARGET to wherever the result comes back.  */
5052       target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
5053                             sqrt_optab, op0, target, 0);
5054
5055       /* If we were unable to expand via the builtin, stop the
5056          sequence (without outputting the insns) and break, causing
5057          a call the the library function.  */
5058       if (target == 0)
5059         {
5060           end_sequence ();
5061           break;
5062         }
5063       emit_label (lab2);
5064
5065
5066       /* Output the entire sequence. */
5067       insns = get_insns ();
5068       end_sequence ();
5069       emit_insns (insns);
5070  
5071       return target;
5072
5073     case BUILT_IN_SAVEREGS:
5074       /* Don't do __builtin_saveregs more than once in a function.
5075          Save the result of the first call and reuse it.  */
5076       if (saveregs_value != 0)
5077         return saveregs_value;
5078       {
5079         /* When this function is called, it means that registers must be
5080            saved on entry to this function.  So we migrate the
5081            call to the first insn of this function.  */
5082         rtx temp;
5083         rtx seq;
5084         rtx valreg, saved_valreg;
5085
5086         /* Now really call the function.  `expand_call' does not call
5087            expand_builtin, so there is no danger of infinite recursion here.  */
5088         start_sequence ();
5089
5090 #ifdef EXPAND_BUILTIN_SAVEREGS
5091         /* Do whatever the machine needs done in this case.  */
5092         temp = EXPAND_BUILTIN_SAVEREGS (arglist);
5093 #else
5094         /* The register where the function returns its value
5095            is likely to have something else in it, such as an argument.
5096            So preserve that register around the call.  */
5097         if (value_mode != VOIDmode)
5098           {
5099             valreg = hard_libcall_value (value_mode);
5100             saved_valreg = gen_reg_rtx (value_mode);
5101             emit_move_insn (saved_valreg, valreg);
5102           }
5103
5104         /* Generate the call, putting the value in a pseudo.  */
5105         temp = expand_call (exp, target, ignore);
5106
5107         if (value_mode != VOIDmode)
5108           emit_move_insn (valreg, saved_valreg);
5109 #endif
5110
5111         seq = get_insns ();
5112         end_sequence ();
5113
5114         saveregs_value = temp;
5115
5116         /* This won't work inside a SEQUENCE--it really has to be
5117            at the start of the function.  */
5118         if (in_sequence_p ())
5119           {
5120             /* Better to do this than to crash.  */
5121             error ("`va_start' used within `({...})'");
5122             return temp;
5123           }
5124
5125         /* Put the sequence after the NOTE that starts the function.  */
5126         emit_insns_before (seq, NEXT_INSN (get_insns ()));
5127         return temp;
5128       }
5129
5130       /* __builtin_args_info (N) returns word N of the arg space info
5131          for the current function.  The number and meanings of words
5132          is controlled by the definition of CUMULATIVE_ARGS.  */
5133     case BUILT_IN_ARGS_INFO:
5134       {
5135         int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
5136         int i;
5137         int *word_ptr = (int *) &current_function_args_info;
5138         tree type, elts, result;
5139
5140         if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
5141           fatal ("CUMULATIVE_ARGS type defined badly; see %s, line %d",
5142                  __FILE__, __LINE__);
5143
5144         if (arglist != 0)
5145           {
5146             tree arg = TREE_VALUE (arglist);
5147             if (TREE_CODE (arg) != INTEGER_CST)
5148               error ("argument of __builtin_args_info must be constant");
5149             else
5150               {
5151                 int wordnum = TREE_INT_CST_LOW (arg);
5152
5153                 if (wordnum < 0 || wordnum >= nwords)
5154                   error ("argument of __builtin_args_info out of range");
5155                 else
5156                   return GEN_INT (word_ptr[wordnum]);
5157               }
5158           }
5159         else
5160           error ("missing argument in __builtin_args_info");
5161
5162         return const0_rtx;
5163
5164 #if 0
5165         for (i = 0; i < nwords; i++)
5166           elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
5167
5168         type = build_array_type (integer_type_node,
5169                                  build_index_type (build_int_2 (nwords, 0)));
5170         result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
5171         TREE_CONSTANT (result) = 1;
5172         TREE_STATIC (result) = 1;
5173         result = build (INDIRECT_REF, build_pointer_type (type), result);
5174         TREE_CONSTANT (result) = 1;
5175         return expand_expr (result, NULL_RTX, VOIDmode, 0);
5176 #endif
5177       }
5178
5179       /* Return the address of the first anonymous stack arg.  */
5180     case BUILT_IN_NEXT_ARG:
5181       {
5182         tree fntype = TREE_TYPE (current_function_decl);
5183         if (!(TYPE_ARG_TYPES (fntype) != 0
5184               && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
5185                   != void_type_node)))
5186           {
5187             error ("`va_start' used in function with fixed args");
5188             return const0_rtx;
5189           }
5190       }
5191
5192       return expand_binop (Pmode, add_optab,
5193                            current_function_internal_arg_pointer,
5194                            current_function_arg_offset_rtx,
5195                            NULL_RTX, 0, OPTAB_LIB_WIDEN);
5196
5197     case BUILT_IN_CLASSIFY_TYPE:
5198       if (arglist != 0)
5199         {
5200           tree type = TREE_TYPE (TREE_VALUE (arglist));
5201           enum tree_code code = TREE_CODE (type);
5202           if (code == VOID_TYPE)
5203             return GEN_INT (void_type_class);
5204           if (code == INTEGER_TYPE)
5205             return GEN_INT (integer_type_class);
5206           if (code == CHAR_TYPE)
5207             return GEN_INT (char_type_class);
5208           if (code == ENUMERAL_TYPE)
5209             return GEN_INT (enumeral_type_class);
5210           if (code == BOOLEAN_TYPE)
5211             return GEN_INT (boolean_type_class);
5212           if (code == POINTER_TYPE)
5213             return GEN_INT (pointer_type_class);
5214           if (code == REFERENCE_TYPE)
5215             return GEN_INT (reference_type_class);
5216           if (code == OFFSET_TYPE)
5217             return GEN_INT (offset_type_class);
5218           if (code == REAL_TYPE)
5219             return GEN_INT (real_type_class);
5220           if (code == COMPLEX_TYPE)
5221             return GEN_INT (complex_type_class);
5222           if (code == FUNCTION_TYPE)
5223             return GEN_INT (function_type_class);
5224           if (code == METHOD_TYPE)
5225             return GEN_INT (method_type_class);
5226           if (code == RECORD_TYPE)
5227             return GEN_INT (record_type_class);
5228           if (code == UNION_TYPE)
5229             return GEN_INT (union_type_class);
5230           if (code == ARRAY_TYPE)
5231             return GEN_INT (array_type_class);
5232           if (code == STRING_TYPE)
5233             return GEN_INT (string_type_class);
5234           if (code == SET_TYPE)
5235             return GEN_INT (set_type_class);
5236           if (code == FILE_TYPE)
5237             return GEN_INT (file_type_class);
5238           if (code == LANG_TYPE)
5239             return GEN_INT (lang_type_class);
5240         }
5241       return GEN_INT (no_type_class);
5242
5243     case BUILT_IN_CONSTANT_P:
5244       if (arglist == 0)
5245         return const0_rtx;
5246       else
5247         return (TREE_CODE_CLASS (TREE_VALUE (arglist)) == 'c'
5248                 ? const1_rtx : const0_rtx);
5249
5250     case BUILT_IN_FRAME_ADDRESS:
5251       /* The argument must be a nonnegative integer constant.
5252          It counts the number of frames to scan up the stack.
5253          The value is the address of that frame.  */
5254     case BUILT_IN_RETURN_ADDRESS:
5255       /* The argument must be a nonnegative integer constant.
5256          It counts the number of frames to scan up the stack.
5257          The value is the return address saved in that frame.  */
5258       if (arglist == 0)
5259         /* Warning about missing arg was already issued.  */
5260         return const0_rtx;
5261       else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST)
5262         {
5263           error ("invalid arg to __builtin_return_address");
5264           return const0_rtx;
5265         }
5266       else if (tree_int_cst_lt (TREE_VALUE (arglist), integer_zero_node))
5267         {
5268           error ("invalid arg to __builtin_return_address");
5269           return const0_rtx;
5270         }
5271       else
5272         {
5273           int count = TREE_INT_CST_LOW (TREE_VALUE (arglist)); 
5274           rtx tem = frame_pointer_rtx;
5275           int i;
5276
5277           /* Scan back COUNT frames to the specified frame.  */
5278           for (i = 0; i < count; i++)
5279             {
5280               /* Assume the dynamic chain pointer is in the word that
5281                  the frame address points to, unless otherwise specified.  */
5282 #ifdef DYNAMIC_CHAIN_ADDRESS
5283               tem = DYNAMIC_CHAIN_ADDRESS (tem);
5284 #endif
5285               tem = memory_address (Pmode, tem);
5286               tem = copy_to_reg (gen_rtx (MEM, Pmode, tem));
5287             }
5288
5289           /* For __builtin_frame_address, return what we've got.  */
5290           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5291             return tem;
5292
5293           /* For __builtin_return_address,
5294              Get the return address from that frame.  */
5295 #ifdef RETURN_ADDR_RTX
5296           return RETURN_ADDR_RTX (count, tem);
5297 #else
5298           tem = memory_address (Pmode,
5299                                 plus_constant (tem, GET_MODE_SIZE (Pmode)));
5300           return copy_to_reg (gen_rtx (MEM, Pmode, tem));
5301 #endif
5302         }
5303
5304     case BUILT_IN_ALLOCA:
5305       if (arglist == 0
5306           /* Arg could be non-integer if user redeclared this fcn wrong.  */
5307           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
5308         return const0_rtx;
5309       current_function_calls_alloca = 1;
5310       /* Compute the argument.  */
5311       op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5312
5313       /* Allocate the desired space.  */
5314       target = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
5315
5316       /* Record the new stack level for nonlocal gotos.  */
5317       if (nonlocal_goto_handler_slot != 0)
5318         emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
5319       return target;
5320
5321     case BUILT_IN_FFS:
5322       /* If not optimizing, call the library function.  */
5323       if (!optimize)
5324         break;
5325
5326       if (arglist == 0
5327           /* Arg could be non-integer if user redeclared this fcn wrong.  */
5328           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
5329         return const0_rtx;
5330
5331       /* Compute the argument.  */
5332       op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
5333       /* Compute ffs, into TARGET if possible.
5334          Set TARGET to wherever the result comes back.  */
5335       target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
5336                             ffs_optab, op0, target, 1);
5337       if (target == 0)
5338         abort ();
5339       return target;
5340
5341     case BUILT_IN_STRLEN:
5342       /* If not optimizing, call the library function.  */
5343       if (!optimize)
5344         break;
5345
5346       if (arglist == 0
5347           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
5348           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
5349         return const0_rtx;
5350       else
5351         {
5352           tree src = TREE_VALUE (arglist);
5353           tree len = c_strlen (src);
5354
5355           int align
5356             = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
5357
5358           rtx result, src_rtx, char_rtx;
5359           enum machine_mode insn_mode = value_mode, char_mode;
5360           enum insn_code icode;
5361
5362           /* If the length is known, just return it. */
5363           if (len != 0)
5364             return expand_expr (len, target, mode, 0);
5365
5366           /* If SRC is not a pointer type, don't do this operation inline. */
5367           if (align == 0)
5368             break;
5369
5370           /* Call a function if we can't compute strlen in the right mode. */
5371
5372           while (insn_mode != VOIDmode)
5373             {
5374               icode = strlen_optab->handlers[(int) insn_mode].insn_code;
5375               if (icode != CODE_FOR_nothing)
5376                 break;
5377
5378               insn_mode = GET_MODE_WIDER_MODE (insn_mode);
5379             }
5380           if (insn_mode == VOIDmode)
5381             break;
5382
5383           /* Make a place to write the result of the instruction.  */
5384           result = target;
5385           if (! (result != 0
5386                  && GET_CODE (result) == REG
5387                  && GET_MODE (result) == insn_mode
5388                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
5389             result = gen_reg_rtx (insn_mode);
5390
5391           /* Make sure the operands are acceptable to the predicates.  */
5392
5393           if (! (*insn_operand_predicate[(int)icode][0]) (result, insn_mode))
5394             result = gen_reg_rtx (insn_mode);
5395
5396           src_rtx = memory_address (BLKmode,
5397                                     expand_expr (src, NULL_RTX, Pmode,
5398                                                  EXPAND_NORMAL));
5399           if (! (*insn_operand_predicate[(int)icode][1]) (src_rtx, Pmode))
5400             src_rtx = copy_to_mode_reg (Pmode, src_rtx);
5401
5402           char_rtx = const0_rtx;
5403           char_mode = insn_operand_mode[(int)icode][2];
5404           if (! (*insn_operand_predicate[(int)icode][2]) (char_rtx, char_mode))
5405             char_rtx = copy_to_mode_reg (char_mode, char_rtx);
5406
5407           emit_insn (GEN_FCN (icode) (result,
5408                                       gen_rtx (MEM, BLKmode, src_rtx),
5409                                       char_rtx, GEN_INT (align)));
5410
5411           /* Return the value in the proper mode for this function.  */
5412           if (GET_MODE (result) == value_mode)
5413             return result;
5414           else if (target != 0)
5415             {
5416               convert_move (target, result, 0);
5417               return target;
5418             }
5419           else
5420             return convert_to_mode (value_mode, result, 0);
5421         }
5422
5423     case BUILT_IN_STRCPY:
5424       /* If not optimizing, call the library function.  */
5425       if (!optimize)
5426         break;
5427
5428       if (arglist == 0
5429           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
5430           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5431           || TREE_CHAIN (arglist) == 0
5432           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
5433         return const0_rtx;
5434       else
5435         {
5436           tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
5437
5438           if (len == 0)
5439             break;
5440
5441           len = size_binop (PLUS_EXPR, len, integer_one_node);
5442
5443           chainon (arglist, build_tree_list (NULL_TREE, len));
5444         }
5445
5446       /* Drops in.  */
5447     case BUILT_IN_MEMCPY:
5448       /* If not optimizing, call the library function.  */
5449       if (!optimize)
5450         break;
5451
5452       if (arglist == 0
5453           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
5454           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5455           || TREE_CHAIN (arglist) == 0
5456           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
5457           || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
5458           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
5459         return const0_rtx;
5460       else
5461         {
5462           tree dest = TREE_VALUE (arglist);
5463           tree src = TREE_VALUE (TREE_CHAIN (arglist));
5464           tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5465
5466           int src_align
5467             = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
5468           int dest_align
5469             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
5470           rtx dest_rtx;
5471
5472           /* If either SRC or DEST is not a pointer type, don't do
5473              this operation in-line.  */
5474           if (src_align == 0 || dest_align == 0)
5475             {
5476               if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRCPY)
5477                 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
5478               break;
5479             }
5480
5481           dest_rtx = expand_expr (dest, NULL_RTX, Pmode, EXPAND_NORMAL);
5482
5483           /* Copy word part most expediently.  */
5484           emit_block_move (gen_rtx (MEM, BLKmode,
5485                                     memory_address (BLKmode, dest_rtx)),
5486                            gen_rtx (MEM, BLKmode,
5487                                     memory_address (BLKmode,
5488                                                     expand_expr (src, NULL_RTX,
5489                                                                  Pmode,
5490                                                                  EXPAND_NORMAL))),
5491                            expand_expr (len, NULL_RTX, VOIDmode, 0),
5492                            MIN (src_align, dest_align));
5493           return dest_rtx;
5494         }
5495
5496 /* These comparison functions need an instruction that returns an actual
5497    index.  An ordinary compare that just sets the condition codes
5498    is not enough.  */
5499 #ifdef HAVE_cmpstrsi
5500     case BUILT_IN_STRCMP:
5501       /* If not optimizing, call the library function.  */
5502       if (!optimize)
5503         break;
5504
5505       if (arglist == 0
5506           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
5507           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5508           || TREE_CHAIN (arglist) == 0
5509           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
5510         return const0_rtx;
5511       else if (!HAVE_cmpstrsi)
5512         break;
5513       {
5514         tree arg1 = TREE_VALUE (arglist);
5515         tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
5516         tree offset;
5517         tree len, len2;
5518
5519         len = c_strlen (arg1);
5520         if (len)
5521           len = size_binop (PLUS_EXPR, integer_one_node, len);
5522         len2 = c_strlen (arg2);
5523         if (len2)
5524           len2 = size_binop (PLUS_EXPR, integer_one_node, len2);
5525
5526         /* If we don't have a constant length for the first, use the length
5527            of the second, if we know it.  We don't require a constant for
5528            this case; some cost analysis could be done if both are available
5529            but neither is constant.  For now, assume they're equally cheap.
5530
5531            If both strings have constant lengths, use the smaller.  This
5532            could arise if optimization results in strcpy being called with
5533            two fixed strings, or if the code was machine-generated.  We should
5534            add some code to the `memcmp' handler below to deal with such
5535            situations, someday.  */
5536         if (!len || TREE_CODE (len) != INTEGER_CST)
5537           {
5538             if (len2)
5539               len = len2;
5540             else if (len == 0)
5541               break;
5542           }
5543         else if (len2 && TREE_CODE (len2) == INTEGER_CST)
5544           {
5545             if (tree_int_cst_lt (len2, len))
5546               len = len2;
5547           }
5548
5549         chainon (arglist, build_tree_list (NULL_TREE, len));
5550       }
5551
5552       /* Drops in.  */
5553     case BUILT_IN_MEMCMP:
5554       /* If not optimizing, call the library function.  */
5555       if (!optimize)
5556         break;
5557
5558       if (arglist == 0
5559           /* Arg could be non-pointer if user redeclared this fcn wrong.  */
5560           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5561           || TREE_CHAIN (arglist) == 0
5562           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
5563           || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
5564           || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
5565         return const0_rtx;
5566       else if (!HAVE_cmpstrsi)
5567         break;
5568       {
5569         tree arg1 = TREE_VALUE (arglist);
5570         tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
5571         tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5572         rtx result;
5573
5574         int arg1_align
5575           = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
5576         int arg2_align
5577           = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
5578         enum machine_mode insn_mode
5579           = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
5580
5581         /* If we don't have POINTER_TYPE, call the function.  */
5582         if (arg1_align == 0 || arg2_align == 0)
5583           {
5584             if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRCMP)
5585               TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
5586             break;
5587           }
5588
5589         /* Make a place to write the result of the instruction.  */
5590         result = target;
5591         if (! (result != 0
5592                && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
5593                && REGNO (result) >= FIRST_PSEUDO_REGISTER))
5594           result = gen_reg_rtx (insn_mode);
5595
5596         emit_insn (gen_cmpstrsi (result,
5597                                  gen_rtx (MEM, BLKmode,
5598                                           expand_expr (arg1, NULL_RTX, Pmode,
5599                                                        EXPAND_NORMAL)),
5600                                  gen_rtx (MEM, BLKmode,
5601                                           expand_expr (arg2, NULL_RTX, Pmode,
5602                                                        EXPAND_NORMAL)),
5603                                  expand_expr (len, NULL_RTX, VOIDmode, 0),
5604                                  GEN_INT (MIN (arg1_align, arg2_align))));
5605
5606         /* Return the value in the proper mode for this function.  */
5607         mode = TYPE_MODE (TREE_TYPE (exp));
5608         if (GET_MODE (result) == mode)
5609           return result;
5610         else if (target != 0)
5611           {
5612             convert_move (target, result, 0);
5613             return target;
5614           }
5615         else
5616           return convert_to_mode (mode, result, 0);
5617       } 
5618 #else
5619     case BUILT_IN_STRCMP:
5620     case BUILT_IN_MEMCMP:
5621       break;
5622 #endif
5623
5624     default:                    /* just do library call, if unknown builtin */
5625       error ("built-in function %s not currently supported",
5626              IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5627     }
5628
5629   /* The switch statement above can drop through to cause the function
5630      to be called normally.  */
5631
5632   return expand_call (exp, target, ignore);
5633 }
5634 \f
5635 /* Expand code for a post- or pre- increment or decrement
5636    and return the RTX for the result.
5637    POST is 1 for postinc/decrements and 0 for preinc/decrements.  */
5638
5639 static rtx
5640 expand_increment (exp, post)
5641      register tree exp;
5642      int post;
5643 {
5644   register rtx op0, op1;
5645   register rtx temp, value;
5646   register tree incremented = TREE_OPERAND (exp, 0);
5647   optab this_optab = add_optab;
5648   int icode;
5649   enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
5650   int op0_is_copy = 0;
5651
5652   /* Stabilize any component ref that might need to be
5653      evaluated more than once below.  */
5654   if (TREE_CODE (incremented) == BIT_FIELD_REF
5655       || (TREE_CODE (incremented) == COMPONENT_REF
5656           && (TREE_CODE (TREE_OPERAND (incremented, 0)) != INDIRECT_REF
5657               || DECL_BIT_FIELD (TREE_OPERAND (incremented, 1)))))
5658     incremented = stabilize_reference (incremented);
5659
5660   /* Compute the operands as RTX.
5661      Note whether OP0 is the actual lvalue or a copy of it:
5662      I believe it is a copy iff it is a register or subreg
5663      and insns were generated in computing it.  */
5664   temp = get_last_insn ();
5665   op0 = expand_expr (incremented, NULL_RTX, VOIDmode, 0);
5666   op0_is_copy = ((GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
5667                  && temp != get_last_insn ());
5668   op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
5669
5670   /* Decide whether incrementing or decrementing.  */
5671   if (TREE_CODE (exp) == POSTDECREMENT_EXPR
5672       || TREE_CODE (exp) == PREDECREMENT_EXPR)
5673     this_optab = sub_optab;
5674
5675   /* If OP0 is not the actual lvalue, but rather a copy in a register,
5676      then we cannot just increment OP0.  We must
5677      therefore contrive to increment the original value.
5678      Then we can return OP0 since it is a copy of the old value.  */
5679   if (op0_is_copy)
5680     {
5681       /* This is the easiest way to increment the value wherever it is.
5682          Problems with multiple evaluation of INCREMENTED
5683          are prevented because either (1) it is a component_ref,
5684          in which case it was stabilized above, or (2) it is an array_ref
5685          with constant index in an array in a register, which is
5686          safe to reevaluate.  */
5687       tree newexp = build ((this_optab == add_optab
5688                             ? PLUS_EXPR : MINUS_EXPR),
5689                            TREE_TYPE (exp),
5690                            incremented,
5691                            TREE_OPERAND (exp, 1));
5692       temp = expand_assignment (incremented, newexp, ! post, 0);
5693       return post ? op0 : temp;
5694     }
5695
5696   /* Convert decrement by a constant into a negative increment.  */
5697   if (this_optab == sub_optab
5698       && GET_CODE (op1) == CONST_INT)
5699     {
5700       op1 = GEN_INT (- INTVAL (op1));
5701       this_optab = add_optab;
5702     }
5703
5704   if (post)
5705     {
5706       /* We have a true reference to the value in OP0.
5707          If there is an insn to add or subtract in this mode, queue it.  */
5708
5709 #if 0  /* Turned off to avoid making extra insn for indexed memref.  */
5710       op0 = stabilize (op0);
5711 #endif
5712
5713       icode = (int) this_optab->handlers[(int) mode].insn_code;
5714       if (icode != (int) CODE_FOR_nothing
5715           /* Make sure that OP0 is valid for operands 0 and 1
5716              of the insn we want to queue.  */
5717           && (*insn_operand_predicate[icode][0]) (op0, mode)
5718           && (*insn_operand_predicate[icode][1]) (op0, mode))
5719         {
5720           if (! (*insn_operand_predicate[icode][2]) (op1, mode))
5721             op1 = force_reg (mode, op1);
5722
5723           return enqueue_insn (op0, GEN_FCN (icode) (op0, op0, op1));
5724         }
5725     }
5726
5727   /* Preincrement, or we can't increment with one simple insn.  */
5728   if (post)
5729     /* Save a copy of the value before inc or dec, to return it later.  */
5730     temp = value = copy_to_reg (op0);
5731   else
5732     /* Arrange to return the incremented value.  */
5733     /* Copy the rtx because expand_binop will protect from the queue,
5734        and the results of that would be invalid for us to return
5735        if our caller does emit_queue before using our result.  */
5736     temp = copy_rtx (value = op0);
5737
5738   /* Increment however we can.  */
5739   op1 = expand_binop (mode, this_optab, value, op1, op0,
5740                       TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
5741   /* Make sure the value is stored into OP0.  */
5742   if (op1 != op0)
5743     emit_move_insn (op0, op1);
5744
5745   return temp;
5746 }
5747 \f
5748 /* Expand all function calls contained within EXP, innermost ones first.
5749    But don't look within expressions that have sequence points.
5750    For each CALL_EXPR, record the rtx for its value
5751    in the CALL_EXPR_RTL field.  */
5752
5753 static void
5754 preexpand_calls (exp)
5755      tree exp;
5756 {
5757   register int nops, i;
5758   int type = TREE_CODE_CLASS (TREE_CODE (exp));
5759
5760   if (! do_preexpand_calls)
5761     return;
5762
5763   /* Only expressions and references can contain calls.  */
5764
5765   if (type != 'e' && type != '<' && type != '1' && type != '2' && type != 'r')
5766     return;
5767
5768   switch (TREE_CODE (exp))
5769     {
5770     case CALL_EXPR:
5771       /* Do nothing if already expanded.  */
5772       if (CALL_EXPR_RTL (exp) != 0)
5773         return;
5774
5775       /* Do nothing to built-in functions.  */
5776       if (TREE_CODE (TREE_OPERAND (exp, 0)) != ADDR_EXPR
5777           || TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != FUNCTION_DECL
5778           || ! DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
5779         CALL_EXPR_RTL (exp) = expand_call (exp, NULL_RTX, 0);
5780       return;
5781
5782     case COMPOUND_EXPR:
5783     case COND_EXPR:
5784     case TRUTH_ANDIF_EXPR:
5785     case TRUTH_ORIF_EXPR:
5786       /* If we find one of these, then we can be sure
5787          the adjust will be done for it (since it makes jumps).
5788          Do it now, so that if this is inside an argument
5789          of a function, we don't get the stack adjustment
5790          after some other args have already been pushed.  */
5791       do_pending_stack_adjust ();
5792       return;
5793
5794     case BLOCK:
5795     case RTL_EXPR:
5796     case WITH_CLEANUP_EXPR:
5797       return;
5798
5799     case SAVE_EXPR:
5800       if (SAVE_EXPR_RTL (exp) != 0)
5801         return;
5802     }
5803
5804   nops = tree_code_length[(int) TREE_CODE (exp)];
5805   for (i = 0; i < nops; i++)
5806     if (TREE_OPERAND (exp, i) != 0)
5807       {
5808         type = TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, i)));
5809         if (type == 'e' || type == '<' || type == '1' || type == '2'
5810             || type == 'r')
5811           preexpand_calls (TREE_OPERAND (exp, i));
5812       }
5813 }
5814 \f
5815 /* At the start of a function, record that we have no previously-pushed
5816    arguments waiting to be popped.  */
5817
5818 void
5819 init_pending_stack_adjust ()
5820 {
5821   pending_stack_adjust = 0;
5822 }
5823
5824 /* When exiting from function, if safe, clear out any pending stack adjust
5825    so the adjustment won't get done.  */
5826
5827 void
5828 clear_pending_stack_adjust ()
5829 {
5830 #ifdef EXIT_IGNORE_STACK
5831   if (! flag_omit_frame_pointer && EXIT_IGNORE_STACK
5832       && ! (TREE_INLINE (current_function_decl) && ! flag_no_inline)
5833       && ! flag_inline_functions)
5834     pending_stack_adjust = 0;
5835 #endif
5836 }
5837
5838 /* Pop any previously-pushed arguments that have not been popped yet.  */
5839
5840 void
5841 do_pending_stack_adjust ()
5842 {
5843   if (inhibit_defer_pop == 0)
5844     {
5845       if (pending_stack_adjust != 0)
5846         adjust_stack (GEN_INT (pending_stack_adjust));
5847       pending_stack_adjust = 0;
5848     }
5849 }
5850
5851 /* Expand all cleanups up to OLD_CLEANUPS.
5852    Needed here, and also for language-dependent calls.  */
5853
5854 void
5855 expand_cleanups_to (old_cleanups)
5856      tree old_cleanups;
5857 {
5858   while (cleanups_this_call != old_cleanups)
5859     {
5860       expand_expr (TREE_VALUE (cleanups_this_call), NULL_RTX, VOIDmode, 0);
5861       cleanups_this_call = TREE_CHAIN (cleanups_this_call);
5862     }
5863 }
5864 \f
5865 /* Expand conditional expressions.  */
5866
5867 /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
5868    LABEL is an rtx of code CODE_LABEL, in this function and all the
5869    functions here.  */
5870
5871 void
5872 jumpifnot (exp, label)
5873      tree exp;
5874      rtx label;
5875 {
5876   do_jump (exp, label, NULL_RTX);
5877 }
5878
5879 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
5880
5881 void
5882 jumpif (exp, label)
5883      tree exp;
5884      rtx label;
5885 {
5886   do_jump (exp, NULL_RTX, label);
5887 }
5888
5889 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
5890    the result is zero, or IF_TRUE_LABEL if the result is one.
5891    Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
5892    meaning fall through in that case.
5893
5894    do_jump always does any pending stack adjust except when it does not
5895    actually perform a jump.  An example where there is no jump
5896    is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
5897
5898    This function is responsible for optimizing cases such as
5899    &&, || and comparison operators in EXP.  */
5900
5901 void
5902 do_jump (exp, if_false_label, if_true_label)
5903      tree exp;
5904      rtx if_false_label, if_true_label;
5905 {
5906   register enum tree_code code = TREE_CODE (exp);
5907   /* Some cases need to create a label to jump to
5908      in order to properly fall through.
5909      These cases set DROP_THROUGH_LABEL nonzero.  */
5910   rtx drop_through_label = 0;
5911   rtx temp;
5912   rtx comparison = 0;
5913   int i;
5914   tree type;
5915
5916   emit_queue ();
5917
5918   switch (code)
5919     {
5920     case ERROR_MARK:
5921       break;
5922
5923     case INTEGER_CST:
5924       temp = integer_zerop (exp) ? if_false_label : if_true_label;
5925       if (temp)
5926         emit_jump (temp);
5927       break;
5928
5929 #if 0
5930       /* This is not true with #pragma weak  */
5931     case ADDR_EXPR:
5932       /* The address of something can never be zero.  */
5933       if (if_true_label)
5934         emit_jump (if_true_label);
5935       break;
5936 #endif
5937
5938     case NOP_EXPR:
5939       if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
5940           || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
5941           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF)
5942         goto normal;
5943     case CONVERT_EXPR:
5944       /* If we are narrowing the operand, we have to do the compare in the
5945          narrower mode.  */
5946       if ((TYPE_PRECISION (TREE_TYPE (exp))
5947            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
5948         goto normal;
5949     case NON_LVALUE_EXPR:
5950     case REFERENCE_EXPR:
5951     case ABS_EXPR:
5952     case NEGATE_EXPR:
5953     case LROTATE_EXPR:
5954     case RROTATE_EXPR:
5955       /* These cannot change zero->non-zero or vice versa.  */
5956       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
5957       break;
5958
5959 #if 0
5960       /* This is never less insns than evaluating the PLUS_EXPR followed by
5961          a test and can be longer if the test is eliminated.  */
5962     case PLUS_EXPR:
5963       /* Reduce to minus.  */
5964       exp = build (MINUS_EXPR, TREE_TYPE (exp),
5965                    TREE_OPERAND (exp, 0),
5966                    fold (build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (exp, 1)),
5967                                  TREE_OPERAND (exp, 1))));
5968       /* Process as MINUS.  */
5969 #endif
5970
5971     case MINUS_EXPR:
5972       /* Non-zero iff operands of minus differ.  */
5973       comparison = compare (build (NE_EXPR, TREE_TYPE (exp),
5974                                    TREE_OPERAND (exp, 0),
5975                                    TREE_OPERAND (exp, 1)),
5976                             NE, NE);
5977       break;
5978
5979     case BIT_AND_EXPR:
5980       /* If we are AND'ing with a small constant, do this comparison in the
5981          smallest type that fits.  If the machine doesn't have comparisons
5982          that small, it will be converted back to the wider comparison.
5983          This helps if we are testing the sign bit of a narrower object.
5984          combine can't do this for us because it can't know whether a
5985          ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
5986
5987       if (! SLOW_BYTE_ACCESS
5988           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
5989           && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
5990           && (i = floor_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))) >= 0
5991           && (type = type_for_size (i + 1, 1)) != 0
5992           && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
5993           && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
5994               != CODE_FOR_nothing))
5995         {
5996           do_jump (convert (type, exp), if_false_label, if_true_label);
5997           break;
5998         }
5999       goto normal;
6000
6001     case TRUTH_NOT_EXPR:
6002       do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
6003       break;
6004
6005     case TRUTH_ANDIF_EXPR:
6006       if (if_false_label == 0)
6007         if_false_label = drop_through_label = gen_label_rtx ();
6008       do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
6009       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
6010       break;
6011
6012     case TRUTH_ORIF_EXPR:
6013       if (if_true_label == 0)
6014         if_true_label = drop_through_label = gen_label_rtx ();
6015       do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
6016       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
6017       break;
6018
6019     case COMPOUND_EXPR:
6020       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
6021       free_temp_slots ();
6022       emit_queue ();
6023       do_pending_stack_adjust ();
6024       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
6025       break;
6026
6027     case COMPONENT_REF:
6028     case BIT_FIELD_REF:
6029     case ARRAY_REF:
6030       {
6031         int bitsize, bitpos, unsignedp;
6032         enum machine_mode mode;
6033         tree type;
6034         tree offset;
6035         int volatilep = 0;
6036
6037         /* Get description of this reference.  We don't actually care
6038            about the underlying object here.  */
6039         get_inner_reference (exp, &bitsize, &bitpos, &offset,
6040                              &mode, &unsignedp, &volatilep);
6041
6042         type = type_for_size (bitsize, unsignedp);
6043         if (! SLOW_BYTE_ACCESS
6044             && type != 0 && bitsize >= 0
6045             && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
6046             && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
6047                 != CODE_FOR_nothing))
6048           {
6049             do_jump (convert (type, exp), if_false_label, if_true_label);
6050             break;
6051           }
6052         goto normal;
6053       }
6054
6055     case COND_EXPR:
6056       /* Do (a ? 1 : 0) and (a ? 0 : 1) as special cases.  */
6057       if (integer_onep (TREE_OPERAND (exp, 1))
6058           && integer_zerop (TREE_OPERAND (exp, 2)))
6059         do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
6060
6061       else if (integer_zerop (TREE_OPERAND (exp, 1))
6062                && integer_onep (TREE_OPERAND (exp, 2)))
6063         do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
6064
6065       else
6066         {
6067           register rtx label1 = gen_label_rtx ();
6068           drop_through_label = gen_label_rtx ();
6069           do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
6070           /* Now the THEN-expression.  */
6071           do_jump (TREE_OPERAND (exp, 1),
6072                    if_false_label ? if_false_label : drop_through_label,
6073                    if_true_label ? if_true_label : drop_through_label);
6074           /* In case the do_jump just above never jumps.  */
6075           do_pending_stack_adjust ();
6076           emit_label (label1);
6077           /* Now the ELSE-expression.  */
6078           do_jump (TREE_OPERAND (exp, 2),
6079                    if_false_label ? if_false_label : drop_through_label,
6080                    if_true_label ? if_true_label : drop_through_label);
6081         }
6082       break;
6083
6084     case EQ_EXPR:
6085       if (integer_zerop (TREE_OPERAND (exp, 1)))
6086         do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
6087       else if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
6088                 == MODE_INT)
6089                && 
6090                !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
6091         do_jump_by_parts_equality (exp, if_false_label, if_true_label);
6092       else
6093         comparison = compare (exp, EQ, EQ);
6094       break;
6095
6096     case NE_EXPR:
6097       if (integer_zerop (TREE_OPERAND (exp, 1)))
6098         do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
6099       else if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
6100                 == MODE_INT)
6101                && 
6102                !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
6103         do_jump_by_parts_equality (exp, if_true_label, if_false_label);
6104       else
6105         comparison = compare (exp, NE, NE);
6106       break;
6107
6108     case LT_EXPR:
6109       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
6110            == MODE_INT)
6111           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
6112         do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label);
6113       else
6114         comparison = compare (exp, LT, LTU);
6115       break;
6116
6117     case LE_EXPR:
6118       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
6119            == MODE_INT)
6120           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
6121         do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label);
6122       else
6123         comparison = compare (exp, LE, LEU);
6124       break;
6125
6126     case GT_EXPR:
6127       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
6128            == MODE_INT)
6129           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
6130         do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label);
6131       else
6132         comparison = compare (exp, GT, GTU);
6133       break;
6134
6135     case GE_EXPR:
6136       if ((GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
6137            == MODE_INT)
6138           && !can_compare_p (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
6139         do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label);
6140       else
6141         comparison = compare (exp, GE, GEU);
6142       break;
6143
6144     default:
6145     normal:
6146       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
6147 #if 0
6148       /* This is not needed any more and causes poor code since it causes
6149          comparisons and tests from non-SI objects to have different code
6150          sequences.  */
6151       /* Copy to register to avoid generating bad insns by cse
6152          from (set (mem ...) (arithop))  (set (cc0) (mem ...)).  */
6153       if (!cse_not_expected && GET_CODE (temp) == MEM)
6154         temp = copy_to_reg (temp);
6155 #endif
6156       do_pending_stack_adjust ();
6157       if (GET_CODE (temp) == CONST_INT)
6158         comparison = (temp == const0_rtx ? const0_rtx : const_true_rtx);
6159       else if (GET_CODE (temp) == LABEL_REF)
6160         comparison = const_true_rtx;
6161       else if (GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
6162                && !can_compare_p (GET_MODE (temp)))
6163         /* Note swapping the labels gives us not-equal.  */
6164         do_jump_by_parts_equality_rtx (temp, if_true_label, if_false_label);
6165       else if (GET_MODE (temp) != VOIDmode)
6166         comparison = compare_from_rtx (temp, CONST0_RTX (GET_MODE (temp)),
6167                                        NE, 1, GET_MODE (temp), NULL_RTX, 0);
6168       else
6169         abort ();
6170     }
6171
6172   /* Do any postincrements in the expression that was tested.  */
6173   emit_queue ();
6174
6175   /* If COMPARISON is nonzero here, it is an rtx that can be substituted
6176      straight into a conditional jump instruction as the jump condition.
6177      Otherwise, all the work has been done already.  */
6178
6179   if (comparison == const_true_rtx)
6180     {
6181       if (if_true_label)
6182         emit_jump (if_true_label);
6183     }
6184   else if (comparison == const0_rtx)
6185     {
6186       if (if_false_label)
6187         emit_jump (if_false_label);
6188     }
6189   else if (comparison)
6190     do_jump_for_compare (comparison, if_false_label, if_true_label);
6191
6192   free_temp_slots ();
6193
6194   if (drop_through_label)
6195     {
6196       /* If do_jump produces code that might be jumped around,
6197          do any stack adjusts from that code, before the place
6198          where control merges in.  */
6199       do_pending_stack_adjust ();
6200       emit_label (drop_through_label);
6201     }
6202 }
6203 \f
6204 /* Given a comparison expression EXP for values too wide to be compared
6205    with one insn, test the comparison and jump to the appropriate label.
6206    The code of EXP is ignored; we always test GT if SWAP is 0,
6207    and LT if SWAP is 1.  */
6208
6209 static void
6210 do_jump_by_parts_greater (exp, swap, if_false_label, if_true_label)
6211      tree exp;
6212      int swap;
6213      rtx if_false_label, if_true_label;
6214 {
6215   rtx op0 = expand_expr (TREE_OPERAND (exp, swap), NULL_RTX, VOIDmode, 0);
6216   rtx op1 = expand_expr (TREE_OPERAND (exp, !swap), NULL_RTX, VOIDmode, 0);
6217   enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
6218   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
6219   rtx drop_through_label = 0;
6220   int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)));
6221   int i;
6222
6223   if (! if_true_label || ! if_false_label)
6224     drop_through_label = gen_label_rtx ();
6225   if (! if_true_label)
6226     if_true_label = drop_through_label;
6227   if (! if_false_label)
6228     if_false_label = drop_through_label;
6229
6230   /* Compare a word at a time, high order first.  */
6231   for (i = 0; i < nwords; i++)
6232     {
6233       rtx comp;
6234       rtx op0_word, op1_word;
6235
6236       if (WORDS_BIG_ENDIAN)
6237         {
6238           op0_word = operand_subword_force (op0, i, mode);
6239           op1_word = operand_subword_force (op1, i, mode);
6240         }
6241       else
6242         {
6243           op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
6244           op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
6245         }
6246
6247       /* All but high-order word must be compared as unsigned.  */
6248       comp = compare_from_rtx (op0_word, op1_word,
6249                                (unsignedp || i > 0) ? GTU : GT,
6250                                unsignedp, word_mode, NULL_RTX, 0);
6251       if (comp == const_true_rtx)
6252         emit_jump (if_true_label);
6253       else if (comp != const0_rtx)
6254         do_jump_for_compare (comp, NULL_RTX, if_true_label);
6255
6256       /* Consider lower words only if these are equal.  */
6257       comp = compare_from_rtx (op0_word, op1_word, NE, unsignedp, word_mode,
6258                                NULL_RTX, 0);
6259       if (comp == const_true_rtx)
6260         emit_jump (if_false_label);
6261       else if (comp != const0_rtx)
6262         do_jump_for_compare (comp, NULL_RTX, if_false_label);
6263     }
6264
6265   if (if_false_label)
6266     emit_jump (if_false_label);
6267   if (drop_through_label)
6268     emit_label (drop_through_label);
6269 }
6270
6271 /* Given an EQ_EXPR expression EXP for values too wide to be compared
6272    with one insn, test the comparison and jump to the appropriate label.  */
6273
6274 static void
6275 do_jump_by_parts_equality (exp, if_false_label, if_true_label)
6276      tree exp;
6277      rtx if_false_label, if_true_label;
6278 {
6279   rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
6280   rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
6281   enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
6282   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
6283   int i;
6284   rtx drop_through_label = 0;
6285
6286   if (! if_false_label)
6287     drop_through_label = if_false_label = gen_label_rtx ();
6288
6289   for (i = 0; i < nwords; i++)
6290     {
6291       rtx comp = compare_from_rtx (operand_subword_force (op0, i, mode),
6292                                    operand_subword_force (op1, i, mode),
6293                                    EQ, 0, word_mode, NULL_RTX, 0);
6294       if (comp == const_true_rtx)
6295         emit_jump (if_false_label);
6296       else if (comp != const0_rtx)
6297         do_jump_for_compare (comp, if_false_label, NULL_RTX);
6298     }
6299
6300   if (if_true_label)
6301     emit_jump (if_true_label);
6302   if (drop_through_label)
6303     emit_label (drop_through_label);
6304 }
6305 \f
6306 /* Jump according to whether OP0 is 0.
6307    We assume that OP0 has an integer mode that is too wide
6308    for the available compare insns.  */
6309
6310 static void
6311 do_jump_by_parts_equality_rtx (op0, if_false_label, if_true_label)
6312      rtx op0;
6313      rtx if_false_label, if_true_label;
6314 {
6315   int nwords = GET_MODE_SIZE (GET_MODE (op0)) / UNITS_PER_WORD;
6316   int i;
6317   rtx drop_through_label = 0;
6318
6319   if (! if_false_label)
6320     drop_through_label = if_false_label = gen_label_rtx ();
6321
6322   for (i = 0; i < nwords; i++)
6323     {
6324       rtx comp = compare_from_rtx (operand_subword_force (op0, i,
6325                                                           GET_MODE (op0)),
6326                                    const0_rtx, EQ, 0, word_mode, NULL_RTX, 0);
6327       if (comp == const_true_rtx)
6328         emit_jump (if_false_label);
6329       else if (comp != const0_rtx)
6330         do_jump_for_compare (comp, if_false_label, NULL_RTX);
6331     }
6332
6333   if (if_true_label)
6334     emit_jump (if_true_label);
6335   if (drop_through_label)
6336     emit_label (drop_through_label);
6337 }
6338
6339 /* Given a comparison expression in rtl form, output conditional branches to
6340    IF_TRUE_LABEL, IF_FALSE_LABEL, or both.  */
6341
6342 static void
6343 do_jump_for_compare (comparison, if_false_label, if_true_label)
6344      rtx comparison, if_false_label, if_true_label;
6345 {
6346   if (if_true_label)
6347     {
6348       if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
6349         emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_true_label));
6350       else
6351         abort ();
6352
6353       if (if_false_label)
6354         emit_jump (if_false_label);
6355     }
6356   else if (if_false_label)
6357     {
6358       rtx insn;
6359       rtx prev = PREV_INSN (get_last_insn ());
6360       rtx branch = 0;
6361
6362       /* Output the branch with the opposite condition.  Then try to invert
6363          what is generated.  If more than one insn is a branch, or if the
6364          branch is not the last insn written, abort. If we can't invert
6365          the branch, emit make a true label, redirect this jump to that,
6366          emit a jump to the false label and define the true label.  */
6367
6368       if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
6369         emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_false_label));
6370       else
6371         abort ();
6372
6373       /* Here we get the insn before what was just emitted.
6374          On some machines, emitting the branch can discard
6375          the previous compare insn and emit a replacement.  */
6376       if (prev == 0)
6377         /* If there's only one preceding insn...  */
6378         insn = get_insns ();
6379       else
6380         insn = NEXT_INSN (prev);
6381
6382       for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
6383         if (GET_CODE (insn) == JUMP_INSN)
6384           {
6385             if (branch)
6386               abort ();
6387             branch = insn;
6388           }
6389
6390       if (branch != get_last_insn ())
6391         abort ();
6392
6393       if (! invert_jump (branch, if_false_label))
6394         {
6395           if_true_label = gen_label_rtx ();
6396           redirect_jump (branch, if_true_label);
6397           emit_jump (if_false_label);
6398           emit_label (if_true_label);
6399         }
6400     }
6401 }
6402 \f
6403 /* Generate code for a comparison expression EXP
6404    (including code to compute the values to be compared)
6405    and set (CC0) according to the result.
6406    SIGNED_CODE should be the rtx operation for this comparison for
6407    signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
6408
6409    We force a stack adjustment unless there are currently
6410    things pushed on the stack that aren't yet used.  */
6411
6412 static rtx
6413 compare (exp, signed_code, unsigned_code)
6414      register tree exp;
6415      enum rtx_code signed_code, unsigned_code;
6416 {
6417   register rtx op0
6418     = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
6419   register rtx op1
6420     = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
6421   register tree type = TREE_TYPE (TREE_OPERAND (exp, 0));
6422   register enum machine_mode mode = TYPE_MODE (type);
6423   int unsignedp = TREE_UNSIGNED (type);
6424   enum rtx_code code = unsignedp ? unsigned_code : signed_code;
6425
6426   return compare_from_rtx (op0, op1, code, unsignedp, mode,
6427                            ((mode == BLKmode)
6428                             ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
6429                            TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
6430 }
6431
6432 /* Like compare but expects the values to compare as two rtx's.
6433    The decision as to signed or unsigned comparison must be made by the caller.
6434
6435    If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
6436    compared.
6437
6438    If ALIGN is non-zero, it is the alignment of this type; if zero, the
6439    size of MODE should be used.  */
6440
6441 rtx
6442 compare_from_rtx (op0, op1, code, unsignedp, mode, size, align)
6443      register rtx op0, op1;
6444      enum rtx_code code;
6445      int unsignedp;
6446      enum machine_mode mode;
6447      rtx size;
6448      int align;
6449 {
6450   /* If one operand is constant, make it the second one.  */
6451
6452   if (GET_CODE (op0) == CONST_INT || GET_CODE (op0) == CONST_DOUBLE)
6453     {
6454       rtx tem = op0;
6455       op0 = op1;
6456       op1 = tem;
6457       code = swap_condition (code);
6458     }
6459
6460   if (flag_force_mem)
6461     {
6462       op0 = force_not_mem (op0);
6463       op1 = force_not_mem (op1);
6464     }
6465
6466   do_pending_stack_adjust ();
6467
6468   if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT)
6469     return simplify_relational_operation (code, mode, op0, op1);
6470
6471   /* If this is a signed equality comparison, we can do it as an
6472      unsigned comparison since zero-extension is cheaper than sign
6473      extension and comparisons with zero are done as unsigned.  This is
6474      the case even on machines that can do fast sign extension, since
6475      zero-extension is easier to combinen with other operations than
6476      sign-extension is.  If we are comparing against a constant, we must
6477      convert it to what it would look like unsigned.  */
6478   if ((code == EQ || code == NE) && ! unsignedp
6479       && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
6480     {
6481       if (GET_CODE (op1) == CONST_INT
6482           && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
6483         op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
6484       unsignedp = 1;
6485     }
6486         
6487   emit_cmp_insn (op0, op1, code, size, mode, unsignedp, align);
6488
6489   return gen_rtx (code, VOIDmode, cc0_rtx, const0_rtx);
6490 }
6491 \f
6492 /* Generate code to calculate EXP using a store-flag instruction
6493    and return an rtx for the result.  EXP is either a comparison
6494    or a TRUTH_NOT_EXPR whose operand is a comparison.
6495
6496    If TARGET is nonzero, store the result there if convenient.
6497
6498    If ONLY_CHEAP is non-zero, only do this if it is likely to be very
6499    cheap.
6500
6501    Return zero if there is no suitable set-flag instruction
6502    available on this machine.
6503
6504    Once expand_expr has been called on the arguments of the comparison,
6505    we are committed to doing the store flag, since it is not safe to
6506    re-evaluate the expression.  We emit the store-flag insn by calling
6507    emit_store_flag, but only expand the arguments if we have a reason
6508    to believe that emit_store_flag will be successful.  If we think that
6509    it will, but it isn't, we have to simulate the store-flag with a
6510    set/jump/set sequence.  */
6511
6512 static rtx
6513 do_store_flag (exp, target, mode, only_cheap)
6514      tree exp;
6515      rtx target;
6516      enum machine_mode mode;
6517      int only_cheap;
6518 {
6519   enum rtx_code code;
6520   tree arg0, arg1, type;
6521   tree tem;
6522   enum machine_mode operand_mode;
6523   int invert = 0;
6524   int unsignedp;
6525   rtx op0, op1;
6526   enum insn_code icode;
6527   rtx subtarget = target;
6528   rtx result, label, pattern, jump_pat;
6529
6530   /* If this is a TRUTH_NOT_EXPR, set a flag indicating we must invert the
6531      result at the end.  We can't simply invert the test since it would
6532      have already been inverted if it were valid.  This case occurs for
6533      some floating-point comparisons.  */
6534
6535   if (TREE_CODE (exp) == TRUTH_NOT_EXPR)
6536     invert = 1, exp = TREE_OPERAND (exp, 0);
6537
6538   arg0 = TREE_OPERAND (exp, 0);
6539   arg1 = TREE_OPERAND (exp, 1);
6540   type = TREE_TYPE (arg0);
6541   operand_mode = TYPE_MODE (type);
6542   unsignedp = TREE_UNSIGNED (type);
6543
6544   /* We won't bother with BLKmode store-flag operations because it would mean
6545      passing a lot of information to emit_store_flag.  */
6546   if (operand_mode == BLKmode)
6547     return 0;
6548
6549   STRIP_NOPS (arg0);
6550   STRIP_NOPS (arg1);
6551
6552   /* Get the rtx comparison code to use.  We know that EXP is a comparison
6553      operation of some type.  Some comparisons against 1 and -1 can be
6554      converted to comparisons with zero.  Do so here so that the tests
6555      below will be aware that we have a comparison with zero.   These
6556      tests will not catch constants in the first operand, but constants
6557      are rarely passed as the first operand.  */
6558
6559   switch (TREE_CODE (exp))
6560     {
6561     case EQ_EXPR:
6562       code = EQ;
6563       break;
6564     case NE_EXPR:
6565       code = NE;
6566       break;
6567     case LT_EXPR:
6568       if (integer_onep (arg1))
6569         arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
6570       else
6571         code = unsignedp ? LTU : LT;
6572       break;
6573     case LE_EXPR:
6574       if (integer_all_onesp (arg1))
6575         arg1 = integer_zero_node, code = unsignedp ? LTU : LT;
6576       else
6577         code = unsignedp ? LEU : LE;
6578       break;
6579     case GT_EXPR:
6580       if (integer_all_onesp (arg1))
6581         arg1 = integer_zero_node, code = unsignedp ? GEU : GE;
6582       else
6583         code = unsignedp ? GTU : GT;
6584       break;
6585     case GE_EXPR:
6586       if (integer_onep (arg1))
6587         arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
6588       else
6589         code = unsignedp ? GEU : GE;
6590       break;
6591     default:
6592       abort ();
6593     }
6594
6595   /* Put a constant second.  */
6596   if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST)
6597     {
6598       tem = arg0; arg0 = arg1; arg1 = tem;
6599       code = swap_condition (code);
6600     }
6601
6602   /* If this is an equality or inequality test of a single bit, we can
6603      do this by shifting the bit being tested to the low-order bit and
6604      masking the result with the constant 1.  If the condition was EQ,
6605      we xor it with 1.  This does not require an scc insn and is faster
6606      than an scc insn even if we have it.  */
6607
6608   if ((code == NE || code == EQ)
6609       && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
6610       && integer_pow2p (TREE_OPERAND (arg0, 1))
6611       && TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT)
6612     {
6613       int bitnum = exact_log2 (INTVAL (expand_expr (TREE_OPERAND (arg0, 1),
6614                                                     NULL_RTX, VOIDmode, 0)));
6615
6616       if (subtarget == 0 || GET_CODE (subtarget) != REG
6617           || GET_MODE (subtarget) != operand_mode
6618           || ! safe_from_p (subtarget, TREE_OPERAND (arg0, 0)))
6619         subtarget = 0;
6620
6621       op0 = expand_expr (TREE_OPERAND (arg0, 0), subtarget, VOIDmode, 0);
6622
6623       if (bitnum != 0)
6624         op0 = expand_shift (RSHIFT_EXPR, GET_MODE (op0), op0,
6625                             size_int (bitnum), target, 1);
6626
6627       if (GET_MODE (op0) != mode)
6628         op0 = convert_to_mode (mode, op0, 1);
6629
6630       if (bitnum != TYPE_PRECISION (type) - 1)
6631         op0 = expand_and (op0, const1_rtx, target);
6632
6633       if ((code == EQ && ! invert) || (code == NE && invert))
6634         op0 = expand_binop (mode, xor_optab, op0, const1_rtx, target, 0,
6635                             OPTAB_LIB_WIDEN);
6636
6637       return op0;
6638     }
6639
6640   /* Now see if we are likely to be able to do this.  Return if not.  */
6641   if (! can_compare_p (operand_mode))
6642     return 0;
6643   icode = setcc_gen_code[(int) code];
6644   if (icode == CODE_FOR_nothing
6645       || (only_cheap && insn_operand_mode[(int) icode][0] != mode))
6646     {
6647       /* We can only do this if it is one of the special cases that
6648          can be handled without an scc insn.  */
6649       if ((code == LT && integer_zerop (arg1))
6650           || (! only_cheap && code == GE && integer_zerop (arg1)))
6651         ;
6652       else if (BRANCH_COST >= 0
6653                && ! only_cheap && (code == NE || code == EQ)
6654                && TREE_CODE (type) != REAL_TYPE
6655                && ((abs_optab->handlers[(int) operand_mode].insn_code
6656                     != CODE_FOR_nothing)
6657                    || (ffs_optab->handlers[(int) operand_mode].insn_code
6658                        != CODE_FOR_nothing)))
6659         ;
6660       else
6661         return 0;
6662     }
6663       
6664   preexpand_calls (exp);
6665   if (subtarget == 0 || GET_CODE (subtarget) != REG
6666       || GET_MODE (subtarget) != operand_mode
6667       || ! safe_from_p (subtarget, arg1))
6668     subtarget = 0;
6669
6670   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
6671   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
6672
6673   if (target == 0)
6674     target = gen_reg_rtx (mode);
6675
6676   result = emit_store_flag (target, code, op0, op1, operand_mode,
6677                             unsignedp, 1);
6678
6679   if (result)
6680     {
6681       if (invert)
6682         result = expand_binop (mode, xor_optab, result, const1_rtx,
6683                                result, 0, OPTAB_LIB_WIDEN);
6684       return result;
6685     }
6686
6687   /* If this failed, we have to do this with set/compare/jump/set code.  */
6688   if (target == 0 || GET_CODE (target) != REG
6689       || reg_mentioned_p (target, op0) || reg_mentioned_p (target, op1))
6690     target = gen_reg_rtx (GET_MODE (target));
6691
6692   emit_move_insn (target, invert ? const0_rtx : const1_rtx);
6693   result = compare_from_rtx (op0, op1, code, unsignedp,
6694                              operand_mode, NULL_RTX, 0);
6695   if (GET_CODE (result) == CONST_INT)
6696     return (((result == const0_rtx && ! invert)
6697              || (result != const0_rtx && invert))
6698             ? const0_rtx : const1_rtx);
6699
6700   label = gen_label_rtx ();
6701   if (bcc_gen_fctn[(int) code] == 0)
6702     abort ();
6703
6704   emit_jump_insn ((*bcc_gen_fctn[(int) code]) (label));
6705   emit_move_insn (target, invert ? const1_rtx : const0_rtx);
6706   emit_label (label);
6707
6708   return target;
6709 }
6710 \f
6711 /* Generate a tablejump instruction (used for switch statements).  */
6712
6713 #ifdef HAVE_tablejump
6714
6715 /* INDEX is the value being switched on, with the lowest value
6716    in the table already subtracted.
6717    MODE is its expected mode (needed if INDEX is constant).
6718    RANGE is the length of the jump table.
6719    TABLE_LABEL is a CODE_LABEL rtx for the table itself.
6720
6721    DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
6722    index value is out of range.  */
6723
6724 void
6725 do_tablejump (index, mode, range, table_label, default_label)
6726      rtx index, range, table_label, default_label;
6727      enum machine_mode mode;
6728 {
6729   register rtx temp, vector;
6730
6731   /* Do an unsigned comparison (in the proper mode) between the index
6732      expression and the value which represents the length of the range.
6733      Since we just finished subtracting the lower bound of the range
6734      from the index expression, this comparison allows us to simultaneously
6735      check that the original index expression value is both greater than
6736      or equal to the minimum value of the range and less than or equal to
6737      the maximum value of the range.  */
6738
6739   emit_cmp_insn (range, index, LTU, NULL_RTX, mode, 0, 0);
6740   emit_jump_insn (gen_bltu (default_label));
6741
6742   /* If index is in range, it must fit in Pmode.
6743      Convert to Pmode so we can index with it.  */
6744   if (mode != Pmode)
6745     index = convert_to_mode (Pmode, index, 1);
6746
6747   /* If flag_force_addr were to affect this address
6748      it could interfere with the tricky assumptions made
6749      about addresses that contain label-refs,
6750      which may be valid only very near the tablejump itself.  */
6751   /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
6752      GET_MODE_SIZE, because this indicates how large insns are.  The other
6753      uses should all be Pmode, because they are addresses.  This code
6754      could fail if addresses and insns are not the same size.  */
6755   index = memory_address_noforce
6756     (CASE_VECTOR_MODE,
6757      gen_rtx (PLUS, Pmode,
6758               gen_rtx (MULT, Pmode, index,
6759                        GEN_INT (GET_MODE_SIZE (CASE_VECTOR_MODE))),
6760               gen_rtx (LABEL_REF, Pmode, table_label)));
6761   temp = gen_reg_rtx (CASE_VECTOR_MODE);
6762   vector = gen_rtx (MEM, CASE_VECTOR_MODE, index);
6763   RTX_UNCHANGING_P (vector) = 1;
6764   convert_move (temp, vector, 0);
6765
6766   emit_jump_insn (gen_tablejump (temp, table_label));
6767
6768 #ifndef CASE_VECTOR_PC_RELATIVE
6769   /* If we are generating PIC code or if the table is PC-relative, the
6770      table and JUMP_INSN must be adjacent, so don't output a BARRIER.  */
6771   if (! flag_pic)
6772     emit_barrier ();
6773 #endif
6774 }
6775
6776 #endif /* HAVE_tablejump */