blob: d3e468cc2ebba1124a451451a409dfb7edd59055 [file] [log] [blame]
Vikram S. Adve70bc4b52001-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
Chris Lattner7e583cf2001-07-21 20:58:30 +000015#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner68498ce2001-07-21 23:24:48 +000016#include "llvm/ConstPoolVals.h"
17#include "llvm/Instruction.h"
18#include <strstream>
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000019
20//************************ Class Implementations **************************/
21
Vikram S. Adve1885da42001-07-31 21:49:28 +000022// Constructor for instructions with fixed #operands (nearly all)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000023MachineInstr::MachineInstr(MachineOpCode _opCode,
24 OpCodeMask _opCodeMask)
25 : opCode(_opCode),
26 opCodeMask(_opCodeMask),
Vikram S. Adve6a175e02001-07-28 04:06:37 +000027 operands(TargetInstrDescriptors[_opCode].numOperands)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000028{
Vikram S. Adve1885da42001-07-31 21:49:28 +000029 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
30}
31
32// Constructor for instructions with variable #operands
33MachineInstr::MachineInstr(MachineOpCode _opCode,
34 unsigned numOperands,
35 OpCodeMask _opCodeMask)
36 : opCode(_opCode),
37 opCodeMask(_opCodeMask),
38 operands(numOperands)
39{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000040}
41
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000042void
43MachineInstr::SetMachineOperand(unsigned int i,
44 MachineOperand::MachineOperandType operandType,
45 Value* _val)
46{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000047 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000048 operands[i].Initialize(operandType, _val);
49}
50
51void
52MachineInstr::SetMachineOperand(unsigned int i,
53 MachineOperand::MachineOperandType operandType,
54 int64_t intValue)
55{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000056 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000057 operands[i].InitializeConst(operandType, intValue);
58}
59
60void
61MachineInstr::SetMachineOperand(unsigned int i,
62 unsigned int regNum)
63{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000064 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000065 operands[i].InitializeReg(regNum);
66}
67
68void
69MachineInstr::dump(unsigned int indent)
70{
71 for (unsigned i=0; i < indent; i++)
72 cout << " ";
73
74 cout << *this;
75}
76
77ostream&
78operator<< (ostream& os, const MachineInstr& minstr)
79{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000080 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000081
82 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
83 os << "\t" << minstr.getOperand(i);
84
Vikram S. Adve6a175e02001-07-28 04:06:37 +000085#undef DEBUG_VAL_OP_ITERATOR
86#ifdef DEBUG_VAL_OP_ITERATOR
87 os << endl << "\tValue operands are: ";
88 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
89 {
90 const Value* val = *vo;
91 os << val << (vo.isDef()? "(def), " : ", ");
92 }
93 os << endl;
94#endif
95
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000096 return os;
97}
98
99ostream&
100operator<< (ostream& os, const MachineOperand& mop)
101{
102 strstream regInfo;
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000103 if (mop.opType == MachineOperand::MO_VirtualRegister)
104 regInfo << "(val " << mop.value << ")" << ends;
105 else if (mop.opType == MachineOperand::MO_MachineRegister)
106 regInfo << "(" << mop.regNum << ")" << ends;
107 else if (mop.opType == MachineOperand::MO_CCRegister)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000108 regInfo << "(val " << mop.value << ")" << ends;
109
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000110 switch(mop.opType)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000111 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000112 case MachineOperand::MO_VirtualRegister:
113 case MachineOperand::MO_MachineRegister:
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000114 os << "%reg" << regInfo.str();
115 free(regInfo.str());
116 break;
117
118 case MachineOperand::MO_CCRegister:
119 os << "%ccreg" << regInfo.str();
120 free(regInfo.str());
121 break;
122
123 case MachineOperand::MO_SignExtendedImmed:
124 os << mop.immedVal;
125 break;
126
127 case MachineOperand::MO_UnextendedImmed:
128 os << mop.immedVal;
129 break;
130
131 case MachineOperand::MO_PCRelativeDisp:
132 os << "%disp(label " << mop.value << ")";
133 break;
134
135 default:
136 assert(0 && "Unrecognized operand type");
137 break;
138 }
139
140 return os;
141}
142
143
144//---------------------------------------------------------------------------
145// Target-independent utility routines for creating machine instructions
146//---------------------------------------------------------------------------
147
148
149//------------------------------------------------------------------------
150// Function Set2OperandsFromInstr
151// Function Set3OperandsFromInstr
152//
153// For the common case of 2- and 3-operand arithmetic/logical instructions,
154// set the m/c instr. operands directly from the VM instruction's operands.
155// Check whether the first or second operand is 0 and can use a dedicated "0" register.
156// Check whether the second operand should use an immediate field or register.
157// (First and third operands are never immediates for such instructions.)
158//
159// Arguments:
160// canDiscardResult: Specifies that the result operand can be discarded
161// by using the dedicated "0"
162//
163// op1position, op2position and resultPosition: Specify in which position
164// in the machine instruction the 3 operands (arg1, arg2
165// and result) should go.
166//
167// RETURN VALUE: unsigned int flags, where
168// flags & 0x01 => operand 1 is constant and needs a register
169// flags & 0x02 => operand 2 is constant and needs a register
170//------------------------------------------------------------------------
171
172void
173Set2OperandsFromInstr(MachineInstr* minstr,
174 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000175 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000176 bool canDiscardResult,
177 int op1Position,
178 int resultPosition)
179{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000180 Set3OperandsFromInstr(minstr, vmInstrNode, target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000181 canDiscardResult, op1Position,
182 /*op2Position*/ -1, resultPosition);
183}
184
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000185#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
186#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000187unsigned
188Set3OperandsFromInstrJUNK(MachineInstr* minstr,
189 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000190 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000191 bool canDiscardResult,
192 int op1Position,
193 int op2Position,
194 int resultPosition)
195{
196 assert(op1Position >= 0);
197 assert(resultPosition >= 0);
198
199 unsigned returnFlags = 0x0;
200
201 // Check if operand 1 is 0 and if so, try to use the register that gives 0, if any.
202 Value* op1Value = vmInstrNode->leftChild()->getValue();
203 bool isValidConstant;
204 int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000205 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
206 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000207 else
208 {
209 if (op1Value->getValueType() == Value::ConstantVal)
210 {// value is constant and must be loaded from constant pool
211 returnFlags = returnFlags | (1 << op1Position);
212 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000213 minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
214 op1Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000215 }
216
217 // Check if operand 2 (if any) fits in the immediate field of the instruction,
218 // of if it is 0 and can use a dedicated machine register
219 if (op2Position >= 0)
220 {
221 Value* op2Value = vmInstrNode->rightChild()->getValue();
222 int64_t immedValue;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000223 unsigned int machineRegNum;
224
225 MachineOperand::MachineOperandType
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000226 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000227 /*canUseImmed*/ true,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000228 machineRegNum, immedValue);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000229
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000230 if (op2type == MachineOperand::MO_MachineRegister)
231 minstr->SetMachineOperand(op2Position, machineRegNum);
232 else if (op2type == MachineOperand::MO_VirtualRegister)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000233 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000234 if (op2Value->getValueType() == Value::ConstantVal)
235 {// value is constant and must be loaded from constant pool
236 returnFlags = returnFlags | (1 << op2Position);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000237 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000238 minstr->SetMachineOperand(op2Position, op2type, op2Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000239 }
240 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000241 {
242 assert(op2type != MO_CCRegister);
243 minstr->SetMachineOperand(op2Position, op2type, immedValue);
244 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000245 }
246
247 // If operand 3 (result) can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000248 if (canDiscardResult && target.zeroRegNum >= 0)
249 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000250 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000251 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000252
253 return returnFlags;
254}
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000255#endif
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000256
257
258void
259Set3OperandsFromInstr(MachineInstr* minstr,
260 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000261 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000262 bool canDiscardResult,
263 int op1Position,
264 int op2Position,
265 int resultPosition)
266{
267 assert(op1Position >= 0);
268 assert(resultPosition >= 0);
269
270 // operand 1
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000271 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000272 vmInstrNode->leftChild()->getValue());
273
274 // operand 2 (if any)
275 if (op2Position >= 0)
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000276 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000277 vmInstrNode->rightChild()->getValue());
278
279 // result operand: if it can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000280 if (canDiscardResult && target.zeroRegNum >= 0)
281 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000282 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000283 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000284}
285
286
287MachineOperand::MachineOperandType
288ChooseRegOrImmed(Value* val,
289 MachineOpCode opCode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000290 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000291 bool canUseImmed,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000292 unsigned int& getMachineRegNum,
293 int64_t& getImmedValue)
294{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000295 MachineOperand::MachineOperandType opType =
296 MachineOperand::MO_VirtualRegister;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000297 getMachineRegNum = 0;
298 getImmedValue = 0;
299
300 // Check for the common case first: argument is not constant
301 //
302 if (val->getValueType() != Value::ConstantVal)
303 return opType;
304
305 // Now get the constant value and check if it fits in the IMMED field.
306 // Take advantage of the fact that the max unsigned value will rarely
307 // fit into any IMMED field and ignore that case (i.e., cast smaller
308 // unsigned constants to signed).
309 //
310 bool isValidConstant;
311 int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);
312
313 if (isValidConstant)
314 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000315 if (intValue == 0 && target.zeroRegNum >= 0)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000316 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000317 opType = MachineOperand::MO_MachineRegister;
318 getMachineRegNum = target.zeroRegNum;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000319 }
320 else if (canUseImmed &&
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000321 target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000322 {
323 opType = MachineOperand::MO_SignExtendedImmed;
324 getImmedValue = intValue;
325 }
326 }
327
328 return opType;
329}