16c9066feSMomchil Velikov #include "AArch64Subtarget.h"
26c9066feSMomchil Velikov #include "AArch64TargetMachine.h"
36c9066feSMomchil Velikov #include "llvm/IR/DataLayout.h"
46c9066feSMomchil Velikov #include "llvm/MC/TargetRegistry.h"
56c9066feSMomchil Velikov #include "llvm/Support/TargetSelect.h"
66c9066feSMomchil Velikov
76c9066feSMomchil Velikov #include "gtest/gtest.h"
86c9066feSMomchil Velikov #include <initializer_list>
96c9066feSMomchil Velikov #include <memory>
106c9066feSMomchil Velikov
116c9066feSMomchil Velikov using namespace llvm;
126c9066feSMomchil Velikov
136c9066feSMomchil Velikov namespace {
146c9066feSMomchil Velikov
156c9066feSMomchil Velikov struct AddrMode : public TargetLowering::AddrMode {
AddrMode__anonb45c0c090111::AddrMode16*cd768ec9SGraham Hunter constexpr AddrMode(GlobalValue *GV, int64_t Offs, bool HasBase, int64_t S,
17*cd768ec9SGraham Hunter int64_t SOffs = 0) {
186c9066feSMomchil Velikov BaseGV = GV;
196c9066feSMomchil Velikov BaseOffs = Offs;
206c9066feSMomchil Velikov HasBaseReg = HasBase;
216c9066feSMomchil Velikov Scale = S;
22*cd768ec9SGraham Hunter ScalableOffset = SOffs;
236c9066feSMomchil Velikov }
246c9066feSMomchil Velikov };
256c9066feSMomchil Velikov struct TestCase {
266c9066feSMomchil Velikov AddrMode AM;
276c9066feSMomchil Velikov unsigned TypeBits;
286c9066feSMomchil Velikov bool Result;
296c9066feSMomchil Velikov };
306c9066feSMomchil Velikov
316c9066feSMomchil Velikov const std::initializer_list<TestCase> Tests = {
326c9066feSMomchil Velikov // {BaseGV, BaseOffs, HasBaseReg, Scale}, Bits, Result
336c9066feSMomchil Velikov {{reinterpret_cast<GlobalValue *>(-1), 0, false, 0}, 64, false},
346c9066feSMomchil Velikov {{nullptr, 8, true, 1}, 64, false},
356c9066feSMomchil Velikov {{nullptr, 0, false, 2}, 64, true},
366c9066feSMomchil Velikov {{nullptr, 0, false, 1}, 64, true},
376c9066feSMomchil Velikov {{nullptr, 4, false, 0}, 64, false},
386c9066feSMomchil Velikov
396c9066feSMomchil Velikov {{nullptr, 0, true, 1}, 64, true},
406c9066feSMomchil Velikov {{nullptr, 0, true, 1}, 32, true},
416c9066feSMomchil Velikov {{nullptr, 0, true, 1}, 16, true},
426c9066feSMomchil Velikov {{nullptr, 0, true, 1}, 8, true},
436c9066feSMomchil Velikov
446c9066feSMomchil Velikov {{nullptr, 0, true, 2}, 64, false},
456c9066feSMomchil Velikov {{nullptr, 0, true, 2}, 32, false},
466c9066feSMomchil Velikov {{nullptr, 0, true, 2}, 16, true},
476c9066feSMomchil Velikov {{nullptr, 0, true, 2}, 8, false},
486c9066feSMomchil Velikov {{nullptr, 0, true, 4}, 64, false},
496c9066feSMomchil Velikov {{nullptr, 0, true, 4}, 32, true},
506c9066feSMomchil Velikov {{nullptr, 0, true, 4}, 16, false},
516c9066feSMomchil Velikov {{nullptr, 0, true, 4}, 8, false},
526c9066feSMomchil Velikov
536c9066feSMomchil Velikov {{nullptr, 0, true, 8}, 64, true},
546c9066feSMomchil Velikov {{nullptr, 0, true, 8}, 32, false},
556c9066feSMomchil Velikov {{nullptr, 0, true, 8}, 16, false},
566c9066feSMomchil Velikov {{nullptr, 0, true, 8}, 8, false},
576c9066feSMomchil Velikov
586c9066feSMomchil Velikov {{nullptr, 0, true, 16}, 64, false},
596c9066feSMomchil Velikov {{nullptr, 0, true, 16}, 32, false},
606c9066feSMomchil Velikov {{nullptr, 0, true, 16}, 16, false},
616c9066feSMomchil Velikov {{nullptr, 0, true, 16}, 8, false},
626c9066feSMomchil Velikov
636c9066feSMomchil Velikov {{nullptr, -257, true, 0}, 64, false},
646c9066feSMomchil Velikov {{nullptr, -256, true, 0}, 64, true},
656c9066feSMomchil Velikov {{nullptr, -255, true, 0}, 64, true},
666c9066feSMomchil Velikov {{nullptr, -1, true, 0}, 64, true},
676c9066feSMomchil Velikov {{nullptr, 0, true, 0}, 64, true},
686c9066feSMomchil Velikov {{nullptr, 1, true, 0}, 64, true},
696c9066feSMomchil Velikov {{nullptr, 254, true, 0}, 64, true},
706c9066feSMomchil Velikov {{nullptr, 255, true, 0}, 64, true},
716c9066feSMomchil Velikov {{nullptr, 256, true, 0}, 64, true},
726c9066feSMomchil Velikov {{nullptr, 257, true, 0}, 64, false},
736c9066feSMomchil Velikov {{nullptr, 258, true, 0}, 64, false},
746c9066feSMomchil Velikov {{nullptr, 259, true, 0}, 64, false},
756c9066feSMomchil Velikov {{nullptr, 260, true, 0}, 64, false},
766c9066feSMomchil Velikov {{nullptr, 261, true, 0}, 64, false},
776c9066feSMomchil Velikov {{nullptr, 262, true, 0}, 64, false},
786c9066feSMomchil Velikov {{nullptr, 263, true, 0}, 64, false},
796c9066feSMomchil Velikov {{nullptr, 264, true, 0}, 64, true},
806c9066feSMomchil Velikov
816c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 8, true, 0}, 64, true},
826c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 7, true, 0}, 64, false},
836c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 6, true, 0}, 64, false},
846c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 5, true, 0}, 64, false},
856c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 4, true, 0}, 64, false},
866c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 3, true, 0}, 64, false},
876c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 2, true, 0}, 64, false},
886c9066feSMomchil Velikov {{nullptr, 4096 * 8 - 1, true, 0}, 64, false},
896c9066feSMomchil Velikov {{nullptr, 4096 * 8, true, 0}, 64, false},
906c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 1, true, 0}, 64, false},
916c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 2, true, 0}, 64, false},
926c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 3, true, 0}, 64, false},
936c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 4, true, 0}, 64, false},
946c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 5, true, 0}, 64, false},
956c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 6, true, 0}, 64, false},
966c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 7, true, 0}, 64, false},
976c9066feSMomchil Velikov {{nullptr, 4096 * 8 + 8, true, 0}, 64, false},
986c9066feSMomchil Velikov
996c9066feSMomchil Velikov {{nullptr, -257, true, 0}, 32, false},
1006c9066feSMomchil Velikov {{nullptr, -256, true, 0}, 32, true},
1016c9066feSMomchil Velikov {{nullptr, -255, true, 0}, 32, true},
1026c9066feSMomchil Velikov {{nullptr, -1, true, 0}, 32, true},
1036c9066feSMomchil Velikov {{nullptr, 0, true, 0}, 32, true},
1046c9066feSMomchil Velikov {{nullptr, 1, true, 0}, 32, true},
1056c9066feSMomchil Velikov {{nullptr, 254, true, 0}, 32, true},
1066c9066feSMomchil Velikov {{nullptr, 255, true, 0}, 32, true},
1076c9066feSMomchil Velikov {{nullptr, 256, true, 0}, 32, true},
1086c9066feSMomchil Velikov {{nullptr, 257, true, 0}, 32, false},
1096c9066feSMomchil Velikov {{nullptr, 258, true, 0}, 32, false},
1106c9066feSMomchil Velikov {{nullptr, 259, true, 0}, 32, false},
1116c9066feSMomchil Velikov {{nullptr, 260, true, 0}, 32, true},
1126c9066feSMomchil Velikov
1136c9066feSMomchil Velikov {{nullptr, 4096 * 4 - 4, true, 0}, 32, true},
1146c9066feSMomchil Velikov {{nullptr, 4096 * 4 - 3, true, 0}, 32, false},
1156c9066feSMomchil Velikov {{nullptr, 4096 * 4 - 2, true, 0}, 32, false},
1166c9066feSMomchil Velikov {{nullptr, 4096 * 4 - 1, true, 0}, 32, false},
1176c9066feSMomchil Velikov {{nullptr, 4096 * 4, true, 0}, 32, false},
1186c9066feSMomchil Velikov {{nullptr, 4096 * 4 + 1, true, 0}, 32, false},
1196c9066feSMomchil Velikov {{nullptr, 4096 * 4 + 2, true, 0}, 32, false},
1206c9066feSMomchil Velikov {{nullptr, 4096 * 4 + 3, true, 0}, 32, false},
1216c9066feSMomchil Velikov {{nullptr, 4096 * 4 + 4, true, 0}, 32, false},
1226c9066feSMomchil Velikov
1236c9066feSMomchil Velikov {{nullptr, -257, true, 0}, 16, false},
1246c9066feSMomchil Velikov {{nullptr, -256, true, 0}, 16, true},
1256c9066feSMomchil Velikov {{nullptr, -255, true, 0}, 16, true},
1266c9066feSMomchil Velikov {{nullptr, -1, true, 0}, 16, true},
1276c9066feSMomchil Velikov {{nullptr, 0, true, 0}, 16, true},
1286c9066feSMomchil Velikov {{nullptr, 1, true, 0}, 16, true},
1296c9066feSMomchil Velikov {{nullptr, 254, true, 0}, 16, true},
1306c9066feSMomchil Velikov {{nullptr, 255, true, 0}, 16, true},
1316c9066feSMomchil Velikov {{nullptr, 256, true, 0}, 16, true},
1326c9066feSMomchil Velikov {{nullptr, 257, true, 0}, 16, false},
1336c9066feSMomchil Velikov {{nullptr, 258, true, 0}, 16, true},
1346c9066feSMomchil Velikov
1356c9066feSMomchil Velikov {{nullptr, 4096 * 2 - 2, true, 0}, 16, true},
1366c9066feSMomchil Velikov {{nullptr, 4096 * 2 - 1, true, 0}, 16, false},
1376c9066feSMomchil Velikov {{nullptr, 4096 * 2, true, 0}, 16, false},
1386c9066feSMomchil Velikov {{nullptr, 4096 * 2 + 1, true, 0}, 16, false},
1396c9066feSMomchil Velikov {{nullptr, 4096 * 2 + 2, true, 0}, 16, false},
1406c9066feSMomchil Velikov
1416c9066feSMomchil Velikov {{nullptr, -257, true, 0}, 8, false},
1426c9066feSMomchil Velikov {{nullptr, -256, true, 0}, 8, true},
1436c9066feSMomchil Velikov {{nullptr, -255, true, 0}, 8, true},
1446c9066feSMomchil Velikov {{nullptr, -1, true, 0}, 8, true},
1456c9066feSMomchil Velikov {{nullptr, 0, true, 0}, 8, true},
1466c9066feSMomchil Velikov {{nullptr, 1, true, 0}, 8, true},
1476c9066feSMomchil Velikov {{nullptr, 254, true, 0}, 8, true},
1486c9066feSMomchil Velikov {{nullptr, 255, true, 0}, 8, true},
1496c9066feSMomchil Velikov {{nullptr, 256, true, 0}, 8, true},
1506c9066feSMomchil Velikov {{nullptr, 257, true, 0}, 8, true},
1516c9066feSMomchil Velikov
1526c9066feSMomchil Velikov {{nullptr, 4096 - 2, true, 0}, 8, true},
1536c9066feSMomchil Velikov {{nullptr, 4096 - 1, true, 0}, 8, true},
1546c9066feSMomchil Velikov {{nullptr, 4096, true, 0}, 8, false},
1556c9066feSMomchil Velikov {{nullptr, 4096 + 1, true, 0}, 8, false},
1566c9066feSMomchil Velikov
1576c9066feSMomchil Velikov };
158*cd768ec9SGraham Hunter
159*cd768ec9SGraham Hunter struct SVETestCase {
160*cd768ec9SGraham Hunter AddrMode AM;
161*cd768ec9SGraham Hunter unsigned TypeBits;
162*cd768ec9SGraham Hunter unsigned NumElts;
163*cd768ec9SGraham Hunter bool Result;
164*cd768ec9SGraham Hunter };
165*cd768ec9SGraham Hunter
166*cd768ec9SGraham Hunter const std::initializer_list<SVETestCase> SVETests = {
167*cd768ec9SGraham Hunter // {BaseGV, BaseOffs, HasBaseReg, Scale, SOffs}, EltBits, Count, Result
168*cd768ec9SGraham Hunter // Test immediate range -- [-8,7] vector's worth.
169*cd768ec9SGraham Hunter // <vscale x 16 x i8>, increment by one vector
170*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, 16}, 8, 16, true},
171*cd768ec9SGraham Hunter // <vscale x 4 x i32>, increment by eight vectors
172*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, 128}, 32, 4, false},
173*cd768ec9SGraham Hunter // <vscale x 8 x i16>, increment by seven vectors
174*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, 112}, 16, 8, true},
175*cd768ec9SGraham Hunter // <vscale x 2 x i64>, decrement by eight vectors
176*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, -128}, 64, 2, true},
177*cd768ec9SGraham Hunter // <vscale x 16 x i8>, decrement by nine vectors
178*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, -144}, 8, 16, false},
179*cd768ec9SGraham Hunter
180*cd768ec9SGraham Hunter // Half the size of a vector register, but allowable with extending
181*cd768ec9SGraham Hunter // loads and truncating stores
182*cd768ec9SGraham Hunter // <vscale x 8 x i8>, increment by three vectors
183*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, 24}, 8, 8, true},
184*cd768ec9SGraham Hunter
185*cd768ec9SGraham Hunter // Test invalid types or offsets
186*cd768ec9SGraham Hunter // <vscale x 5 x i32>, increment by one vector (base size > 16B)
187*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, 20}, 32, 5, false},
188*cd768ec9SGraham Hunter // <vscale x 8 x i16>, increment by half a vector
189*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, 8}, 16, 8, false},
190*cd768ec9SGraham Hunter // <vscale x 3 x i8>, increment by 3 vectors (non-power-of-two)
191*cd768ec9SGraham Hunter {{nullptr, 0, true, 0, 9}, 8, 3, false},
192*cd768ec9SGraham Hunter
193*cd768ec9SGraham Hunter // Scalable and fixed offsets
194*cd768ec9SGraham Hunter // <vscale x 16 x i8>, increment by 32 then decrement by vscale x 16
195*cd768ec9SGraham Hunter {{nullptr, 32, true, 0, -16}, 8, 16, false},
196*cd768ec9SGraham Hunter };
1976c9066feSMomchil Velikov } // namespace
1986c9066feSMomchil Velikov
TEST(AddressingModes,AddressingModes)1996c9066feSMomchil Velikov TEST(AddressingModes, AddressingModes) {
2006c9066feSMomchil Velikov LLVMInitializeAArch64TargetInfo();
2016c9066feSMomchil Velikov LLVMInitializeAArch64Target();
2026c9066feSMomchil Velikov LLVMInitializeAArch64TargetMC();
2036c9066feSMomchil Velikov
2046c9066feSMomchil Velikov std::string Error;
2056c9066feSMomchil Velikov auto TT = Triple::normalize("aarch64");
2066c9066feSMomchil Velikov const Target *T = TargetRegistry::lookupTarget(TT, Error);
2076c9066feSMomchil Velikov
2086c9066feSMomchil Velikov std::unique_ptr<TargetMachine> TM(
2096c9066feSMomchil Velikov T->createTargetMachine(TT, "generic", "", TargetOptions(), std::nullopt,
2100a1aa6cdSArthur Eubanks std::nullopt, CodeGenOptLevel::Default));
2116c9066feSMomchil Velikov AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
2126c9066feSMomchil Velikov TM->getTargetCPU(), TM->getTargetFeatureString(), *TM,
2136c9066feSMomchil Velikov true);
2146c9066feSMomchil Velikov
2156c9066feSMomchil Velikov auto *TLI = ST.getTargetLowering();
2166c9066feSMomchil Velikov DataLayout DL("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
2176c9066feSMomchil Velikov LLVMContext Ctx;
2186c9066feSMomchil Velikov
2196c9066feSMomchil Velikov for (const auto &Test : Tests) {
2206c9066feSMomchil Velikov Type *Typ = Type::getIntNTy(Ctx, Test.TypeBits);
2216c9066feSMomchil Velikov ASSERT_EQ(TLI->isLegalAddressingMode(DL, Test.AM, Typ, 0), Test.Result);
2226c9066feSMomchil Velikov }
223*cd768ec9SGraham Hunter
224*cd768ec9SGraham Hunter for (const auto &SVETest : SVETests) {
225*cd768ec9SGraham Hunter Type *Ty = VectorType::get(Type::getIntNTy(Ctx, SVETest.TypeBits),
226*cd768ec9SGraham Hunter ElementCount::getScalable(SVETest.NumElts));
227*cd768ec9SGraham Hunter ASSERT_EQ(TLI->isLegalAddressingMode(DL, SVETest.AM, Ty, 0),
228*cd768ec9SGraham Hunter SVETest.Result);
229*cd768ec9SGraham Hunter }
2306c9066feSMomchil Velikov }
231