Skip to content

Commit 4049420

Browse files
committed
Experiment with adding new ABI
1 parent d4e43b1 commit 4049420

File tree

2 files changed

+124
-4
lines changed

2 files changed

+124
-4
lines changed

gcc/config/aarch64/aarch64.cc

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ handle_aarch64_vector_pcs_attribute (tree *node, tree name, tree,
736736
{
737737
case ARM_PCS_AAPCS64:
738738
case ARM_PCS_SIMD:
739+
case ARM_PCS_MS_VARIADIC:
739740
return NULL_TREE;
740741

741742
case ARM_PCS_SVE:
@@ -1238,6 +1239,21 @@ aarch64_some_values_include_pst_objects_p (const_tree type)
12381239
return false;
12391240
}
12401241

1242+
/* Return the descriptor of the Windows Arm64 variadic function ABI. */
1243+
1244+
static const predefined_function_abi &
1245+
aarch64_ms_variadic_abi (void)
1246+
{
1247+
predefined_function_abi &ms_variadic_abi = function_abis[ARM_PCS_MS_VARIADIC];
1248+
if (!ms_variadic_abi.initialized_p ())
1249+
{
1250+
HARD_REG_SET full_reg_clobbers
1251+
= default_function_abi.full_reg_clobbers ();
1252+
ms_variadic_abi.initialize (ARM_PCS_MS_VARIADIC, full_reg_clobbers);
1253+
}
1254+
return ms_variadic_abi;
1255+
}
1256+
12411257
/* Return the descriptor of the SIMD ABI. */
12421258

12431259
static const predefined_function_abi &
@@ -2235,9 +2251,24 @@ aarch64_takes_arguments_in_sve_regs_p (const_tree fntype)
22352251

22362252
/* Implement TARGET_FNTYPE_ABI. */
22372253

2254+
static bool is_variadic_function_type (const_tree fntype) {
2255+
tree arg_types = TYPE_ARG_TYPES (fntype);
2256+
for (tree arg = arg_types; arg; arg = TREE_CHAIN (arg)) {
2257+
if (TREE_VALUE (arg) == void_type_node) {
2258+
return false;
2259+
}
2260+
}
2261+
return true;
2262+
}
2263+
22382264
static const predefined_function_abi &
22392265
aarch64_fntype_abi (const_tree fntype)
22402266
{
2267+
#if TARGET_AARCH64_MS_ABI
2268+
if (is_variadic_function_type (fntype))
2269+
return aarch64_ms_variadic_abi ();
2270+
#endif
2271+
22412272
if (lookup_attribute ("aarch64_vector_pcs", TYPE_ATTRIBUTES (fntype)))
22422273
return aarch64_simd_abi ();
22432274

@@ -2449,6 +2480,7 @@ aarch64_reg_save_mode (unsigned int regno)
24492480
switch (crtl->abi->id ())
24502481
{
24512482
case ARM_PCS_AAPCS64:
2483+
case ARM_PCS_MS_VARIADIC:
24522484
/* Only the low 64 bits are saved by the base PCS. */
24532485
return DFmode;
24542486

@@ -5241,6 +5273,7 @@ aarch64_sme_mode_switch_regs::add_call_preserved_reg (unsigned int regno)
52415273
add_reg (V16QImode, regno);
52425274
break;
52435275
case ARM_PCS_AAPCS64:
5276+
case ARM_PCS_MS_VARIADIC:
52445277
add_reg (DImode, regno);
52455278
break;
52465279
default:
@@ -6906,6 +6939,55 @@ bitint_or_aggr_of_bitint_p (tree type)
69066939
return false;
69076940
}
69086941

6942+
static void
6943+
aarch64_ms_variadic_abi_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
6944+
{
6945+
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
6946+
tree type = arg.type;
6947+
machine_mode mode = arg.mode;
6948+
HOST_WIDE_INT size;
6949+
unsigned int abi_break_gcc_9;
6950+
unsigned int abi_break_gcc_13;
6951+
unsigned int abi_break_gcc_14;
6952+
6953+
/* We need to do this once per argument. */
6954+
if (pcum->aapcs_arg_processed)
6955+
return;
6956+
6957+
pcum->aapcs_arg_processed = true;
6958+
6959+
/* Size in bytes, rounded to the nearest multiple of 8 bytes. */
6960+
if (type)
6961+
size = int_size_in_bytes (type);
6962+
else
6963+
/* No frontends can create types with variable-sized modes, so we
6964+
shouldn't be asked to pass or return them. */
6965+
size = GET_MODE_SIZE (mode).to_constant ();
6966+
size = ROUND_UP (size, UNITS_PER_WORD);
6967+
6968+
unsigned int alignment
6969+
= aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
6970+
&abi_break_gcc_13, &abi_break_gcc_14);
6971+
6972+
gcc_assert ((alignment <= 16 * BITS_PER_UNIT)
6973+
&& (!alignment || abi_break_gcc_9 < alignment)
6974+
&& (!abi_break_gcc_13 || alignment < abi_break_gcc_13));
6975+
6976+
/* The argument is passed on stack; record the needed number of words for
6977+
this argument and align the total size if necessary. */
6978+
pcum->aapcs_stack_words = size / UNITS_PER_WORD;
6979+
6980+
if (alignment == 16 * BITS_PER_UNIT)
6981+
{
6982+
int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
6983+
if (pcum->aapcs_stack_size != new_size)
6984+
{
6985+
pcum->aapcs_stack_size = new_size;
6986+
}
6987+
}
6988+
return;
6989+
}
6990+
69096991
/* Layout a function argument according to the AAPCS64 rules. The rule
69106992
numbers refer to the rule numbers in the AAPCS64. ORIG_MODE is the
69116993
mode that was originally given to us by the target hook, whereas the
@@ -6929,6 +7011,11 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
69297011
if (pcum->aapcs_arg_processed)
69307012
return;
69317013

7014+
if (pcum->pcs_variant == ARM_PCS_MS_VARIADIC) {
7015+
aarch64_ms_variadic_abi_layout_arg (pcum_v, arg);
7016+
return;
7017+
}
7018+
69327019
bool warn_pcs_change
69337020
= (warn_psabi
69347021
&& !pcum->silent_p
@@ -7294,7 +7381,8 @@ aarch64_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
72947381
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
72957382
gcc_assert (pcum->pcs_variant == ARM_PCS_AAPCS64
72967383
|| pcum->pcs_variant == ARM_PCS_SIMD
7297-
|| pcum->pcs_variant == ARM_PCS_SVE);
7384+
|| pcum->pcs_variant == ARM_PCS_SVE
7385+
|| pcum->pcs_variant == ARM_PCS_MS_VARIADIC);
72987386

72997387
if (arg.end_marker_p ())
73007388
{
@@ -7382,7 +7470,8 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v,
73827470
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
73837471
if (pcum->pcs_variant == ARM_PCS_AAPCS64
73847472
|| pcum->pcs_variant == ARM_PCS_SIMD
7385-
|| pcum->pcs_variant == ARM_PCS_SVE)
7473+
|| pcum->pcs_variant == ARM_PCS_SVE
7474+
|| pcum->pcs_variant == ARM_PCS_MS_VARIADIC)
73867475
{
73877476
aarch64_layout_arg (pcum_v, arg);
73887477
gcc_assert ((pcum->aapcs_reg != NULL_RTX)
@@ -11265,6 +11354,31 @@ aarch64_restore_zt0 (bool from_lazy_save_p)
1126511354
: gen_aarch64_sme_ldr_zt0 (mem));
1126611355
}
1126711356

11357+
static void
11358+
aarch64_ms_variadic_abi_call_args (cumulative_args_t, rtx arg, tree fntype)
11359+
{
11360+
// TODO: Load first 64 bytes of stack to x0-x7 registers.
11361+
if (fntype && is_variadic_function_type (fntype))
11362+
{
11363+
machine_mode mode = aarch64_reg_save_mode (R0_REGNUM);
11364+
11365+
/*rtx cfi_ops = NULL;
11366+
aarch64_pop_regs (R0_REGNUM, R1_REGNUM, 0, &cfi_ops);*/
11367+
11368+
/*move_block_to_reg (R0_REGNUM, mem, NUM_ARG_REGS, mode);*/
11369+
11370+
// TODO: Load only registers that are used in the function.
11371+
for (int i = 0; i < 8; i++)
11372+
{
11373+
HOST_WIDE_INT offset = i * UNITS_PER_WORD;
11374+
rtx sp = stack_pointer_rtx;
11375+
rtx reg = gen_rtx_REG (mode, R0_REGNUM + i);
11376+
rtx mem = gen_rtx_MEM (mode, plus_constant (Pmode, sp, offset));
11377+
emit_move_insn (reg, mem);
11378+
}
11379+
}
11380+
}
11381+
1126811382
/* Implement TARGET_START_CALL_ARGS. */
1126911383

