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