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