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