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" 11 12 #include "gtest/gtest.h" 13 14 #define GET_COMPUTE_FEATURES 15 #include "AArch64GenInstrInfo.inc" 16 17 using namespace llvm; 18 19 namespace { 20 21 std::unique_ptr<TargetMachine> createTargetMachine(const std::string &CPU) { 22 auto TT(Triple::normalize("aarch64--")); 23 24 LLVMInitializeAArch64TargetInfo(); 25 LLVMInitializeAArch64Target(); 26 LLVMInitializeAArch64TargetMC(); 27 28 std::string Error; 29 const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); 30 31 return std::unique_ptr<TargetMachine>( 32 TheTarget->createTargetMachine(TT, CPU, "", TargetOptions(), std::nullopt, 33 std::nullopt, CodeGenOptLevel::Default)); 34 } 35 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); 41 } 42 43 TEST(AArch64LaneBitmasks, SubRegs) { 44 std::unique_ptr<TargetMachine> TM = createTargetMachine(""); 45 ASSERT_TRUE(TM); 46 47 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get()); 48 ASSERT_TRUE(II); 49 50 const AArch64RegisterInfo &TRI = II->getRegisterInfo(); 51 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)); 57 58 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::hsub) | 59 TRI.getSubRegIndexLaneMask(AArch64::hsub_hi), 60 TRI.getSubRegIndexLaneMask(AArch64::ssub)); 61 62 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::ssub) | 63 TRI.getSubRegIndexLaneMask(AArch64::ssub_hi), 64 TRI.getSubRegIndexLaneMask(AArch64::dsub)); 65 66 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub) | 67 TRI.getSubRegIndexLaneMask(AArch64::dsub_hi), 68 TRI.getSubRegIndexLaneMask(AArch64::zsub)); 69 70 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::zsub) | 71 TRI.getSubRegIndexLaneMask(AArch64::zsub_hi), 72 TRI.getSubRegIndexLaneMask(AArch64::zsub0)); 73 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)); 78 79 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub) | 80 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub_hi), 81 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub)); 82 83 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub) | 84 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub_hi), 85 TRI.getSubRegIndexLaneMask(AArch64::dsub1)); 86 87 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1) | 88 TRI.getSubRegIndexLaneMask(AArch64::qsub1_then_dsub_hi), 89 TRI.getSubRegIndexLaneMask(AArch64::qsub1)); 90 91 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sub_32) | 92 TRI.getSubRegIndexLaneMask(AArch64::sub_32_hi), 93 TRI.getSubRegIndexLaneMask(AArch64::sube64)); 94 95 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32) | 96 TRI.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32_hi), 97 TRI.getSubRegIndexLaneMask(AArch64::subo64)); 98 99 // Test that there is no overlap between different (sub)registers 100 // in a tuple. 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()); 106 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()); 112 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()); 118 119 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sube32) & 120 TRI.getSubRegIndexLaneMask(AArch64::subo32), 121 LaneBitmask::getNone()); 122 123 EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sube64) & 124 TRI.getSubRegIndexLaneMask(AArch64::subo64), 125 LaneBitmask::getNone()); 126 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); 134 135 EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_bsub), 136 AArch64::B8); 137 EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_hsub), 138 AArch64::H8); 139 EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_ssub), 140 AArch64::S8); 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); 144 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), 149 AArch64::W1); 150 } 151 152 } // namespace 153