blob: d636d3af963a5d346983f53645c93d08375e74ab [file] [log] [blame]
Vikram S. Adveab9e5572001-07-21 12:41:50 +00001// $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
Vikram S. Adve5f72f422001-08-28 23:02:39 +000015
16//************************** System Include Files ***************************/
17
18#include <strstream>
19
20
21//*************************** User Include Files ***************************/
22
23#include "llvm/Method.h"
Chris Lattnerb2990682001-07-21 23:24:48 +000024#include "llvm/ConstPoolVals.h"
25#include "llvm/Instruction.h"
Vikram S. Adve5f72f422001-08-28 23:02:39 +000026#include "llvm/CodeGen/MachineInstr.h"
27
Vikram S. Adveab9e5572001-07-21 12:41:50 +000028
29//************************ Class Implementations **************************/
30
Vikram S. Adveff7070b2001-07-31 21:49:28 +000031// Constructor for instructions with fixed #operands (nearly all)
Vikram S. Adveab9e5572001-07-21 12:41:50 +000032MachineInstr::MachineInstr(MachineOpCode _opCode,
33 OpCodeMask _opCodeMask)
34 : opCode(_opCode),
35 opCodeMask(_opCodeMask),
Vikram S. Advebff682d2001-07-28 04:06:37 +000036 operands(TargetInstrDescriptors[_opCode].numOperands)
Vikram S. Adveab9e5572001-07-21 12:41:50 +000037{
Vikram S. Adveff7070b2001-07-31 21:49:28 +000038 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
39}
40
41// Constructor for instructions with variable #operands
42MachineInstr::MachineInstr(MachineOpCode _opCode,
43 unsigned numOperands,
44 OpCodeMask _opCodeMask)
45 : opCode(_opCode),
46 opCodeMask(_opCodeMask),
47 operands(numOperands)
48{
Vikram S. Adveab9e5572001-07-21 12:41:50 +000049}
50
Vikram S. Adveab9e5572001-07-21 12:41:50 +000051void
52MachineInstr::SetMachineOperand(unsigned int i,
53 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka4ac29752001-08-07 20:16:52 +000054 Value* _val, bool isdef=false)
Vikram S. Adveab9e5572001-07-21 12:41:50 +000055{
Vikram S. Advebff682d2001-07-28 04:06:37 +000056 assert(i < operands.size());
Vikram S. Adveab9e5572001-07-21 12:41:50 +000057 operands[i].Initialize(operandType, _val);
Vikram S. Adve17000682001-08-13 16:32:45 +000058 operands[i].isDef = isdef ||
59 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adveab9e5572001-07-21 12:41:50 +000060}
61
62void
63MachineInstr::SetMachineOperand(unsigned int i,
64 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka4ac29752001-08-07 20:16:52 +000065 int64_t intValue, bool isdef=false)
Vikram S. Adveab9e5572001-07-21 12:41:50 +000066{
Vikram S. Advebff682d2001-07-28 04:06:37 +000067 assert(i < operands.size());
Vikram S. Adveab9e5572001-07-21 12:41:50 +000068 operands[i].InitializeConst(operandType, intValue);
Vikram S. Adve17000682001-08-13 16:32:45 +000069 operands[i].isDef = isdef ||
70 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adveab9e5572001-07-21 12:41:50 +000071}
72
73void
74MachineInstr::SetMachineOperand(unsigned int i,
Ruchira Sasanka4ac29752001-08-07 20:16:52 +000075 unsigned int regNum, bool isdef=false)
Vikram S. Adveab9e5572001-07-21 12:41:50 +000076{
Vikram S. Advebff682d2001-07-28 04:06:37 +000077 assert(i < operands.size());
Vikram S. Adveab9e5572001-07-21 12:41:50 +000078 operands[i].InitializeReg(regNum);
Vikram S. Adve17000682001-08-13 16:32:45 +000079 operands[i].isDef = isdef ||
80 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adveab9e5572001-07-21 12:41:50 +000081}
82
83void
Ruchira Sasankac82322c2001-08-07 21:01:23 +000084MachineInstr::dump(unsigned int indent) const
Vikram S. Adveab9e5572001-07-21 12:41:50 +000085{
86 for (unsigned i=0; i < indent; i++)
87 cout << " ";
88
89 cout << *this;
90}
91
92ostream&
93operator<< (ostream& os, const MachineInstr& minstr)
94{
Vikram S. Advebff682d2001-07-28 04:06:37 +000095 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adveab9e5572001-07-21 12:41:50 +000096
97 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
98 os << "\t" << minstr.getOperand(i);
99
Vikram S. Advebff682d2001-07-28 04:06:37 +0000100#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
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000111 return os;
112}
113
114ostream&
115operator<< (ostream& os, const MachineOperand& mop)
116{
117 strstream regInfo;
Vikram S. Advebff682d2001-07-28 04:06:37 +0000118 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)
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000123 regInfo << "(val " << mop.value << ")" << ends;
124
Vikram S. Advebff682d2001-07-28 04:06:37 +0000125 switch(mop.opType)
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000126 {
Vikram S. Advebff682d2001-07-28 04:06:37 +0000127 case MachineOperand::MO_VirtualRegister:
128 case MachineOperand::MO_MachineRegister:
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000129 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
187void
188Set2OperandsFromInstr(MachineInstr* minstr,
189 InstructionNode* vmInstrNode,
Vikram S. Advebff682d2001-07-28 04:06:37 +0000190 const TargetMachine& target,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000191 bool canDiscardResult,
192 int op1Position,
193 int resultPosition)
194{
Vikram S. Advebff682d2001-07-28 04:06:37 +0000195 Set3OperandsFromInstr(minstr, vmInstrNode, target,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000196 canDiscardResult, op1Position,
197 /*op2Position*/ -1, resultPosition);
198}
199
Vikram S. Advebff682d2001-07-28 04:06:37 +0000200#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
201#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000202unsigned
203Set3OperandsFromInstrJUNK(MachineInstr* minstr,
204 InstructionNode* vmInstrNode,
Vikram S. Advebff682d2001-07-28 04:06:37 +0000205 const TargetMachine& target,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000206 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
Vikram S. Adve5f72f422001-08-28 23:02:39 +0000216 // Check if operand 1 is 0. If so, try to use a hardwired 0 register.
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000217 Value* op1Value = vmInstrNode->leftChild()->getValue();
218 bool isValidConstant;
219 int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
Vikram S. Advebff682d2001-07-28 04:06:37 +0000220 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
221 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000222 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 }
Vikram S. Advebff682d2001-07-28 04:06:37 +0000228 minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
229 op1Value);
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000230 }
231
Vikram S. Adve5f72f422001-08-28 23:02:39 +0000232 // 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
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000234 if (op2Position >= 0)
235 {
236 Value* op2Value = vmInstrNode->rightChild()->getValue();
237 int64_t immedValue;
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000238 unsigned int machineRegNum;
239
240 MachineOperand::MachineOperandType
Vikram S. Advebff682d2001-07-28 04:06:37 +0000241 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000242 /*canUseImmed*/ true,
Vikram S. Advebff682d2001-07-28 04:06:37 +0000243 machineRegNum, immedValue);
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000244
Vikram S. Advebff682d2001-07-28 04:06:37 +0000245 if (op2type == MachineOperand::MO_MachineRegister)
246 minstr->SetMachineOperand(op2Position, machineRegNum);
247 else if (op2type == MachineOperand::MO_VirtualRegister)
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000248 {
Vikram S. Advebff682d2001-07-28 04:06:37 +0000249 if (op2Value->getValueType() == Value::ConstantVal)
250 {// value is constant and must be loaded from constant pool
251 returnFlags = returnFlags | (1 << op2Position);
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000252 }
Vikram S. Advebff682d2001-07-28 04:06:37 +0000253 minstr->SetMachineOperand(op2Position, op2type, op2Value);
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000254 }
255 else
Vikram S. Advebff682d2001-07-28 04:06:37 +0000256 {
257 assert(op2type != MO_CCRegister);
258 minstr->SetMachineOperand(op2Position, op2type, immedValue);
259 }
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000260 }
261
262 // If operand 3 (result) can be discarded, use a dead register if one exists
Vikram S. Advebff682d2001-07-28 04:06:37 +0000263 if (canDiscardResult && target.zeroRegNum >= 0)
Vikram S. Adve17000682001-08-13 16:32:45 +0000264 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000265 else
Vikram S. Adve17000682001-08-13 16:32:45 +0000266 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000267
268 return returnFlags;
269}
Vikram S. Advebff682d2001-07-28 04:06:37 +0000270#endif
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000271
272
273void
274Set3OperandsFromInstr(MachineInstr* minstr,
275 InstructionNode* vmInstrNode,
Vikram S. Advebff682d2001-07-28 04:06:37 +0000276 const TargetMachine& target,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000277 bool canDiscardResult,
278 int op1Position,
279 int op2Position,
280 int resultPosition)
281{
282 assert(op1Position >= 0);
283 assert(resultPosition >= 0);
284
285 // operand 1
Vikram S. Advebff682d2001-07-28 04:06:37 +0000286 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000287 vmInstrNode->leftChild()->getValue());
288
289 // operand 2 (if any)
290 if (op2Position >= 0)
Vikram S. Advebff682d2001-07-28 04:06:37 +0000291 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000292 vmInstrNode->rightChild()->getValue());
293
294 // result operand: if it can be discarded, use a dead register if one exists
Vikram S. Advebff682d2001-07-28 04:06:37 +0000295 if (canDiscardResult && target.zeroRegNum >= 0)
Vikram S. Adve17000682001-08-13 16:32:45 +0000296 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000297 else
Vikram S. Adve17000682001-08-13 16:32:45 +0000298 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000299}
300
301
302MachineOperand::MachineOperandType
303ChooseRegOrImmed(Value* val,
304 MachineOpCode opCode,
Vikram S. Advebff682d2001-07-28 04:06:37 +0000305 const TargetMachine& target,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000306 bool canUseImmed,
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000307 unsigned int& getMachineRegNum,
308 int64_t& getImmedValue)
309{
Vikram S. Advebff682d2001-07-28 04:06:37 +0000310 MachineOperand::MachineOperandType opType =
311 MachineOperand::MO_VirtualRegister;
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000312 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 {
Vikram S. Advebff682d2001-07-28 04:06:37 +0000330 if (intValue == 0 && target.zeroRegNum >= 0)
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000331 {
Vikram S. Advebff682d2001-07-28 04:06:37 +0000332 opType = MachineOperand::MO_MachineRegister;
333 getMachineRegNum = target.zeroRegNum;
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000334 }
335 else if (canUseImmed &&
Vikram S. Advebff682d2001-07-28 04:06:37 +0000336 target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
Vikram S. Adveab9e5572001-07-21 12:41:50 +0000337 {
338 opType = MachineOperand::MO_SignExtendedImmed;
339 getImmedValue = intValue;
340 }
341 }
342
343 return opType;
344}
Vikram S. Adve5f72f422001-08-28 23:02:39 +0000345
346
347void
348PrintMachineInstructions(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}