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