Skip to content

Commit 5476988

Browse files
committed
Experiment with adding new ABI
1 parent 157819e commit 5476988

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
@@ -735,6 +735,7 @@ handle_aarch64_vector_pcs_attribute (tree *node, tree name, tree,
735735
{
736736
case ARM_PCS_AAPCS64:
737737
case ARM_PCS_SIMD:
738+
case ARM_PCS_MS_VARIADIC:
738739
return NULL_TREE;
739740

740741
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 &
@@ -2264,9 +2280,24 @@ aarch64_takes_arguments_in_sve_regs_p (const_tree fntype)
22642280

22652281
/* Implement TARGET_FNTYPE_ABI. */
22662282

2283+
static bool is_variadic_function_type (const_tree fntype) {
2284+
tree arg_types = TYPE_ARG_TYPES (fntype);
2285+
for (tree arg = arg_types; arg; arg = TREE_CHAIN (arg)) {
2286+
if (TREE_VALUE (arg) == void_type_node) {
2287+
return false;
2288+
}
2289+
}
2290+
return true;
2291+
}
2292+
22672293
static const predefined_function_abi &
22682294
aarch64_fntype_abi (const_tree fntype)
22692295
{
2296+
#if TARGET_AARCH64_MS_ABI
2297+
if (is_variadic_function_type (fntype))
2298+
return aarch64_ms_variadic_abi ();
2299+
#endif
2300+
22702301
if (lookup_attribute ("aarch64_vector_pcs", TYPE_ATTRIBUTES (fntype)))
22712302
return aarch64_simd_abi ();
22722303

@@ -2478,6 +2509,7 @@ aarch64_reg_save_mode (unsigned int regno)
24782509
switch (crtl->abi->id ())
24792510
{
24802511
case ARM_PCS_AAPCS64:
2512+
case ARM_PCS_MS_VARIADIC:
24812513
/* Only the low 64 bits are saved by the base PCS. */
24822514
return DFmode;
24832515

@@ -5313,6 +5345,7 @@ aarch64_sme_mode_switch_regs::add_call_preserved_reg (unsigned int regno)
53135345
add_reg (V16QImode, regno);
53145346
break;
53155347
case ARM_PCS_AAPCS64:
5348+
case ARM_PCS_MS_VARIADIC:
53165349
add_reg (DImode, regno);
53175350
break;
53185351
default:
@@ -6977,6 +7010,55 @@ bitint_or_aggr_of_bitint_p (tree type)
69777010
return false;
69787011
}
69797012

7013+
static void
7014+
aarch64_ms_variadic_abi_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
7015+
{
7016+
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
7017+
tree type = arg.type;
7018+
machine_mode mode = arg.mode;
7019+
HOST_WIDE_INT size;
7020+
unsigned int abi_break_gcc_9;
7021+
unsigned int abi_break_gcc_13;
7022+
unsigned int abi_break_gcc_14;
7023+
7024+
/* We need to do this once per argument. */
7025+
if (pcum->aapcs_arg_processed)
7026+
return;
7027+
7028+
pcum->aapcs_arg_processed = true;
7029+
7030+
/* Size in bytes, rounded to the nearest multiple of 8 bytes. */
7031+
if (type)
7032+
size = int_size_in_bytes (type);
7033+
else
7034+
/* No frontends can create types with variable-sized modes, so we
7035+
shouldn't be asked to pass or return them. */
7036+
size = GET_MODE_SIZE (mode).to_constant ();
7037+
size = ROUND_UP (size, UNITS_PER_WORD);
7038+
7039+
unsigned int alignment
7040+
= aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
7041+
&abi_break_gcc_13, &abi_break_gcc_14);
7042+
7043+
gcc_assert ((alignment <= 16 * BITS_PER_UNIT)
7044+
&& (!alignment || abi_break_gcc_9 < alignment)
7045+
&& (!abi_break_gcc_13 || alignment < abi_break_gcc_13));
7046+
7047+
/* The argument is passed on stack; record the needed number of words for
7048+
this argument and align the total size if necessary. */
7049+
pcum->aapcs_stack_words = size / UNITS_PER_WORD;
7050+
7051+
if (alignment == 16 * BITS_PER_UNIT)
7052+
{
7053+
int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
7054+
if (pcum->aapcs_stack_size != new_size)
7055+
{
7056+
pcum->aapcs_stack_size = new_size;
7057+
}
7058+
}
7059+
return;
7060+
}
7061+
69807062
/* Layout a function argument according to the AAPCS64 rules. The rule
69817063
numbers refer to the rule numbers in the AAPCS64. ORIG_MODE is the
69827064
mode that was originally given to us by the target hook, whereas the
@@ -7000,6 +7082,11 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
70007082
if (pcum->aapcs_arg_processed)
70017083
return;
70027084

7085+
if (pcum->pcs_variant == ARM_PCS_MS_VARIADIC) {
7086+
aarch64_ms_variadic_abi_layout_arg (pcum_v, arg);
7087+
return;
7088+
}
7089+
70037090
bool warn_pcs_change
70047091
= (warn_psabi
70057092
&& !pcum->silent_p
@@ -7365,7 +7452,8 @@ aarch64_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
73657452
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
73667453
gcc_assert (pcum->pcs_variant == ARM_PCS_AAPCS64
73677454
|| pcum->pcs_variant == ARM_PCS_SIMD
7368-
|| pcum->pcs_variant == ARM_PCS_SVE);
7455+
|| pcum->pcs_variant == ARM_PCS_SVE
7456+
|| pcum->pcs_variant == ARM_PCS_MS_VARIADIC);
73697457

73707458
if (arg.end_marker_p ())
73717459
{
@@ -7457,7 +7545,8 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v,
74577545
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
74587546
if (pcum->pcs_variant == ARM_PCS_AAPCS64
74597547
|| pcum->pcs_variant == ARM_PCS_SIMD
7460-
|| pcum->pcs_variant == ARM_PCS_SVE)
7548+
|| pcum->pcs_variant == ARM_PCS_SVE
7549+
|| pcum->pcs_variant == ARM_PCS_MS_VARIADIC)
74617550
{
74627551
aarch64_layout_arg (pcum_v, arg);
74637552
gcc_assert ((pcum->aapcs_reg != NULL_RTX)
@@ -11349,6 +11438,31 @@ aarch64_restore_zt0 (bool from_lazy_save_p)
1134911438
: gen_aarch64_sme_ldr_zt0 (mem));
1135011439
}
1135111440

11441+
static void
11442+
aarch64_ms_variadic_abi_call_args (cumulative_args_t, rtx arg, tree fntype)
11443+
{
11444+
// TODO: Load first 64 bytes of stack to x0-x7 registers.
11445+
if (fntype && is_variadic_function_type (fntype))
11446+
{
11447+
machine_mode mode = aarch64_reg_save_mode (R0_REGNUM);
11448+
11449+
/*rtx cfi_ops = NULL;
11450+
aarch64_pop_regs (R0_REGNUM, R1_REGNUM, 0, &cfi_ops);*/
11451+
11452+
/*move_block_to_reg (R0_REGNUM, mem, NUM_ARG_REGS, mode);*/
11453+
11454+
// TODO: Load only registers that are used in the function.
11455+
for (int i = 0; i < 8; i++)
11456+
{
11457+
HOST_WIDE_INT offset = i * UNITS_PER_WORD;
11458+
rtx sp = stack_pointer_rtx;
11459+
rtx reg = gen_rtx_REG (mode, R0_REGNUM + i);
11460+
rtx mem = gen_rtx_MEM (mode, plus_constant (Pmode, sp, offset));
11461+
emit_move_insn (reg, mem);
11462+
}
11463+
}
11464+
}
11465+
1135211466
/* Implement TARGET_START_CALL_ARGS. */
1135311467

