xref: /llvm-project/llvm/lib/CodeGen/MachineInstr.cpp (revision 5f72f42aee9092c83d91d1ac7d62dac27c0adb81)
1 // $Id$
2 //***************************************************************************
3 // File:
4 //	MachineInstr.cpp
5 //
6 // Purpose:
7 //
8 //
9 // Strategy:
10 //
11 // History:
12 //	7/2/01	 -  Vikram Adve  -  Created
13 //**************************************************************************/
14 
15 
16 //************************** System Include Files ***************************/
17 
18 #include <strstream>
19 
20 
21 //*************************** User Include Files ***************************/
22 
23 #include "llvm/Method.h"
24 #include "llvm/ConstPoolVals.h"
25 #include "llvm/Instruction.h"
26 #include "llvm/CodeGen/MachineInstr.h"
27 
28 
29 //************************ Class Implementations **************************/
30 
31 // Constructor for instructions with fixed #operands (nearly all)
32 MachineInstr::MachineInstr(MachineOpCode _opCode,
33 			   OpCodeMask    _opCodeMask)
34   : opCode(_opCode),
35     opCodeMask(_opCodeMask),
36     operands(TargetInstrDescriptors[_opCode].numOperands)
37 {
38   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
39 }
40 
41 // Constructor for instructions with variable #operands
42 MachineInstr::MachineInstr(MachineOpCode _opCode,
43 			   unsigned	 numOperands,
44 			   OpCodeMask    _opCodeMask)
45   : opCode(_opCode),
46     opCodeMask(_opCodeMask),
47     operands(numOperands)
48 {
49 }
50 
51 void
52 MachineInstr::SetMachineOperand(unsigned int i,
53 				MachineOperand::MachineOperandType operandType,
54 				Value* _val, bool isdef=false)
55 {
56   assert(i < operands.size());
57   operands[i].Initialize(operandType, _val);
58   operands[i].isDef = isdef ||
59 		      TargetInstrDescriptors[opCode].resultPos == (int) i;
60 }
61 
62 void
63 MachineInstr::SetMachineOperand(unsigned int i,
64 				MachineOperand::MachineOperandType operandType,
65 				int64_t intValue, bool isdef=false)
66 {
67   assert(i < operands.size());
68   operands[i].InitializeConst(operandType, intValue);
69   operands[i].isDef = isdef ||
70 		      TargetInstrDescriptors[opCode].resultPos == (int) i;
71 }
72 
73 void
74 MachineInstr::SetMachineOperand(unsigned int i,
75 				unsigned int regNum, bool isdef=false)
76 {
77   assert(i < operands.size());
78   operands[i].InitializeReg(regNum);
79   operands[i].isDef = isdef ||
80 		      TargetInstrDescriptors[opCode].resultPos == (int) i;
81 }
82 
83 void
84 MachineInstr::dump(unsigned int indent) const
85 {
86   for (unsigned i=0; i < indent; i++)
87     cout << "    ";
88 
89   cout << *this;
90 }
91 
92 ostream&
93 operator<< (ostream& os, const MachineInstr& minstr)
94 {
95   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
96 
97   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
98     os << "\t" << minstr.getOperand(i);
99 
100 #undef DEBUG_VAL_OP_ITERATOR
101 #ifdef DEBUG_VAL_OP_ITERATOR
102   os << endl << "\tValue operands are: ";
103   for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
104     {
105       const Value* val = *vo;
106       os << val << (vo.isDef()? "(def), " : ", ");
107     }
108   os << endl;
109 #endif
110 
111   return os;
112 }
113 
114 ostream&
115 operator<< (ostream& os, const MachineOperand& mop)
116 {
117   strstream regInfo;
118   if (mop.opType == MachineOperand::MO_VirtualRegister)
119     regInfo << "(val " << mop.value << ")" << ends;
120   else if (mop.opType == MachineOperand::MO_MachineRegister)
121     regInfo << "("       << mop.regNum << ")" << ends;
122   else if (mop.opType == MachineOperand::MO_CCRegister)
123     regInfo << "(val " << mop.value << ")" << ends;
124 
125   switch(mop.opType)
126     {
127     case MachineOperand::MO_VirtualRegister:
128     case MachineOperand::MO_MachineRegister:
129       os << "%reg" << regInfo.str();
130       free(regInfo.str());
131       break;
132 
133     case MachineOperand::MO_CCRegister:
134       os << "%ccreg" << regInfo.str();
135       free(regInfo.str());
136       break;
137 
138     case MachineOperand::MO_SignExtendedImmed:
139       os << mop.immedVal;
140       break;
141 
142     case MachineOperand::MO_UnextendedImmed:
143       os << mop.immedVal;
144       break;
145 
146     case MachineOperand::MO_PCRelativeDisp:
147       os << "%disp(label " << mop.value << ")";
148       break;
149 
150     default:
151       assert(0 && "Unrecognized operand type");
152       break;
153     }
154 
155   return os;
156 }
157 
158 
159 //---------------------------------------------------------------------------
160 // Target-independent utility routines for creating machine instructions
161 //---------------------------------------------------------------------------
162 
163 
164 //------------------------------------------------------------------------
165 // Function Set2OperandsFromInstr
166 // Function Set3OperandsFromInstr
167 //
168 // For the common case of 2- and 3-operand arithmetic/logical instructions,
169 // set the m/c instr. operands directly from the VM instruction's operands.
170 // Check whether the first or second operand is 0 and can use a dedicated "0" register.
171 // Check whether the second operand should use an immediate field or register.
172 // (First and third operands are never immediates for such instructions.)
173 //
174 // Arguments:
175 // canDiscardResult: Specifies that the result operand can be discarded
176 //		     by using the dedicated "0"
177 //
178 // op1position, op2position and resultPosition: Specify in which position
179 //		     in the machine instruction the 3 operands (arg1, arg2
180 //		     and result) should go.
181 //
182 // RETURN VALUE: unsigned int flags, where
183 //	flags & 0x01	=> operand 1 is constant and needs a register
184 //	flags & 0x02	=> operand 2 is constant and needs a register
185 //------------------------------------------------------------------------
186 
187 void
188 Set2OperandsFromInstr(MachineInstr* minstr,
189 		      InstructionNode* vmInstrNode,
190 		      const TargetMachine& target,
191 		      bool canDiscardResult,
192 		      int op1Position,
193 		      int resultPosition)
194 {
195   Set3OperandsFromInstr(minstr, vmInstrNode, target,
196 			canDiscardResult, op1Position,
197 			/*op2Position*/ -1, resultPosition);
198 }
199 
200 #undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
201 #ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
202 unsigned
203 Set3OperandsFromInstrJUNK(MachineInstr* minstr,
204 		      InstructionNode* vmInstrNode,
205 		      const TargetMachine& target,
206 		      bool canDiscardResult,
207 		      int op1Position,
208 		      int op2Position,
209 		      int resultPosition)
210 {
211   assert(op1Position >= 0);
212   assert(resultPosition >= 0);
213 
214   unsigned returnFlags = 0x0;
215 
216   // Check if operand 1 is 0.  If so, try to use a hardwired 0 register.
217   Value* op1Value = vmInstrNode->leftChild()->getValue();
218   bool isValidConstant;
219   int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
220   if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
221     minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
222   else
223     {
224       if (op1Value->getValueType() == Value::ConstantVal)
225 	{// value is constant and must be loaded from constant pool
226 	  returnFlags = returnFlags | (1 << op1Position);
227 	}
228       minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
229 					    op1Value);
230     }
231 
232   // Check if operand 2 (if any) fits in the immed. field of the instruction,
233   // or if it is 0 and can use a dedicated machine register
234   if (op2Position >= 0)
235     {
236       Value* op2Value = vmInstrNode->rightChild()->getValue();
237       int64_t immedValue;
238       unsigned int machineRegNum;
239 
240       MachineOperand::MachineOperandType
241 	op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
242 				   /*canUseImmed*/ true,
243 				   machineRegNum, immedValue);
244 
245       if (op2type == MachineOperand::MO_MachineRegister)
246 	minstr->SetMachineOperand(op2Position, machineRegNum);
247       else if (op2type == MachineOperand::MO_VirtualRegister)
248 	{
249 	  if (op2Value->getValueType() == Value::ConstantVal)
250 	    {// value is constant and must be loaded from constant pool
251 	      returnFlags = returnFlags | (1 << op2Position);
252 	    }
253 	  minstr->SetMachineOperand(op2Position, op2type, op2Value);
254 	}
255       else
256 	{
257 	  assert(op2type != MO_CCRegister);
258 	  minstr->SetMachineOperand(op2Position, op2type, immedValue);
259 	}
260     }
261 
262   // If operand 3 (result) can be discarded, use a dead register if one exists
263   if (canDiscardResult && target.zeroRegNum >= 0)
264     minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
265   else
266     minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
267 
268   return returnFlags;
269 }
270 #endif
271 
272 
273 void
274 Set3OperandsFromInstr(MachineInstr* minstr,
275 		      InstructionNode* vmInstrNode,
276 		      const TargetMachine& target,
277 		      bool canDiscardResult,
278 		      int op1Position,
279 		      int op2Position,
280 		      int resultPosition)
281 {
282   assert(op1Position >= 0);
283   assert(resultPosition >= 0);
284 
285   // operand 1
286   minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
287 			    vmInstrNode->leftChild()->getValue());
288 
289   // operand 2 (if any)
290   if (op2Position >= 0)
291     minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
292 			      vmInstrNode->rightChild()->getValue());
293 
294   // result operand: if it can be discarded, use a dead register if one exists
295   if (canDiscardResult && target.zeroRegNum >= 0)
296     minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
297   else
298     minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
299 }
300 
301 
302 MachineOperand::MachineOperandType
303 ChooseRegOrImmed(Value* val,
304 		 MachineOpCode opCode,
305 		 const TargetMachine& target,
306 		 bool canUseImmed,
307 		 unsigned int& getMachineRegNum,
308 		 int64_t& getImmedValue)
309 {
310   MachineOperand::MachineOperandType opType =
311     MachineOperand::MO_VirtualRegister;
312   getMachineRegNum = 0;
313   getImmedValue = 0;
314 
315   // Check for the common case first: argument is not constant
316   //
317   if (val->getValueType() != Value::ConstantVal)
318     return opType;
319 
320   // Now get the constant value and check if it fits in the IMMED field.
321   // Take advantage of the fact that the max unsigned value will rarely
322   // fit into any IMMED field and ignore that case (i.e., cast smaller
323   // unsigned constants to signed).
324   //
325   bool isValidConstant;
326   int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);
327 
328   if (isValidConstant)
329     {
330       if (intValue == 0 && target.zeroRegNum >= 0)
331 	{
332 	  opType = MachineOperand::MO_MachineRegister;
333 	  getMachineRegNum = target.zeroRegNum;
334 	}
335       else if (canUseImmed &&
336 	       target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
337 	{
338 	  opType = MachineOperand::MO_SignExtendedImmed;
339 	  getImmedValue = intValue;
340 	}
341     }
342 
343   return opType;
344 }
345 
346 
347 void
348 PrintMachineInstructions(Method* method)
349 {
350   cout << "\n" << method->getReturnType()
351        << " \"" << method->getName() << "\"" << endl;
352 
353   for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
354     {
355       BasicBlock* bb = *BI;
356       cout << "\n"
357 	   << (bb->hasName()? bb->getName() : "Label")
358 	   << " (" << bb << ")" << ":"
359 	   << endl;
360 
361       MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
362       for (unsigned i=0; i < mvec.size(); i++)
363 	cout << "\t" << *mvec[i] << endl;
364     }
365   cout << endl << "End method \"" << method->getName() << "\""
366        << endl << endl;
367 }
368