Lines 2256-2288
aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
Link Here
|
2256 |
NULL); |
2256 |
NULL); |
2257 |
} |
2257 |
} |
2258 |
|
2258 |
|
|
|
2259 |
struct aarch64_fn_arg_alignment |
2260 |
{ |
2261 |
/* alignment for FIELD_DECLS in function arguments. */ |
2262 |
unsigned int alignment; |
2263 |
/* alignment for everything other than FIELD_DECLS in function arguments. */ |
2264 |
unsigned int warning_alignment; |
2265 |
}; |
2266 |
|
2259 |
/* Given MODE and TYPE of a function argument, return the alignment in |
2267 |
/* Given MODE and TYPE of a function argument, return the alignment in |
2260 |
bits. The idea is to suppress any stronger alignment requested by |
2268 |
bits. The idea is to suppress any stronger alignment requested by |
2261 |
the user and opt for the natural alignment (specified in AAPCS64 \S 4.1). |
2269 |
the user and opt for the natural alignment (specified in AAPCS64 \S 4.1). |
2262 |
This is a helper function for local use only. */ |
2270 |
This is a helper function for local use only. */ |
2263 |
|
2271 |
|
2264 |
static unsigned int |
2272 |
static struct aarch64_fn_arg_alignment |
2265 |
aarch64_function_arg_alignment (machine_mode mode, const_tree type) |
2273 |
aarch64_function_arg_alignment (machine_mode mode, const_tree type) |
2266 |
{ |
2274 |
{ |
|
|
2275 |
struct aarch64_fn_arg_alignment a; |
2276 |
a.alignment = 0; |
2277 |
a.warning_alignment = 0; |
2278 |
|
2267 |
if (!type) |
2279 |
if (!type) |
2268 |
return GET_MODE_ALIGNMENT (mode); |
2280 |
{ |
|
|
2281 |
a.alignment = GET_MODE_ALIGNMENT (mode); |
2282 |
a.warning_alignment = GET_MODE_ALIGNMENT (mode); |
2283 |
return a; |
2284 |
} |
2285 |
|
2269 |
if (integer_zerop (TYPE_SIZE (type))) |
2286 |
if (integer_zerop (TYPE_SIZE (type))) |
2270 |
return 0; |
2287 |
return a; |
2271 |
|
2288 |
|
2272 |
gcc_assert (TYPE_MODE (type) == mode); |
2289 |
gcc_assert (TYPE_MODE (type) == mode); |
2273 |
|
2290 |
|
2274 |
if (!AGGREGATE_TYPE_P (type)) |
2291 |
if (!AGGREGATE_TYPE_P (type)) |
2275 |
return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)); |
2292 |
{ |
|
|
2293 |
a.alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type)); |
2294 |
a.warning_alignment = a.alignment; |
2295 |
return a; |
2296 |
} |
2276 |
|
2297 |
|
2277 |
if (TREE_CODE (type) == ARRAY_TYPE) |
2298 |
if (TREE_CODE (type) == ARRAY_TYPE) |
2278 |
return TYPE_ALIGN (TREE_TYPE (type)); |
2299 |
{ |
2279 |
|
2300 |
a.alignment = TYPE_ALIGN (TREE_TYPE (type)); |
2280 |
unsigned int alignment = 0; |
2301 |
a.warning_alignment = a.alignment; |
|
|
2302 |
return a; |
2303 |
} |
2281 |
|
2304 |
|
2282 |
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) |
2305 |
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) |
2283 |
alignment = std::max (alignment, DECL_ALIGN (field)); |
2306 |
{ |
|
|
2307 |
if (TREE_CODE (field) == FIELD_DECL) |
2308 |
a.alignment = std::max (a.alignment, DECL_ALIGN (field)); |
2309 |
else |
2310 |
a.warning_alignment = std::max (a.warning_alignment, |
2311 |
DECL_ALIGN (field)); |
2312 |
} |
2284 |
|
2313 |
|
2285 |
return alignment; |
2314 |
if (a.warning_alignment <= a.alignment) |
|
|
2315 |
a.warning_alignment = a.alignment; |
2316 |
|
2317 |
return a; |
2286 |
} |
2318 |
} |
2287 |
|
2319 |
|
2288 |
/* Layout a function argument according to the AAPCS64 rules. The rule |
2320 |
/* Layout a function argument according to the AAPCS64 rules. The rule |
Lines 2369-2378
aarch64_layout_arg (cumulative_args_t pcum_v, machine_mode mode,
Link Here
|
2369 |
entirely general registers. */ |
2401 |
entirely general registers. */ |
2370 |
if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS)) |
2402 |
if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS)) |
2371 |
{ |
2403 |
{ |
2372 |
unsigned int alignment = aarch64_function_arg_alignment (mode, type); |
2404 |
struct aarch64_fn_arg_alignment a = aarch64_function_arg_alignment (mode, |
|
|
2405 |
type); |
2406 |
unsigned int alignment = a.alignment; |
2373 |
|
2407 |
|
2374 |
gcc_assert (nregs == 0 || nregs == 1 || nregs == 2); |
2408 |
gcc_assert (nregs == 0 || nregs == 1 || nregs == 2); |
2375 |
|
2409 |
|
|
|
2410 |
if (nregs == 2 |
2411 |
&& a.warning_alignment == 16 * BITS_PER_UNIT |
2412 |
&& ncrn % 2) |
2413 |
{ |
2414 |
if (a.warning_alignment < a.alignment |
2415 |
&& warn_psabi) |
2416 |
inform (input_location, |
2417 |
"parameter passing changed for argument %qT " |
2418 |
"since GCC 7.1", |
2419 |
type); |
2420 |
} |
2421 |
|
2376 |
/* C.8 if the argument has an alignment of 16 then the NGRN is |
2422 |
/* C.8 if the argument has an alignment of 16 then the NGRN is |
2377 |
rounded up to the next even number. */ |
2423 |
rounded up to the next even number. */ |
2378 |
if (nregs == 2 && alignment == 16 * BITS_PER_UNIT && ncrn % 2) |
2424 |
if (nregs == 2 && alignment == 16 * BITS_PER_UNIT && ncrn % 2) |
Lines 2414-2420
aarch64_layout_arg (cumulative_args_t pcum_v, machine_mode mode,
Link Here
|
2414 |
this argument and align the total size if necessary. */ |
2460 |
this argument and align the total size if necessary. */ |
2415 |
on_stack: |
2461 |
on_stack: |
2416 |
pcum->aapcs_stack_words = size / UNITS_PER_WORD; |
2462 |
pcum->aapcs_stack_words = size / UNITS_PER_WORD; |
2417 |
if (aarch64_function_arg_alignment (mode, type) == 16 * BITS_PER_UNIT) |
2463 |
struct aarch64_fn_arg_alignment ab; |
|
|
2464 |
ab = aarch64_function_arg_alignment (mode, type); |
2465 |
|
2466 |
if (ab.alignment == 16 * BITS_PER_UNIT) |
2418 |
pcum->aapcs_stack_size = ROUND_UP (pcum->aapcs_stack_size, |
2467 |
pcum->aapcs_stack_size = ROUND_UP (pcum->aapcs_stack_size, |
2419 |
16 / UNITS_PER_WORD); |
2468 |
16 / UNITS_PER_WORD); |
2420 |
return; |
2469 |
return; |
Lines 2505-2516
aarch64_function_arg_regno_p (unsigned regno)
Link Here
|
2505 |
static unsigned int |
2554 |
static unsigned int |
2506 |
aarch64_function_arg_boundary (machine_mode mode, const_tree type) |
2555 |
aarch64_function_arg_boundary (machine_mode mode, const_tree type) |
2507 |
{ |
2556 |
{ |
2508 |
unsigned int alignment = aarch64_function_arg_alignment (mode, type); |
2557 |
struct aarch64_fn_arg_alignment a = aarch64_function_arg_alignment (mode, |
2509 |
|
2558 |
type); |
|
|
2559 |
unsigned int alignment = a.alignment; |
2510 |
if (alignment < PARM_BOUNDARY) |
2560 |
if (alignment < PARM_BOUNDARY) |
2511 |
alignment = PARM_BOUNDARY; |
2561 |
alignment = PARM_BOUNDARY; |
2512 |
if (alignment > STACK_BOUNDARY) |
2562 |
if (alignment > STACK_BOUNDARY) |
2513 |
alignment = STACK_BOUNDARY; |
2563 |
alignment = STACK_BOUNDARY; |
|
|
2564 |
|
2565 |
if (a.warning_alignment < PARM_BOUNDARY) |
2566 |
a.warning_alignment = PARM_BOUNDARY; |
2567 |
|
2568 |
if (a.warning_alignment > STACK_BOUNDARY) |
2569 |
a.warning_alignment = STACK_BOUNDARY; |
2570 |
|
2571 |
if (warn_psabi |
2572 |
&& a.warning_alignment > alignment) |
2573 |
inform (input_location, |
2574 |
"parameter passing changed for argument of type %qT " |
2575 |
"since GCC 7.1", |
2576 |
type); |
2577 |
|
2514 |
return alignment; |
2578 |
return alignment; |
2515 |
} |
2579 |
} |
2516 |
|
2580 |
|
Lines 10211-10217
aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
Link Here
|
10211 |
stack = build3 (COMPONENT_REF, TREE_TYPE (f_stack), unshare_expr (valist), |
10275 |
stack = build3 (COMPONENT_REF, TREE_TYPE (f_stack), unshare_expr (valist), |
10212 |
f_stack, NULL_TREE); |
10276 |
f_stack, NULL_TREE); |
10213 |
size = int_size_in_bytes (type); |
10277 |
size = int_size_in_bytes (type); |
10214 |
align = aarch64_function_arg_alignment (mode, type) / BITS_PER_UNIT; |
10278 |
struct aarch64_fn_arg_alignment a = aarch64_function_arg_alignment (mode, |
|
|
10279 |
type); |
10280 |
align = a.alignment / BITS_PER_UNIT; |
10215 |
|
10281 |
|
10216 |
dw_align = false; |
10282 |
dw_align = false; |
10217 |
adjust = 0; |
10283 |
adjust = 0; |