1135411468
static void
@@ -21587,7 +21701,7 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2158721701
#ifdef TARGET_AARCH64_MS_ABI
2158821702

2158921703
static void
21590-
aarch64_ms_abi_expand_builtin_va_start (tree valist, rtx nextarg)
21704+
aarch64_ms_variadic_abi_expand_builtin_va_start (tree valist, rtx nextarg)
2159121705
{
2159221706
nextarg = plus_constant (Pmode, nextarg, cfun->machine->frame.first_vararg_offset, true);
2159321707
std_expand_builtin_va_start (valist, nextarg);
@@ -31359,7 +31473,7 @@ aarch64_run_selftests (void)
3135931473

3136031474
#undef TARGET_EXPAND_BUILTIN_VA_START
3136131475
#ifdef TARGET_AARCH64_MS_ABI
31362-
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_ms_abi_expand_builtin_va_start
31476+
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_ms_variadic_abi_expand_builtin_va_start
3136331477
#else
3136431478
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_expand_builtin_va_start
3136531479
#endif
@@ -31393,6 +31507,11 @@ aarch64_run_selftests (void)
3139331507
#undef TARGET_FUNCTION_VALUE_REGNO_P
3139431508
#define TARGET_FUNCTION_VALUE_REGNO_P aarch64_function_value_regno_p
3139531509

31510+
#ifdef TARGET_AARCH64_MS_ABI
31511+
#undef TARGET_CALL_ARGS
31512+
#define TARGET_CALL_ARGS aarch64_ms_variadic_abi_call_args
31513+
#endif
31514+
3139631515
#undef TARGET_START_CALL_ARGS
3139731516
#define TARGET_START_CALL_ARGS aarch64_start_call_args
3139831517

gcc/config/aarch64/aarch64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,7 @@ enum arm_pcs
11791179
ARM_PCS_SVE, /* For functions that pass or return
11801180
values in SVE registers. */
11811181
ARM_PCS_TLSDESC, /* For targets of tlsdesc calls. */
1182+
ARM_PCS_MS_VARIADIC, /* For Windows Arm64 variadic functions. */
11821183
ARM_PCS_UNKNOWN
11831184
};
11841185

0 commit comments

Comments
 (0)