|
|
1.1 root 1: /* Subroutines for manipulating rtx's in semantically interesting ways.
2: Copyright (C) 1987 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: #include "config.h"
23: #include "rtl.h"
24: #include "tree.h"
25: #include "flags.h"
26: #include "expr.h"
27:
28: /* Return an rtx for the sum of X and the integer C. */
29:
30: rtx
31: plus_constant (x, c)
32: register rtx x;
33: register int c;
34: {
35: register RTX_CODE code = GET_CODE (x);
36: register enum machine_mode mode = GET_MODE (x);
37: int all_constant = 0;
38:
39: if (c == 0)
40: return x;
41:
42: if (code == CONST_INT)
43: return gen_rtx (CONST_INT, VOIDmode, (INTVAL (x) + c));
44:
45: /* If adding to something entirely constant, set a flag
46: so that we can add a CONST around the result. */
47: if (code == CONST)
48: {
49: x = XEXP (x, 0);
50: all_constant = 1;
51: }
52: else if (code == SYMBOL_REF || code == LABEL_REF)
53: all_constant = 1;
54:
55: /* The interesting case is adding the integer to a sum.
56: Look for constant term in the sum and combine
57: with C. For an integer constant term, we make a combined
58: integer. For a constant term that is not an explicit integer,
59: we cannot really combine, but group them together anyway. */
60:
61: if (GET_CODE (x) == PLUS)
62: {
63: if (GET_CODE (XEXP (x, 0)) == CONST_INT)
64: {
65: c += INTVAL (XEXP (x, 0));
66: x = XEXP (x, 1);
67: }
68: else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
69: {
70: c += INTVAL (XEXP (x, 1));
71: x = XEXP (x, 0);
72: }
73: else if (CONSTANT_P (XEXP (x, 0)))
74: {
75: return gen_rtx (PLUS, mode,
76: plus_constant (XEXP (x, 0), c),
77: XEXP (x, 1));
78: }
79: else if (CONSTANT_P (XEXP (x, 1)))
80: {
81: return gen_rtx (PLUS, mode,
82: XEXP (x, 0),
83: plus_constant (XEXP (x, 1), c));
84: }
85: #ifdef OLD_INDEXING
86: /* Detect adding a constant to an indexed address
87: of the form (PLUS (MULT (REG) (CONST)) regs-and-constants).
88: Keep the (MULT ...) at the top level of addition so that
89: the result is still suitable for indexing and constants
90: are combined. */
91: else if (GET_CODE (XEXP (x, 0)) == MULT)
92: {
93: return gen_rtx (PLUS, mode, XEXP (x, 0),
94: plus_constant (XEXP (x, 1), c));
95: }
96: else if (GET_CODE (XEXP (x, 1)) == MULT)
97: {
98: return gen_rtx (PLUS, mode, plus_constant (XEXP (x, 0), c),
99: XEXP (x, 1));
100: }
101: #endif
102: }
103: if (c != 0)
104: x = gen_rtx (PLUS, mode, x, gen_rtx (CONST_INT, VOIDmode, c));
105:
106: if (all_constant)
107: return gen_rtx (CONST, mode, x);
108: else
109: return x;
110: }
111:
112: /* If X is a sum, return a new sum like X but lacking any constant terms.
113: Add all the removed constant terms into *CONSTPTR.
114: X itself is not altered. The result != X if and only if
115: it is not isomorphic to X. */
116:
117: rtx
118: eliminate_constant_term (x, constptr)
119: rtx x;
120: int *constptr;
121: {
122: int c;
123: register rtx x0, x1;
124:
125: if (GET_CODE (x) != PLUS)
126: return x;
127:
128: /* First handle constants appearing at this level explicitly. */
129: if (GET_CODE (XEXP (x, 0)) == CONST_INT)
130: {
131: *constptr += INTVAL (XEXP (x, 0));
132: return eliminate_constant_term (XEXP (x, 1), constptr);
133: }
134:
135: if (GET_CODE (XEXP (x, 1)) == CONST_INT)
136: {
137: *constptr += INTVAL (XEXP (x, 1));
138: return eliminate_constant_term (XEXP (x, 0), constptr);
139: }
140:
141: c = 0;
142: x0 = eliminate_constant_term (XEXP (x, 0), &c);
143: x1 = eliminate_constant_term (XEXP (x, 1), &c);
144: if (x1 != XEXP (x, 1) || x0 != XEXP (x, 0))
145: {
146: *constptr += c;
147: return gen_rtx (PLUS, GET_MODE (x), x0, x1);
148: }
149: return x;
150: }
151:
152: /* Return an rtx for the size in bytes of the value of EXP. */
153:
154: rtx
155: expr_size (exp)
156: tree exp;
157: {
158: return expand_expr (size_in_bytes (TREE_TYPE (exp)), 0, SImode, 0);
159: }
160:
161: /* Not yet really written since C does not need it. */
162:
163: rtx
164: lookup_static_chain ()
165: {
166: abort ();
167: }
168:
169: /* Return a copy of X in which all memory references
170: and all constants that involve symbol refs
171: have been replaced with new temporary registers.
172: Also emit code to load the memory locations and constants
173: into those registers.
174:
175: If X contains no such constants or memory references,
176: X itself (not a copy) is returned.
177:
178: X may contain no arithmetic except addition, subtraction and multiplication.
179: Values returned by expand_expr with 1 for sum_ok fit this constraint. */
180:
181: static rtx
182: break_out_memory_refs (x)
183: register rtx x;
184: {
185: if (GET_CODE (x) == MEM || GET_CODE (x) == CONST
186: || GET_CODE (x) == SYMBOL_REF)
187: {
188: register rtx temp = force_reg (Pmode, x);
189: mark_reg_pointer (temp);
190: x = temp;
191: }
192: else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
193: || GET_CODE (x) == MULT)
194: {
195: register rtx op0 = break_out_memory_refs (XEXP (x, 0));
196: register rtx op1 = break_out_memory_refs (XEXP (x, 1));
197: if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
198: x = gen_rtx (GET_CODE (x), Pmode, op0, op1);
199: }
200: return x;
201: }
202:
203: /* Given a memory address or facsimile X, construct a new address,
204: currently equivalent, that is stable: future stores won't change it.
205:
206: X must be composed of constants, register and memory references
207: combined with addition, subtraction and multiplication:
208: in other words, just what you can get from expand_expr if sum_ok is 1.
209:
210: Works by making copies of all regs and memory locations used
211: by X and combining them the same way X does.
212: You could also stabilize the reference to this address
213: by copying the address to a register with copy_to_reg;
214: but then you wouldn't get indexed addressing in the reference. */
215:
216: rtx
217: copy_all_regs (x)
218: register rtx x;
219: {
220: if (GET_CODE (x) == REG)
221: {
222: if (REGNO (x) != FRAME_POINTER_REGNUM)
223: x = copy_to_reg (x);
224: }
225: else if (GET_CODE (x) == MEM)
226: x = copy_to_reg (x);
227: else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
228: || GET_CODE (x) == MULT)
229: {
230: register rtx op0 = copy_all_regs (XEXP (x, 0));
231: register rtx op1 = copy_all_regs (XEXP (x, 1));
232: if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
233: x = gen_rtx (GET_CODE (x), Pmode, op0, op1);
234: }
235: return x;
236: }
237:
238: /* Return something equivalent to X but valid as a memory address
239: for something of mode MODE. When X is not itself valid, this
240: works by copying X or subexpressions of it into registers. */
241:
242: rtx
243: memory_address (mode, x)
244: enum machine_mode mode;
245: register rtx x;
246: {
247: register rtx tem, oldx;
248:
249: /* By passing constant addresses thru registers
250: we get a chance to cse them. */
251: if (! cse_not_expected && CONSTANT_P (x))
252: return force_reg (Pmode, x);
253:
254: /* Accept a QUEUED that refers to a REG
255: even though that isn't a valid address.
256: On attempting to put this in an insn we will call protect_from_queue
257: which will turn it into a REG, which is valid. */
258: if (GET_CODE (x) == QUEUED
259: && GET_CODE (QUEUED_VAR (x)) == REG)
260: return x;
261:
262: /* We get better cse by rejecting indirect addressing at this stage.
263: Let the combiner create indirect addresses where appropriate.
264: For now, generate the code so that the subexpressions useful to share
265: are visible. But not if cse won't be done! */
266: oldx = x;
267: if (! cse_not_expected && GET_CODE (x) != REG)
268: x = break_out_memory_refs (x);
269:
270: /* At this point, any valid address is accepted. */
271: GO_IF_LEGITIMATE_ADDRESS (mode, x, win);
272:
273: /* If it was valid before but breaking out memory refs invalidated it,
274: use it the old way. */
275: if (memory_address_p (mode, oldx))
276: goto win2;
277:
278: /* Perform machine-dependent transformations on X
279: in certain cases. This is not necessary since the code
280: below can handle all possible cases, but machine-dependent
281: transformations can make better code. */
282: LEGITIMIZE_ADDRESS (x, oldx, mode, win);
283:
284: /* PLUS and MULT can appear in special ways
285: as the result of attempts to make an address usable for indexing.
286: Usually they are dealt with by calling force_operand, below.
287: But a sum containing constant terms is special
288: if removing them makes the sum a valid address:
289: then we generate that address in a register
290: and index off of it. We do this because it often makes
291: shorter code, and because the addresses thus generated
292: in registers often become common subexpressions. */
293: if (GET_CODE (x) == PLUS)
294: {
295: int constant_term = 0;
296: rtx y = eliminate_constant_term (x, &constant_term);
297: if (constant_term == 0
298: || ! memory_address_p (mode, y))
299: return force_operand (x, 0);
300:
301: y = plus_constant (copy_to_reg (y), constant_term);
302: if (! memory_address_p (mode, y))
303: return force_operand (x, 0);
304: return y;
305: }
306: if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS)
307: return force_operand (x, 0);
308:
309: /* Last resort: copy the value to a register, since
310: the register is a valid address. */
311: return force_reg (Pmode, x);
312:
313: win2:
314: x = oldx;
315: win:
316: if (flag_force_addr && optimize && GET_CODE (x) != REG
317: /* Don't copy an addr via a reg if it is one of our stack slots.
318: If we did, it would cause invalid REG_EQUIV notes for parms. */
319: && ! (GET_CODE (x) == PLUS
320: && (XEXP (x, 0) == frame_pointer_rtx
321: || XEXP (x, 0) == arg_pointer_rtx)))
322: return force_reg (Pmode, x);
323: return x;
324: }
325:
326: /* Return a modified copy of X with its memory address copied
327: into a temporary register to protect it from side effects.
328: If X is not a MEM, it is returned unchanged (and not copied).
329: Perhaps even if it is a MEM, if there is no need to change it. */
330:
331: rtx
332: stabilize (x)
333: rtx x;
334: {
335: register rtx addr;
336: if (GET_CODE (x) != MEM)
337: return x;
338: addr = XEXP (x, 0);
339: if (rtx_unstable_p (addr))
340: {
341: rtx temp = copy_all_regs (addr);
342: rtx mem;
343: if (GET_CODE (temp) != REG)
344: temp = copy_to_reg (temp);
345: mem = gen_rtx (MEM, GET_MODE (x), temp);
346: /* Mark returned memref with in_struct
347: if it's in an array or structure. */
348: if (GET_CODE (addr) == PLUS || x->in_struct)
349: mem->in_struct = 1;
350: return mem;
351: }
352: return x;
353: }
354:
355: /* Copy the value or contents of X to a new temp reg and return that reg. */
356:
357: rtx
358: copy_to_reg (x)
359: rtx x;
360: {
361: register rtx temp = gen_reg_rtx (GET_MODE (x));
362: emit_move_insn (temp, x);
363: return temp;
364: }
365:
366: /* Like copy_to_reg but always give the new register mode Pmode
367: in case X is a constant. */
368:
369: rtx
370: copy_addr_to_reg (x)
371: rtx x;
372: {
373: register rtx temp = gen_reg_rtx (Pmode);
374: emit_move_insn (temp, x);
375: return temp;
376: }
377:
378: /* Like copy_to_reg but always give the new register mode MODE
379: in case X is a constant. */
380:
381: rtx
382: copy_to_mode_reg (mode, x)
383: enum machine_mode mode;
384: rtx x;
385: {
386: register rtx temp = gen_reg_rtx (mode);
387: if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)
388: abort ();
389: emit_move_insn (temp, x);
390: return temp;
391: }
392:
393: /* Load X into a register if it is not already one.
394: Use mode MODE for the register.
395: X should be valid for mode MODE, but it may be a constant which
396: is valid for all integer modes; that's why caller must specify MODE.
397:
398: The caller must not alter the value in the register we return,
399: since we mark it as a "constant" register. */
400:
401: rtx
402: force_reg (mode, x)
403: enum machine_mode mode;
404: rtx x;
405: {
406: register rtx temp, insn;
407:
408: if (GET_CODE (x) == REG)
409: return x;
410: temp = gen_reg_rtx (mode);
411: insn = emit_move_insn (temp, x);
412: /* Let optimizers know that TEMP's value never changes
413: and that X can be substituted for it. */
414: if (CONSTANT_P (x))
415: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV, x, 0);
416: return temp;
417: }
418:
419: /* If X is a memory ref, copy its contents to a new temp reg and return
420: that reg. Otherwise, return X. */
421:
422: rtx
423: force_not_mem (x)
424: rtx x;
425: {
426: register rtx temp;
427: if (GET_CODE (x) != MEM)
428: return x;
429: temp = gen_reg_rtx (GET_MODE (x));
430: emit_move_insn (temp, x);
431: return temp;
432: }
433:
434: /* Copy X to TARGET (if it's nonzero and a reg)
435: or to a new temp reg and return that reg. */
436:
437: rtx
438: copy_to_suggested_reg (x, target)
439: rtx x, target;
440: {
441: register rtx temp;
442: if (target && GET_CODE (target) == REG)
443: temp = target;
444: else
445: temp = gen_reg_rtx (GET_MODE (x));
446: emit_move_insn (temp, x);
447: return temp;
448: }
449:
450: /* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
451: This pops when ADJUST is positive. ADJUST need not be constant. */
452:
453: void
454: adjust_stack (adjust)
455: rtx adjust;
456: {
457: adjust = protect_from_queue (adjust, 0);
458:
459: #ifdef STACK_GROWS_DOWNWARD
460: emit_insn (gen_add2_insn (stack_pointer_rtx, adjust));
461: #else
462: emit_insn (gen_sub2_insn (stack_pointer_rtx, adjust));
463: #endif
464: }
465:
466: /* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes).
467: This pushes when ADJUST is positive. ADJUST need not be constant. */
468:
469: void
470: anti_adjust_stack (adjust)
471: rtx adjust;
472: {
473: adjust = protect_from_queue (adjust, 0);
474:
475: #ifdef STACK_GROWS_DOWNWARD
476: emit_insn (gen_sub2_insn (stack_pointer_rtx, adjust));
477: #else
478: emit_insn (gen_add2_insn (stack_pointer_rtx, adjust));
479: #endif
480: }
481:
482: /* Round the size of a block to be pushed up to the boundary required
483: by this machine. SIZE is the desired size, which need not be constant. */
484:
485: rtx
486: round_push (size)
487: rtx size;
488: {
489: #ifdef STACK_BOUNDARY
490: int align = STACK_BOUNDARY / BITS_PER_UNIT;
491: if (align == 1)
492: ;
493: if (GET_CODE (size) == CONST_INT)
494: {
495: int new = (INTVAL (size) + align - 1) / align * align;
496: if (INTVAL (size) != new)
497: size = gen_rtx (CONST_INT, VOIDmode, new);
498: }
499: else
500: {
501: size = expand_divmod (0, CEIL_DIV_EXPR, Pmode, size,
502: gen_rtx (CONST_INT, VOIDmode, align),
503: 0, 1);
504: size = expand_mult (Pmode, size,
505: gen_rtx (CONST_INT, VOIDmode, align),
506: 0, 1);
507: }
508: #endif /* STACK_BOUNDARY */
509: return size;
510: }
511:
512: /* Return an rtx representing the register or memory location
513: in which a scalar value of data type VALTYPE
514: was returned by a function call to function FUNC.
515: FUNC is a FUNCTION_DECL node if the precise function is known,
516: otherwise 0. */
517:
518: rtx
519: hard_function_value (valtype, func)
520: tree valtype;
521: tree func;
522: {
523: return FUNCTION_VALUE (valtype, func);
524: }
525:
526: /* Return an rtx representing the register or memory location
527: in which a scalar value of mode MODE was returned by a library call. */
528:
529: rtx
530: hard_libcall_value (mode)
531: enum machine_mode mode;
532: {
533: return LIBCALL_VALUE (mode);
534: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.