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