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