xref: /llvm-project/llvm/unittests/Target/AArch64/AArch64RegisterInfoTest.cpp (revision 318c69de52b61d64d5ea113dc2e9f307f7fd4d51)
1*318c69deSSander de Smalen #include "AArch64RegisterInfo.h"
2*318c69deSSander de Smalen #include "AArch64InstrInfo.h"
3*318c69deSSander de Smalen #include "AArch64Subtarget.h"
4*318c69deSSander de Smalen #include "AArch64TargetMachine.h"
5*318c69deSSander de Smalen #include "llvm/MC/MCSubtargetInfo.h"
6*318c69deSSander de Smalen #include "llvm/MC/TargetRegistry.h"
7*318c69deSSander de Smalen #include "llvm/Support/TargetSelect.h"
8*318c69deSSander de Smalen #include "llvm/Support/raw_ostream.h"
9*318c69deSSander de Smalen #include "llvm/Target/TargetMachine.h"
10*318c69deSSander de Smalen #include "llvm/Target/TargetOptions.h"
11*318c69deSSander de Smalen 
12*318c69deSSander de Smalen #include "gtest/gtest.h"
13*318c69deSSander de Smalen 
14*318c69deSSander de Smalen #define GET_COMPUTE_FEATURES
15*318c69deSSander de Smalen #include "AArch64GenInstrInfo.inc"
16*318c69deSSander de Smalen 
17*318c69deSSander de Smalen using namespace llvm;
18*318c69deSSander de Smalen 
19*318c69deSSander de Smalen namespace {
20*318c69deSSander de Smalen 
21*318c69deSSander de Smalen std::unique_ptr<TargetMachine> createTargetMachine(const std::string &CPU) {
22*318c69deSSander de Smalen   auto TT(Triple::normalize("aarch64--"));
23*318c69deSSander de Smalen 
24*318c69deSSander de Smalen   LLVMInitializeAArch64TargetInfo();
25*318c69deSSander de Smalen   LLVMInitializeAArch64Target();
26*318c69deSSander de Smalen   LLVMInitializeAArch64TargetMC();
27*318c69deSSander de Smalen 
28*318c69deSSander de Smalen   std::string Error;
29*318c69deSSander de Smalen   const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
30*318c69deSSander de Smalen 
31*318c69deSSander de Smalen   return std::unique_ptr<TargetMachine>(
32*318c69deSSander de Smalen       TheTarget->createTargetMachine(TT, CPU, "", TargetOptions(), std::nullopt,
33*318c69deSSander de Smalen                                      std::nullopt, CodeGenOptLevel::Default));
34*318c69deSSander de Smalen }
35*318c69deSSander de Smalen 
36*318c69deSSander de Smalen std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
37*318c69deSSander de Smalen   AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
38*318c69deSSander de Smalen                       std::string(TM->getTargetCPU()),
39*318c69deSSander de Smalen                       std::string(TM->getTargetFeatureString()), *TM, true);
40*318c69deSSander de Smalen   return std::make_unique<AArch64InstrInfo>(ST);
41*318c69deSSander de Smalen }
42*318c69deSSander de Smalen 
43*318c69deSSander de Smalen TEST(AArch64LaneBitmasks, SubRegs) {
44*318c69deSSander de Smalen   std::unique_ptr<TargetMachine> TM = createTargetMachine("");
45*318c69deSSander de Smalen   ASSERT_TRUE(TM);
46*318c69deSSander de Smalen 
47*318c69deSSander de Smalen   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
48*318c69deSSander de Smalen   ASSERT_TRUE(II);
49*318c69deSSander de Smalen 
50*318c69deSSander de Smalen   const AArch64RegisterInfo &TRI = II->getRegisterInfo();
51*318c69deSSander de Smalen 
52*318c69deSSander de Smalen   // Test that the lane masks for the subregisters 'bsub, hsub, ssub, etc'
53*318c69deSSander de Smalen   // are composed correctly.
54*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::bsub) |
55*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::bsub_hi),
56*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::hsub));
57*318c69deSSander de Smalen 
58*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::hsub) |
59*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::hsub_hi),
60*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::ssub));
61*318c69deSSander de Smalen 
62*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::ssub) |
63*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::ssub_hi),
64*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::dsub));
65*318c69deSSander de Smalen 
66*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub) |
67*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::dsub_hi),
68*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::zsub));
69*318c69deSSander de Smalen 
70*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::zsub) |
71*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::zsub_hi),
72*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::zsub0));
73*318c69deSSander de Smalen 
74*318c69deSSander de Smalen   // Test that the lane masks for tuples are composed correctly.
75*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_bsub) |
76*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_bsub_hi),
77*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub));
78*318c69deSSander de Smalen 
79*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub) |
80*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub_hi),
81*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub));
82*318c69deSSander de Smalen 
83*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub) |
84*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub_hi),
85*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::dsub1));
86*318c69deSSander de Smalen 
87*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1) |
88*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::qsub1_then_dsub_hi),
89*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::qsub1));
90*318c69deSSander de Smalen 
91*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sub_32) |
92*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::sub_32_hi),
93*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::sube64));
94*318c69deSSander de Smalen 
95*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32) |
96*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32_hi),
97*318c69deSSander de Smalen             TRI.getSubRegIndexLaneMask(AArch64::subo64));
98*318c69deSSander de Smalen 
99*318c69deSSander de Smalen   // Test that there is no overlap between different (sub)registers
100*318c69deSSander de Smalen   // in a tuple.
101*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub0) &
102*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::dsub1) &
103*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::dsub2) &
104*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::dsub3),
105*318c69deSSander de Smalen             LaneBitmask::getNone());
106*318c69deSSander de Smalen 
107*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::qsub0) &
108*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::qsub1) &
109*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::qsub2) &
110*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::qsub3),
111*318c69deSSander de Smalen             LaneBitmask::getNone());
112*318c69deSSander de Smalen 
113*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::zsub0) &
114*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::zsub1) &
115*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::zsub2) &
116*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::zsub3),
117*318c69deSSander de Smalen             LaneBitmask::getNone());
118*318c69deSSander de Smalen 
119*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sube32) &
120*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::subo32),
121*318c69deSSander de Smalen             LaneBitmask::getNone());
122*318c69deSSander de Smalen 
123*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sube64) &
124*318c69deSSander de Smalen                 TRI.getSubRegIndexLaneMask(AArch64::subo64),
125*318c69deSSander de Smalen             LaneBitmask::getNone());
126*318c69deSSander de Smalen 
127*318c69deSSander de Smalen   // Test that getting a subregister results in the expected subregister.
128*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::bsub), AArch64::B0);
129*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::hsub), AArch64::H0);
130*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::ssub), AArch64::S0);
131*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub), AArch64::D0);
132*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::zsub), AArch64::Q0);
133*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::zsub0), AArch64::Z0);
134*318c69deSSander de Smalen 
135*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_bsub),
136*318c69deSSander de Smalen             AArch64::B8);
137*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_hsub),
138*318c69deSSander de Smalen             AArch64::H8);
139*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_ssub),
140*318c69deSSander de Smalen             AArch64::S8);
141*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1), AArch64::D8);
142*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::qsub1), AArch64::Q8);
143*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::zsub1), AArch64::Z8);
144*318c69deSSander de Smalen 
145*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::sube64), AArch64::X0);
146*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::subo64), AArch64::X1);
147*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::sub_32), AArch64::W0);
148*318c69deSSander de Smalen   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::subo64_then_sub_32),
149*318c69deSSander de Smalen             AArch64::W1);
150*318c69deSSander de Smalen }
151*318c69deSSander de Smalen 
152*318c69deSSander de Smalen } // namespace
153