blob: 64fcaa0577174e87a9070f72592541bb0abae0e7 [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
22
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{
29}
30
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000031void
32MachineInstr::SetMachineOperand(unsigned int i,
33 MachineOperand::MachineOperandType operandType,
34 Value* _val)
35{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000036 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000037 operands[i].Initialize(operandType, _val);
38}
39
40void
41MachineInstr::SetMachineOperand(unsigned int i,
42 MachineOperand::MachineOperandType operandType,
43 int64_t intValue)
44{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000045 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000046 operands[i].InitializeConst(operandType, intValue);
47}
48
49void
50MachineInstr::SetMachineOperand(unsigned int i,
51 unsigned int regNum)
52{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000053 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000054 operands[i].InitializeReg(regNum);
55}
56
57void
58MachineInstr::dump(unsigned int indent)
59{
60 for (unsigned i=0; i < indent; i++)
61 cout << " ";
62
63 cout << *this;
64}
65
66ostream&
67operator<< (ostream& os, const MachineInstr& minstr)
68{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000069 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000070
71 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
72 os << "\t" << minstr.getOperand(i);
73
Vikram S. Adve6a175e02001-07-28 04:06:37 +000074#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
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000085 return os;
86}
87
88ostream&
89operator<< (ostream& os, const MachineOperand& mop)
90{
91 strstream regInfo;
Vikram S. Adve6a175e02001-07-28 04:06:37 +000092 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)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000097 regInfo << "(val " << mop.value << ")" << ends;
98
Vikram S. Adve6a175e02001-07-28 04:06:37 +000099 switch(mop.opType)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000100 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000101 case MachineOperand::MO_VirtualRegister:
102 case MachineOperand::MO_MachineRegister:
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000103 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
161void
162Set2OperandsFromInstr(MachineInstr* minstr,
163 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000164 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000165 bool canDiscardResult,
166 int op1Position,
167 int resultPosition)
168{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000169 Set3OperandsFromInstr(minstr, vmInstrNode, target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000170 canDiscardResult, op1Position,
171 /*op2Position*/ -1, resultPosition);
172}
173
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000174#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
175#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000176unsigned
177Set3OperandsFromInstrJUNK(MachineInstr* minstr,
178 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000179 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000180 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);
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000194 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
195 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000196 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 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000202 minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
203 op1Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000204 }
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;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000212 unsigned int machineRegNum;
213
214 MachineOperand::MachineOperandType
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000215 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000216 /*canUseImmed*/ true,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000217 machineRegNum, immedValue);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000218
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000219 if (op2type == MachineOperand::MO_MachineRegister)
220 minstr->SetMachineOperand(op2Position, machineRegNum);
221 else if (op2type == MachineOperand::MO_VirtualRegister)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000222 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000223 if (op2Value->getValueType() == Value::ConstantVal)
224 {// value is constant and must be loaded from constant pool
225 returnFlags = returnFlags | (1 << op2Position);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000226 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000227 minstr->SetMachineOperand(op2Position, op2type, op2Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000228 }
229 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000230 {
231 assert(op2type != MO_CCRegister);
232 minstr->SetMachineOperand(op2Position, op2type, immedValue);
233 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000234 }
235
236 // If operand 3 (result) can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000237 if (canDiscardResult && target.zeroRegNum >= 0)
238 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000239 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000240 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000241
242 return returnFlags;
243}
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000244#endif
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000245
246
247void
248Set3OperandsFromInstr(MachineInstr* minstr,
249 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000250 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000251 bool canDiscardResult,
252 int op1Position,
253 int op2Position,
254 int resultPosition)
255{
256 assert(op1Position >= 0);
257 assert(resultPosition >= 0);
258
259 // operand 1
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000260 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000261 vmInstrNode->leftChild()->getValue());
262
263 // operand 2 (if any)
264 if (op2Position >= 0)
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000265 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000266 vmInstrNode->rightChild()->getValue());
267
268 // result operand: if it can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000269 if (canDiscardResult && target.zeroRegNum >= 0)
270 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000271 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000272 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000273}
274
275
276MachineOperand::MachineOperandType
277ChooseRegOrImmed(Value* val,
278 MachineOpCode opCode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000279 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000280 bool canUseImmed,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000281 unsigned int& getMachineRegNum,
282 int64_t& getImmedValue)
283{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000284 MachineOperand::MachineOperandType opType =
285 MachineOperand::MO_VirtualRegister;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000286 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 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000304 if (intValue == 0 && target.zeroRegNum >= 0)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000305 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000306 opType = MachineOperand::MO_MachineRegister;
307 getMachineRegNum = target.zeroRegNum;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000308 }
309 else if (canUseImmed &&
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000310 target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000311 {
312 opType = MachineOperand::MO_SignExtendedImmed;
313 getImmedValue = intValue;
314 }
315 }
316
317 return opType;
318}