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/ADT/ilist_node.h"
1161f48ca3SMarcello Maggioni #include "llvm/CodeGen/MachineOperand.h"
126c4ca713SFrancis Visoiu Mistrih #include "llvm/IR/Constants.h"
136c4ca713SFrancis Visoiu Mistrih #include "llvm/IR/LLVMContext.h"
14440f69c9SFrancis Visoiu Mistrih #include "llvm/IR/ModuleSlotTracker.h"
15a8a83d15SFrancis Visoiu Mistrih #include "llvm/Support/raw_ostream.h"
1661f48ca3SMarcello Maggioni #include "gtest/gtest.h"
1761f48ca3SMarcello Maggioni 
1861f48ca3SMarcello Maggioni using namespace llvm;
1961f48ca3SMarcello Maggioni 
2061f48ca3SMarcello Maggioni namespace {
2161f48ca3SMarcello Maggioni 
2261f48ca3SMarcello Maggioni TEST(MachineOperandTest, ChangeToTargetIndexTest) {
2361f48ca3SMarcello Maggioni   // Creating a MachineOperand to change it to TargetIndex
2461f48ca3SMarcello Maggioni   MachineOperand MO = MachineOperand::CreateImm(50);
2561f48ca3SMarcello Maggioni 
2661f48ca3SMarcello Maggioni   // Checking some precondition on the newly created
2761f48ca3SMarcello Maggioni   // MachineOperand.
2861f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.isImm());
2961f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getImm() == 50);
3061f48ca3SMarcello Maggioni   ASSERT_FALSE(MO.isTargetIndex());
3161f48ca3SMarcello Maggioni 
3261f48ca3SMarcello Maggioni   // Changing to TargetIndex with some arbitrary values
3361f48ca3SMarcello Maggioni   // for index, offset and flags.
3461f48ca3SMarcello Maggioni   MO.ChangeToTargetIndex(74, 57, 12);
3561f48ca3SMarcello Maggioni 
3661f48ca3SMarcello Maggioni   // Checking that the mutation to TargetIndex happened
3761f48ca3SMarcello Maggioni   // correctly.
3861f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.isTargetIndex());
3961f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getIndex() == 74);
4061f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getOffset() == 57);
4161f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getTargetFlags() == 12);
4261f48ca3SMarcello Maggioni }
4361f48ca3SMarcello Maggioni 
44a8a83d15SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintRegisterMask) {
45a8a83d15SFrancis Visoiu Mistrih   uint32_t Dummy;
46a8a83d15SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateRegMask(&Dummy);
47a8a83d15SFrancis Visoiu Mistrih 
48a8a83d15SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
49a8a83d15SFrancis Visoiu Mistrih   // MachineOperand.
50a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isRegMask());
51a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getRegMask() == &Dummy);
52a8a83d15SFrancis Visoiu Mistrih 
53a8a83d15SFrancis Visoiu Mistrih   // Print a MachineOperand containing a RegMask. Here we check that without a
54a8a83d15SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we still print a less detailed regmask.
55a8a83d15SFrancis Visoiu Mistrih   std::string str;
56a8a83d15SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
57a8a83d15SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
58a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "<regmask ...>");
59a8a83d15SFrancis Visoiu Mistrih }
60a8a83d15SFrancis Visoiu Mistrih 
61a8a83d15SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintSubReg) {
62a8a83d15SFrancis Visoiu Mistrih   // Create a MachineOperand with RegNum=1 and SubReg=5.
63a8a83d15SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateReg(
64a8a83d15SFrancis Visoiu Mistrih       /*Reg=*/1, /*isDef=*/false, /*isImp=*/false, /*isKill=*/false,
65a8a83d15SFrancis Visoiu Mistrih       /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/false,
66a8a83d15SFrancis Visoiu Mistrih       /*SubReg=*/5, /*isDebug=*/false, /*isInternalRead=*/false);
67a8a83d15SFrancis Visoiu Mistrih 
68a8a83d15SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
69a8a83d15SFrancis Visoiu Mistrih   // MachineOperand.
70a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isReg());
71a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getReg() == 1);
72a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getSubReg() == 5);
73a8a83d15SFrancis Visoiu Mistrih 
74a8a83d15SFrancis Visoiu Mistrih   // Print a MachineOperand containing a SubReg. Here we check that without a
75a8a83d15SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we can still print the subreg index.
76a8a83d15SFrancis Visoiu Mistrih   std::string str;
77a8a83d15SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
78a8a83d15SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
79a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "%physreg1.subreg5");
80a8a83d15SFrancis Visoiu Mistrih }
81a8a83d15SFrancis Visoiu Mistrih 
826c4ca713SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintCImm) {
836c4ca713SFrancis Visoiu Mistrih   LLVMContext Context;
846c4ca713SFrancis Visoiu Mistrih   APInt Int(128, UINT64_MAX);
856c4ca713SFrancis Visoiu Mistrih   ++Int;
866c4ca713SFrancis Visoiu Mistrih   ConstantInt *CImm = ConstantInt::get(Context, Int);
876c4ca713SFrancis Visoiu Mistrih   // Create a MachineOperand with an Imm=(UINT64_MAX + 1)
886c4ca713SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateCImm(CImm);
896c4ca713SFrancis Visoiu Mistrih 
906c4ca713SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
916c4ca713SFrancis Visoiu Mistrih   // MachineOperand.
926c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isCImm());
936c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getCImm() == CImm);
946c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getCImm()->getValue() == Int);
956c4ca713SFrancis Visoiu Mistrih 
966c4ca713SFrancis Visoiu Mistrih   // Print a MachineOperand containing a SubReg. Here we check that without a
976c4ca713SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we can still print the subreg index.
986c4ca713SFrancis Visoiu Mistrih   std::string str;
996c4ca713SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
1006c4ca713SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
1016c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "i128 18446744073709551616");
1026c4ca713SFrancis Visoiu Mistrih }
1036c4ca713SFrancis Visoiu Mistrih 
104440f69c9SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintSubRegIndex) {
105440f69c9SFrancis Visoiu Mistrih   // Create a MachineOperand with an immediate and print it as a subreg index.
106440f69c9SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateImm(3);
107440f69c9SFrancis Visoiu Mistrih 
108440f69c9SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
109440f69c9SFrancis Visoiu Mistrih   // MachineOperand.
110440f69c9SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isImm());
111440f69c9SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getImm() == 3);
112440f69c9SFrancis Visoiu Mistrih 
113440f69c9SFrancis Visoiu Mistrih   // Print a MachineOperand containing a SubRegIdx. Here we check that without a
114440f69c9SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we can print the operand as a subreg index.
115440f69c9SFrancis Visoiu Mistrih   std::string str;
116440f69c9SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
117440f69c9SFrancis Visoiu Mistrih   ModuleSlotTracker DummyMST(nullptr);
118440f69c9SFrancis Visoiu Mistrih   MachineOperand::printSubregIdx(OS, MO.getImm(), nullptr);
119440f69c9SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "%subreg.3");
120440f69c9SFrancis Visoiu Mistrih }
121440f69c9SFrancis Visoiu Mistrih 
122*26ae8a65SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintCPI) {
123*26ae8a65SFrancis Visoiu Mistrih   // Create a MachineOperand with a constant pool index and print it.
124*26ae8a65SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateCPI(0, 8);
125*26ae8a65SFrancis Visoiu Mistrih 
126*26ae8a65SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
127*26ae8a65SFrancis Visoiu Mistrih   // MachineOperand.
128*26ae8a65SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isCPI());
129*26ae8a65SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getIndex() == 0);
130*26ae8a65SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getOffset() == 8);
131*26ae8a65SFrancis Visoiu Mistrih 
132*26ae8a65SFrancis Visoiu Mistrih   // Print a MachineOperand containing a constant pool index and a positive
133*26ae8a65SFrancis Visoiu Mistrih   // offset.
134*26ae8a65SFrancis Visoiu Mistrih   std::string str;
135*26ae8a65SFrancis Visoiu Mistrih   {
136*26ae8a65SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
137*26ae8a65SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
138*26ae8a65SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "%const.0 + 8");
139*26ae8a65SFrancis Visoiu Mistrih   }
140*26ae8a65SFrancis Visoiu Mistrih 
141*26ae8a65SFrancis Visoiu Mistrih   str.clear();
142*26ae8a65SFrancis Visoiu Mistrih 
143*26ae8a65SFrancis Visoiu Mistrih   MO.setOffset(-12);
144*26ae8a65SFrancis Visoiu Mistrih 
145*26ae8a65SFrancis Visoiu Mistrih   // Print a MachineOperand containing a constant pool index and a negative
146*26ae8a65SFrancis Visoiu Mistrih   // offset.
147*26ae8a65SFrancis Visoiu Mistrih   {
148*26ae8a65SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
149*26ae8a65SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
150*26ae8a65SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "%const.0 - 12");
151*26ae8a65SFrancis Visoiu Mistrih   }
152*26ae8a65SFrancis Visoiu Mistrih }
153*26ae8a65SFrancis Visoiu Mistrih 
15461f48ca3SMarcello Maggioni } // end namespace
155