@@ -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
12431259static 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+
22672293static const predefined_function_abi &
22682294aarch64_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
1135411468static void
@@ -21587,7 +21701,7 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2158721701#ifdef TARGET_AARCH64_MS_ABI
2158821702
2158921703static 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
0 commit comments