161f48ca3SMarcello Maggioni //===- MachineOperandTest.cpp ---------------------------------===// 261f48ca3SMarcello Maggioni // 361f48ca3SMarcello Maggioni // The LLVM Compiler Infrastructure 461f48ca3SMarcello Maggioni // 561f48ca3SMarcello Maggioni // This file is distributed under the University of Illinois Open Source 661f48ca3SMarcello Maggioni // License. See LICENSE.TXT for details. 761f48ca3SMarcello Maggioni // 861f48ca3SMarcello Maggioni //===----------------------------------------------------------------------===// 961f48ca3SMarcello Maggioni 1061f48ca3SMarcello Maggioni #include "llvm/CodeGen/MachineOperand.h" 11*5df3bbf3SFrancis Visoiu Mistrih #include "llvm/ADT/ilist_node.h" 126c4ca713SFrancis Visoiu Mistrih #include "llvm/IR/Constants.h" 136c4ca713SFrancis Visoiu Mistrih #include "llvm/IR/LLVMContext.h" 14*5df3bbf3SFrancis Visoiu Mistrih #include "llvm/IR/Module.h" 15440f69c9SFrancis Visoiu Mistrih #include "llvm/IR/ModuleSlotTracker.h" 16a8a83d15SFrancis Visoiu Mistrih #include "llvm/Support/raw_ostream.h" 1761f48ca3SMarcello Maggioni #include "gtest/gtest.h" 1861f48ca3SMarcello Maggioni 1961f48ca3SMarcello Maggioni using namespace llvm; 2061f48ca3SMarcello Maggioni 2161f48ca3SMarcello Maggioni namespace { 2261f48ca3SMarcello Maggioni 2361f48ca3SMarcello Maggioni TEST(MachineOperandTest, ChangeToTargetIndexTest) { 2461f48ca3SMarcello Maggioni // Creating a MachineOperand to change it to TargetIndex 2561f48ca3SMarcello Maggioni MachineOperand MO = MachineOperand::CreateImm(50); 2661f48ca3SMarcello Maggioni 2761f48ca3SMarcello Maggioni // Checking some precondition on the newly created 2861f48ca3SMarcello Maggioni // MachineOperand. 2961f48ca3SMarcello Maggioni ASSERT_TRUE(MO.isImm()); 3061f48ca3SMarcello Maggioni ASSERT_TRUE(MO.getImm() == 50); 3161f48ca3SMarcello Maggioni ASSERT_FALSE(MO.isTargetIndex()); 3261f48ca3SMarcello Maggioni 3361f48ca3SMarcello Maggioni // Changing to TargetIndex with some arbitrary values 3461f48ca3SMarcello Maggioni // for index, offset and flags. 3561f48ca3SMarcello Maggioni MO.ChangeToTargetIndex(74, 57, 12); 3661f48ca3SMarcello Maggioni 3761f48ca3SMarcello Maggioni // Checking that the mutation to TargetIndex happened 3861f48ca3SMarcello Maggioni // correctly. 3961f48ca3SMarcello Maggioni ASSERT_TRUE(MO.isTargetIndex()); 4061f48ca3SMarcello Maggioni ASSERT_TRUE(MO.getIndex() == 74); 4161f48ca3SMarcello Maggioni ASSERT_TRUE(MO.getOffset() == 57); 4261f48ca3SMarcello Maggioni ASSERT_TRUE(MO.getTargetFlags() == 12); 4361f48ca3SMarcello Maggioni } 4461f48ca3SMarcello Maggioni 45a8a83d15SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintRegisterMask) { 46a8a83d15SFrancis Visoiu Mistrih uint32_t Dummy; 47a8a83d15SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateRegMask(&Dummy); 48a8a83d15SFrancis Visoiu Mistrih 49a8a83d15SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 50a8a83d15SFrancis Visoiu Mistrih // MachineOperand. 51a8a83d15SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isRegMask()); 52a8a83d15SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getRegMask() == &Dummy); 53a8a83d15SFrancis Visoiu Mistrih 54a8a83d15SFrancis Visoiu Mistrih // Print a MachineOperand containing a RegMask. Here we check that without a 55a8a83d15SFrancis Visoiu Mistrih // TRI and IntrinsicInfo we still print a less detailed regmask. 56a8a83d15SFrancis Visoiu Mistrih std::string str; 57a8a83d15SFrancis Visoiu Mistrih raw_string_ostream OS(str); 58a8a83d15SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 59a8a83d15SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "<regmask ...>"); 60a8a83d15SFrancis Visoiu Mistrih } 61a8a83d15SFrancis Visoiu Mistrih 62a8a83d15SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintSubReg) { 63a8a83d15SFrancis Visoiu Mistrih // Create a MachineOperand with RegNum=1 and SubReg=5. 64a8a83d15SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateReg( 65a8a83d15SFrancis Visoiu Mistrih /*Reg=*/1, /*isDef=*/false, /*isImp=*/false, /*isKill=*/false, 66a8a83d15SFrancis Visoiu Mistrih /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/false, 67a8a83d15SFrancis Visoiu Mistrih /*SubReg=*/5, /*isDebug=*/false, /*isInternalRead=*/false); 68a8a83d15SFrancis Visoiu Mistrih 69a8a83d15SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 70a8a83d15SFrancis Visoiu Mistrih // MachineOperand. 71a8a83d15SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isReg()); 72a8a83d15SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getReg() == 1); 73a8a83d15SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getSubReg() == 5); 74a8a83d15SFrancis Visoiu Mistrih 75a8a83d15SFrancis Visoiu Mistrih // Print a MachineOperand containing a SubReg. Here we check that without a 76a8a83d15SFrancis Visoiu Mistrih // TRI and IntrinsicInfo we can still print the subreg index. 77a8a83d15SFrancis Visoiu Mistrih std::string str; 78a8a83d15SFrancis Visoiu Mistrih raw_string_ostream OS(str); 79a8a83d15SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 80a8a83d15SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "%physreg1.subreg5"); 81a8a83d15SFrancis Visoiu Mistrih } 82a8a83d15SFrancis Visoiu Mistrih 836c4ca713SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintCImm) { 846c4ca713SFrancis Visoiu Mistrih LLVMContext Context; 856c4ca713SFrancis Visoiu Mistrih APInt Int(128, UINT64_MAX); 866c4ca713SFrancis Visoiu Mistrih ++Int; 876c4ca713SFrancis Visoiu Mistrih ConstantInt *CImm = ConstantInt::get(Context, Int); 886c4ca713SFrancis Visoiu Mistrih // Create a MachineOperand with an Imm=(UINT64_MAX + 1) 896c4ca713SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateCImm(CImm); 906c4ca713SFrancis Visoiu Mistrih 916c4ca713SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 926c4ca713SFrancis Visoiu Mistrih // MachineOperand. 936c4ca713SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isCImm()); 946c4ca713SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getCImm() == CImm); 956c4ca713SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getCImm()->getValue() == Int); 966c4ca713SFrancis Visoiu Mistrih 976c4ca713SFrancis Visoiu Mistrih // Print a MachineOperand containing a SubReg. Here we check that without a 986c4ca713SFrancis Visoiu Mistrih // TRI and IntrinsicInfo we can still print the subreg index. 996c4ca713SFrancis Visoiu Mistrih std::string str; 1006c4ca713SFrancis Visoiu Mistrih raw_string_ostream OS(str); 1016c4ca713SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 1026c4ca713SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "i128 18446744073709551616"); 1036c4ca713SFrancis Visoiu Mistrih } 1046c4ca713SFrancis Visoiu Mistrih 105440f69c9SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintSubRegIndex) { 106440f69c9SFrancis Visoiu Mistrih // Create a MachineOperand with an immediate and print it as a subreg index. 107440f69c9SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateImm(3); 108440f69c9SFrancis Visoiu Mistrih 109440f69c9SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 110440f69c9SFrancis Visoiu Mistrih // MachineOperand. 111440f69c9SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isImm()); 112440f69c9SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getImm() == 3); 113440f69c9SFrancis Visoiu Mistrih 114440f69c9SFrancis Visoiu Mistrih // Print a MachineOperand containing a SubRegIdx. Here we check that without a 115440f69c9SFrancis Visoiu Mistrih // TRI and IntrinsicInfo we can print the operand as a subreg index. 116440f69c9SFrancis Visoiu Mistrih std::string str; 117440f69c9SFrancis Visoiu Mistrih raw_string_ostream OS(str); 118440f69c9SFrancis Visoiu Mistrih ModuleSlotTracker DummyMST(nullptr); 119440f69c9SFrancis Visoiu Mistrih MachineOperand::printSubregIdx(OS, MO.getImm(), nullptr); 120440f69c9SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "%subreg.3"); 121440f69c9SFrancis Visoiu Mistrih } 122440f69c9SFrancis Visoiu Mistrih 12326ae8a65SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintCPI) { 12426ae8a65SFrancis Visoiu Mistrih // Create a MachineOperand with a constant pool index and print it. 12526ae8a65SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateCPI(0, 8); 12626ae8a65SFrancis Visoiu Mistrih 12726ae8a65SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 12826ae8a65SFrancis Visoiu Mistrih // MachineOperand. 12926ae8a65SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isCPI()); 13026ae8a65SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getIndex() == 0); 13126ae8a65SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getOffset() == 8); 13226ae8a65SFrancis Visoiu Mistrih 13326ae8a65SFrancis Visoiu Mistrih // Print a MachineOperand containing a constant pool index and a positive 13426ae8a65SFrancis Visoiu Mistrih // offset. 13526ae8a65SFrancis Visoiu Mistrih std::string str; 13626ae8a65SFrancis Visoiu Mistrih { 13726ae8a65SFrancis Visoiu Mistrih raw_string_ostream OS(str); 13826ae8a65SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 13926ae8a65SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "%const.0 + 8"); 14026ae8a65SFrancis Visoiu Mistrih } 14126ae8a65SFrancis Visoiu Mistrih 14226ae8a65SFrancis Visoiu Mistrih str.clear(); 14326ae8a65SFrancis Visoiu Mistrih 14426ae8a65SFrancis Visoiu Mistrih MO.setOffset(-12); 14526ae8a65SFrancis Visoiu Mistrih 14626ae8a65SFrancis Visoiu Mistrih // Print a MachineOperand containing a constant pool index and a negative 14726ae8a65SFrancis Visoiu Mistrih // offset. 14826ae8a65SFrancis Visoiu Mistrih { 14926ae8a65SFrancis Visoiu Mistrih raw_string_ostream OS(str); 15026ae8a65SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 15126ae8a65SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "%const.0 - 12"); 15226ae8a65SFrancis Visoiu Mistrih } 15326ae8a65SFrancis Visoiu Mistrih } 15426ae8a65SFrancis Visoiu Mistrih 155b3a0d513SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintTargetIndexName) { 156b3a0d513SFrancis Visoiu Mistrih // Create a MachineOperand with a target index and print it. 157b3a0d513SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateTargetIndex(0, 8); 158b3a0d513SFrancis Visoiu Mistrih 159b3a0d513SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 160b3a0d513SFrancis Visoiu Mistrih // MachineOperand. 161b3a0d513SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isTargetIndex()); 162b3a0d513SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getIndex() == 0); 163b3a0d513SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getOffset() == 8); 164b3a0d513SFrancis Visoiu Mistrih 165b3a0d513SFrancis Visoiu Mistrih // Print a MachineOperand containing a target index and a positive offset. 166b3a0d513SFrancis Visoiu Mistrih std::string str; 167b3a0d513SFrancis Visoiu Mistrih { 168b3a0d513SFrancis Visoiu Mistrih raw_string_ostream OS(str); 169b3a0d513SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 170b3a0d513SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "target-index(<unknown>) + 8"); 171b3a0d513SFrancis Visoiu Mistrih } 172b3a0d513SFrancis Visoiu Mistrih 173b3a0d513SFrancis Visoiu Mistrih str.clear(); 174b3a0d513SFrancis Visoiu Mistrih 175b3a0d513SFrancis Visoiu Mistrih MO.setOffset(-12); 176b3a0d513SFrancis Visoiu Mistrih 177b3a0d513SFrancis Visoiu Mistrih // Print a MachineOperand containing a target index and a negative offset. 178b3a0d513SFrancis Visoiu Mistrih { 179b3a0d513SFrancis Visoiu Mistrih raw_string_ostream OS(str); 180b3a0d513SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 181b3a0d513SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "target-index(<unknown>) - 12"); 182b3a0d513SFrancis Visoiu Mistrih } 183b3a0d513SFrancis Visoiu Mistrih } 184b3a0d513SFrancis Visoiu Mistrih 185b41dbbe3SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintJumpTableIndex) { 186b41dbbe3SFrancis Visoiu Mistrih // Create a MachineOperand with a jump-table index and print it. 187b41dbbe3SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateJTI(3); 188b41dbbe3SFrancis Visoiu Mistrih 189b41dbbe3SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 190b41dbbe3SFrancis Visoiu Mistrih // MachineOperand. 191b41dbbe3SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isJTI()); 192b41dbbe3SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getIndex() == 3); 193b41dbbe3SFrancis Visoiu Mistrih 194b41dbbe3SFrancis Visoiu Mistrih // Print a MachineOperand containing a jump-table index. 195b41dbbe3SFrancis Visoiu Mistrih std::string str; 196b41dbbe3SFrancis Visoiu Mistrih raw_string_ostream OS(str); 197b41dbbe3SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 198b41dbbe3SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "%jump-table.3"); 199b41dbbe3SFrancis Visoiu Mistrih } 200b41dbbe3SFrancis Visoiu Mistrih 201e76c5fcdSFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintExternalSymbol) { 202e76c5fcdSFrancis Visoiu Mistrih // Create a MachineOperand with an external symbol and print it. 203e76c5fcdSFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateES("foo"); 204e76c5fcdSFrancis Visoiu Mistrih 205e76c5fcdSFrancis Visoiu Mistrih // Checking some preconditions on the newly created 206e76c5fcdSFrancis Visoiu Mistrih // MachineOperand. 207e76c5fcdSFrancis Visoiu Mistrih ASSERT_TRUE(MO.isSymbol()); 208e76c5fcdSFrancis Visoiu Mistrih ASSERT_TRUE(MO.getSymbolName() == StringRef("foo")); 209e76c5fcdSFrancis Visoiu Mistrih 210e76c5fcdSFrancis Visoiu Mistrih // Print a MachineOperand containing an external symbol and no offset. 211e76c5fcdSFrancis Visoiu Mistrih std::string str; 212e76c5fcdSFrancis Visoiu Mistrih { 213e76c5fcdSFrancis Visoiu Mistrih raw_string_ostream OS(str); 214e76c5fcdSFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 215e76c5fcdSFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "$foo"); 216e76c5fcdSFrancis Visoiu Mistrih } 217e76c5fcdSFrancis Visoiu Mistrih 218e76c5fcdSFrancis Visoiu Mistrih str.clear(); 219e76c5fcdSFrancis Visoiu Mistrih MO.setOffset(12); 220e76c5fcdSFrancis Visoiu Mistrih 221e76c5fcdSFrancis Visoiu Mistrih // Print a MachineOperand containing an external symbol and a positive offset. 222e76c5fcdSFrancis Visoiu Mistrih { 223e76c5fcdSFrancis Visoiu Mistrih raw_string_ostream OS(str); 224e76c5fcdSFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 225e76c5fcdSFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "$foo + 12"); 226e76c5fcdSFrancis Visoiu Mistrih } 227e76c5fcdSFrancis Visoiu Mistrih 228e76c5fcdSFrancis Visoiu Mistrih str.clear(); 229e76c5fcdSFrancis Visoiu Mistrih MO.setOffset(-12); 230e76c5fcdSFrancis Visoiu Mistrih 231e76c5fcdSFrancis Visoiu Mistrih // Print a MachineOperand containing an external symbol and a negative offset. 232e76c5fcdSFrancis Visoiu Mistrih { 233e76c5fcdSFrancis Visoiu Mistrih raw_string_ostream OS(str); 234e76c5fcdSFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 235e76c5fcdSFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "$foo - 12"); 236e76c5fcdSFrancis Visoiu Mistrih } 237e76c5fcdSFrancis Visoiu Mistrih } 238e76c5fcdSFrancis Visoiu Mistrih 239*5df3bbf3SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintGlobalAddress) { 240*5df3bbf3SFrancis Visoiu Mistrih LLVMContext Ctx; 241*5df3bbf3SFrancis Visoiu Mistrih Module M("MachineOperandGVTest", Ctx); 242*5df3bbf3SFrancis Visoiu Mistrih M.getOrInsertGlobal("foo", Type::getInt32Ty(Ctx)); 243*5df3bbf3SFrancis Visoiu Mistrih 244*5df3bbf3SFrancis Visoiu Mistrih GlobalValue *GV = M.getNamedValue("foo"); 245*5df3bbf3SFrancis Visoiu Mistrih 246*5df3bbf3SFrancis Visoiu Mistrih // Create a MachineOperand with a global address and a positive offset and 247*5df3bbf3SFrancis Visoiu Mistrih // print it. 248*5df3bbf3SFrancis Visoiu Mistrih MachineOperand MO = MachineOperand::CreateGA(GV, 12); 249*5df3bbf3SFrancis Visoiu Mistrih 250*5df3bbf3SFrancis Visoiu Mistrih // Checking some preconditions on the newly created 251*5df3bbf3SFrancis Visoiu Mistrih // MachineOperand. 252*5df3bbf3SFrancis Visoiu Mistrih ASSERT_TRUE(MO.isGlobal()); 253*5df3bbf3SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getGlobal() == GV); 254*5df3bbf3SFrancis Visoiu Mistrih ASSERT_TRUE(MO.getOffset() == 12); 255*5df3bbf3SFrancis Visoiu Mistrih 256*5df3bbf3SFrancis Visoiu Mistrih std::string str; 257*5df3bbf3SFrancis Visoiu Mistrih // Print a MachineOperand containing a global address and a positive offset. 258*5df3bbf3SFrancis Visoiu Mistrih { 259*5df3bbf3SFrancis Visoiu Mistrih raw_string_ostream OS(str); 260*5df3bbf3SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 261*5df3bbf3SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "@foo + 12"); 262*5df3bbf3SFrancis Visoiu Mistrih } 263*5df3bbf3SFrancis Visoiu Mistrih 264*5df3bbf3SFrancis Visoiu Mistrih str.clear(); 265*5df3bbf3SFrancis Visoiu Mistrih MO.setOffset(-12); 266*5df3bbf3SFrancis Visoiu Mistrih 267*5df3bbf3SFrancis Visoiu Mistrih // Print a MachineOperand containing a global address and a negative offset. 268*5df3bbf3SFrancis Visoiu Mistrih { 269*5df3bbf3SFrancis Visoiu Mistrih raw_string_ostream OS(str); 270*5df3bbf3SFrancis Visoiu Mistrih MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 271*5df3bbf3SFrancis Visoiu Mistrih ASSERT_TRUE(OS.str() == "@foo - 12"); 272*5df3bbf3SFrancis Visoiu Mistrih } 273*5df3bbf3SFrancis Visoiu Mistrih } 274*5df3bbf3SFrancis Visoiu Mistrih 27561f48ca3SMarcello Maggioni } // end namespace 276