@@ -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
12441260static 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+
22682294static const predefined_function_abi &
22692295aarch64_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
1134911463static void
@@ -21583,7 +21697,7 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2158321697#ifdef TARGET_AARCH64_MS_ABI
2158421698
2158521699static 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
0 commit comments