@@ -157,6 +157,81 @@ static bool CC_SkipOdd(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
157157
158158#include " HexagonGenCallingConv.inc"
159159
160+ unsigned HexagonTargetLowering::getVectorTypeBreakdownForCallingConv (
161+ LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
162+ unsigned &NumIntermediates, MVT &RegisterVT) const {
163+
164+ bool isBoolVector = VT.getVectorElementType () == MVT::i1;
165+ bool isPowerOf2 = VT.isPow2VectorType ();
166+ unsigned NumElts = VT.getVectorNumElements ();
167+
168+ // Split vectors of type vXi1 into (X/8) vectors of type v8i1,
169+ // where X is divisible by 8.
170+ if (isBoolVector && !Subtarget.useHVXOps () && isPowerOf2 && NumElts >= 8 ) {
171+ RegisterVT = MVT::v8i8;
172+ IntermediateVT = MVT::v8i1;
173+ NumIntermediates = NumElts / 8 ;
174+ return NumIntermediates;
175+ }
176+
177+ // In HVX 64-byte mode, vectors of type vXi1 are split into (X / 64) vectors
178+ // of type v64i1, provided that X is divisible by 64.
179+ if (isBoolVector && Subtarget.useHVX64BOps () && isPowerOf2 && NumElts >= 64 ) {
180+ RegisterVT = MVT::v64i8;
181+ IntermediateVT = MVT::v64i1;
182+ NumIntermediates = NumElts / 64 ;
183+ return NumIntermediates;
184+ }
185+
186+ // In HVX 128-byte mode, vectors of type vXi1 are split into (X / 128) vectors
187+ // of type v128i1, provided that X is divisible by 128.
188+ if (isBoolVector && Subtarget.useHVX128BOps () && isPowerOf2 &&
189+ NumElts >= 128 ) {
190+ RegisterVT = MVT::v128i8;
191+ IntermediateVT = MVT::v128i1;
192+ NumIntermediates = NumElts / 128 ;
193+ return NumIntermediates;
194+ }
195+
196+ return TargetLowering::getVectorTypeBreakdownForCallingConv (
197+ Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
198+ }
199+
200+ std::pair<MVT, unsigned >
201+ HexagonTargetLowering::handleMaskRegisterForCallingConv (
202+ const HexagonSubtarget &Subtarget, EVT VT) const {
203+ assert (VT.getVectorElementType () == MVT::i1);
204+
205+ const unsigned NumElems = VT.getVectorNumElements ();
206+
207+ if (!VT.isPow2VectorType ())
208+ return {MVT::INVALID_SIMPLE_VALUE_TYPE, 0 };
209+
210+ if (!Subtarget.useHVXOps () && NumElems >= 8 )
211+ return {MVT::v8i8, NumElems / 8 };
212+
213+ if (Subtarget.useHVX64BOps () && NumElems >= 64 )
214+ return {MVT::v64i8, NumElems / 64 };
215+
216+ if (Subtarget.useHVX128BOps () && NumElems >= 128 )
217+ return {MVT::v128i8, NumElems / 128 };
218+
219+ return {MVT::INVALID_SIMPLE_VALUE_TYPE, 0 };
220+ }
221+
222+ MVT HexagonTargetLowering::getRegisterTypeForCallingConv (LLVMContext &Context,
223+ CallingConv::ID CC,
224+ EVT VT) const {
225+
226+ if (VT.isVector () && VT.getVectorElementType () == MVT::i1) {
227+ auto [RegisterVT, NumRegisters] =
228+ handleMaskRegisterForCallingConv (Subtarget, VT);
229+ if (RegisterVT != MVT::INVALID_SIMPLE_VALUE_TYPE)
230+ return RegisterVT;
231+ }
232+
233+ return TargetLowering::getRegisterTypeForCallingConv (Context, CC, VT);
234+ }
160235
161236SDValue
162237HexagonTargetLowering::LowerINTRINSIC_WO_CHAIN (SDValue Op, SelectionDAG &DAG)
0 commit comments