{
fixed_size_mode mode = targetm.calls.get_raw_arg_mode (regno);
- gcc_assert (mode != VOIDmode);
-
- align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
- if (size % align != 0)
- size = CEIL (size, align) * align;
- size += GET_MODE_SIZE (mode);
- apply_args_mode[regno] = mode;
+ if (mode != VOIDmode)
+ {
+ align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
+ if (size % align != 0)
+ size = CEIL (size, align) * align;
+ size += GET_MODE_SIZE (mode);
+ apply_args_mode[regno] = mode;
+ }
+ else
+ apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
}
else
- {
- apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
- }
+ apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
}
return size;
}
{
fixed_size_mode mode = targetm.calls.get_raw_result_mode (regno);
- gcc_assert (mode != VOIDmode);
-
- align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
- if (size % align != 0)
- size = CEIL (size, align) * align;
- size += GET_MODE_SIZE (mode);
- apply_result_mode[regno] = mode;
+ if (mode != VOIDmode)
+ {
+ align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
+ if (size % align != 0)
+ size = CEIL (size, align) * align;
+ size += GET_MODE_SIZE (mode);
+ apply_result_mode[regno] = mode;
+ }
+ else
+ apply_result_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
}
else
apply_result_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
if (regno >= V0_REGNUM && regno < V0_REGNUM + HA_MAX_NUM_FLDS)
return TARGET_FLOAT;
+ if (regno >= P0_REGNUM && regno < P0_REGNUM + HA_MAX_NUM_FLDS)
+ return TARGET_SVE;
+
return false;
}
aarch64_function_arg_regno_p (unsigned regno)
{
return ((GP_REGNUM_P (regno) && regno < R0_REGNUM + NUM_ARG_REGS)
- || (FP_REGNUM_P (regno) && regno < V0_REGNUM + NUM_FP_ARG_REGS));
+ || (FP_REGNUM_P (regno) && regno < V0_REGNUM + NUM_FP_ARG_REGS)
+ || (PR_REGNUM_P (regno) && regno < P0_REGNUM + NUM_PR_ARG_REGS));
}
/* Implement FUNCTION_ARG_BOUNDARY. Every parameter gets at least
for SVE types are fundamentally incompatible with the
__builtin_return/__builtin_apply interface. */
return as_a <fixed_size_mode> (V16QImode);
+ if (PR_REGNUM_P (regno))
+ /* For SVE PR regs, indicate that they should be ignored for
+ __builtin_apply/__builtin_return. */
+ return as_a <fixed_size_mode> (VOIDmode);
return default_get_reg_raw_mode (regno);
}
@deftypefn {Target Hook} fixed_size_mode TARGET_GET_RAW_RESULT_MODE (int @var{regno})
This target hook returns the mode to be used when accessing raw return
registers in @code{__builtin_return}. Define this macro if the value
-in @var{reg_raw_mode} is not correct.
+in @var{reg_raw_mode} is not correct. Use @code{VOIDmode} if a register
+should be ignored for @code{__builtin_return} purposes.
@end deftypefn
@deftypefn {Target Hook} fixed_size_mode TARGET_GET_RAW_ARG_MODE (int @var{regno})
This target hook returns the mode to be used when accessing raw argument
registers in @code{__builtin_apply_args}. Define this macro if the value
-in @var{reg_raw_mode} is not correct.
+in @var{reg_raw_mode} is not correct. Use @code{VOIDmode} if a register
+should be ignored for @code{__builtin_apply_args} purposes.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_EMPTY_RECORD_P (const_tree @var{type})
(get_raw_result_mode,
"This target hook returns the mode to be used when accessing raw return\n\
registers in @code{__builtin_return}. Define this macro if the value\n\
-in @var{reg_raw_mode} is not correct.",
+in @var{reg_raw_mode} is not correct. Use @code{VOIDmode} if a register\n\
+should be ignored for @code{__builtin_return} purposes.",
fixed_size_mode, (int regno),
default_get_reg_raw_mode)
(get_raw_arg_mode,
"This target hook returns the mode to be used when accessing raw argument\n\
registers in @code{__builtin_apply_args}. Define this macro if the value\n\
-in @var{reg_raw_mode} is not correct.",
+in @var{reg_raw_mode} is not correct. Use @code{VOIDmode} if a register\n\
+should be ignored for @code{__builtin_apply_args} purposes.",
fixed_size_mode, (int regno),
default_get_reg_raw_mode)
--- /dev/null
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -funroll-loops" } */
+
+#include <arm_sve.h>
+
+svfloat32_t __attribute__((noipa))
+func_demo (svfloat32_t x, svfloat32_t y, svbool_t pg)
+{
+ svfloat32_t z = svadd_f32_x (pg, x, svdup_f32 (0x1.800fep19f));
+ svbool_t cmp = svcmplt_f32 (pg, z, svdup_f32 (0.0f));
+ svfloat32_t zM1 = svsub_f32_x (pg, z, svdup_n_f32 (1.0f));
+ z = svsel_f32 (cmp, zM1, z);
+ svfloat32_t sum = svadd_f32_x (pg, z, y);
+ return sum;
+}
+
+int
+main ()
+{
+ float arr[2];
+ svfloat32_t x = svinsr_n_f32 (svdup_f32 (-0x1.880fep19f), 2.0f);
+ svfloat32_t res = func_demo (x, svdup_f32 (0.5f), svptrue_b32 ());
+ svst1_f32 (svptrue_pat_b32 (SV_VL2), arr, res);
+ if (arr[0] != 786561.5f || arr[1] != -16384.5f)
+ __builtin_abort ();
+ return 0;
+}