1*38fd1498Szrj /* Subroutines for manipulating rtx's in semantically interesting ways.
2*38fd1498Szrj Copyright (C) 1987-2018 Free Software Foundation, Inc.
3*38fd1498Szrj
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*38fd1498Szrj for more details.
15*38fd1498Szrj
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3. If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>. */
19*38fd1498Szrj
20*38fd1498Szrj
21*38fd1498Szrj #include "config.h"
22*38fd1498Szrj #include "system.h"
23*38fd1498Szrj #include "coretypes.h"
24*38fd1498Szrj #include "target.h"
25*38fd1498Szrj #include "function.h"
26*38fd1498Szrj #include "rtl.h"
27*38fd1498Szrj #include "tree.h"
28*38fd1498Szrj #include "memmodel.h"
29*38fd1498Szrj #include "tm_p.h"
30*38fd1498Szrj #include "expmed.h"
31*38fd1498Szrj #include "profile-count.h"
32*38fd1498Szrj #include "optabs.h"
33*38fd1498Szrj #include "emit-rtl.h"
34*38fd1498Szrj #include "recog.h"
35*38fd1498Szrj #include "diagnostic-core.h"
36*38fd1498Szrj #include "stor-layout.h"
37*38fd1498Szrj #include "except.h"
38*38fd1498Szrj #include "dojump.h"
39*38fd1498Szrj #include "explow.h"
40*38fd1498Szrj #include "expr.h"
41*38fd1498Szrj #include "common/common-target.h"
42*38fd1498Szrj #include "output.h"
43*38fd1498Szrj #include "params.h"
44*38fd1498Szrj
45*38fd1498Szrj static rtx break_out_memory_refs (rtx);
46*38fd1498Szrj static void anti_adjust_stack_and_probe_stack_clash (rtx);
47*38fd1498Szrj
48*38fd1498Szrj
49*38fd1498Szrj /* Truncate and perhaps sign-extend C as appropriate for MODE. */
50*38fd1498Szrj
51*38fd1498Szrj HOST_WIDE_INT
trunc_int_for_mode(HOST_WIDE_INT c,machine_mode mode)52*38fd1498Szrj trunc_int_for_mode (HOST_WIDE_INT c, machine_mode mode)
53*38fd1498Szrj {
54*38fd1498Szrj /* Not scalar_int_mode because we also allow pointer bound modes. */
55*38fd1498Szrj scalar_mode smode = as_a <scalar_mode> (mode);
56*38fd1498Szrj int width = GET_MODE_PRECISION (smode);
57*38fd1498Szrj
58*38fd1498Szrj /* You want to truncate to a _what_? */
59*38fd1498Szrj gcc_assert (SCALAR_INT_MODE_P (mode)
60*38fd1498Szrj || POINTER_BOUNDS_MODE_P (mode));
61*38fd1498Szrj
62*38fd1498Szrj /* Canonicalize BImode to 0 and STORE_FLAG_VALUE. */
63*38fd1498Szrj if (smode == BImode)
64*38fd1498Szrj return c & 1 ? STORE_FLAG_VALUE : 0;
65*38fd1498Szrj
66*38fd1498Szrj /* Sign-extend for the requested mode. */
67*38fd1498Szrj
68*38fd1498Szrj if (width < HOST_BITS_PER_WIDE_INT)
69*38fd1498Szrj {
70*38fd1498Szrj HOST_WIDE_INT sign = 1;
71*38fd1498Szrj sign <<= width - 1;
72*38fd1498Szrj c &= (sign << 1) - 1;
73*38fd1498Szrj c ^= sign;
74*38fd1498Szrj c -= sign;
75*38fd1498Szrj }
76*38fd1498Szrj
77*38fd1498Szrj return c;
78*38fd1498Szrj }
79*38fd1498Szrj
80*38fd1498Szrj /* Likewise for polynomial values, using the sign-extended representation
81*38fd1498Szrj for each individual coefficient. */
82*38fd1498Szrj
83*38fd1498Szrj poly_int64
trunc_int_for_mode(poly_int64 x,machine_mode mode)84*38fd1498Szrj trunc_int_for_mode (poly_int64 x, machine_mode mode)
85*38fd1498Szrj {
86*38fd1498Szrj for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
87*38fd1498Szrj x.coeffs[i] = trunc_int_for_mode (x.coeffs[i], mode);
88*38fd1498Szrj return x;
89*38fd1498Szrj }
90*38fd1498Szrj
91*38fd1498Szrj /* Return an rtx for the sum of X and the integer C, given that X has
92*38fd1498Szrj mode MODE. INPLACE is true if X can be modified inplace or false
93*38fd1498Szrj if it must be treated as immutable. */
94*38fd1498Szrj
95*38fd1498Szrj rtx
plus_constant(machine_mode mode,rtx x,poly_int64 c,bool inplace)96*38fd1498Szrj plus_constant (machine_mode mode, rtx x, poly_int64 c, bool inplace)
97*38fd1498Szrj {
98*38fd1498Szrj RTX_CODE code;
99*38fd1498Szrj rtx y;
100*38fd1498Szrj rtx tem;
101*38fd1498Szrj int all_constant = 0;
102*38fd1498Szrj
103*38fd1498Szrj gcc_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);
104*38fd1498Szrj
105*38fd1498Szrj if (known_eq (c, 0))
106*38fd1498Szrj return x;
107*38fd1498Szrj
108*38fd1498Szrj restart:
109*38fd1498Szrj
110*38fd1498Szrj code = GET_CODE (x);
111*38fd1498Szrj y = x;
112*38fd1498Szrj
113*38fd1498Szrj switch (code)
114*38fd1498Szrj {
115*38fd1498Szrj CASE_CONST_SCALAR_INT:
116*38fd1498Szrj return immed_wide_int_const (wi::add (rtx_mode_t (x, mode), c), mode);
117*38fd1498Szrj case MEM:
118*38fd1498Szrj /* If this is a reference to the constant pool, try replacing it with
119*38fd1498Szrj a reference to a new constant. If the resulting address isn't
120*38fd1498Szrj valid, don't return it because we have no way to validize it. */
121*38fd1498Szrj if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
122*38fd1498Szrj && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
123*38fd1498Szrj {
124*38fd1498Szrj rtx cst = get_pool_constant (XEXP (x, 0));
125*38fd1498Szrj
126*38fd1498Szrj if (GET_CODE (cst) == CONST_VECTOR
127*38fd1498Szrj && GET_MODE_INNER (GET_MODE (cst)) == mode)
128*38fd1498Szrj {
129*38fd1498Szrj cst = gen_lowpart (mode, cst);
130*38fd1498Szrj gcc_assert (cst);
131*38fd1498Szrj }
132*38fd1498Szrj if (GET_MODE (cst) == VOIDmode || GET_MODE (cst) == mode)
133*38fd1498Szrj {
134*38fd1498Szrj tem = plus_constant (mode, cst, c);
135*38fd1498Szrj tem = force_const_mem (GET_MODE (x), tem);
136*38fd1498Szrj /* Targets may disallow some constants in the constant pool, thus
137*38fd1498Szrj force_const_mem may return NULL_RTX. */
138*38fd1498Szrj if (tem && memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
139*38fd1498Szrj return tem;
140*38fd1498Szrj }
141*38fd1498Szrj }
142*38fd1498Szrj break;
143*38fd1498Szrj
144*38fd1498Szrj case CONST:
145*38fd1498Szrj /* If adding to something entirely constant, set a flag
146*38fd1498Szrj so that we can add a CONST around the result. */
147*38fd1498Szrj if (inplace && shared_const_p (x))
148*38fd1498Szrj inplace = false;
149*38fd1498Szrj x = XEXP (x, 0);
150*38fd1498Szrj all_constant = 1;
151*38fd1498Szrj goto restart;
152*38fd1498Szrj
153*38fd1498Szrj case SYMBOL_REF:
154*38fd1498Szrj case LABEL_REF:
155*38fd1498Szrj all_constant = 1;
156*38fd1498Szrj break;
157*38fd1498Szrj
158*38fd1498Szrj case PLUS:
159*38fd1498Szrj /* The interesting case is adding the integer to a sum. Look
160*38fd1498Szrj for constant term in the sum and combine with C. For an
161*38fd1498Szrj integer constant term or a constant term that is not an
162*38fd1498Szrj explicit integer, we combine or group them together anyway.
163*38fd1498Szrj
164*38fd1498Szrj We may not immediately return from the recursive call here, lest
165*38fd1498Szrj all_constant gets lost. */
166*38fd1498Szrj
167*38fd1498Szrj if (CONSTANT_P (XEXP (x, 1)))
168*38fd1498Szrj {
169*38fd1498Szrj rtx term = plus_constant (mode, XEXP (x, 1), c, inplace);
170*38fd1498Szrj if (term == const0_rtx)
171*38fd1498Szrj x = XEXP (x, 0);
172*38fd1498Szrj else if (inplace)
173*38fd1498Szrj XEXP (x, 1) = term;
174*38fd1498Szrj else
175*38fd1498Szrj x = gen_rtx_PLUS (mode, XEXP (x, 0), term);
176*38fd1498Szrj c = 0;
177*38fd1498Szrj }
178*38fd1498Szrj else if (rtx *const_loc = find_constant_term_loc (&y))
179*38fd1498Szrj {
180*38fd1498Szrj if (!inplace)
181*38fd1498Szrj {
182*38fd1498Szrj /* We need to be careful since X may be shared and we can't
183*38fd1498Szrj modify it in place. */
184*38fd1498Szrj x = copy_rtx (x);
185*38fd1498Szrj const_loc = find_constant_term_loc (&x);
186*38fd1498Szrj }
187*38fd1498Szrj *const_loc = plus_constant (mode, *const_loc, c, true);
188*38fd1498Szrj c = 0;
189*38fd1498Szrj }
190*38fd1498Szrj break;
191*38fd1498Szrj
192*38fd1498Szrj default:
193*38fd1498Szrj if (CONST_POLY_INT_P (x))
194*38fd1498Szrj return immed_wide_int_const (const_poly_int_value (x) + c, mode);
195*38fd1498Szrj break;
196*38fd1498Szrj }
197*38fd1498Szrj
198*38fd1498Szrj if (maybe_ne (c, 0))
199*38fd1498Szrj x = gen_rtx_PLUS (mode, x, gen_int_mode (c, mode));
200*38fd1498Szrj
201*38fd1498Szrj if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
202*38fd1498Szrj return x;
203*38fd1498Szrj else if (all_constant)
204*38fd1498Szrj return gen_rtx_CONST (mode, x);
205*38fd1498Szrj else
206*38fd1498Szrj return x;
207*38fd1498Szrj }
208*38fd1498Szrj
209*38fd1498Szrj /* If X is a sum, return a new sum like X but lacking any constant terms.
210*38fd1498Szrj Add all the removed constant terms into *CONSTPTR.
211*38fd1498Szrj X itself is not altered. The result != X if and only if
212*38fd1498Szrj it is not isomorphic to X. */
213*38fd1498Szrj
214*38fd1498Szrj rtx
eliminate_constant_term(rtx x,rtx * constptr)215*38fd1498Szrj eliminate_constant_term (rtx x, rtx *constptr)
216*38fd1498Szrj {
217*38fd1498Szrj rtx x0, x1;
218*38fd1498Szrj rtx tem;
219*38fd1498Szrj
220*38fd1498Szrj if (GET_CODE (x) != PLUS)
221*38fd1498Szrj return x;
222*38fd1498Szrj
223*38fd1498Szrj /* First handle constants appearing at this level explicitly. */
224*38fd1498Szrj if (CONST_INT_P (XEXP (x, 1))
225*38fd1498Szrj && (tem = simplify_binary_operation (PLUS, GET_MODE (x), *constptr,
226*38fd1498Szrj XEXP (x, 1))) != 0
227*38fd1498Szrj && CONST_INT_P (tem))
228*38fd1498Szrj {
229*38fd1498Szrj *constptr = tem;
230*38fd1498Szrj return eliminate_constant_term (XEXP (x, 0), constptr);
231*38fd1498Szrj }
232*38fd1498Szrj
233*38fd1498Szrj tem = const0_rtx;
234*38fd1498Szrj x0 = eliminate_constant_term (XEXP (x, 0), &tem);
235*38fd1498Szrj x1 = eliminate_constant_term (XEXP (x, 1), &tem);
236*38fd1498Szrj if ((x1 != XEXP (x, 1) || x0 != XEXP (x, 0))
237*38fd1498Szrj && (tem = simplify_binary_operation (PLUS, GET_MODE (x),
238*38fd1498Szrj *constptr, tem)) != 0
239*38fd1498Szrj && CONST_INT_P (tem))
240*38fd1498Szrj {
241*38fd1498Szrj *constptr = tem;
242*38fd1498Szrj return gen_rtx_PLUS (GET_MODE (x), x0, x1);
243*38fd1498Szrj }
244*38fd1498Szrj
245*38fd1498Szrj return x;
246*38fd1498Szrj }
247*38fd1498Szrj
248*38fd1498Szrj
249*38fd1498Szrj /* Return a copy of X in which all memory references
250*38fd1498Szrj and all constants that involve symbol refs
251*38fd1498Szrj have been replaced with new temporary registers.
252*38fd1498Szrj Also emit code to load the memory locations and constants
253*38fd1498Szrj into those registers.
254*38fd1498Szrj
255*38fd1498Szrj If X contains no such constants or memory references,
256*38fd1498Szrj X itself (not a copy) is returned.
257*38fd1498Szrj
258*38fd1498Szrj If a constant is found in the address that is not a legitimate constant
259*38fd1498Szrj in an insn, it is left alone in the hope that it might be valid in the
260*38fd1498Szrj address.
261*38fd1498Szrj
262*38fd1498Szrj X may contain no arithmetic except addition, subtraction and multiplication.
263*38fd1498Szrj Values returned by expand_expr with 1 for sum_ok fit this constraint. */
264*38fd1498Szrj
265*38fd1498Szrj static rtx
break_out_memory_refs(rtx x)266*38fd1498Szrj break_out_memory_refs (rtx x)
267*38fd1498Szrj {
268*38fd1498Szrj if (MEM_P (x)
269*38fd1498Szrj || (CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)
270*38fd1498Szrj && GET_MODE (x) != VOIDmode))
271*38fd1498Szrj x = force_reg (GET_MODE (x), x);
272*38fd1498Szrj else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
273*38fd1498Szrj || GET_CODE (x) == MULT)
274*38fd1498Szrj {
275*38fd1498Szrj rtx op0 = break_out_memory_refs (XEXP (x, 0));
276*38fd1498Szrj rtx op1 = break_out_memory_refs (XEXP (x, 1));
277*38fd1498Szrj
278*38fd1498Szrj if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
279*38fd1498Szrj x = simplify_gen_binary (GET_CODE (x), GET_MODE (x), op0, op1);
280*38fd1498Szrj }
281*38fd1498Szrj
282*38fd1498Szrj return x;
283*38fd1498Szrj }
284*38fd1498Szrj
285*38fd1498Szrj /* Given X, a memory address in address space AS' pointer mode, convert it to
286*38fd1498Szrj an address in the address space's address mode, or vice versa (TO_MODE says
287*38fd1498Szrj which way). We take advantage of the fact that pointers are not allowed to
288*38fd1498Szrj overflow by commuting arithmetic operations over conversions so that address
289*38fd1498Szrj arithmetic insns can be used. IN_CONST is true if this conversion is inside
290*38fd1498Szrj a CONST. NO_EMIT is true if no insns should be emitted, and instead
291*38fd1498Szrj it should return NULL if it can't be simplified without emitting insns. */
292*38fd1498Szrj
293*38fd1498Szrj rtx
convert_memory_address_addr_space_1(scalar_int_mode to_mode ATTRIBUTE_UNUSED,rtx x,addr_space_t as ATTRIBUTE_UNUSED,bool in_const ATTRIBUTE_UNUSED,bool no_emit ATTRIBUTE_UNUSED)294*38fd1498Szrj convert_memory_address_addr_space_1 (scalar_int_mode to_mode ATTRIBUTE_UNUSED,
295*38fd1498Szrj rtx x, addr_space_t as ATTRIBUTE_UNUSED,
296*38fd1498Szrj bool in_const ATTRIBUTE_UNUSED,
297*38fd1498Szrj bool no_emit ATTRIBUTE_UNUSED)
298*38fd1498Szrj {
299*38fd1498Szrj #ifndef POINTERS_EXTEND_UNSIGNED
300*38fd1498Szrj gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode);
301*38fd1498Szrj return x;
302*38fd1498Szrj #else /* defined(POINTERS_EXTEND_UNSIGNED) */
303*38fd1498Szrj scalar_int_mode pointer_mode, address_mode, from_mode;
304*38fd1498Szrj rtx temp;
305*38fd1498Szrj enum rtx_code code;
306*38fd1498Szrj
307*38fd1498Szrj /* If X already has the right mode, just return it. */
308*38fd1498Szrj if (GET_MODE (x) == to_mode)
309*38fd1498Szrj return x;
310*38fd1498Szrj
311*38fd1498Szrj pointer_mode = targetm.addr_space.pointer_mode (as);
312*38fd1498Szrj address_mode = targetm.addr_space.address_mode (as);
313*38fd1498Szrj from_mode = to_mode == pointer_mode ? address_mode : pointer_mode;
314*38fd1498Szrj
315*38fd1498Szrj /* Here we handle some special cases. If none of them apply, fall through
316*38fd1498Szrj to the default case. */
317*38fd1498Szrj switch (GET_CODE (x))
318*38fd1498Szrj {
319*38fd1498Szrj CASE_CONST_SCALAR_INT:
320*38fd1498Szrj if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode))
321*38fd1498Szrj code = TRUNCATE;
322*38fd1498Szrj else if (POINTERS_EXTEND_UNSIGNED < 0)
323*38fd1498Szrj break;
324*38fd1498Szrj else if (POINTERS_EXTEND_UNSIGNED > 0)
325*38fd1498Szrj code = ZERO_EXTEND;
326*38fd1498Szrj else
327*38fd1498Szrj code = SIGN_EXTEND;
328*38fd1498Szrj temp = simplify_unary_operation (code, to_mode, x, from_mode);
329*38fd1498Szrj if (temp)
330*38fd1498Szrj return temp;
331*38fd1498Szrj break;
332*38fd1498Szrj
333*38fd1498Szrj case SUBREG:
334*38fd1498Szrj if ((SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x)))
335*38fd1498Szrj && GET_MODE (SUBREG_REG (x)) == to_mode)
336*38fd1498Szrj return SUBREG_REG (x);
337*38fd1498Szrj break;
338*38fd1498Szrj
339*38fd1498Szrj case LABEL_REF:
340*38fd1498Szrj temp = gen_rtx_LABEL_REF (to_mode, label_ref_label (x));
341*38fd1498Szrj LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x);
342*38fd1498Szrj return temp;
343*38fd1498Szrj
344*38fd1498Szrj case SYMBOL_REF:
345*38fd1498Szrj temp = shallow_copy_rtx (x);
346*38fd1498Szrj PUT_MODE (temp, to_mode);
347*38fd1498Szrj return temp;
348*38fd1498Szrj
349*38fd1498Szrj case CONST:
350*38fd1498Szrj temp = convert_memory_address_addr_space_1 (to_mode, XEXP (x, 0), as,
351*38fd1498Szrj true, no_emit);
352*38fd1498Szrj return temp ? gen_rtx_CONST (to_mode, temp) : temp;
353*38fd1498Szrj
354*38fd1498Szrj case PLUS:
355*38fd1498Szrj case MULT:
356*38fd1498Szrj /* For addition we can safely permute the conversion and addition
357*38fd1498Szrj operation if one operand is a constant and converting the constant
358*38fd1498Szrj does not change it or if one operand is a constant and we are
359*38fd1498Szrj using a ptr_extend instruction (POINTERS_EXTEND_UNSIGNED < 0).
360*38fd1498Szrj We can always safely permute them if we are making the address
361*38fd1498Szrj narrower. Inside a CONST RTL, this is safe for both pointers
362*38fd1498Szrj zero or sign extended as pointers cannot wrap. */
363*38fd1498Szrj if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
364*38fd1498Szrj || (GET_CODE (x) == PLUS
365*38fd1498Szrj && CONST_INT_P (XEXP (x, 1))
366*38fd1498Szrj && ((in_const && POINTERS_EXTEND_UNSIGNED != 0)
367*38fd1498Szrj || XEXP (x, 1) == convert_memory_address_addr_space_1
368*38fd1498Szrj (to_mode, XEXP (x, 1), as, in_const,
369*38fd1498Szrj no_emit)
370*38fd1498Szrj || POINTERS_EXTEND_UNSIGNED < 0)))
371*38fd1498Szrj {
372*38fd1498Szrj temp = convert_memory_address_addr_space_1 (to_mode, XEXP (x, 0),
373*38fd1498Szrj as, in_const, no_emit);
374*38fd1498Szrj return (temp ? gen_rtx_fmt_ee (GET_CODE (x), to_mode,
375*38fd1498Szrj temp, XEXP (x, 1))
376*38fd1498Szrj : temp);
377*38fd1498Szrj }
378*38fd1498Szrj break;
379*38fd1498Szrj
380*38fd1498Szrj default:
381*38fd1498Szrj break;
382*38fd1498Szrj }
383*38fd1498Szrj
384*38fd1498Szrj if (no_emit)
385*38fd1498Szrj return NULL_RTX;
386*38fd1498Szrj
387*38fd1498Szrj return convert_modes (to_mode, from_mode,
388*38fd1498Szrj x, POINTERS_EXTEND_UNSIGNED);
389*38fd1498Szrj #endif /* defined(POINTERS_EXTEND_UNSIGNED) */
390*38fd1498Szrj }
391*38fd1498Szrj
392*38fd1498Szrj /* Given X, a memory address in address space AS' pointer mode, convert it to
393*38fd1498Szrj an address in the address space's address mode, or vice versa (TO_MODE says
394*38fd1498Szrj which way). We take advantage of the fact that pointers are not allowed to
395*38fd1498Szrj overflow by commuting arithmetic operations over conversions so that address
396*38fd1498Szrj arithmetic insns can be used. */
397*38fd1498Szrj
398*38fd1498Szrj rtx
convert_memory_address_addr_space(scalar_int_mode to_mode,rtx x,addr_space_t as)399*38fd1498Szrj convert_memory_address_addr_space (scalar_int_mode to_mode, rtx x,
400*38fd1498Szrj addr_space_t as)
401*38fd1498Szrj {
402*38fd1498Szrj return convert_memory_address_addr_space_1 (to_mode, x, as, false, false);
403*38fd1498Szrj }
404*38fd1498Szrj
405*38fd1498Szrj
406*38fd1498Szrj /* Return something equivalent to X but valid as a memory address for something
407*38fd1498Szrj of mode MODE in the named address space AS. When X is not itself valid,
408*38fd1498Szrj this works by copying X or subexpressions of it into registers. */
409*38fd1498Szrj
410*38fd1498Szrj rtx
memory_address_addr_space(machine_mode mode,rtx x,addr_space_t as)411*38fd1498Szrj memory_address_addr_space (machine_mode mode, rtx x, addr_space_t as)
412*38fd1498Szrj {
413*38fd1498Szrj rtx oldx = x;
414*38fd1498Szrj scalar_int_mode address_mode = targetm.addr_space.address_mode (as);
415*38fd1498Szrj
416*38fd1498Szrj x = convert_memory_address_addr_space (address_mode, x, as);
417*38fd1498Szrj
418*38fd1498Szrj /* By passing constant addresses through registers
419*38fd1498Szrj we get a chance to cse them. */
420*38fd1498Szrj if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x))
421*38fd1498Szrj x = force_reg (address_mode, x);
422*38fd1498Szrj
423*38fd1498Szrj /* We get better cse by rejecting indirect addressing at this stage.
424*38fd1498Szrj Let the combiner create indirect addresses where appropriate.
425*38fd1498Szrj For now, generate the code so that the subexpressions useful to share
426*38fd1498Szrj are visible. But not if cse won't be done! */
427*38fd1498Szrj else
428*38fd1498Szrj {
429*38fd1498Szrj if (! cse_not_expected && !REG_P (x))
430*38fd1498Szrj x = break_out_memory_refs (x);
431*38fd1498Szrj
432*38fd1498Szrj /* At this point, any valid address is accepted. */
433*38fd1498Szrj if (memory_address_addr_space_p (mode, x, as))
434*38fd1498Szrj goto done;
435*38fd1498Szrj
436*38fd1498Szrj /* If it was valid before but breaking out memory refs invalidated it,
437*38fd1498Szrj use it the old way. */
438*38fd1498Szrj if (memory_address_addr_space_p (mode, oldx, as))
439*38fd1498Szrj {
440*38fd1498Szrj x = oldx;
441*38fd1498Szrj goto done;
442*38fd1498Szrj }
443*38fd1498Szrj
444*38fd1498Szrj /* Perform machine-dependent transformations on X
445*38fd1498Szrj in certain cases. This is not necessary since the code
446*38fd1498Szrj below can handle all possible cases, but machine-dependent
447*38fd1498Szrj transformations can make better code. */
448*38fd1498Szrj {
449*38fd1498Szrj rtx orig_x = x;
450*38fd1498Szrj x = targetm.addr_space.legitimize_address (x, oldx, mode, as);
451*38fd1498Szrj if (orig_x != x && memory_address_addr_space_p (mode, x, as))
452*38fd1498Szrj goto done;
453*38fd1498Szrj }
454*38fd1498Szrj
455*38fd1498Szrj /* PLUS and MULT can appear in special ways
456*38fd1498Szrj as the result of attempts to make an address usable for indexing.
457*38fd1498Szrj Usually they are dealt with by calling force_operand, below.
458*38fd1498Szrj But a sum containing constant terms is special
459*38fd1498Szrj if removing them makes the sum a valid address:
460*38fd1498Szrj then we generate that address in a register
461*38fd1498Szrj and index off of it. We do this because it often makes
462*38fd1498Szrj shorter code, and because the addresses thus generated
463*38fd1498Szrj in registers often become common subexpressions. */
464*38fd1498Szrj if (GET_CODE (x) == PLUS)
465*38fd1498Szrj {
466*38fd1498Szrj rtx constant_term = const0_rtx;
467*38fd1498Szrj rtx y = eliminate_constant_term (x, &constant_term);
468*38fd1498Szrj if (constant_term == const0_rtx
469*38fd1498Szrj || ! memory_address_addr_space_p (mode, y, as))
470*38fd1498Szrj x = force_operand (x, NULL_RTX);
471*38fd1498Szrj else
472*38fd1498Szrj {
473*38fd1498Szrj y = gen_rtx_PLUS (GET_MODE (x), copy_to_reg (y), constant_term);
474*38fd1498Szrj if (! memory_address_addr_space_p (mode, y, as))
475*38fd1498Szrj x = force_operand (x, NULL_RTX);
476*38fd1498Szrj else
477*38fd1498Szrj x = y;
478*38fd1498Szrj }
479*38fd1498Szrj }
480*38fd1498Szrj
481*38fd1498Szrj else if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS)
482*38fd1498Szrj x = force_operand (x, NULL_RTX);
483*38fd1498Szrj
484*38fd1498Szrj /* If we have a register that's an invalid address,
485*38fd1498Szrj it must be a hard reg of the wrong class. Copy it to a pseudo. */
486*38fd1498Szrj else if (REG_P (x))
487*38fd1498Szrj x = copy_to_reg (x);
488*38fd1498Szrj
489*38fd1498Szrj /* Last resort: copy the value to a register, since
490*38fd1498Szrj the register is a valid address. */
491*38fd1498Szrj else
492*38fd1498Szrj x = force_reg (address_mode, x);
493*38fd1498Szrj }
494*38fd1498Szrj
495*38fd1498Szrj done:
496*38fd1498Szrj
497*38fd1498Szrj gcc_assert (memory_address_addr_space_p (mode, x, as));
498*38fd1498Szrj /* If we didn't change the address, we are done. Otherwise, mark
499*38fd1498Szrj a reg as a pointer if we have REG or REG + CONST_INT. */
500*38fd1498Szrj if (oldx == x)
501*38fd1498Szrj return x;
502*38fd1498Szrj else if (REG_P (x))
503*38fd1498Szrj mark_reg_pointer (x, BITS_PER_UNIT);
504*38fd1498Szrj else if (GET_CODE (x) == PLUS
505*38fd1498Szrj && REG_P (XEXP (x, 0))
506*38fd1498Szrj && CONST_INT_P (XEXP (x, 1)))
507*38fd1498Szrj mark_reg_pointer (XEXP (x, 0), BITS_PER_UNIT);
508*38fd1498Szrj
509*38fd1498Szrj /* OLDX may have been the address on a temporary. Update the address
510*38fd1498Szrj to indicate that X is now used. */
511*38fd1498Szrj update_temp_slot_address (oldx, x);
512*38fd1498Szrj
513*38fd1498Szrj return x;
514*38fd1498Szrj }
515*38fd1498Szrj
516*38fd1498Szrj /* Convert a mem ref into one with a valid memory address.
517*38fd1498Szrj Pass through anything else unchanged. */
518*38fd1498Szrj
519*38fd1498Szrj rtx
validize_mem(rtx ref)520*38fd1498Szrj validize_mem (rtx ref)
521*38fd1498Szrj {
522*38fd1498Szrj if (!MEM_P (ref))
523*38fd1498Szrj return ref;
524*38fd1498Szrj ref = use_anchored_address (ref);
525*38fd1498Szrj if (memory_address_addr_space_p (GET_MODE (ref), XEXP (ref, 0),
526*38fd1498Szrj MEM_ADDR_SPACE (ref)))
527*38fd1498Szrj return ref;
528*38fd1498Szrj
529*38fd1498Szrj /* Don't alter REF itself, since that is probably a stack slot. */
530*38fd1498Szrj return replace_equiv_address (ref, XEXP (ref, 0));
531*38fd1498Szrj }
532*38fd1498Szrj
533*38fd1498Szrj /* If X is a memory reference to a member of an object block, try rewriting
534*38fd1498Szrj it to use an anchor instead. Return the new memory reference on success
535*38fd1498Szrj and the old one on failure. */
536*38fd1498Szrj
537*38fd1498Szrj rtx
use_anchored_address(rtx x)538*38fd1498Szrj use_anchored_address (rtx x)
539*38fd1498Szrj {
540*38fd1498Szrj rtx base;
541*38fd1498Szrj HOST_WIDE_INT offset;
542*38fd1498Szrj machine_mode mode;
543*38fd1498Szrj
544*38fd1498Szrj if (!flag_section_anchors)
545*38fd1498Szrj return x;
546*38fd1498Szrj
547*38fd1498Szrj if (!MEM_P (x))
548*38fd1498Szrj return x;
549*38fd1498Szrj
550*38fd1498Szrj /* Split the address into a base and offset. */
551*38fd1498Szrj base = XEXP (x, 0);
552*38fd1498Szrj offset = 0;
553*38fd1498Szrj if (GET_CODE (base) == CONST
554*38fd1498Szrj && GET_CODE (XEXP (base, 0)) == PLUS
555*38fd1498Szrj && CONST_INT_P (XEXP (XEXP (base, 0), 1)))
556*38fd1498Szrj {
557*38fd1498Szrj offset += INTVAL (XEXP (XEXP (base, 0), 1));
558*38fd1498Szrj base = XEXP (XEXP (base, 0), 0);
559*38fd1498Szrj }
560*38fd1498Szrj
561*38fd1498Szrj /* Check whether BASE is suitable for anchors. */
562*38fd1498Szrj if (GET_CODE (base) != SYMBOL_REF
563*38fd1498Szrj || !SYMBOL_REF_HAS_BLOCK_INFO_P (base)
564*38fd1498Szrj || SYMBOL_REF_ANCHOR_P (base)
565*38fd1498Szrj || SYMBOL_REF_BLOCK (base) == NULL
566*38fd1498Szrj || !targetm.use_anchors_for_symbol_p (base))
567*38fd1498Szrj return x;
568*38fd1498Szrj
569*38fd1498Szrj /* Decide where BASE is going to be. */
570*38fd1498Szrj place_block_symbol (base);
571*38fd1498Szrj
572*38fd1498Szrj /* Get the anchor we need to use. */
573*38fd1498Szrj offset += SYMBOL_REF_BLOCK_OFFSET (base);
574*38fd1498Szrj base = get_section_anchor (SYMBOL_REF_BLOCK (base), offset,
575*38fd1498Szrj SYMBOL_REF_TLS_MODEL (base));
576*38fd1498Szrj
577*38fd1498Szrj /* Work out the offset from the anchor. */
578*38fd1498Szrj offset -= SYMBOL_REF_BLOCK_OFFSET (base);
579*38fd1498Szrj
580*38fd1498Szrj /* If we're going to run a CSE pass, force the anchor into a register.
581*38fd1498Szrj We will then be able to reuse registers for several accesses, if the
582*38fd1498Szrj target costs say that that's worthwhile. */
583*38fd1498Szrj mode = GET_MODE (base);
584*38fd1498Szrj if (!cse_not_expected)
585*38fd1498Szrj base = force_reg (mode, base);
586*38fd1498Szrj
587*38fd1498Szrj return replace_equiv_address (x, plus_constant (mode, base, offset));
588*38fd1498Szrj }
589*38fd1498Szrj
590*38fd1498Szrj /* Copy the value or contents of X to a new temp reg and return that reg. */
591*38fd1498Szrj
592*38fd1498Szrj rtx
copy_to_reg(rtx x)593*38fd1498Szrj copy_to_reg (rtx x)
594*38fd1498Szrj {
595*38fd1498Szrj rtx temp = gen_reg_rtx (GET_MODE (x));
596*38fd1498Szrj
597*38fd1498Szrj /* If not an operand, must be an address with PLUS and MULT so
598*38fd1498Szrj do the computation. */
599*38fd1498Szrj if (! general_operand (x, VOIDmode))
600*38fd1498Szrj x = force_operand (x, temp);
601*38fd1498Szrj
602*38fd1498Szrj if (x != temp)
603*38fd1498Szrj emit_move_insn (temp, x);
604*38fd1498Szrj
605*38fd1498Szrj return temp;
606*38fd1498Szrj }
607*38fd1498Szrj
608*38fd1498Szrj /* Like copy_to_reg but always give the new register mode Pmode
609*38fd1498Szrj in case X is a constant. */
610*38fd1498Szrj
611*38fd1498Szrj rtx
copy_addr_to_reg(rtx x)612*38fd1498Szrj copy_addr_to_reg (rtx x)
613*38fd1498Szrj {
614*38fd1498Szrj return copy_to_mode_reg (Pmode, x);
615*38fd1498Szrj }
616*38fd1498Szrj
617*38fd1498Szrj /* Like copy_to_reg but always give the new register mode MODE
618*38fd1498Szrj in case X is a constant. */
619*38fd1498Szrj
620*38fd1498Szrj rtx
copy_to_mode_reg(machine_mode mode,rtx x)621*38fd1498Szrj copy_to_mode_reg (machine_mode mode, rtx x)
622*38fd1498Szrj {
623*38fd1498Szrj rtx temp = gen_reg_rtx (mode);
624*38fd1498Szrj
625*38fd1498Szrj /* If not an operand, must be an address with PLUS and MULT so
626*38fd1498Szrj do the computation. */
627*38fd1498Szrj if (! general_operand (x, VOIDmode))
628*38fd1498Szrj x = force_operand (x, temp);
629*38fd1498Szrj
630*38fd1498Szrj gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
631*38fd1498Szrj if (x != temp)
632*38fd1498Szrj emit_move_insn (temp, x);
633*38fd1498Szrj return temp;
634*38fd1498Szrj }
635*38fd1498Szrj
636*38fd1498Szrj /* Load X into a register if it is not already one.
637*38fd1498Szrj Use mode MODE for the register.
638*38fd1498Szrj X should be valid for mode MODE, but it may be a constant which
639*38fd1498Szrj is valid for all integer modes; that's why caller must specify MODE.
640*38fd1498Szrj
641*38fd1498Szrj The caller must not alter the value in the register we return,
642*38fd1498Szrj since we mark it as a "constant" register. */
643*38fd1498Szrj
644*38fd1498Szrj rtx
force_reg(machine_mode mode,rtx x)645*38fd1498Szrj force_reg (machine_mode mode, rtx x)
646*38fd1498Szrj {
647*38fd1498Szrj rtx temp, set;
648*38fd1498Szrj rtx_insn *insn;
649*38fd1498Szrj
650*38fd1498Szrj if (REG_P (x))
651*38fd1498Szrj return x;
652*38fd1498Szrj
653*38fd1498Szrj if (general_operand (x, mode))
654*38fd1498Szrj {
655*38fd1498Szrj temp = gen_reg_rtx (mode);
656*38fd1498Szrj insn = emit_move_insn (temp, x);
657*38fd1498Szrj }
658*38fd1498Szrj else
659*38fd1498Szrj {
660*38fd1498Szrj temp = force_operand (x, NULL_RTX);
661*38fd1498Szrj if (REG_P (temp))
662*38fd1498Szrj insn = get_last_insn ();
663*38fd1498Szrj else
664*38fd1498Szrj {
665*38fd1498Szrj rtx temp2 = gen_reg_rtx (mode);
666*38fd1498Szrj insn = emit_move_insn (temp2, temp);
667*38fd1498Szrj temp = temp2;
668*38fd1498Szrj }
669*38fd1498Szrj }
670*38fd1498Szrj
671*38fd1498Szrj /* Let optimizers know that TEMP's value never changes
672*38fd1498Szrj and that X can be substituted for it. Don't get confused
673*38fd1498Szrj if INSN set something else (such as a SUBREG of TEMP). */
674*38fd1498Szrj if (CONSTANT_P (x)
675*38fd1498Szrj && (set = single_set (insn)) != 0
676*38fd1498Szrj && SET_DEST (set) == temp
677*38fd1498Szrj && ! rtx_equal_p (x, SET_SRC (set)))
678*38fd1498Szrj set_unique_reg_note (insn, REG_EQUAL, x);
679*38fd1498Szrj
680*38fd1498Szrj /* Let optimizers know that TEMP is a pointer, and if so, the
681*38fd1498Szrj known alignment of that pointer. */
682*38fd1498Szrj {
683*38fd1498Szrj unsigned align = 0;
684*38fd1498Szrj if (GET_CODE (x) == SYMBOL_REF)
685*38fd1498Szrj {
686*38fd1498Szrj align = BITS_PER_UNIT;
687*38fd1498Szrj if (SYMBOL_REF_DECL (x) && DECL_P (SYMBOL_REF_DECL (x)))
688*38fd1498Szrj align = DECL_ALIGN (SYMBOL_REF_DECL (x));
689*38fd1498Szrj }
690*38fd1498Szrj else if (GET_CODE (x) == LABEL_REF)
691*38fd1498Szrj align = BITS_PER_UNIT;
692*38fd1498Szrj else if (GET_CODE (x) == CONST
693*38fd1498Szrj && GET_CODE (XEXP (x, 0)) == PLUS
694*38fd1498Szrj && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
695*38fd1498Szrj && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
696*38fd1498Szrj {
697*38fd1498Szrj rtx s = XEXP (XEXP (x, 0), 0);
698*38fd1498Szrj rtx c = XEXP (XEXP (x, 0), 1);
699*38fd1498Szrj unsigned sa, ca;
700*38fd1498Szrj
701*38fd1498Szrj sa = BITS_PER_UNIT;
702*38fd1498Szrj if (SYMBOL_REF_DECL (s) && DECL_P (SYMBOL_REF_DECL (s)))
703*38fd1498Szrj sa = DECL_ALIGN (SYMBOL_REF_DECL (s));
704*38fd1498Szrj
705*38fd1498Szrj if (INTVAL (c) == 0)
706*38fd1498Szrj align = sa;
707*38fd1498Szrj else
708*38fd1498Szrj {
709*38fd1498Szrj ca = ctz_hwi (INTVAL (c)) * BITS_PER_UNIT;
710*38fd1498Szrj align = MIN (sa, ca);
711*38fd1498Szrj }
712*38fd1498Szrj }
713*38fd1498Szrj
714*38fd1498Szrj if (align || (MEM_P (x) && MEM_POINTER (x)))
715*38fd1498Szrj mark_reg_pointer (temp, align);
716*38fd1498Szrj }
717*38fd1498Szrj
718*38fd1498Szrj return temp;
719*38fd1498Szrj }
720*38fd1498Szrj
721*38fd1498Szrj /* If X is a memory ref, copy its contents to a new temp reg and return
722*38fd1498Szrj that reg. Otherwise, return X. */
723*38fd1498Szrj
724*38fd1498Szrj rtx
force_not_mem(rtx x)725*38fd1498Szrj force_not_mem (rtx x)
726*38fd1498Szrj {
727*38fd1498Szrj rtx temp;
728*38fd1498Szrj
729*38fd1498Szrj if (!MEM_P (x) || GET_MODE (x) == BLKmode)
730*38fd1498Szrj return x;
731*38fd1498Szrj
732*38fd1498Szrj temp = gen_reg_rtx (GET_MODE (x));
733*38fd1498Szrj
734*38fd1498Szrj if (MEM_POINTER (x))
735*38fd1498Szrj REG_POINTER (temp) = 1;
736*38fd1498Szrj
737*38fd1498Szrj emit_move_insn (temp, x);
738*38fd1498Szrj return temp;
739*38fd1498Szrj }
740*38fd1498Szrj
741*38fd1498Szrj /* Copy X to TARGET (if it's nonzero and a reg)
742*38fd1498Szrj or to a new temp reg and return that reg.
743*38fd1498Szrj MODE is the mode to use for X in case it is a constant. */
744*38fd1498Szrj
745*38fd1498Szrj rtx
copy_to_suggested_reg(rtx x,rtx target,machine_mode mode)746*38fd1498Szrj copy_to_suggested_reg (rtx x, rtx target, machine_mode mode)
747*38fd1498Szrj {
748*38fd1498Szrj rtx temp;
749*38fd1498Szrj
750*38fd1498Szrj if (target && REG_P (target))
751*38fd1498Szrj temp = target;
752*38fd1498Szrj else
753*38fd1498Szrj temp = gen_reg_rtx (mode);
754*38fd1498Szrj
755*38fd1498Szrj emit_move_insn (temp, x);
756*38fd1498Szrj return temp;
757*38fd1498Szrj }
758*38fd1498Szrj
759*38fd1498Szrj /* Return the mode to use to pass or return a scalar of TYPE and MODE.
760*38fd1498Szrj PUNSIGNEDP points to the signedness of the type and may be adjusted
761*38fd1498Szrj to show what signedness to use on extension operations.
762*38fd1498Szrj
763*38fd1498Szrj FOR_RETURN is nonzero if the caller is promoting the return value
764*38fd1498Szrj of FNDECL, else it is for promoting args. */
765*38fd1498Szrj
766*38fd1498Szrj machine_mode
promote_function_mode(const_tree type,machine_mode mode,int * punsignedp,const_tree funtype,int for_return)767*38fd1498Szrj promote_function_mode (const_tree type, machine_mode mode, int *punsignedp,
768*38fd1498Szrj const_tree funtype, int for_return)
769*38fd1498Szrj {
770*38fd1498Szrj /* Called without a type node for a libcall. */
771*38fd1498Szrj if (type == NULL_TREE)
772*38fd1498Szrj {
773*38fd1498Szrj if (INTEGRAL_MODE_P (mode))
774*38fd1498Szrj return targetm.calls.promote_function_mode (NULL_TREE, mode,
775*38fd1498Szrj punsignedp, funtype,
776*38fd1498Szrj for_return);
777*38fd1498Szrj else
778*38fd1498Szrj return mode;
779*38fd1498Szrj }
780*38fd1498Szrj
781*38fd1498Szrj switch (TREE_CODE (type))
782*38fd1498Szrj {
783*38fd1498Szrj case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
784*38fd1498Szrj case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE:
785*38fd1498Szrj case POINTER_TYPE: case REFERENCE_TYPE:
786*38fd1498Szrj return targetm.calls.promote_function_mode (type, mode, punsignedp, funtype,
787*38fd1498Szrj for_return);
788*38fd1498Szrj
789*38fd1498Szrj default:
790*38fd1498Szrj return mode;
791*38fd1498Szrj }
792*38fd1498Szrj }
793*38fd1498Szrj /* Return the mode to use to store a scalar of TYPE and MODE.
794*38fd1498Szrj PUNSIGNEDP points to the signedness of the type and may be adjusted
795*38fd1498Szrj to show what signedness to use on extension operations. */
796*38fd1498Szrj
797*38fd1498Szrj machine_mode
promote_mode(const_tree type ATTRIBUTE_UNUSED,machine_mode mode,int * punsignedp ATTRIBUTE_UNUSED)798*38fd1498Szrj promote_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode,
799*38fd1498Szrj int *punsignedp ATTRIBUTE_UNUSED)
800*38fd1498Szrj {
801*38fd1498Szrj #ifdef PROMOTE_MODE
802*38fd1498Szrj enum tree_code code;
803*38fd1498Szrj int unsignedp;
804*38fd1498Szrj scalar_mode smode;
805*38fd1498Szrj #endif
806*38fd1498Szrj
807*38fd1498Szrj /* For libcalls this is invoked without TYPE from the backends
808*38fd1498Szrj TARGET_PROMOTE_FUNCTION_MODE hooks. Don't do anything in that
809*38fd1498Szrj case. */
810*38fd1498Szrj if (type == NULL_TREE)
811*38fd1498Szrj return mode;
812*38fd1498Szrj
813*38fd1498Szrj /* FIXME: this is the same logic that was there until GCC 4.4, but we
814*38fd1498Szrj probably want to test POINTERS_EXTEND_UNSIGNED even if PROMOTE_MODE
815*38fd1498Szrj is not defined. The affected targets are M32C, S390, SPARC. */
816*38fd1498Szrj #ifdef PROMOTE_MODE
817*38fd1498Szrj code = TREE_CODE (type);
818*38fd1498Szrj unsignedp = *punsignedp;
819*38fd1498Szrj
820*38fd1498Szrj switch (code)
821*38fd1498Szrj {
822*38fd1498Szrj case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
823*38fd1498Szrj case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE:
824*38fd1498Szrj /* Values of these types always have scalar mode. */
825*38fd1498Szrj smode = as_a <scalar_mode> (mode);
826*38fd1498Szrj PROMOTE_MODE (smode, unsignedp, type);
827*38fd1498Szrj *punsignedp = unsignedp;
828*38fd1498Szrj return smode;
829*38fd1498Szrj
830*38fd1498Szrj #ifdef POINTERS_EXTEND_UNSIGNED
831*38fd1498Szrj case REFERENCE_TYPE:
832*38fd1498Szrj case POINTER_TYPE:
833*38fd1498Szrj *punsignedp = POINTERS_EXTEND_UNSIGNED;
834*38fd1498Szrj return targetm.addr_space.address_mode
835*38fd1498Szrj (TYPE_ADDR_SPACE (TREE_TYPE (type)));
836*38fd1498Szrj #endif
837*38fd1498Szrj
838*38fd1498Szrj default:
839*38fd1498Szrj return mode;
840*38fd1498Szrj }
841*38fd1498Szrj #else
842*38fd1498Szrj return mode;
843*38fd1498Szrj #endif
844*38fd1498Szrj }
845*38fd1498Szrj
846*38fd1498Szrj
847*38fd1498Szrj /* Use one of promote_mode or promote_function_mode to find the promoted
848*38fd1498Szrj mode of DECL. If PUNSIGNEDP is not NULL, store there the unsignedness
849*38fd1498Szrj of DECL after promotion. */
850*38fd1498Szrj
851*38fd1498Szrj machine_mode
promote_decl_mode(const_tree decl,int * punsignedp)852*38fd1498Szrj promote_decl_mode (const_tree decl, int *punsignedp)
853*38fd1498Szrj {
854*38fd1498Szrj tree type = TREE_TYPE (decl);
855*38fd1498Szrj int unsignedp = TYPE_UNSIGNED (type);
856*38fd1498Szrj machine_mode mode = DECL_MODE (decl);
857*38fd1498Szrj machine_mode pmode;
858*38fd1498Szrj
859*38fd1498Szrj if (TREE_CODE (decl) == RESULT_DECL && !DECL_BY_REFERENCE (decl))
860*38fd1498Szrj pmode = promote_function_mode (type, mode, &unsignedp,
861*38fd1498Szrj TREE_TYPE (current_function_decl), 1);
862*38fd1498Szrj else if (TREE_CODE (decl) == RESULT_DECL || TREE_CODE (decl) == PARM_DECL)
863*38fd1498Szrj pmode = promote_function_mode (type, mode, &unsignedp,
864*38fd1498Szrj TREE_TYPE (current_function_decl), 2);
865*38fd1498Szrj else
866*38fd1498Szrj pmode = promote_mode (type, mode, &unsignedp);
867*38fd1498Szrj
868*38fd1498Szrj if (punsignedp)
869*38fd1498Szrj *punsignedp = unsignedp;
870*38fd1498Szrj return pmode;
871*38fd1498Szrj }
872*38fd1498Szrj
873*38fd1498Szrj /* Return the promoted mode for name. If it is a named SSA_NAME, it
874*38fd1498Szrj is the same as promote_decl_mode. Otherwise, it is the promoted
875*38fd1498Szrj mode of a temp decl of same type as the SSA_NAME, if we had created
876*38fd1498Szrj one. */
877*38fd1498Szrj
878*38fd1498Szrj machine_mode
promote_ssa_mode(const_tree name,int * punsignedp)879*38fd1498Szrj promote_ssa_mode (const_tree name, int *punsignedp)
880*38fd1498Szrj {
881*38fd1498Szrj gcc_assert (TREE_CODE (name) == SSA_NAME);
882*38fd1498Szrj
883*38fd1498Szrj /* Partitions holding parms and results must be promoted as expected
884*38fd1498Szrj by function.c. */
885*38fd1498Szrj if (SSA_NAME_VAR (name)
886*38fd1498Szrj && (TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL
887*38fd1498Szrj || TREE_CODE (SSA_NAME_VAR (name)) == RESULT_DECL))
888*38fd1498Szrj {
889*38fd1498Szrj machine_mode mode = promote_decl_mode (SSA_NAME_VAR (name), punsignedp);
890*38fd1498Szrj if (mode != BLKmode)
891*38fd1498Szrj return mode;
892*38fd1498Szrj }
893*38fd1498Szrj
894*38fd1498Szrj tree type = TREE_TYPE (name);
895*38fd1498Szrj int unsignedp = TYPE_UNSIGNED (type);
896*38fd1498Szrj machine_mode mode = TYPE_MODE (type);
897*38fd1498Szrj
898*38fd1498Szrj /* Bypass TYPE_MODE when it maps vector modes to BLKmode. */
899*38fd1498Szrj if (mode == BLKmode)
900*38fd1498Szrj {
901*38fd1498Szrj gcc_assert (VECTOR_TYPE_P (type));
902*38fd1498Szrj mode = type->type_common.mode;
903*38fd1498Szrj }
904*38fd1498Szrj
905*38fd1498Szrj machine_mode pmode = promote_mode (type, mode, &unsignedp);
906*38fd1498Szrj if (punsignedp)
907*38fd1498Szrj *punsignedp = unsignedp;
908*38fd1498Szrj
909*38fd1498Szrj return pmode;
910*38fd1498Szrj }
911*38fd1498Szrj
912*38fd1498Szrj
913*38fd1498Szrj
914*38fd1498Szrj /* Controls the behavior of {anti_,}adjust_stack. */
915*38fd1498Szrj static bool suppress_reg_args_size;
916*38fd1498Szrj
917*38fd1498Szrj /* A helper for adjust_stack and anti_adjust_stack. */
918*38fd1498Szrj
919*38fd1498Szrj static void
adjust_stack_1(rtx adjust,bool anti_p)920*38fd1498Szrj adjust_stack_1 (rtx adjust, bool anti_p)
921*38fd1498Szrj {
922*38fd1498Szrj rtx temp;
923*38fd1498Szrj rtx_insn *insn;
924*38fd1498Szrj
925*38fd1498Szrj /* Hereafter anti_p means subtract_p. */
926*38fd1498Szrj if (!STACK_GROWS_DOWNWARD)
927*38fd1498Szrj anti_p = !anti_p;
928*38fd1498Szrj
929*38fd1498Szrj temp = expand_binop (Pmode,
930*38fd1498Szrj anti_p ? sub_optab : add_optab,
931*38fd1498Szrj stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
932*38fd1498Szrj OPTAB_LIB_WIDEN);
933*38fd1498Szrj
934*38fd1498Szrj if (temp != stack_pointer_rtx)
935*38fd1498Szrj insn = emit_move_insn (stack_pointer_rtx, temp);
936*38fd1498Szrj else
937*38fd1498Szrj {
938*38fd1498Szrj insn = get_last_insn ();
939*38fd1498Szrj temp = single_set (insn);
940*38fd1498Szrj gcc_assert (temp != NULL && SET_DEST (temp) == stack_pointer_rtx);
941*38fd1498Szrj }
942*38fd1498Szrj
943*38fd1498Szrj if (!suppress_reg_args_size)
944*38fd1498Szrj add_args_size_note (insn, stack_pointer_delta);
945*38fd1498Szrj }
946*38fd1498Szrj
947*38fd1498Szrj /* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
948*38fd1498Szrj This pops when ADJUST is positive. ADJUST need not be constant. */
949*38fd1498Szrj
950*38fd1498Szrj void
adjust_stack(rtx adjust)951*38fd1498Szrj adjust_stack (rtx adjust)
952*38fd1498Szrj {
953*38fd1498Szrj if (adjust == const0_rtx)
954*38fd1498Szrj return;
955*38fd1498Szrj
956*38fd1498Szrj /* We expect all variable sized adjustments to be multiple of
957*38fd1498Szrj PREFERRED_STACK_BOUNDARY. */
958*38fd1498Szrj if (CONST_INT_P (adjust))
959*38fd1498Szrj stack_pointer_delta -= INTVAL (adjust);
960*38fd1498Szrj
961*38fd1498Szrj adjust_stack_1 (adjust, false);
962*38fd1498Szrj }
963*38fd1498Szrj
964*38fd1498Szrj /* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes).
965*38fd1498Szrj This pushes when ADJUST is positive. ADJUST need not be constant. */
966*38fd1498Szrj
967*38fd1498Szrj void
anti_adjust_stack(rtx adjust)968*38fd1498Szrj anti_adjust_stack (rtx adjust)
969*38fd1498Szrj {
970*38fd1498Szrj if (adjust == const0_rtx)
971*38fd1498Szrj return;
972*38fd1498Szrj
973*38fd1498Szrj /* We expect all variable sized adjustments to be multiple of
974*38fd1498Szrj PREFERRED_STACK_BOUNDARY. */
975*38fd1498Szrj if (CONST_INT_P (adjust))
976*38fd1498Szrj stack_pointer_delta += INTVAL (adjust);
977*38fd1498Szrj
978*38fd1498Szrj adjust_stack_1 (adjust, true);
979*38fd1498Szrj }
980*38fd1498Szrj
981*38fd1498Szrj /* Round the size of a block to be pushed up to the boundary required
982*38fd1498Szrj by this machine. SIZE is the desired size, which need not be constant. */
983*38fd1498Szrj
984*38fd1498Szrj static rtx
round_push(rtx size)985*38fd1498Szrj round_push (rtx size)
986*38fd1498Szrj {
987*38fd1498Szrj rtx align_rtx, alignm1_rtx;
988*38fd1498Szrj
989*38fd1498Szrj if (!SUPPORTS_STACK_ALIGNMENT
990*38fd1498Szrj || crtl->preferred_stack_boundary == MAX_SUPPORTED_STACK_ALIGNMENT)
991*38fd1498Szrj {
992*38fd1498Szrj int align = crtl->preferred_stack_boundary / BITS_PER_UNIT;
993*38fd1498Szrj
994*38fd1498Szrj if (align == 1)
995*38fd1498Szrj return size;
996*38fd1498Szrj
997*38fd1498Szrj if (CONST_INT_P (size))
998*38fd1498Szrj {
999*38fd1498Szrj HOST_WIDE_INT new_size = (INTVAL (size) + align - 1) / align * align;
1000*38fd1498Szrj
1001*38fd1498Szrj if (INTVAL (size) != new_size)
1002*38fd1498Szrj size = GEN_INT (new_size);
1003*38fd1498Szrj return size;
1004*38fd1498Szrj }
1005*38fd1498Szrj
1006*38fd1498Szrj align_rtx = GEN_INT (align);
1007*38fd1498Szrj alignm1_rtx = GEN_INT (align - 1);
1008*38fd1498Szrj }
1009*38fd1498Szrj else
1010*38fd1498Szrj {
1011*38fd1498Szrj /* If crtl->preferred_stack_boundary might still grow, use
1012*38fd1498Szrj virtual_preferred_stack_boundary_rtx instead. This will be
1013*38fd1498Szrj substituted by the right value in vregs pass and optimized
1014*38fd1498Szrj during combine. */
1015*38fd1498Szrj align_rtx = virtual_preferred_stack_boundary_rtx;
1016*38fd1498Szrj alignm1_rtx = force_operand (plus_constant (Pmode, align_rtx, -1),
1017*38fd1498Szrj NULL_RTX);
1018*38fd1498Szrj }
1019*38fd1498Szrj
1020*38fd1498Szrj /* CEIL_DIV_EXPR needs to worry about the addition overflowing,
1021*38fd1498Szrj but we know it can't. So add ourselves and then do
1022*38fd1498Szrj TRUNC_DIV_EXPR. */
1023*38fd1498Szrj size = expand_binop (Pmode, add_optab, size, alignm1_rtx,
1024*38fd1498Szrj NULL_RTX, 1, OPTAB_LIB_WIDEN);
1025*38fd1498Szrj size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, align_rtx,
1026*38fd1498Szrj NULL_RTX, 1);
1027*38fd1498Szrj size = expand_mult (Pmode, size, align_rtx, NULL_RTX, 1);
1028*38fd1498Szrj
1029*38fd1498Szrj return size;
1030*38fd1498Szrj }
1031*38fd1498Szrj
1032*38fd1498Szrj /* Save the stack pointer for the purpose in SAVE_LEVEL. PSAVE is a pointer
1033*38fd1498Szrj to a previously-created save area. If no save area has been allocated,
1034*38fd1498Szrj this function will allocate one. If a save area is specified, it
1035*38fd1498Szrj must be of the proper mode. */
1036*38fd1498Szrj
1037*38fd1498Szrj void
emit_stack_save(enum save_level save_level,rtx * psave)1038*38fd1498Szrj emit_stack_save (enum save_level save_level, rtx *psave)
1039*38fd1498Szrj {
1040*38fd1498Szrj rtx sa = *psave;
1041*38fd1498Szrj /* The default is that we use a move insn and save in a Pmode object. */
1042*38fd1498Szrj rtx_insn *(*fcn) (rtx, rtx) = gen_move_insn;
1043*38fd1498Szrj machine_mode mode = STACK_SAVEAREA_MODE (save_level);
1044*38fd1498Szrj
1045*38fd1498Szrj /* See if this machine has anything special to do for this kind of save. */
1046*38fd1498Szrj switch (save_level)
1047*38fd1498Szrj {
1048*38fd1498Szrj case SAVE_BLOCK:
1049*38fd1498Szrj if (targetm.have_save_stack_block ())
1050*38fd1498Szrj fcn = targetm.gen_save_stack_block;
1051*38fd1498Szrj break;
1052*38fd1498Szrj case SAVE_FUNCTION:
1053*38fd1498Szrj if (targetm.have_save_stack_function ())
1054*38fd1498Szrj fcn = targetm.gen_save_stack_function;
1055*38fd1498Szrj break;
1056*38fd1498Szrj case SAVE_NONLOCAL:
1057*38fd1498Szrj if (targetm.have_save_stack_nonlocal ())
1058*38fd1498Szrj fcn = targetm.gen_save_stack_nonlocal;
1059*38fd1498Szrj break;
1060*38fd1498Szrj default:
1061*38fd1498Szrj break;
1062*38fd1498Szrj }
1063*38fd1498Szrj
1064*38fd1498Szrj /* If there is no save area and we have to allocate one, do so. Otherwise
1065*38fd1498Szrj verify the save area is the proper mode. */
1066*38fd1498Szrj
1067*38fd1498Szrj if (sa == 0)
1068*38fd1498Szrj {
1069*38fd1498Szrj if (mode != VOIDmode)
1070*38fd1498Szrj {
1071*38fd1498Szrj if (save_level == SAVE_NONLOCAL)
1072*38fd1498Szrj *psave = sa = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
1073*38fd1498Szrj else
1074*38fd1498Szrj *psave = sa = gen_reg_rtx (mode);
1075*38fd1498Szrj }
1076*38fd1498Szrj }
1077*38fd1498Szrj
1078*38fd1498Szrj do_pending_stack_adjust ();
1079*38fd1498Szrj if (sa != 0)
1080*38fd1498Szrj sa = validize_mem (sa);
1081*38fd1498Szrj emit_insn (fcn (sa, stack_pointer_rtx));
1082*38fd1498Szrj }
1083*38fd1498Szrj
1084*38fd1498Szrj /* Restore the stack pointer for the purpose in SAVE_LEVEL. SA is the save
1085*38fd1498Szrj area made by emit_stack_save. If it is zero, we have nothing to do. */
1086*38fd1498Szrj
1087*38fd1498Szrj void
emit_stack_restore(enum save_level save_level,rtx sa)1088*38fd1498Szrj emit_stack_restore (enum save_level save_level, rtx sa)
1089*38fd1498Szrj {
1090*38fd1498Szrj /* The default is that we use a move insn. */
1091*38fd1498Szrj rtx_insn *(*fcn) (rtx, rtx) = gen_move_insn;
1092*38fd1498Szrj
1093*38fd1498Szrj /* If stack_realign_drap, the x86 backend emits a prologue that aligns both
1094*38fd1498Szrj STACK_POINTER and HARD_FRAME_POINTER.
1095*38fd1498Szrj If stack_realign_fp, the x86 backend emits a prologue that aligns only
1096*38fd1498Szrj STACK_POINTER. This renders the HARD_FRAME_POINTER unusable for accessing
1097*38fd1498Szrj aligned variables, which is reflected in ix86_can_eliminate.
1098*38fd1498Szrj We normally still have the realigned STACK_POINTER that we can use.
1099*38fd1498Szrj But if there is a stack restore still present at reload, it can trigger
1100*38fd1498Szrj mark_not_eliminable for the STACK_POINTER, leaving no way to eliminate
1101*38fd1498Szrj FRAME_POINTER into a hard reg.
1102*38fd1498Szrj To prevent this situation, we force need_drap if we emit a stack
1103*38fd1498Szrj restore. */
1104*38fd1498Szrj if (SUPPORTS_STACK_ALIGNMENT)
1105*38fd1498Szrj crtl->need_drap = true;
1106*38fd1498Szrj
1107*38fd1498Szrj /* See if this machine has anything special to do for this kind of save. */
1108*38fd1498Szrj switch (save_level)
1109*38fd1498Szrj {
1110*38fd1498Szrj case SAVE_BLOCK:
1111*38fd1498Szrj if (targetm.have_restore_stack_block ())
1112*38fd1498Szrj fcn = targetm.gen_restore_stack_block;
1113*38fd1498Szrj break;
1114*38fd1498Szrj case SAVE_FUNCTION:
1115*38fd1498Szrj if (targetm.have_restore_stack_function ())
1116*38fd1498Szrj fcn = targetm.gen_restore_stack_function;
1117*38fd1498Szrj break;
1118*38fd1498Szrj case SAVE_NONLOCAL:
1119*38fd1498Szrj if (targetm.have_restore_stack_nonlocal ())
1120*38fd1498Szrj fcn = targetm.gen_restore_stack_nonlocal;
1121*38fd1498Szrj break;
1122*38fd1498Szrj default:
1123*38fd1498Szrj break;
1124*38fd1498Szrj }
1125*38fd1498Szrj
1126*38fd1498Szrj if (sa != 0)
1127*38fd1498Szrj {
1128*38fd1498Szrj sa = validize_mem (sa);
1129*38fd1498Szrj /* These clobbers prevent the scheduler from moving
1130*38fd1498Szrj references to variable arrays below the code
1131*38fd1498Szrj that deletes (pops) the arrays. */
1132*38fd1498Szrj emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1133*38fd1498Szrj emit_clobber (gen_rtx_MEM (BLKmode, stack_pointer_rtx));
1134*38fd1498Szrj }
1135*38fd1498Szrj
1136*38fd1498Szrj discard_pending_stack_adjust ();
1137*38fd1498Szrj
1138*38fd1498Szrj emit_insn (fcn (stack_pointer_rtx, sa));
1139*38fd1498Szrj }
1140*38fd1498Szrj
1141*38fd1498Szrj /* Invoke emit_stack_save on the nonlocal_goto_save_area for the current
1142*38fd1498Szrj function. This should be called whenever we allocate or deallocate
1143*38fd1498Szrj dynamic stack space. */
1144*38fd1498Szrj
1145*38fd1498Szrj void
update_nonlocal_goto_save_area(void)1146*38fd1498Szrj update_nonlocal_goto_save_area (void)
1147*38fd1498Szrj {
1148*38fd1498Szrj tree t_save;
1149*38fd1498Szrj rtx r_save;
1150*38fd1498Szrj
1151*38fd1498Szrj /* The nonlocal_goto_save_area object is an array of N pointers. The
1152*38fd1498Szrj first one is used for the frame pointer save; the rest are sized by
1153*38fd1498Szrj STACK_SAVEAREA_MODE. Create a reference to array index 1, the first
1154*38fd1498Szrj of the stack save area slots. */
1155*38fd1498Szrj t_save = build4 (ARRAY_REF,
1156*38fd1498Szrj TREE_TYPE (TREE_TYPE (cfun->nonlocal_goto_save_area)),
1157*38fd1498Szrj cfun->nonlocal_goto_save_area,
1158*38fd1498Szrj integer_one_node, NULL_TREE, NULL_TREE);
1159*38fd1498Szrj r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
1160*38fd1498Szrj
1161*38fd1498Szrj emit_stack_save (SAVE_NONLOCAL, &r_save);
1162*38fd1498Szrj }
1163*38fd1498Szrj
1164*38fd1498Szrj /* Record a new stack level for the current function. This should be called
1165*38fd1498Szrj whenever we allocate or deallocate dynamic stack space. */
1166*38fd1498Szrj
1167*38fd1498Szrj void
record_new_stack_level(void)1168*38fd1498Szrj record_new_stack_level (void)
1169*38fd1498Szrj {
1170*38fd1498Szrj /* Record the new stack level for nonlocal gotos. */
1171*38fd1498Szrj if (cfun->nonlocal_goto_save_area)
1172*38fd1498Szrj update_nonlocal_goto_save_area ();
1173*38fd1498Szrj
1174*38fd1498Szrj /* Record the new stack level for SJLJ exceptions. */
1175*38fd1498Szrj if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
1176*38fd1498Szrj update_sjlj_context ();
1177*38fd1498Szrj }
1178*38fd1498Szrj
1179*38fd1498Szrj /* Return an rtx doing runtime alignment to REQUIRED_ALIGN on TARGET. */
1180*38fd1498Szrj static rtx
align_dynamic_address(rtx target,unsigned required_align)1181*38fd1498Szrj align_dynamic_address (rtx target, unsigned required_align)
1182*38fd1498Szrj {
1183*38fd1498Szrj /* CEIL_DIV_EXPR needs to worry about the addition overflowing,
1184*38fd1498Szrj but we know it can't. So add ourselves and then do
1185*38fd1498Szrj TRUNC_DIV_EXPR. */
1186*38fd1498Szrj target = expand_binop (Pmode, add_optab, target,
1187*38fd1498Szrj gen_int_mode (required_align / BITS_PER_UNIT - 1,
1188*38fd1498Szrj Pmode),
1189*38fd1498Szrj NULL_RTX, 1, OPTAB_LIB_WIDEN);
1190*38fd1498Szrj target = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, target,
1191*38fd1498Szrj gen_int_mode (required_align / BITS_PER_UNIT,
1192*38fd1498Szrj Pmode),
1193*38fd1498Szrj NULL_RTX, 1);
1194*38fd1498Szrj target = expand_mult (Pmode, target,
1195*38fd1498Szrj gen_int_mode (required_align / BITS_PER_UNIT,
1196*38fd1498Szrj Pmode),
1197*38fd1498Szrj NULL_RTX, 1);
1198*38fd1498Szrj
1199*38fd1498Szrj return target;
1200*38fd1498Szrj }
1201*38fd1498Szrj
1202*38fd1498Szrj /* Return an rtx through *PSIZE, representing the size of an area of memory to
1203*38fd1498Szrj be dynamically pushed on the stack.
1204*38fd1498Szrj
1205*38fd1498Szrj *PSIZE is an rtx representing the size of the area.
1206*38fd1498Szrj
1207*38fd1498Szrj SIZE_ALIGN is the alignment (in bits) that we know SIZE has. This
1208*38fd1498Szrj parameter may be zero. If so, a proper value will be extracted
1209*38fd1498Szrj from SIZE if it is constant, otherwise BITS_PER_UNIT will be assumed.
1210*38fd1498Szrj
1211*38fd1498Szrj REQUIRED_ALIGN is the alignment (in bits) required for the region
1212*38fd1498Szrj of memory.
1213*38fd1498Szrj
1214*38fd1498Szrj If PSTACK_USAGE_SIZE is not NULL it points to a value that is increased for
1215*38fd1498Szrj the additional size returned. */
1216*38fd1498Szrj void
get_dynamic_stack_size(rtx * psize,unsigned size_align,unsigned required_align,HOST_WIDE_INT * pstack_usage_size)1217*38fd1498Szrj get_dynamic_stack_size (rtx *psize, unsigned size_align,
1218*38fd1498Szrj unsigned required_align,
1219*38fd1498Szrj HOST_WIDE_INT *pstack_usage_size)
1220*38fd1498Szrj {
1221*38fd1498Szrj rtx size = *psize;
1222*38fd1498Szrj
1223*38fd1498Szrj /* Ensure the size is in the proper mode. */
1224*38fd1498Szrj if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
1225*38fd1498Szrj size = convert_to_mode (Pmode, size, 1);
1226*38fd1498Szrj
1227*38fd1498Szrj if (CONST_INT_P (size))
1228*38fd1498Szrj {
1229*38fd1498Szrj unsigned HOST_WIDE_INT lsb;
1230*38fd1498Szrj
1231*38fd1498Szrj lsb = INTVAL (size);
1232*38fd1498Szrj lsb &= -lsb;
1233*38fd1498Szrj
1234*38fd1498Szrj /* Watch out for overflow truncating to "unsigned". */
1235*38fd1498Szrj if (lsb > UINT_MAX / BITS_PER_UNIT)
1236*38fd1498Szrj size_align = 1u << (HOST_BITS_PER_INT - 1);
1237*38fd1498Szrj else
1238*38fd1498Szrj size_align = (unsigned)lsb * BITS_PER_UNIT;
1239*38fd1498Szrj }
1240*38fd1498Szrj else if (size_align < BITS_PER_UNIT)
1241*38fd1498Szrj size_align = BITS_PER_UNIT;
1242*38fd1498Szrj
1243*38fd1498Szrj /* We can't attempt to minimize alignment necessary, because we don't
1244*38fd1498Szrj know the final value of preferred_stack_boundary yet while executing
1245*38fd1498Szrj this code. */
1246*38fd1498Szrj if (crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
1247*38fd1498Szrj crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
1248*38fd1498Szrj
1249*38fd1498Szrj /* We will need to ensure that the address we return is aligned to
1250*38fd1498Szrj REQUIRED_ALIGN. At this point in the compilation, we don't always
1251*38fd1498Szrj know the final value of the STACK_DYNAMIC_OFFSET used in function.c
1252*38fd1498Szrj (it might depend on the size of the outgoing parameter lists, for
1253*38fd1498Szrj example), so we must preventively align the value. We leave space
1254*38fd1498Szrj in SIZE for the hole that might result from the alignment operation. */
1255*38fd1498Szrj
1256*38fd1498Szrj unsigned known_align = REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM);
1257*38fd1498Szrj if (known_align == 0)
1258*38fd1498Szrj known_align = BITS_PER_UNIT;
1259*38fd1498Szrj if (required_align > known_align)
1260*38fd1498Szrj {
1261*38fd1498Szrj unsigned extra = (required_align - known_align) / BITS_PER_UNIT;
1262*38fd1498Szrj size = plus_constant (Pmode, size, extra);
1263*38fd1498Szrj size = force_operand (size, NULL_RTX);
1264*38fd1498Szrj if (size_align > known_align)
1265*38fd1498Szrj size_align = known_align;
1266*38fd1498Szrj
1267*38fd1498Szrj if (flag_stack_usage_info && pstack_usage_size)
1268*38fd1498Szrj *pstack_usage_size += extra;
1269*38fd1498Szrj }
1270*38fd1498Szrj
1271*38fd1498Szrj /* Round the size to a multiple of the required stack alignment.
1272*38fd1498Szrj Since the stack is presumed to be rounded before this allocation,
1273*38fd1498Szrj this will maintain the required alignment.
1274*38fd1498Szrj
1275*38fd1498Szrj If the stack grows downward, we could save an insn by subtracting
1276*38fd1498Szrj SIZE from the stack pointer and then aligning the stack pointer.
1277*38fd1498Szrj The problem with this is that the stack pointer may be unaligned
1278*38fd1498Szrj between the execution of the subtraction and alignment insns and
1279*38fd1498Szrj some machines do not allow this. Even on those that do, some
1280*38fd1498Szrj signal handlers malfunction if a signal should occur between those
1281*38fd1498Szrj insns. Since this is an extremely rare event, we have no reliable
1282*38fd1498Szrj way of knowing which systems have this problem. So we avoid even
1283*38fd1498Szrj momentarily mis-aligning the stack. */
1284*38fd1498Szrj if (size_align % MAX_SUPPORTED_STACK_ALIGNMENT != 0)
1285*38fd1498Szrj {
1286*38fd1498Szrj size = round_push (size);
1287*38fd1498Szrj
1288*38fd1498Szrj if (flag_stack_usage_info && pstack_usage_size)
1289*38fd1498Szrj {
1290*38fd1498Szrj int align = crtl->preferred_stack_boundary / BITS_PER_UNIT;
1291*38fd1498Szrj *pstack_usage_size =
1292*38fd1498Szrj (*pstack_usage_size + align - 1) / align * align;
1293*38fd1498Szrj }
1294*38fd1498Szrj }
1295*38fd1498Szrj
1296*38fd1498Szrj *psize = size;
1297*38fd1498Szrj }
1298*38fd1498Szrj
1299*38fd1498Szrj /* Return the number of bytes to "protect" on the stack for -fstack-check.
1300*38fd1498Szrj
1301*38fd1498Szrj "protect" in the context of -fstack-check means how many bytes we
1302*38fd1498Szrj should always ensure are available on the stack. More importantly
1303*38fd1498Szrj this is how many bytes are skipped when probing the stack.
1304*38fd1498Szrj
1305*38fd1498Szrj On some targets we want to reuse the -fstack-check prologue support
1306*38fd1498Szrj to give a degree of protection against stack clashing style attacks.
1307*38fd1498Szrj
1308*38fd1498Szrj In that scenario we do not want to skip bytes before probing as that
1309*38fd1498Szrj would render the stack clash protections useless.
1310*38fd1498Szrj
1311*38fd1498Szrj So we never use STACK_CHECK_PROTECT directly. Instead we indirect though
1312*38fd1498Szrj this helper which allows us to provide different values for
1313*38fd1498Szrj -fstack-check and -fstack-clash-protection. */
1314*38fd1498Szrj HOST_WIDE_INT
get_stack_check_protect(void)1315*38fd1498Szrj get_stack_check_protect (void)
1316*38fd1498Szrj {
1317*38fd1498Szrj if (flag_stack_clash_protection)
1318*38fd1498Szrj return 0;
1319*38fd1498Szrj return STACK_CHECK_PROTECT;
1320*38fd1498Szrj }
1321*38fd1498Szrj
1322*38fd1498Szrj /* Return an rtx representing the address of an area of memory dynamically
1323*38fd1498Szrj pushed on the stack.
1324*38fd1498Szrj
1325*38fd1498Szrj Any required stack pointer alignment is preserved.
1326*38fd1498Szrj
1327*38fd1498Szrj SIZE is an rtx representing the size of the area.
1328*38fd1498Szrj
1329*38fd1498Szrj SIZE_ALIGN is the alignment (in bits) that we know SIZE has. This
1330*38fd1498Szrj parameter may be zero. If so, a proper value will be extracted
1331*38fd1498Szrj from SIZE if it is constant, otherwise BITS_PER_UNIT will be assumed.
1332*38fd1498Szrj
1333*38fd1498Szrj REQUIRED_ALIGN is the alignment (in bits) required for the region
1334*38fd1498Szrj of memory.
1335*38fd1498Szrj
1336*38fd1498Szrj MAX_SIZE is an upper bound for SIZE, if SIZE is not constant, or -1 if
1337*38fd1498Szrj no such upper bound is known.
1338*38fd1498Szrj
1339*38fd1498Szrj If CANNOT_ACCUMULATE is set to TRUE, the caller guarantees that the
1340*38fd1498Szrj stack space allocated by the generated code cannot be added with itself
1341*38fd1498Szrj in the course of the execution of the function. It is always safe to
1342*38fd1498Szrj pass FALSE here and the following criterion is sufficient in order to
1343*38fd1498Szrj pass TRUE: every path in the CFG that starts at the allocation point and
1344*38fd1498Szrj loops to it executes the associated deallocation code. */
1345*38fd1498Szrj
1346*38fd1498Szrj rtx
allocate_dynamic_stack_space(rtx size,unsigned size_align,unsigned required_align,HOST_WIDE_INT max_size,bool cannot_accumulate)1347*38fd1498Szrj allocate_dynamic_stack_space (rtx size, unsigned size_align,
1348*38fd1498Szrj unsigned required_align,
1349*38fd1498Szrj HOST_WIDE_INT max_size,
1350*38fd1498Szrj bool cannot_accumulate)
1351*38fd1498Szrj {
1352*38fd1498Szrj HOST_WIDE_INT stack_usage_size = -1;
1353*38fd1498Szrj rtx_code_label *final_label;
1354*38fd1498Szrj rtx final_target, target;
1355*38fd1498Szrj
1356*38fd1498Szrj /* If we're asking for zero bytes, it doesn't matter what we point
1357*38fd1498Szrj to since we can't dereference it. But return a reasonable
1358*38fd1498Szrj address anyway. */
1359*38fd1498Szrj if (size == const0_rtx)
1360*38fd1498Szrj return virtual_stack_dynamic_rtx;
1361*38fd1498Szrj
1362*38fd1498Szrj /* Otherwise, show we're calling alloca or equivalent. */
1363*38fd1498Szrj cfun->calls_alloca = 1;
1364*38fd1498Szrj
1365*38fd1498Szrj /* If stack usage info is requested, look into the size we are passed.
1366*38fd1498Szrj We need to do so this early to avoid the obfuscation that may be
1367*38fd1498Szrj introduced later by the various alignment operations. */
1368*38fd1498Szrj if (flag_stack_usage_info)
1369*38fd1498Szrj {
1370*38fd1498Szrj if (CONST_INT_P (size))
1371*38fd1498Szrj stack_usage_size = INTVAL (size);
1372*38fd1498Szrj else if (REG_P (size))
1373*38fd1498Szrj {
1374*38fd1498Szrj /* Look into the last emitted insn and see if we can deduce
1375*38fd1498Szrj something for the register. */
1376*38fd1498Szrj rtx_insn *insn;
1377*38fd1498Szrj rtx set, note;
1378*38fd1498Szrj insn = get_last_insn ();
1379*38fd1498Szrj if ((set = single_set (insn)) && rtx_equal_p (SET_DEST (set), size))
1380*38fd1498Szrj {
1381*38fd1498Szrj if (CONST_INT_P (SET_SRC (set)))
1382*38fd1498Szrj stack_usage_size = INTVAL (SET_SRC (set));
1383*38fd1498Szrj else if ((note = find_reg_equal_equiv_note (insn))
1384*38fd1498Szrj && CONST_INT_P (XEXP (note, 0)))
1385*38fd1498Szrj stack_usage_size = INTVAL (XEXP (note, 0));
1386*38fd1498Szrj }
1387*38fd1498Szrj }
1388*38fd1498Szrj
1389*38fd1498Szrj /* If the size is not constant, try the maximum size. */
1390*38fd1498Szrj if (stack_usage_size < 0)
1391*38fd1498Szrj stack_usage_size = max_size;
1392*38fd1498Szrj
1393*38fd1498Szrj /* If the size is still not constant, we can't say anything. */
1394*38fd1498Szrj if (stack_usage_size < 0)
1395*38fd1498Szrj {
1396*38fd1498Szrj current_function_has_unbounded_dynamic_stack_size = 1;
1397*38fd1498Szrj stack_usage_size = 0;
1398*38fd1498Szrj }
1399*38fd1498Szrj }
1400*38fd1498Szrj
1401*38fd1498Szrj get_dynamic_stack_size (&size, size_align, required_align, &stack_usage_size);
1402*38fd1498Szrj
1403*38fd1498Szrj target = gen_reg_rtx (Pmode);
1404*38fd1498Szrj
1405*38fd1498Szrj /* The size is supposed to be fully adjusted at this point so record it
1406*38fd1498Szrj if stack usage info is requested. */
1407*38fd1498Szrj if (flag_stack_usage_info)
1408*38fd1498Szrj {
1409*38fd1498Szrj current_function_dynamic_stack_size += stack_usage_size;
1410*38fd1498Szrj
1411*38fd1498Szrj /* ??? This is gross but the only safe stance in the absence
1412*38fd1498Szrj of stack usage oriented flow analysis. */
1413*38fd1498Szrj if (!cannot_accumulate)
1414*38fd1498Szrj current_function_has_unbounded_dynamic_stack_size = 1;
1415*38fd1498Szrj }
1416*38fd1498Szrj
1417*38fd1498Szrj do_pending_stack_adjust ();
1418*38fd1498Szrj
1419*38fd1498Szrj final_label = NULL;
1420*38fd1498Szrj final_target = NULL_RTX;
1421*38fd1498Szrj
1422*38fd1498Szrj /* If we are splitting the stack, we need to ask the backend whether
1423*38fd1498Szrj there is enough room on the current stack. If there isn't, or if
1424*38fd1498Szrj the backend doesn't know how to tell is, then we need to call a
1425*38fd1498Szrj function to allocate memory in some other way. This memory will
1426*38fd1498Szrj be released when we release the current stack segment. The
1427*38fd1498Szrj effect is that stack allocation becomes less efficient, but at
1428*38fd1498Szrj least it doesn't cause a stack overflow. */
1429*38fd1498Szrj if (flag_split_stack)
1430*38fd1498Szrj {
1431*38fd1498Szrj rtx_code_label *available_label;
1432*38fd1498Szrj rtx ask, space, func;
1433*38fd1498Szrj
1434*38fd1498Szrj available_label = NULL;
1435*38fd1498Szrj
1436*38fd1498Szrj if (targetm.have_split_stack_space_check ())
1437*38fd1498Szrj {
1438*38fd1498Szrj available_label = gen_label_rtx ();
1439*38fd1498Szrj
1440*38fd1498Szrj /* This instruction will branch to AVAILABLE_LABEL if there
1441*38fd1498Szrj are SIZE bytes available on the stack. */
1442*38fd1498Szrj emit_insn (targetm.gen_split_stack_space_check
1443*38fd1498Szrj (size, available_label));
1444*38fd1498Szrj }
1445*38fd1498Szrj
1446*38fd1498Szrj /* The __morestack_allocate_stack_space function will allocate
1447*38fd1498Szrj memory using malloc. If the alignment of the memory returned
1448*38fd1498Szrj by malloc does not meet REQUIRED_ALIGN, we increase SIZE to
1449*38fd1498Szrj make sure we allocate enough space. */
1450*38fd1498Szrj if (MALLOC_ABI_ALIGNMENT >= required_align)
1451*38fd1498Szrj ask = size;
1452*38fd1498Szrj else
1453*38fd1498Szrj ask = expand_binop (Pmode, add_optab, size,
1454*38fd1498Szrj gen_int_mode (required_align / BITS_PER_UNIT - 1,
1455*38fd1498Szrj Pmode),
1456*38fd1498Szrj NULL_RTX, 1, OPTAB_LIB_WIDEN);
1457*38fd1498Szrj
1458*38fd1498Szrj func = init_one_libfunc ("__morestack_allocate_stack_space");
1459*38fd1498Szrj
1460*38fd1498Szrj space = emit_library_call_value (func, target, LCT_NORMAL, Pmode,
1461*38fd1498Szrj ask, Pmode);
1462*38fd1498Szrj
1463*38fd1498Szrj if (available_label == NULL_RTX)
1464*38fd1498Szrj return space;
1465*38fd1498Szrj
1466*38fd1498Szrj final_target = gen_reg_rtx (Pmode);
1467*38fd1498Szrj
1468*38fd1498Szrj emit_move_insn (final_target, space);
1469*38fd1498Szrj
1470*38fd1498Szrj final_label = gen_label_rtx ();
1471*38fd1498Szrj emit_jump (final_label);
1472*38fd1498Szrj
1473*38fd1498Szrj emit_label (available_label);
1474*38fd1498Szrj }
1475*38fd1498Szrj
1476*38fd1498Szrj /* We ought to be called always on the toplevel and stack ought to be aligned
1477*38fd1498Szrj properly. */
1478*38fd1498Szrj gcc_assert (multiple_p (stack_pointer_delta,
1479*38fd1498Szrj PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT));
1480*38fd1498Szrj
1481*38fd1498Szrj /* If needed, check that we have the required amount of stack. Take into
1482*38fd1498Szrj account what has already been checked. */
1483*38fd1498Szrj if (STACK_CHECK_MOVING_SP)
1484*38fd1498Szrj ;
1485*38fd1498Szrj else if (flag_stack_check == GENERIC_STACK_CHECK)
1486*38fd1498Szrj probe_stack_range (STACK_OLD_CHECK_PROTECT + STACK_CHECK_MAX_FRAME_SIZE,
1487*38fd1498Szrj size);
1488*38fd1498Szrj else if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
1489*38fd1498Szrj probe_stack_range (get_stack_check_protect (), size);
1490*38fd1498Szrj
1491*38fd1498Szrj /* Don't let anti_adjust_stack emit notes. */
1492*38fd1498Szrj suppress_reg_args_size = true;
1493*38fd1498Szrj
1494*38fd1498Szrj /* Perform the required allocation from the stack. Some systems do
1495*38fd1498Szrj this differently than simply incrementing/decrementing from the
1496*38fd1498Szrj stack pointer, such as acquiring the space by calling malloc(). */
1497*38fd1498Szrj if (targetm.have_allocate_stack ())
1498*38fd1498Szrj {
1499*38fd1498Szrj struct expand_operand ops[2];
1500*38fd1498Szrj /* We don't have to check against the predicate for operand 0 since
1501*38fd1498Szrj TARGET is known to be a pseudo of the proper mode, which must
1502*38fd1498Szrj be valid for the operand. */
1503*38fd1498Szrj create_fixed_operand (&ops[0], target);
1504*38fd1498Szrj create_convert_operand_to (&ops[1], size, STACK_SIZE_MODE, true);
1505*38fd1498Szrj expand_insn (targetm.code_for_allocate_stack, 2, ops);
1506*38fd1498Szrj }
1507*38fd1498Szrj else
1508*38fd1498Szrj {
1509*38fd1498Szrj poly_int64 saved_stack_pointer_delta;
1510*38fd1498Szrj
1511*38fd1498Szrj if (!STACK_GROWS_DOWNWARD)
1512*38fd1498Szrj emit_move_insn (target, virtual_stack_dynamic_rtx);
1513*38fd1498Szrj
1514*38fd1498Szrj /* Check stack bounds if necessary. */
1515*38fd1498Szrj if (crtl->limit_stack)
1516*38fd1498Szrj {
1517*38fd1498Szrj rtx available;
1518*38fd1498Szrj rtx_code_label *space_available = gen_label_rtx ();
1519*38fd1498Szrj if (STACK_GROWS_DOWNWARD)
1520*38fd1498Szrj available = expand_binop (Pmode, sub_optab,
1521*38fd1498Szrj stack_pointer_rtx, stack_limit_rtx,
1522*38fd1498Szrj NULL_RTX, 1, OPTAB_WIDEN);
1523*38fd1498Szrj else
1524*38fd1498Szrj available = expand_binop (Pmode, sub_optab,
1525*38fd1498Szrj stack_limit_rtx, stack_pointer_rtx,
1526*38fd1498Szrj NULL_RTX, 1, OPTAB_WIDEN);
1527*38fd1498Szrj
1528*38fd1498Szrj emit_cmp_and_jump_insns (available, size, GEU, NULL_RTX, Pmode, 1,
1529*38fd1498Szrj space_available);
1530*38fd1498Szrj if (targetm.have_trap ())
1531*38fd1498Szrj emit_insn (targetm.gen_trap ());
1532*38fd1498Szrj else
1533*38fd1498Szrj error ("stack limits not supported on this target");
1534*38fd1498Szrj emit_barrier ();
1535*38fd1498Szrj emit_label (space_available);
1536*38fd1498Szrj }
1537*38fd1498Szrj
1538*38fd1498Szrj saved_stack_pointer_delta = stack_pointer_delta;
1539*38fd1498Szrj
1540*38fd1498Szrj if (flag_stack_check && STACK_CHECK_MOVING_SP)
1541*38fd1498Szrj anti_adjust_stack_and_probe (size, false);
1542*38fd1498Szrj else if (flag_stack_clash_protection)
1543*38fd1498Szrj anti_adjust_stack_and_probe_stack_clash (size);
1544*38fd1498Szrj else
1545*38fd1498Szrj anti_adjust_stack (size);
1546*38fd1498Szrj
1547*38fd1498Szrj /* Even if size is constant, don't modify stack_pointer_delta.
1548*38fd1498Szrj The constant size alloca should preserve
1549*38fd1498Szrj crtl->preferred_stack_boundary alignment. */
1550*38fd1498Szrj stack_pointer_delta = saved_stack_pointer_delta;
1551*38fd1498Szrj
1552*38fd1498Szrj if (STACK_GROWS_DOWNWARD)
1553*38fd1498Szrj emit_move_insn (target, virtual_stack_dynamic_rtx);
1554*38fd1498Szrj }
1555*38fd1498Szrj
1556*38fd1498Szrj suppress_reg_args_size = false;
1557*38fd1498Szrj
1558*38fd1498Szrj /* Finish up the split stack handling. */
1559*38fd1498Szrj if (final_label != NULL_RTX)
1560*38fd1498Szrj {
1561*38fd1498Szrj gcc_assert (flag_split_stack);
1562*38fd1498Szrj emit_move_insn (final_target, target);
1563*38fd1498Szrj emit_label (final_label);
1564*38fd1498Szrj target = final_target;
1565*38fd1498Szrj }
1566*38fd1498Szrj
1567*38fd1498Szrj target = align_dynamic_address (target, required_align);
1568*38fd1498Szrj
1569*38fd1498Szrj /* Now that we've committed to a return value, mark its alignment. */
1570*38fd1498Szrj mark_reg_pointer (target, required_align);
1571*38fd1498Szrj
1572*38fd1498Szrj /* Record the new stack level. */
1573*38fd1498Szrj record_new_stack_level ();
1574*38fd1498Szrj
1575*38fd1498Szrj return target;
1576*38fd1498Szrj }
1577*38fd1498Szrj
1578*38fd1498Szrj /* Return an rtx representing the address of an area of memory already
1579*38fd1498Szrj statically pushed onto the stack in the virtual stack vars area. (It is
1580*38fd1498Szrj assumed that the area is allocated in the function prologue.)
1581*38fd1498Szrj
1582*38fd1498Szrj Any required stack pointer alignment is preserved.
1583*38fd1498Szrj
1584*38fd1498Szrj OFFSET is the offset of the area into the virtual stack vars area.
1585*38fd1498Szrj
1586*38fd1498Szrj REQUIRED_ALIGN is the alignment (in bits) required for the region
1587*38fd1498Szrj of memory. */
1588*38fd1498Szrj
1589*38fd1498Szrj rtx
get_dynamic_stack_base(poly_int64 offset,unsigned required_align)1590*38fd1498Szrj get_dynamic_stack_base (poly_int64 offset, unsigned required_align)
1591*38fd1498Szrj {
1592*38fd1498Szrj rtx target;
1593*38fd1498Szrj
1594*38fd1498Szrj if (crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
1595*38fd1498Szrj crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
1596*38fd1498Szrj
1597*38fd1498Szrj target = gen_reg_rtx (Pmode);
1598*38fd1498Szrj emit_move_insn (target, virtual_stack_vars_rtx);
1599*38fd1498Szrj target = expand_binop (Pmode, add_optab, target,
1600*38fd1498Szrj gen_int_mode (offset, Pmode),
1601*38fd1498Szrj NULL_RTX, 1, OPTAB_LIB_WIDEN);
1602*38fd1498Szrj target = align_dynamic_address (target, required_align);
1603*38fd1498Szrj
1604*38fd1498Szrj /* Now that we've committed to a return value, mark its alignment. */
1605*38fd1498Szrj mark_reg_pointer (target, required_align);
1606*38fd1498Szrj
1607*38fd1498Szrj return target;
1608*38fd1498Szrj }
1609*38fd1498Szrj
1610*38fd1498Szrj /* A front end may want to override GCC's stack checking by providing a
1611*38fd1498Szrj run-time routine to call to check the stack, so provide a mechanism for
1612*38fd1498Szrj calling that routine. */
1613*38fd1498Szrj
1614*38fd1498Szrj static GTY(()) rtx stack_check_libfunc;
1615*38fd1498Szrj
1616*38fd1498Szrj void
set_stack_check_libfunc(const char * libfunc_name)1617*38fd1498Szrj set_stack_check_libfunc (const char *libfunc_name)
1618*38fd1498Szrj {
1619*38fd1498Szrj gcc_assert (stack_check_libfunc == NULL_RTX);
1620*38fd1498Szrj stack_check_libfunc = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
1621*38fd1498Szrj }
1622*38fd1498Szrj
1623*38fd1498Szrj /* Emit one stack probe at ADDRESS, an address within the stack. */
1624*38fd1498Szrj
1625*38fd1498Szrj void
emit_stack_probe(rtx address)1626*38fd1498Szrj emit_stack_probe (rtx address)
1627*38fd1498Szrj {
1628*38fd1498Szrj if (targetm.have_probe_stack_address ())
1629*38fd1498Szrj {
1630*38fd1498Szrj struct expand_operand ops[1];
1631*38fd1498Szrj insn_code icode = targetm.code_for_probe_stack_address;
1632*38fd1498Szrj create_address_operand (ops, address);
1633*38fd1498Szrj maybe_legitimize_operands (icode, 0, 1, ops);
1634*38fd1498Szrj expand_insn (icode, 1, ops);
1635*38fd1498Szrj }
1636*38fd1498Szrj else
1637*38fd1498Szrj {
1638*38fd1498Szrj rtx memref = gen_rtx_MEM (word_mode, address);
1639*38fd1498Szrj
1640*38fd1498Szrj MEM_VOLATILE_P (memref) = 1;
1641*38fd1498Szrj memref = validize_mem (memref);
1642*38fd1498Szrj
1643*38fd1498Szrj /* See if we have an insn to probe the stack. */
1644*38fd1498Szrj if (targetm.have_probe_stack ())
1645*38fd1498Szrj emit_insn (targetm.gen_probe_stack (memref));
1646*38fd1498Szrj else
1647*38fd1498Szrj emit_move_insn (memref, const0_rtx);
1648*38fd1498Szrj }
1649*38fd1498Szrj }
1650*38fd1498Szrj
1651*38fd1498Szrj /* Probe a range of stack addresses from FIRST to FIRST+SIZE, inclusive.
1652*38fd1498Szrj FIRST is a constant and size is a Pmode RTX. These are offsets from
1653*38fd1498Szrj the current stack pointer. STACK_GROWS_DOWNWARD says whether to add
1654*38fd1498Szrj or subtract them from the stack pointer. */
1655*38fd1498Szrj
1656*38fd1498Szrj #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
1657*38fd1498Szrj
1658*38fd1498Szrj #if STACK_GROWS_DOWNWARD
1659*38fd1498Szrj #define STACK_GROW_OP MINUS
1660*38fd1498Szrj #define STACK_GROW_OPTAB sub_optab
1661*38fd1498Szrj #define STACK_GROW_OFF(off) -(off)
1662*38fd1498Szrj #else
1663*38fd1498Szrj #define STACK_GROW_OP PLUS
1664*38fd1498Szrj #define STACK_GROW_OPTAB add_optab
1665*38fd1498Szrj #define STACK_GROW_OFF(off) (off)
1666*38fd1498Szrj #endif
1667*38fd1498Szrj
1668*38fd1498Szrj void
probe_stack_range(HOST_WIDE_INT first,rtx size)1669*38fd1498Szrj probe_stack_range (HOST_WIDE_INT first, rtx size)
1670*38fd1498Szrj {
1671*38fd1498Szrj /* First ensure SIZE is Pmode. */
1672*38fd1498Szrj if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
1673*38fd1498Szrj size = convert_to_mode (Pmode, size, 1);
1674*38fd1498Szrj
1675*38fd1498Szrj /* Next see if we have a function to check the stack. */
1676*38fd1498Szrj if (stack_check_libfunc)
1677*38fd1498Szrj {
1678*38fd1498Szrj rtx addr = memory_address (Pmode,
1679*38fd1498Szrj gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
1680*38fd1498Szrj stack_pointer_rtx,
1681*38fd1498Szrj plus_constant (Pmode,
1682*38fd1498Szrj size, first)));
1683*38fd1498Szrj emit_library_call (stack_check_libfunc, LCT_THROW, VOIDmode,
1684*38fd1498Szrj addr, Pmode);
1685*38fd1498Szrj }
1686*38fd1498Szrj
1687*38fd1498Szrj /* Next see if we have an insn to check the stack. */
1688*38fd1498Szrj else if (targetm.have_check_stack ())
1689*38fd1498Szrj {
1690*38fd1498Szrj struct expand_operand ops[1];
1691*38fd1498Szrj rtx addr = memory_address (Pmode,
1692*38fd1498Szrj gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
1693*38fd1498Szrj stack_pointer_rtx,
1694*38fd1498Szrj plus_constant (Pmode,
1695*38fd1498Szrj size, first)));
1696*38fd1498Szrj bool success;
1697*38fd1498Szrj create_input_operand (&ops[0], addr, Pmode);
1698*38fd1498Szrj success = maybe_expand_insn (targetm.code_for_check_stack, 1, ops);
1699*38fd1498Szrj gcc_assert (success);
1700*38fd1498Szrj }
1701*38fd1498Szrj
1702*38fd1498Szrj /* Otherwise we have to generate explicit probes. If we have a constant
1703*38fd1498Szrj small number of them to generate, that's the easy case. */
1704*38fd1498Szrj else if (CONST_INT_P (size) && INTVAL (size) < 7 * PROBE_INTERVAL)
1705*38fd1498Szrj {
1706*38fd1498Szrj HOST_WIDE_INT isize = INTVAL (size), i;
1707*38fd1498Szrj rtx addr;
1708*38fd1498Szrj
1709*38fd1498Szrj /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
1710*38fd1498Szrj it exceeds SIZE. If only one probe is needed, this will not
1711*38fd1498Szrj generate any code. Then probe at FIRST + SIZE. */
1712*38fd1498Szrj for (i = PROBE_INTERVAL; i < isize; i += PROBE_INTERVAL)
1713*38fd1498Szrj {
1714*38fd1498Szrj addr = memory_address (Pmode,
1715*38fd1498Szrj plus_constant (Pmode, stack_pointer_rtx,
1716*38fd1498Szrj STACK_GROW_OFF (first + i)));
1717*38fd1498Szrj emit_stack_probe (addr);
1718*38fd1498Szrj }
1719*38fd1498Szrj
1720*38fd1498Szrj addr = memory_address (Pmode,
1721*38fd1498Szrj plus_constant (Pmode, stack_pointer_rtx,
1722*38fd1498Szrj STACK_GROW_OFF (first + isize)));
1723*38fd1498Szrj emit_stack_probe (addr);
1724*38fd1498Szrj }
1725*38fd1498Szrj
1726*38fd1498Szrj /* In the variable case, do the same as above, but in a loop. Note that we
1727*38fd1498Szrj must be extra careful with variables wrapping around because we might be
1728*38fd1498Szrj at the very top (or the very bottom) of the address space and we have to
1729*38fd1498Szrj be able to handle this case properly; in particular, we use an equality
1730*38fd1498Szrj test for the loop condition. */
1731*38fd1498Szrj else
1732*38fd1498Szrj {
1733*38fd1498Szrj rtx rounded_size, rounded_size_op, test_addr, last_addr, temp;
1734*38fd1498Szrj rtx_code_label *loop_lab = gen_label_rtx ();
1735*38fd1498Szrj rtx_code_label *end_lab = gen_label_rtx ();
1736*38fd1498Szrj
1737*38fd1498Szrj /* Step 1: round SIZE to the previous multiple of the interval. */
1738*38fd1498Szrj
1739*38fd1498Szrj /* ROUNDED_SIZE = SIZE & -PROBE_INTERVAL */
1740*38fd1498Szrj rounded_size
1741*38fd1498Szrj = simplify_gen_binary (AND, Pmode, size,
1742*38fd1498Szrj gen_int_mode (-PROBE_INTERVAL, Pmode));
1743*38fd1498Szrj rounded_size_op = force_operand (rounded_size, NULL_RTX);
1744*38fd1498Szrj
1745*38fd1498Szrj
1746*38fd1498Szrj /* Step 2: compute initial and final value of the loop counter. */
1747*38fd1498Szrj
1748*38fd1498Szrj /* TEST_ADDR = SP + FIRST. */
1749*38fd1498Szrj test_addr = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
1750*38fd1498Szrj stack_pointer_rtx,
1751*38fd1498Szrj gen_int_mode (first, Pmode)),
1752*38fd1498Szrj NULL_RTX);
1753*38fd1498Szrj
1754*38fd1498Szrj /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
1755*38fd1498Szrj last_addr = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
1756*38fd1498Szrj test_addr,
1757*38fd1498Szrj rounded_size_op), NULL_RTX);
1758*38fd1498Szrj
1759*38fd1498Szrj
1760*38fd1498Szrj /* Step 3: the loop
1761*38fd1498Szrj
1762*38fd1498Szrj while (TEST_ADDR != LAST_ADDR)
1763*38fd1498Szrj {
1764*38fd1498Szrj TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
1765*38fd1498Szrj probe at TEST_ADDR
1766*38fd1498Szrj }
1767*38fd1498Szrj
1768*38fd1498Szrj probes at FIRST + N * PROBE_INTERVAL for values of N from 1
1769*38fd1498Szrj until it is equal to ROUNDED_SIZE. */
1770*38fd1498Szrj
1771*38fd1498Szrj emit_label (loop_lab);
1772*38fd1498Szrj
1773*38fd1498Szrj /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
1774*38fd1498Szrj emit_cmp_and_jump_insns (test_addr, last_addr, EQ, NULL_RTX, Pmode, 1,
1775*38fd1498Szrj end_lab);
1776*38fd1498Szrj
1777*38fd1498Szrj /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
1778*38fd1498Szrj temp = expand_binop (Pmode, STACK_GROW_OPTAB, test_addr,
1779*38fd1498Szrj gen_int_mode (PROBE_INTERVAL, Pmode), test_addr,
1780*38fd1498Szrj 1, OPTAB_WIDEN);
1781*38fd1498Szrj
1782*38fd1498Szrj gcc_assert (temp == test_addr);
1783*38fd1498Szrj
1784*38fd1498Szrj /* Probe at TEST_ADDR. */
1785*38fd1498Szrj emit_stack_probe (test_addr);
1786*38fd1498Szrj
1787*38fd1498Szrj emit_jump (loop_lab);
1788*38fd1498Szrj
1789*38fd1498Szrj emit_label (end_lab);
1790*38fd1498Szrj
1791*38fd1498Szrj
1792*38fd1498Szrj /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
1793*38fd1498Szrj that SIZE is equal to ROUNDED_SIZE. */
1794*38fd1498Szrj
1795*38fd1498Szrj /* TEMP = SIZE - ROUNDED_SIZE. */
1796*38fd1498Szrj temp = simplify_gen_binary (MINUS, Pmode, size, rounded_size);
1797*38fd1498Szrj if (temp != const0_rtx)
1798*38fd1498Szrj {
1799*38fd1498Szrj rtx addr;
1800*38fd1498Szrj
1801*38fd1498Szrj if (CONST_INT_P (temp))
1802*38fd1498Szrj {
1803*38fd1498Szrj /* Use [base + disp} addressing mode if supported. */
1804*38fd1498Szrj HOST_WIDE_INT offset = INTVAL (temp);
1805*38fd1498Szrj addr = memory_address (Pmode,
1806*38fd1498Szrj plus_constant (Pmode, last_addr,
1807*38fd1498Szrj STACK_GROW_OFF (offset)));
1808*38fd1498Szrj }
1809*38fd1498Szrj else
1810*38fd1498Szrj {
1811*38fd1498Szrj /* Manual CSE if the difference is not known at compile-time. */
1812*38fd1498Szrj temp = gen_rtx_MINUS (Pmode, size, rounded_size_op);
1813*38fd1498Szrj addr = memory_address (Pmode,
1814*38fd1498Szrj gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
1815*38fd1498Szrj last_addr, temp));
1816*38fd1498Szrj }
1817*38fd1498Szrj
1818*38fd1498Szrj emit_stack_probe (addr);
1819*38fd1498Szrj }
1820*38fd1498Szrj }
1821*38fd1498Szrj
1822*38fd1498Szrj /* Make sure nothing is scheduled before we are done. */
1823*38fd1498Szrj emit_insn (gen_blockage ());
1824*38fd1498Szrj }
1825*38fd1498Szrj
1826*38fd1498Szrj /* Compute parameters for stack clash probing a dynamic stack
1827*38fd1498Szrj allocation of SIZE bytes.
1828*38fd1498Szrj
1829*38fd1498Szrj We compute ROUNDED_SIZE, LAST_ADDR, RESIDUAL and PROBE_INTERVAL.
1830*38fd1498Szrj
1831*38fd1498Szrj Additionally we conditionally dump the type of probing that will
1832*38fd1498Szrj be needed given the values computed. */
1833*38fd1498Szrj
1834*38fd1498Szrj void
compute_stack_clash_protection_loop_data(rtx * rounded_size,rtx * last_addr,rtx * residual,HOST_WIDE_INT * probe_interval,rtx size)1835*38fd1498Szrj compute_stack_clash_protection_loop_data (rtx *rounded_size, rtx *last_addr,
1836*38fd1498Szrj rtx *residual,
1837*38fd1498Szrj HOST_WIDE_INT *probe_interval,
1838*38fd1498Szrj rtx size)
1839*38fd1498Szrj {
1840*38fd1498Szrj /* Round SIZE down to STACK_CLASH_PROTECTION_PROBE_INTERVAL */
1841*38fd1498Szrj *probe_interval
1842*38fd1498Szrj = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL);
1843*38fd1498Szrj *rounded_size = simplify_gen_binary (AND, Pmode, size,
1844*38fd1498Szrj GEN_INT (-*probe_interval));
1845*38fd1498Szrj
1846*38fd1498Szrj /* Compute the value of the stack pointer for the last iteration.
1847*38fd1498Szrj It's just SP + ROUNDED_SIZE. */
1848*38fd1498Szrj rtx rounded_size_op = force_operand (*rounded_size, NULL_RTX);
1849*38fd1498Szrj *last_addr = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
1850*38fd1498Szrj stack_pointer_rtx,
1851*38fd1498Szrj rounded_size_op),
1852*38fd1498Szrj NULL_RTX);
1853*38fd1498Szrj
1854*38fd1498Szrj /* Compute any residuals not allocated by the loop above. Residuals
1855*38fd1498Szrj are just the ROUNDED_SIZE - SIZE. */
1856*38fd1498Szrj *residual = simplify_gen_binary (MINUS, Pmode, size, *rounded_size);
1857*38fd1498Szrj
1858*38fd1498Szrj /* Dump key information to make writing tests easy. */
1859*38fd1498Szrj if (dump_file)
1860*38fd1498Szrj {
1861*38fd1498Szrj if (*rounded_size == CONST0_RTX (Pmode))
1862*38fd1498Szrj fprintf (dump_file,
1863*38fd1498Szrj "Stack clash skipped dynamic allocation and probing loop.\n");
1864*38fd1498Szrj else if (CONST_INT_P (*rounded_size)
1865*38fd1498Szrj && INTVAL (*rounded_size) <= 4 * *probe_interval)
1866*38fd1498Szrj fprintf (dump_file,
1867*38fd1498Szrj "Stack clash dynamic allocation and probing inline.\n");
1868*38fd1498Szrj else if (CONST_INT_P (*rounded_size))
1869*38fd1498Szrj fprintf (dump_file,
1870*38fd1498Szrj "Stack clash dynamic allocation and probing in "
1871*38fd1498Szrj "rotated loop.\n");
1872*38fd1498Szrj else
1873*38fd1498Szrj fprintf (dump_file,
1874*38fd1498Szrj "Stack clash dynamic allocation and probing in loop.\n");
1875*38fd1498Szrj
1876*38fd1498Szrj if (*residual != CONST0_RTX (Pmode))
1877*38fd1498Szrj fprintf (dump_file,
1878*38fd1498Szrj "Stack clash dynamic allocation and probing residuals.\n");
1879*38fd1498Szrj else
1880*38fd1498Szrj fprintf (dump_file,
1881*38fd1498Szrj "Stack clash skipped dynamic allocation and "
1882*38fd1498Szrj "probing residuals.\n");
1883*38fd1498Szrj }
1884*38fd1498Szrj }
1885*38fd1498Szrj
1886*38fd1498Szrj /* Emit the start of an allocate/probe loop for stack
1887*38fd1498Szrj clash protection.
1888*38fd1498Szrj
1889*38fd1498Szrj LOOP_LAB and END_LAB are returned for use when we emit the
1890*38fd1498Szrj end of the loop.
1891*38fd1498Szrj
1892*38fd1498Szrj LAST addr is the value for SP which stops the loop. */
1893*38fd1498Szrj void
emit_stack_clash_protection_probe_loop_start(rtx * loop_lab,rtx * end_lab,rtx last_addr,bool rotated)1894*38fd1498Szrj emit_stack_clash_protection_probe_loop_start (rtx *loop_lab,
1895*38fd1498Szrj rtx *end_lab,
1896*38fd1498Szrj rtx last_addr,
1897*38fd1498Szrj bool rotated)
1898*38fd1498Szrj {
1899*38fd1498Szrj /* Essentially we want to emit any setup code, the top of loop
1900*38fd1498Szrj label and the comparison at the top of the loop. */
1901*38fd1498Szrj *loop_lab = gen_label_rtx ();
1902*38fd1498Szrj *end_lab = gen_label_rtx ();
1903*38fd1498Szrj
1904*38fd1498Szrj emit_label (*loop_lab);
1905*38fd1498Szrj if (!rotated)
1906*38fd1498Szrj emit_cmp_and_jump_insns (stack_pointer_rtx, last_addr, EQ, NULL_RTX,
1907*38fd1498Szrj Pmode, 1, *end_lab);
1908*38fd1498Szrj }
1909*38fd1498Szrj
1910*38fd1498Szrj /* Emit the end of a stack clash probing loop.
1911*38fd1498Szrj
1912*38fd1498Szrj This consists of just the jump back to LOOP_LAB and
1913*38fd1498Szrj emitting END_LOOP after the loop. */
1914*38fd1498Szrj
1915*38fd1498Szrj void
emit_stack_clash_protection_probe_loop_end(rtx loop_lab,rtx end_loop,rtx last_addr,bool rotated)1916*38fd1498Szrj emit_stack_clash_protection_probe_loop_end (rtx loop_lab, rtx end_loop,
1917*38fd1498Szrj rtx last_addr, bool rotated)
1918*38fd1498Szrj {
1919*38fd1498Szrj if (rotated)
1920*38fd1498Szrj emit_cmp_and_jump_insns (stack_pointer_rtx, last_addr, NE, NULL_RTX,
1921*38fd1498Szrj Pmode, 1, loop_lab);
1922*38fd1498Szrj else
1923*38fd1498Szrj emit_jump (loop_lab);
1924*38fd1498Szrj
1925*38fd1498Szrj emit_label (end_loop);
1926*38fd1498Szrj
1927*38fd1498Szrj }
1928*38fd1498Szrj
1929*38fd1498Szrj /* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes)
1930*38fd1498Szrj while probing it. This pushes when SIZE is positive. SIZE need not
1931*38fd1498Szrj be constant.
1932*38fd1498Szrj
1933*38fd1498Szrj This is subtly different than anti_adjust_stack_and_probe to try and
1934*38fd1498Szrj prevent stack-clash attacks
1935*38fd1498Szrj
1936*38fd1498Szrj 1. It must assume no knowledge of the probing state, any allocation
1937*38fd1498Szrj must probe.
1938*38fd1498Szrj
1939*38fd1498Szrj Consider the case of a 1 byte alloca in a loop. If the sum of the
1940*38fd1498Szrj allocations is large, then this could be used to jump the guard if
1941*38fd1498Szrj probes were not emitted.
1942*38fd1498Szrj
1943*38fd1498Szrj 2. It never skips probes, whereas anti_adjust_stack_and_probe will
1944*38fd1498Szrj skip probes on the first couple PROBE_INTERVALs on the assumption
1945*38fd1498Szrj they're done elsewhere.
1946*38fd1498Szrj
1947*38fd1498Szrj 3. It only allocates and probes SIZE bytes, it does not need to
1948*38fd1498Szrj allocate/probe beyond that because this probing style does not
1949*38fd1498Szrj guarantee signal handling capability if the guard is hit. */
1950*38fd1498Szrj
1951*38fd1498Szrj static void
anti_adjust_stack_and_probe_stack_clash(rtx size)1952*38fd1498Szrj anti_adjust_stack_and_probe_stack_clash (rtx size)
1953*38fd1498Szrj {
1954*38fd1498Szrj /* First ensure SIZE is Pmode. */
1955*38fd1498Szrj if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
1956*38fd1498Szrj size = convert_to_mode (Pmode, size, 1);
1957*38fd1498Szrj
1958*38fd1498Szrj /* We can get here with a constant size on some targets. */
1959*38fd1498Szrj rtx rounded_size, last_addr, residual;
1960*38fd1498Szrj HOST_WIDE_INT probe_interval;
1961*38fd1498Szrj compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
1962*38fd1498Szrj &residual, &probe_interval, size);
1963*38fd1498Szrj
1964*38fd1498Szrj if (rounded_size != CONST0_RTX (Pmode))
1965*38fd1498Szrj {
1966*38fd1498Szrj if (CONST_INT_P (rounded_size)
1967*38fd1498Szrj && INTVAL (rounded_size) <= 4 * probe_interval)
1968*38fd1498Szrj {
1969*38fd1498Szrj for (HOST_WIDE_INT i = 0;
1970*38fd1498Szrj i < INTVAL (rounded_size);
1971*38fd1498Szrj i += probe_interval)
1972*38fd1498Szrj {
1973*38fd1498Szrj anti_adjust_stack (GEN_INT (probe_interval));
1974*38fd1498Szrj
1975*38fd1498Szrj /* The prologue does not probe residuals. Thus the offset
1976*38fd1498Szrj here to probe just beyond what the prologue had already
1977*38fd1498Szrj allocated. */
1978*38fd1498Szrj emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
1979*38fd1498Szrj (probe_interval
1980*38fd1498Szrj - GET_MODE_SIZE (word_mode))));
1981*38fd1498Szrj emit_insn (gen_blockage ());
1982*38fd1498Szrj }
1983*38fd1498Szrj }
1984*38fd1498Szrj else
1985*38fd1498Szrj {
1986*38fd1498Szrj rtx loop_lab, end_loop;
1987*38fd1498Szrj bool rotate_loop = CONST_INT_P (rounded_size);
1988*38fd1498Szrj emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
1989*38fd1498Szrj last_addr, rotate_loop);
1990*38fd1498Szrj
1991*38fd1498Szrj anti_adjust_stack (GEN_INT (probe_interval));
1992*38fd1498Szrj
1993*38fd1498Szrj /* The prologue does not probe residuals. Thus the offset here
1994*38fd1498Szrj to probe just beyond what the prologue had already allocated. */
1995*38fd1498Szrj emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
1996*38fd1498Szrj (probe_interval
1997*38fd1498Szrj - GET_MODE_SIZE (word_mode))));
1998*38fd1498Szrj
1999*38fd1498Szrj emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
2000*38fd1498Szrj last_addr, rotate_loop);
2001*38fd1498Szrj emit_insn (gen_blockage ());
2002*38fd1498Szrj }
2003*38fd1498Szrj }
2004*38fd1498Szrj
2005*38fd1498Szrj if (residual != CONST0_RTX (Pmode))
2006*38fd1498Szrj {
2007*38fd1498Szrj rtx label = NULL_RTX;
2008*38fd1498Szrj /* RESIDUAL could be zero at runtime and in that case *sp could
2009*38fd1498Szrj hold live data. Furthermore, we do not want to probe into the
2010*38fd1498Szrj red zone.
2011*38fd1498Szrj
2012*38fd1498Szrj Go ahead and just guard the probe at *sp on RESIDUAL != 0 at
2013*38fd1498Szrj runtime if RESIDUAL is not a compile time constant. */
2014*38fd1498Szrj if (!CONST_INT_P (residual))
2015*38fd1498Szrj {
2016*38fd1498Szrj label = gen_label_rtx ();
2017*38fd1498Szrj emit_cmp_and_jump_insns (residual, CONST0_RTX (GET_MODE (residual)),
2018*38fd1498Szrj EQ, NULL_RTX, Pmode, 1, label);
2019*38fd1498Szrj }
2020*38fd1498Szrj
2021*38fd1498Szrj rtx x = force_reg (Pmode, plus_constant (Pmode, residual,
2022*38fd1498Szrj -GET_MODE_SIZE (word_mode)));
2023*38fd1498Szrj anti_adjust_stack (residual);
2024*38fd1498Szrj emit_stack_probe (gen_rtx_PLUS (Pmode, stack_pointer_rtx, x));
2025*38fd1498Szrj emit_insn (gen_blockage ());
2026*38fd1498Szrj if (!CONST_INT_P (residual))
2027*38fd1498Szrj emit_label (label);
2028*38fd1498Szrj }
2029*38fd1498Szrj
2030*38fd1498Szrj /* Some targets make optimistic assumptions in their prologues about
2031*38fd1498Szrj how the caller may have probed the stack. Make sure we honor
2032*38fd1498Szrj those assumptions when needed. */
2033*38fd1498Szrj if (size != CONST0_RTX (Pmode)
2034*38fd1498Szrj && targetm.stack_clash_protection_final_dynamic_probe (residual))
2035*38fd1498Szrj {
2036*38fd1498Szrj /* SIZE could be zero at runtime and in that case *sp could hold
2037*38fd1498Szrj live data. Furthermore, we don't want to probe into the red
2038*38fd1498Szrj zone.
2039*38fd1498Szrj
2040*38fd1498Szrj Go ahead and just guard the probe at *sp on SIZE != 0 at runtime
2041*38fd1498Szrj if SIZE is not a compile time constant. */
2042*38fd1498Szrj rtx label = NULL_RTX;
2043*38fd1498Szrj if (!CONST_INT_P (size))
2044*38fd1498Szrj {
2045*38fd1498Szrj label = gen_label_rtx ();
2046*38fd1498Szrj emit_cmp_and_jump_insns (size, CONST0_RTX (GET_MODE (size)),
2047*38fd1498Szrj EQ, NULL_RTX, Pmode, 1, label);
2048*38fd1498Szrj }
2049*38fd1498Szrj
2050*38fd1498Szrj emit_stack_probe (stack_pointer_rtx);
2051*38fd1498Szrj emit_insn (gen_blockage ());
2052*38fd1498Szrj if (!CONST_INT_P (size))
2053*38fd1498Szrj emit_label (label);
2054*38fd1498Szrj }
2055*38fd1498Szrj }
2056*38fd1498Szrj
2057*38fd1498Szrj
2058*38fd1498Szrj /* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes)
2059*38fd1498Szrj while probing it. This pushes when SIZE is positive. SIZE need not
2060*38fd1498Szrj be constant. If ADJUST_BACK is true, adjust back the stack pointer
2061*38fd1498Szrj by plus SIZE at the end. */
2062*38fd1498Szrj
2063*38fd1498Szrj void
anti_adjust_stack_and_probe(rtx size,bool adjust_back)2064*38fd1498Szrj anti_adjust_stack_and_probe (rtx size, bool adjust_back)
2065*38fd1498Szrj {
2066*38fd1498Szrj /* We skip the probe for the first interval + a small dope of 4 words and
2067*38fd1498Szrj probe that many bytes past the specified size to maintain a protection
2068*38fd1498Szrj area at the botton of the stack. */
2069*38fd1498Szrj const int dope = 4 * UNITS_PER_WORD;
2070*38fd1498Szrj
2071*38fd1498Szrj /* First ensure SIZE is Pmode. */
2072*38fd1498Szrj if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
2073*38fd1498Szrj size = convert_to_mode (Pmode, size, 1);
2074*38fd1498Szrj
2075*38fd1498Szrj /* If we have a constant small number of probes to generate, that's the
2076*38fd1498Szrj easy case. */
2077*38fd1498Szrj if (CONST_INT_P (size) && INTVAL (size) < 7 * PROBE_INTERVAL)
2078*38fd1498Szrj {
2079*38fd1498Szrj HOST_WIDE_INT isize = INTVAL (size), i;
2080*38fd1498Szrj bool first_probe = true;
2081*38fd1498Szrj
2082*38fd1498Szrj /* Adjust SP and probe at PROBE_INTERVAL + N * PROBE_INTERVAL for
2083*38fd1498Szrj values of N from 1 until it exceeds SIZE. If only one probe is
2084*38fd1498Szrj needed, this will not generate any code. Then adjust and probe
2085*38fd1498Szrj to PROBE_INTERVAL + SIZE. */
2086*38fd1498Szrj for (i = PROBE_INTERVAL; i < isize; i += PROBE_INTERVAL)
2087*38fd1498Szrj {
2088*38fd1498Szrj if (first_probe)
2089*38fd1498Szrj {
2090*38fd1498Szrj anti_adjust_stack (GEN_INT (2 * PROBE_INTERVAL + dope));
2091*38fd1498Szrj first_probe = false;
2092*38fd1498Szrj }
2093*38fd1498Szrj else
2094*38fd1498Szrj anti_adjust_stack (GEN_INT (PROBE_INTERVAL));
2095*38fd1498Szrj emit_stack_probe (stack_pointer_rtx);
2096*38fd1498Szrj }
2097*38fd1498Szrj
2098*38fd1498Szrj if (first_probe)
2099*38fd1498Szrj anti_adjust_stack (plus_constant (Pmode, size, PROBE_INTERVAL + dope));
2100*38fd1498Szrj else
2101*38fd1498Szrj anti_adjust_stack (plus_constant (Pmode, size, PROBE_INTERVAL - i));
2102*38fd1498Szrj emit_stack_probe (stack_pointer_rtx);
2103*38fd1498Szrj }
2104*38fd1498Szrj
2105*38fd1498Szrj /* In the variable case, do the same as above, but in a loop. Note that we
2106*38fd1498Szrj must be extra careful with variables wrapping around because we might be
2107*38fd1498Szrj at the very top (or the very bottom) of the address space and we have to
2108*38fd1498Szrj be able to handle this case properly; in particular, we use an equality
2109*38fd1498Szrj test for the loop condition. */
2110*38fd1498Szrj else
2111*38fd1498Szrj {
2112*38fd1498Szrj rtx rounded_size, rounded_size_op, last_addr, temp;
2113*38fd1498Szrj rtx_code_label *loop_lab = gen_label_rtx ();
2114*38fd1498Szrj rtx_code_label *end_lab = gen_label_rtx ();
2115*38fd1498Szrj
2116*38fd1498Szrj
2117*38fd1498Szrj /* Step 1: round SIZE to the previous multiple of the interval. */
2118*38fd1498Szrj
2119*38fd1498Szrj /* ROUNDED_SIZE = SIZE & -PROBE_INTERVAL */
2120*38fd1498Szrj rounded_size
2121*38fd1498Szrj = simplify_gen_binary (AND, Pmode, size,
2122*38fd1498Szrj gen_int_mode (-PROBE_INTERVAL, Pmode));
2123*38fd1498Szrj rounded_size_op = force_operand (rounded_size, NULL_RTX);
2124*38fd1498Szrj
2125*38fd1498Szrj
2126*38fd1498Szrj /* Step 2: compute initial and final value of the loop counter. */
2127*38fd1498Szrj
2128*38fd1498Szrj /* SP = SP_0 + PROBE_INTERVAL. */
2129*38fd1498Szrj anti_adjust_stack (GEN_INT (PROBE_INTERVAL + dope));
2130*38fd1498Szrj
2131*38fd1498Szrj /* LAST_ADDR = SP_0 + PROBE_INTERVAL + ROUNDED_SIZE. */
2132*38fd1498Szrj last_addr = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
2133*38fd1498Szrj stack_pointer_rtx,
2134*38fd1498Szrj rounded_size_op), NULL_RTX);
2135*38fd1498Szrj
2136*38fd1498Szrj
2137*38fd1498Szrj /* Step 3: the loop
2138*38fd1498Szrj
2139*38fd1498Szrj while (SP != LAST_ADDR)
2140*38fd1498Szrj {
2141*38fd1498Szrj SP = SP + PROBE_INTERVAL
2142*38fd1498Szrj probe at SP
2143*38fd1498Szrj }
2144*38fd1498Szrj
2145*38fd1498Szrj adjusts SP and probes at PROBE_INTERVAL + N * PROBE_INTERVAL for
2146*38fd1498Szrj values of N from 1 until it is equal to ROUNDED_SIZE. */
2147*38fd1498Szrj
2148*38fd1498Szrj emit_label (loop_lab);
2149*38fd1498Szrj
2150*38fd1498Szrj /* Jump to END_LAB if SP == LAST_ADDR. */
2151*38fd1498Szrj emit_cmp_and_jump_insns (stack_pointer_rtx, last_addr, EQ, NULL_RTX,
2152*38fd1498Szrj Pmode, 1, end_lab);
2153*38fd1498Szrj
2154*38fd1498Szrj /* SP = SP + PROBE_INTERVAL and probe at SP. */
2155*38fd1498Szrj anti_adjust_stack (GEN_INT (PROBE_INTERVAL));
2156*38fd1498Szrj emit_stack_probe (stack_pointer_rtx);
2157*38fd1498Szrj
2158*38fd1498Szrj emit_jump (loop_lab);
2159*38fd1498Szrj
2160*38fd1498Szrj emit_label (end_lab);
2161*38fd1498Szrj
2162*38fd1498Szrj
2163*38fd1498Szrj /* Step 4: adjust SP and probe at PROBE_INTERVAL + SIZE if we cannot
2164*38fd1498Szrj assert at compile-time that SIZE is equal to ROUNDED_SIZE. */
2165*38fd1498Szrj
2166*38fd1498Szrj /* TEMP = SIZE - ROUNDED_SIZE. */
2167*38fd1498Szrj temp = simplify_gen_binary (MINUS, Pmode, size, rounded_size);
2168*38fd1498Szrj if (temp != const0_rtx)
2169*38fd1498Szrj {
2170*38fd1498Szrj /* Manual CSE if the difference is not known at compile-time. */
2171*38fd1498Szrj if (GET_CODE (temp) != CONST_INT)
2172*38fd1498Szrj temp = gen_rtx_MINUS (Pmode, size, rounded_size_op);
2173*38fd1498Szrj anti_adjust_stack (temp);
2174*38fd1498Szrj emit_stack_probe (stack_pointer_rtx);
2175*38fd1498Szrj }
2176*38fd1498Szrj }
2177*38fd1498Szrj
2178*38fd1498Szrj /* Adjust back and account for the additional first interval. */
2179*38fd1498Szrj if (adjust_back)
2180*38fd1498Szrj adjust_stack (plus_constant (Pmode, size, PROBE_INTERVAL + dope));
2181*38fd1498Szrj else
2182*38fd1498Szrj adjust_stack (GEN_INT (PROBE_INTERVAL + dope));
2183*38fd1498Szrj }
2184*38fd1498Szrj
2185*38fd1498Szrj /* Return an rtx representing the register or memory location
2186*38fd1498Szrj in which a scalar value of data type VALTYPE
2187*38fd1498Szrj was returned by a function call to function FUNC.
2188*38fd1498Szrj FUNC is a FUNCTION_DECL, FNTYPE a FUNCTION_TYPE node if the precise
2189*38fd1498Szrj function is known, otherwise 0.
2190*38fd1498Szrj OUTGOING is 1 if on a machine with register windows this function
2191*38fd1498Szrj should return the register in which the function will put its result
2192*38fd1498Szrj and 0 otherwise. */
2193*38fd1498Szrj
2194*38fd1498Szrj rtx
hard_function_value(const_tree valtype,const_tree func,const_tree fntype,int outgoing ATTRIBUTE_UNUSED)2195*38fd1498Szrj hard_function_value (const_tree valtype, const_tree func, const_tree fntype,
2196*38fd1498Szrj int outgoing ATTRIBUTE_UNUSED)
2197*38fd1498Szrj {
2198*38fd1498Szrj rtx val;
2199*38fd1498Szrj
2200*38fd1498Szrj val = targetm.calls.function_value (valtype, func ? func : fntype, outgoing);
2201*38fd1498Szrj
2202*38fd1498Szrj if (REG_P (val)
2203*38fd1498Szrj && GET_MODE (val) == BLKmode)
2204*38fd1498Szrj {
2205*38fd1498Szrj unsigned HOST_WIDE_INT bytes = arg_int_size_in_bytes (valtype);
2206*38fd1498Szrj opt_scalar_int_mode tmpmode;
2207*38fd1498Szrj
2208*38fd1498Szrj /* int_size_in_bytes can return -1. We don't need a check here
2209*38fd1498Szrj since the value of bytes will then be large enough that no
2210*38fd1498Szrj mode will match anyway. */
2211*38fd1498Szrj
2212*38fd1498Szrj FOR_EACH_MODE_IN_CLASS (tmpmode, MODE_INT)
2213*38fd1498Szrj {
2214*38fd1498Szrj /* Have we found a large enough mode? */
2215*38fd1498Szrj if (GET_MODE_SIZE (tmpmode.require ()) >= bytes)
2216*38fd1498Szrj break;
2217*38fd1498Szrj }
2218*38fd1498Szrj
2219*38fd1498Szrj PUT_MODE (val, tmpmode.require ());
2220*38fd1498Szrj }
2221*38fd1498Szrj return val;
2222*38fd1498Szrj }
2223*38fd1498Szrj
2224*38fd1498Szrj /* Return an rtx representing the register or memory location
2225*38fd1498Szrj in which a scalar value of mode MODE was returned by a library call. */
2226*38fd1498Szrj
2227*38fd1498Szrj rtx
hard_libcall_value(machine_mode mode,rtx fun)2228*38fd1498Szrj hard_libcall_value (machine_mode mode, rtx fun)
2229*38fd1498Szrj {
2230*38fd1498Szrj return targetm.calls.libcall_value (mode, fun);
2231*38fd1498Szrj }
2232*38fd1498Szrj
2233*38fd1498Szrj /* Look up the tree code for a given rtx code
2234*38fd1498Szrj to provide the arithmetic operation for real_arithmetic.
2235*38fd1498Szrj The function returns an int because the caller may not know
2236*38fd1498Szrj what `enum tree_code' means. */
2237*38fd1498Szrj
2238*38fd1498Szrj int
rtx_to_tree_code(enum rtx_code code)2239*38fd1498Szrj rtx_to_tree_code (enum rtx_code code)
2240*38fd1498Szrj {
2241*38fd1498Szrj enum tree_code tcode;
2242*38fd1498Szrj
2243*38fd1498Szrj switch (code)
2244*38fd1498Szrj {
2245*38fd1498Szrj case PLUS:
2246*38fd1498Szrj tcode = PLUS_EXPR;
2247*38fd1498Szrj break;
2248*38fd1498Szrj case MINUS:
2249*38fd1498Szrj tcode = MINUS_EXPR;
2250*38fd1498Szrj break;
2251*38fd1498Szrj case MULT:
2252*38fd1498Szrj tcode = MULT_EXPR;
2253*38fd1498Szrj break;
2254*38fd1498Szrj case DIV:
2255*38fd1498Szrj tcode = RDIV_EXPR;
2256*38fd1498Szrj break;
2257*38fd1498Szrj case SMIN:
2258*38fd1498Szrj tcode = MIN_EXPR;
2259*38fd1498Szrj break;
2260*38fd1498Szrj case SMAX:
2261*38fd1498Szrj tcode = MAX_EXPR;
2262*38fd1498Szrj break;
2263*38fd1498Szrj default:
2264*38fd1498Szrj tcode = LAST_AND_UNUSED_TREE_CODE;
2265*38fd1498Szrj break;
2266*38fd1498Szrj }
2267*38fd1498Szrj return ((int) tcode);
2268*38fd1498Szrj }
2269*38fd1498Szrj
2270*38fd1498Szrj #include "gt-explow.h"
2271