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