View | Details | Return to bug 77728 | Differences between
and this patch

Collapse All | Expand All

(-)a/gcc/config/aarch64/aarch64.c (-13 / +72 lines)
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;

Return to bug 77728