OSDN Git Service

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