119 lines
4.2 KiB
Diff
119 lines
4.2 KiB
Diff
|
|
From e3c0d3d98ab1f60900533f3f75c598f899f37c9f Mon Sep 17 00:00:00 2001
|
||
|
|
From: Richard Sandiford <richard.sandiford@arm.com>
|
||
|
|
Date: Tue, 5 Dec 2023 10:11:27 +0000
|
||
|
|
Subject: [PATCH 110/157] [Backport][SME] aarch64: Generalise
|
||
|
|
unspec_based_function_base
|
||
|
|
|
||
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1ec23d5a29bc5d89cef60e2aba2fe4095ee12a8f
|
||
|
|
|
||
|
|
Until now, SVE intrinsics that map directly to unspecs
|
||
|
|
have always used type suffix 0 to distinguish between signed
|
||
|
|
integers, unsigned integers, and floating-point values.
|
||
|
|
SME adds functions that need to use type suffix 1 instead.
|
||
|
|
This patch generalises the classes accordingly.
|
||
|
|
|
||
|
|
gcc/
|
||
|
|
* config/aarch64/aarch64-sve-builtins-functions.h
|
||
|
|
(unspec_based_function_base): Allow type suffix 1 to determine
|
||
|
|
the mode of the operation.
|
||
|
|
(unspec_based_function): Update accordingly.
|
||
|
|
(unspec_based_fused_function): Likewise.
|
||
|
|
(unspec_based_fused_lane_function): Likewise.
|
||
|
|
---
|
||
|
|
.../aarch64/aarch64-sve-builtins-functions.h | 29 ++++++++++++-------
|
||
|
|
1 file changed, 18 insertions(+), 11 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-functions.h b/gcc/config/aarch64/aarch64-sve-builtins-functions.h
|
||
|
|
index 94a6d1207..f5fa4030c 100644
|
||
|
|
--- a/gcc/config/aarch64/aarch64-sve-builtins-functions.h
|
||
|
|
+++ b/gcc/config/aarch64/aarch64-sve-builtins-functions.h
|
||
|
|
@@ -250,18 +250,21 @@ class unspec_based_function_base : public function_base
|
||
|
|
public:
|
||
|
|
CONSTEXPR unspec_based_function_base (int unspec_for_sint,
|
||
|
|
int unspec_for_uint,
|
||
|
|
- int unspec_for_fp)
|
||
|
|
+ int unspec_for_fp,
|
||
|
|
+ unsigned int suffix_index = 0)
|
||
|
|
: m_unspec_for_sint (unspec_for_sint),
|
||
|
|
m_unspec_for_uint (unspec_for_uint),
|
||
|
|
- m_unspec_for_fp (unspec_for_fp)
|
||
|
|
+ m_unspec_for_fp (unspec_for_fp),
|
||
|
|
+ m_suffix_index (suffix_index)
|
||
|
|
{}
|
||
|
|
|
||
|
|
/* Return the unspec code to use for INSTANCE, based on type suffix 0. */
|
||
|
|
int
|
||
|
|
unspec_for (const function_instance &instance) const
|
||
|
|
{
|
||
|
|
- return (!instance.type_suffix (0).integer_p ? m_unspec_for_fp
|
||
|
|
- : instance.type_suffix (0).unsigned_p ? m_unspec_for_uint
|
||
|
|
+ auto &suffix = instance.type_suffix (m_suffix_index);
|
||
|
|
+ return (!suffix.integer_p ? m_unspec_for_fp
|
||
|
|
+ : suffix.unsigned_p ? m_unspec_for_uint
|
||
|
|
: m_unspec_for_sint);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -270,6 +273,9 @@ public:
|
||
|
|
int m_unspec_for_sint;
|
||
|
|
int m_unspec_for_uint;
|
||
|
|
int m_unspec_for_fp;
|
||
|
|
+
|
||
|
|
+ /* Which type suffix is used to choose between the unspecs. */
|
||
|
|
+ unsigned int m_suffix_index;
|
||
|
|
};
|
||
|
|
|
||
|
|
/* A function_base for functions that have an associated unspec code.
|
||
|
|
@@ -336,7 +342,8 @@ public:
|
||
|
|
rtx
|
||
|
|
expand (function_expander &e) const OVERRIDE
|
||
|
|
{
|
||
|
|
- return e.use_exact_insn (CODE (unspec_for (e), e.vector_mode (0)));
|
||
|
|
+ return e.use_exact_insn (CODE (unspec_for (e),
|
||
|
|
+ e.vector_mode (m_suffix_index)));
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
@@ -395,16 +402,16 @@ public:
|
||
|
|
{
|
||
|
|
int unspec = unspec_for (e);
|
||
|
|
insn_code icode;
|
||
|
|
- if (e.type_suffix (0).float_p)
|
||
|
|
+ if (e.type_suffix (m_suffix_index).float_p)
|
||
|
|
{
|
||
|
|
/* Put the operands in the normal (fma ...) order, with the accumulator
|
||
|
|
last. This fits naturally since that's also the unprinted operand
|
||
|
|
in the asm output. */
|
||
|
|
e.rotate_inputs_left (0, e.pred != PRED_none ? 4 : 3);
|
||
|
|
- icode = code_for_aarch64_sve (unspec, e.vector_mode (0));
|
||
|
|
+ icode = code_for_aarch64_sve (unspec, e.vector_mode (m_suffix_index));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- icode = INT_CODE (unspec, e.vector_mode (0));
|
||
|
|
+ icode = INT_CODE (unspec, e.vector_mode (m_suffix_index));
|
||
|
|
return e.use_exact_insn (icode);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
@@ -430,16 +437,16 @@ public:
|
||
|
|
{
|
||
|
|
int unspec = unspec_for (e);
|
||
|
|
insn_code icode;
|
||
|
|
- if (e.type_suffix (0).float_p)
|
||
|
|
+ if (e.type_suffix (m_suffix_index).float_p)
|
||
|
|
{
|
||
|
|
/* Put the operands in the normal (fma ...) order, with the accumulator
|
||
|
|
last. This fits naturally since that's also the unprinted operand
|
||
|
|
in the asm output. */
|
||
|
|
e.rotate_inputs_left (0, e.pred != PRED_none ? 5 : 4);
|
||
|
|
- icode = code_for_aarch64_lane (unspec, e.vector_mode (0));
|
||
|
|
+ icode = code_for_aarch64_lane (unspec, e.vector_mode (m_suffix_index));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- icode = INT_CODE (unspec, e.vector_mode (0));
|
||
|
|
+ icode = INT_CODE (unspec, e.vector_mode (m_suffix_index));
|
||
|
|
return e.use_exact_insn (icode);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|