1127011384
static void
@@ -21487,7 +21601,7 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2148721601
#ifdef TARGET_AARCH64_MS_ABI
2148821602

2148921603
static void
21490-
aarch64_ms_abi_expand_builtin_va_start (tree valist, rtx nextarg)
21604+
aarch64_ms_variadic_abi_expand_builtin_va_start (tree valist, rtx nextarg)
2149121605
{
2149221606
nextarg = plus_constant (Pmode, nextarg, cfun->machine->frame.first_vararg_offset, true);
2149321607
std_expand_builtin_va_start (valist, nextarg);
@@ -31080,7 +31194,7 @@ aarch64_run_selftests (void)
3108031194

3108131195
#undef TARGET_EXPAND_BUILTIN_VA_START
3108231196
#ifdef TARGET_AARCH64_MS_ABI
31083-
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_ms_abi_expand_builtin_va_start
31197+
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_ms_variadic_abi_expand_builtin_va_start
3108431198
#else
3108531199
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_expand_builtin_va_start
3108631200
#endif
@@ -31114,6 +31228,11 @@ aarch64_run_selftests (void)
3111431228
#undef TARGET_FUNCTION_VALUE_REGNO_P
3111531229
#define TARGET_FUNCTION_VALUE_REGNO_P aarch64_function_value_regno_p
3111631230

31231+
#ifdef TARGET_AARCH64_MS_ABI
31232+
#undef TARGET_CALL_ARGS
31233+
#define TARGET_CALL_ARGS aarch64_ms_variadic_abi_call_args
31234+
#endif
31235+
3111731236
#undef TARGET_START_CALL_ARGS
3111831237
#define TARGET_START_CALL_ARGS aarch64_start_call_args
3111931238

gcc/config/aarch64/aarch64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,7 @@ enum arm_pcs
11141114
ARM_PCS_SVE, /* For functions that pass or return
11151115
values in SVE registers. */
11161116
ARM_PCS_TLSDESC, /* For targets of tlsdesc calls. */
1117+
ARM_PCS_MS_VARIADIC, /* For Windows Arm64 variadic functions. */
11171118
ARM_PCS_UNKNOWN
11181119
};
11191120

0 commit comments

Comments
 (0)