1 #include "AArch64RegisterInfo.h"
2 #include "AArch64InstrInfo.h"
3 #include "AArch64Subtarget.h"
4 #include "AArch64TargetMachine.h"
5 #include "llvm/MC/MCSubtargetInfo.h"
6 #include "llvm/MC/TargetRegistry.h"
7 #include "llvm/Support/TargetSelect.h"
8 #include "llvm/Support/raw_ostream.h"
9 #include "llvm/Target/TargetMachine.h"
10 #include "llvm/Target/TargetOptions.h"
12 #include "gtest/gtest.h"
14 #define GET_COMPUTE_FEATURES
15 #include "AArch64GenInstrInfo.inc"
21 std::unique_ptr
<TargetMachine
> createTargetMachine(const std::string
&CPU
) {
22 auto TT(Triple::normalize("aarch64--"));
24 LLVMInitializeAArch64TargetInfo();
25 LLVMInitializeAArch64Target();
26 LLVMInitializeAArch64TargetMC();
29 const Target
*TheTarget
= TargetRegistry::lookupTarget(TT
, Error
);
31 return std::unique_ptr
<TargetMachine
>(
32 TheTarget
->createTargetMachine(TT
, CPU
, "", TargetOptions(), std::nullopt
,
33 std::nullopt
, CodeGenOptLevel::Default
));
36 std::unique_ptr
<AArch64InstrInfo
> createInstrInfo(TargetMachine
*TM
) {
37 AArch64Subtarget
ST(TM
->getTargetTriple(), std::string(TM
->getTargetCPU()),
38 std::string(TM
->getTargetCPU()),
39 std::string(TM
->getTargetFeatureString()), *TM
, true);
40 return std::make_unique
<AArch64InstrInfo
>(ST
);
43 TEST(AArch64LaneBitmasks
, SubRegs
) {
44 std::unique_ptr
<TargetMachine
> TM
= createTargetMachine("");
47 std::unique_ptr
<AArch64InstrInfo
> II
= createInstrInfo(TM
.get());
50 const AArch64RegisterInfo
&TRI
= II
->getRegisterInfo();
52 // Test that the lane masks for the subregisters 'bsub, hsub, ssub, etc'
53 // are composed correctly.
54 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::bsub
) |
55 TRI
.getSubRegIndexLaneMask(AArch64::bsub_hi
),
56 TRI
.getSubRegIndexLaneMask(AArch64::hsub
));
58 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::hsub
) |
59 TRI
.getSubRegIndexLaneMask(AArch64::hsub_hi
),
60 TRI
.getSubRegIndexLaneMask(AArch64::ssub
));
62 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::ssub
) |
63 TRI
.getSubRegIndexLaneMask(AArch64::ssub_hi
),
64 TRI
.getSubRegIndexLaneMask(AArch64::dsub
));
66 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::dsub
) |
67 TRI
.getSubRegIndexLaneMask(AArch64::dsub_hi
),
68 TRI
.getSubRegIndexLaneMask(AArch64::zsub
));
70 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::zsub
) |
71 TRI
.getSubRegIndexLaneMask(AArch64::zsub_hi
),
72 TRI
.getSubRegIndexLaneMask(AArch64::zsub0
));
74 // Test that the lane masks for tuples are composed correctly.
75 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_bsub
) |
76 TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_bsub_hi
),
77 TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub
));
79 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub
) |
80 TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub_hi
),
81 TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub
));
83 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub
) |
84 TRI
.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub_hi
),
85 TRI
.getSubRegIndexLaneMask(AArch64::dsub1
));
87 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::dsub1
) |
88 TRI
.getSubRegIndexLaneMask(AArch64::qsub1_then_dsub_hi
),
89 TRI
.getSubRegIndexLaneMask(AArch64::qsub1
));
91 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::sub_32
) |
92 TRI
.getSubRegIndexLaneMask(AArch64::sub_32_hi
),
93 TRI
.getSubRegIndexLaneMask(AArch64::sube64
));
95 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32
) |
96 TRI
.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32_hi
),
97 TRI
.getSubRegIndexLaneMask(AArch64::subo64
));
99 // Test that there is no overlap between different (sub)registers
101 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::dsub0
) &
102 TRI
.getSubRegIndexLaneMask(AArch64::dsub1
) &
103 TRI
.getSubRegIndexLaneMask(AArch64::dsub2
) &
104 TRI
.getSubRegIndexLaneMask(AArch64::dsub3
),
105 LaneBitmask::getNone());
107 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::qsub0
) &
108 TRI
.getSubRegIndexLaneMask(AArch64::qsub1
) &
109 TRI
.getSubRegIndexLaneMask(AArch64::qsub2
) &
110 TRI
.getSubRegIndexLaneMask(AArch64::qsub3
),
111 LaneBitmask::getNone());
113 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::zsub0
) &
114 TRI
.getSubRegIndexLaneMask(AArch64::zsub1
) &
115 TRI
.getSubRegIndexLaneMask(AArch64::zsub2
) &
116 TRI
.getSubRegIndexLaneMask(AArch64::zsub3
),
117 LaneBitmask::getNone());
119 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::sube32
) &
120 TRI
.getSubRegIndexLaneMask(AArch64::subo32
),
121 LaneBitmask::getNone());
123 EXPECT_EQ(TRI
.getSubRegIndexLaneMask(AArch64::sube64
) &
124 TRI
.getSubRegIndexLaneMask(AArch64::subo64
),
125 LaneBitmask::getNone());
127 // Test that getting a subregister results in the expected subregister.
128 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::bsub
), AArch64::B0
);
129 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::hsub
), AArch64::H0
);
130 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::ssub
), AArch64::S0
);
131 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::dsub
), AArch64::D0
);
132 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::zsub
), AArch64::Q0
);
133 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::zsub0
), AArch64::Z0
);
135 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::dsub1_then_bsub
),
137 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::dsub1_then_hsub
),
139 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::dsub1_then_ssub
),
141 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::dsub1
), AArch64::D8
);
142 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::qsub1
), AArch64::Q8
);
143 EXPECT_EQ(TRI
.getSubReg(AArch64::Z0_Z8
, AArch64::zsub1
), AArch64::Z8
);
145 EXPECT_EQ(TRI
.getSubReg(AArch64::X0_X1
, AArch64::sube64
), AArch64::X0
);
146 EXPECT_EQ(TRI
.getSubReg(AArch64::X0_X1
, AArch64::subo64
), AArch64::X1
);
147 EXPECT_EQ(TRI
.getSubReg(AArch64::X0_X1
, AArch64::sub_32
), AArch64::W0
);
148 EXPECT_EQ(TRI
.getSubReg(AArch64::X0_X1
, AArch64::subo64_then_sub_32
),