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