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

Collapse All | Expand All

(-)a/gcc/config/aarch64/aarch64.c (-14 / +80 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
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;

Return to bug 77728