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