153 lines · cpp
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_FEATURES15#include "AArch64GenInstrInfo.inc"16 17using namespace llvm;18 19namespace {20 21std::unique_ptr<TargetMachine> createTargetMachine(const std::string &CPU) {22 Triple TT("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 36std::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 43TEST(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)registers100 // 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} // namespace153