Skip to content

Commit 0d90f62

Browse files
committed
Experiment with adding new ABI
1 parent d996620 commit 0d90f62

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:
@@ -1239,6 +1240,21 @@ aarch64_some_values_include_pst_objects_p (const_tree type)
12391240
return false;
12401241
}
12411242

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

12441260
static const predefined_function_abi &
@@ -2265,9 +2281,24 @@ aarch64_takes_arguments_in_sve_regs_p (const_tree fntype)
22652281

22662282
/* Implement TARGET_FNTYPE_ABI. */
22672283

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

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

@@ -5299,6 +5331,7 @@ aarch64_sme_mode_switch_regs::add_call_preserved_reg (unsigned int regno)
52995331
add_reg (V16QImode, regno);
53005332
break;
53015333
case ARM_PCS_AAPCS64:
5334+
case ARM_PCS_MS_VARIADIC:
53025335
add_reg (DImode, regno);
53035336
break;
53045337
default:
@@ -6972,6 +7005,55 @@ bitint_or_aggr_of_bitint_p (tree type)
69727005
return false;
69737006
}
69747007

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

7080+
if (pcum->pcs_variant == ARM_PCS_MS_VARIADIC) {
7081+
aarch64_ms_variadic_abi_layout_arg (pcum_v, arg);
7082+
return;
7083+
}
7084+
69987085
bool warn_pcs_change
69997086
= (warn_psabi
70007087
&& !pcum->silent_p
@@ -7360,7 +7447,8 @@ aarch64_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
73607447
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
73617448
gcc_assert (pcum->pcs_variant == ARM_PCS_AAPCS64
73627449
|| pcum->pcs_variant == ARM_PCS_SIMD
7363-
|| pcum->pcs_variant == ARM_PCS_SVE);
7450+
|| pcum->pcs_variant == ARM_PCS_SVE
7451+
|| pcum->pcs_variant == ARM_PCS_MS_VARIADIC);
73647452

73657453
if (arg.end_marker_p ())
73667454
{
@@ -7452,7 +7540,8 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v,
74527540
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
74537541
if (pcum->pcs_variant == ARM_PCS_AAPCS64
74547542
|| pcum->pcs_variant == ARM_PCS_SIMD
7455-
|| pcum->pcs_variant == ARM_PCS_SVE)
7543+
|| pcum->pcs_variant == ARM_PCS_SVE
7544+
|| pcum->pcs_variant == ARM_PCS_MS_VARIADIC)
74567545
{
74577546
aarch64_layout_arg (pcum_v, arg);
74587547
gcc_assert ((pcum->aapcs_reg != NULL_RTX)
@@ -11344,6 +11433,31 @@ aarch64_restore_zt0 (bool from_lazy_save_p)
1134411433
: gen_aarch64_sme_ldr_zt0 (mem));
1134511434
}
1134611435

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

1134911463
static void
@@ -21583,7 +21697,7 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2158321697
#ifdef TARGET_AARCH64_MS_ABI
2158421698

2158521699
static void
21586-
aarch64_ms_abi_expand_builtin_va_start (tree valist, rtx nextarg)
21700+
aarch64_ms_variadic_abi_expand_builtin_va_start (tree valist, rtx nextarg)
2158721701
{
2158821702
nextarg = plus_constant (Pmode, nextarg, cfun->machine->frame.first_vararg_offset, true);
2158921703
std_expand_builtin_va_start (valist, nextarg);
@@ -31287,7 +31401,7 @@ aarch64_run_selftests (void)
3128731401

3128831402
#undef TARGET_EXPAND_BUILTIN_VA_START
3128931403
#ifdef TARGET_AARCH64_MS_ABI
31290-
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_ms_abi_expand_builtin_va_start
31404+
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_ms_variadic_abi_expand_builtin_va_start
3129131405
#else
3129231406
#define TARGET_EXPAND_BUILTIN_VA_START aarch64_expand_builtin_va_start
3129331407
#endif
@@ -31321,6 +31435,11 @@ aarch64_run_selftests (void)
3132131435
#undef TARGET_FUNCTION_VALUE_REGNO_P
3132231436
#define TARGET_FUNCTION_VALUE_REGNO_P aarch64_function_value_regno_p
3132331437

31438+
#ifdef TARGET_AARCH64_MS_ABI
31439+
#undef TARGET_CALL_ARGS
31440+
#define TARGET_CALL_ARGS aarch64_ms_variadic_abi_call_args
31441+
#endif
31442+
3132431443
#undef TARGET_START_CALL_ARGS
3132531444
#define TARGET_START_CALL_ARGS aarch64_start_call_args
3132631445

gcc/config/aarch64/aarch64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,7 @@ enum arm_pcs
11251125
ARM_PCS_SVE, /* For functions that pass or return
11261126
values in SVE registers. */
11271127
ARM_PCS_TLSDESC, /* For targets of tlsdesc calls. */
1128+
ARM_PCS_MS_VARIADIC, /* For Windows Arm64 variadic functions. */
11281129
ARM_PCS_UNKNOWN
11291130
};
11301131

0 commit comments

Comments
 (0)