blob: 1e3300763de2b3dda02f48f7f3a1febe1671cccb [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
Vikram S. Adve5b795912001-08-28 23:02:39 +000015
Chris Lattner822b4fb2001-09-07 17:18:30 +000016#include "llvm/CodeGen/MachineInstr.h"
Vikram S. Adve6e447182001-09-18 12:56:28 +000017#include "llvm/Target/MachineRegInfo.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000018#include "llvm/Method.h"
Chris Lattner68498ce2001-07-21 23:24:48 +000019#include "llvm/ConstPoolVals.h"
20#include "llvm/Instruction.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000021
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000022
23//************************ Class Implementations **************************/
24
Vikram S. Adve1885da42001-07-31 21:49:28 +000025// Constructor for instructions with fixed #operands (nearly all)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000026MachineInstr::MachineInstr(MachineOpCode _opCode,
27 OpCodeMask _opCodeMask)
28 : opCode(_opCode),
29 opCodeMask(_opCodeMask),
Vikram S. Adve6a175e02001-07-28 04:06:37 +000030 operands(TargetInstrDescriptors[_opCode].numOperands)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000031{
Vikram S. Adve1885da42001-07-31 21:49:28 +000032 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
33}
34
35// Constructor for instructions with variable #operands
36MachineInstr::MachineInstr(MachineOpCode _opCode,
37 unsigned numOperands,
38 OpCodeMask _opCodeMask)
39 : opCode(_opCode),
40 opCodeMask(_opCodeMask),
41 operands(numOperands)
42{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000043}
44
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000045void
46MachineInstr::SetMachineOperand(unsigned int i,
47 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000048 Value* _val, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000049{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000050 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000051 operands[i].Initialize(operandType, _val);
Vikram S. Adve149977b2001-08-13 16:32:45 +000052 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000053 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000054}
55
56void
57MachineInstr::SetMachineOperand(unsigned int i,
58 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000059 int64_t intValue, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000060{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000061 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000062 operands[i].InitializeConst(operandType, intValue);
Vikram S. Adve149977b2001-08-13 16:32:45 +000063 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000064 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000065}
66
67void
68MachineInstr::SetMachineOperand(unsigned int i,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000069 unsigned int regNum, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000070{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000071 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000072 operands[i].InitializeReg(regNum);
Vikram S. Adve149977b2001-08-13 16:32:45 +000073 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000074 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000075}
76
77void
Ruchira Sasanka0b03c6a2001-08-07 21:01:23 +000078MachineInstr::dump(unsigned int indent) const
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000079{
80 for (unsigned i=0; i < indent; i++)
81 cout << " ";
82
83 cout << *this;
84}
85
86ostream&
87operator<< (ostream& os, const MachineInstr& minstr)
88{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000089 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000090
91 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
92 os << "\t" << minstr.getOperand(i);
93
Vikram S. Adve6a175e02001-07-28 04:06:37 +000094#undef DEBUG_VAL_OP_ITERATOR
95#ifdef DEBUG_VAL_OP_ITERATOR
96 os << endl << "\tValue operands are: ";
97 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
98 {
99 const Value* val = *vo;
100 os << val << (vo.isDef()? "(def), " : ", ");
101 }
102 os << endl;
103#endif
104
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000105 return os;
106}
107
Vikram S. Adve6e447182001-09-18 12:56:28 +0000108static inline ostream&
109OutputOperand(ostream &os, const MachineOperand &mop)
110{
111 switch (mop.getOperandType())
112 {
113 case MachineOperand::MO_CCRegister:
114 case MachineOperand::MO_VirtualRegister:
115 return os << "(val " << mop.getVRegValue() << ")";
116 case MachineOperand::MO_MachineRegister:
117 return os << "(" << mop.getMachineRegNum() << ")";
118 default:
119 assert(0 && "Unknown operand type");
120 return os;
121 }
Chris Lattnere6fdb112001-09-09 22:26:29 +0000122}
123
124
Vikram S. Adve6e447182001-09-18 12:56:28 +0000125ostream&
126operator<<(ostream &os, const MachineOperand &mop)
127{
128 switch(mop.opType)
129 {
130 case MachineOperand::MO_VirtualRegister:
131 case MachineOperand::MO_MachineRegister:
132 os << "%reg";
133 return OutputOperand(os, mop);
134 case MachineOperand::MO_CCRegister:
135 os << "%ccreg";
136 return OutputOperand(os, mop);
137 case MachineOperand::MO_SignExtendedImmed:
138 return os << mop.immedVal;
139 case MachineOperand::MO_UnextendedImmed:
140 return os << mop.immedVal;
141 case MachineOperand::MO_PCRelativeDisp:
Vikram S. Advee949da52001-09-30 23:44:19 +0000142 {
143 const Value* opVal = mop.getVRegValue();
144 bool isLabel = opVal->isMethod() || opVal->isBasicBlock();
145 return os << "%disp("
146 << (isLabel? "label " : "addr-of-val ")
147 << opVal << ")";
148 }
Vikram S. Adve6e447182001-09-18 12:56:28 +0000149 default:
150 assert(0 && "Unrecognized operand type");
151 break;
152 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000153
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000154 return os;
155}
156
157
158//---------------------------------------------------------------------------
159// Target-independent utility routines for creating machine instructions
160//---------------------------------------------------------------------------
161
162
163//------------------------------------------------------------------------
164// Function Set2OperandsFromInstr
165// Function Set3OperandsFromInstr
166//
167// For the common case of 2- and 3-operand arithmetic/logical instructions,
168// set the m/c instr. operands directly from the VM instruction's operands.
Chris Lattnerc2a23962001-09-11 23:22:43 +0000169// Check whether the first or second operand is 0 and can use a dedicated "0"
170// register.
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000171// 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. 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 resultPosition)
194{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000195 Set3OperandsFromInstr(minstr, vmInstrNode, target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000196 canDiscardResult, op1Position,
197 /*op2Position*/ -1, resultPosition);
198}
199
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000200#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
201#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000202unsigned
203Set3OperandsFromInstrJUNK(MachineInstr* minstr,
Vikram S. Adve6e447182001-09-18 12:56:28 +0000204 InstructionNode* vmInstrNode,
205 const TargetMachine& target,
206 bool canDiscardResult,
207 int op1Position,
208 int op2Position,
209 int resultPosition)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000210{
211 assert(op1Position >= 0);
212 assert(resultPosition >= 0);
213
214 unsigned returnFlags = 0x0;
215
Vikram S. Adve5b795912001-08-28 23:02:39 +0000216 // Check if operand 1 is 0. If so, try to use a hardwired 0 register.
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000217 Value* op1Value = vmInstrNode->leftChild()->getValue();
218 bool isValidConstant;
219 int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000220 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
221 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000222 else
223 {
Vikram S. Adve6e447182001-09-18 12:56:28 +0000224 if (op1Value->isConstant())
225 {
226 // value is constant and must be loaded from constant pool
227 returnFlags = returnFlags | (1 << op1Position);
228 }
Chris Lattnerb221a762001-09-10 19:43:38 +0000229 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
230 op1Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000231 }
232
Vikram S. Adve5b795912001-08-28 23:02:39 +0000233 // Check if operand 2 (if any) fits in the immed. field of the instruction,
234 // or if it is 0 and can use a dedicated machine register
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000235 if (op2Position >= 0)
236 {
237 Value* op2Value = vmInstrNode->rightChild()->getValue();
238 int64_t immedValue;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000239 unsigned int machineRegNum;
240
241 MachineOperand::MachineOperandType
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000242 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000243 /*canUseImmed*/ true,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000244 machineRegNum, immedValue);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000245
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000246 if (op2type == MachineOperand::MO_MachineRegister)
247 minstr->SetMachineOperand(op2Position, machineRegNum);
248 else if (op2type == MachineOperand::MO_VirtualRegister)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000249 {
Vikram S. Adve6e447182001-09-18 12:56:28 +0000250 if (op2Value->isConstant())
251 {
252 // value is constant and must be loaded from constant pool
253 returnFlags = returnFlags | (1 << op2Position);
254 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000255 minstr->SetMachineOperand(op2Position, op2type, op2Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000256 }
257 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000258 {
259 assert(op2type != MO_CCRegister);
260 minstr->SetMachineOperand(op2Position, op2type, immedValue);
261 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000262 }
263
264 // If operand 3 (result) can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000265 if (canDiscardResult && target.zeroRegNum >= 0)
Vikram S. Adve149977b2001-08-13 16:32:45 +0000266 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000267 else
Vikram S. Adve149977b2001-08-13 16:32:45 +0000268 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000269
270 return returnFlags;
271}
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000272#endif
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000273
274
275void
276Set3OperandsFromInstr(MachineInstr* minstr,
277 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000278 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000279 bool canDiscardResult,
280 int op1Position,
281 int op2Position,
282 int resultPosition)
283{
284 assert(op1Position >= 0);
285 assert(resultPosition >= 0);
286
287 // operand 1
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000288 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000289 vmInstrNode->leftChild()->getValue());
290
291 // operand 2 (if any)
292 if (op2Position >= 0)
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000293 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000294 vmInstrNode->rightChild()->getValue());
295
296 // result operand: if it can be discarded, use a dead register if one exists
Vikram S. Adve6e447182001-09-18 12:56:28 +0000297 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0)
298 minstr->SetMachineOperand(resultPosition,
299 target.getRegInfo().getZeroRegNum());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000300 else
Vikram S. Adve6e447182001-09-18 12:56:28 +0000301 minstr->SetMachineOperand(resultPosition,
302 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000303}
304
305
306MachineOperand::MachineOperandType
307ChooseRegOrImmed(Value* val,
308 MachineOpCode opCode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000309 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000310 bool canUseImmed,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000311 unsigned int& getMachineRegNum,
312 int64_t& getImmedValue)
313{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000314 MachineOperand::MachineOperandType opType =
315 MachineOperand::MO_VirtualRegister;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000316 getMachineRegNum = 0;
317 getImmedValue = 0;
318
319 // Check for the common case first: argument is not constant
320 //
Chris Lattner990f2a52001-09-09 23:01:32 +0000321 ConstPoolVal *CPV = val->castConstant();
322 if (!CPV) return opType;
323
Vikram S. Adve6e447182001-09-18 12:56:28 +0000324 if (CPV->getType() == Type::BoolTy)
325 {
326 ConstPoolBool *CPB = (ConstPoolBool*)CPV;
327 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
328 {
329 getMachineRegNum = target.getRegInfo().getZeroRegNum();
330 return MachineOperand::MO_MachineRegister;
331 }
Chris Lattner990f2a52001-09-09 23:01:32 +0000332
Vikram S. Adve6e447182001-09-18 12:56:28 +0000333 getImmedValue = 1;
334 return MachineOperand::MO_SignExtendedImmed;
335 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000336
Chris Lattner990f2a52001-09-09 23:01:32 +0000337 if (!CPV->getType()->isIntegral()) return opType;
338
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000339 // Now get the constant value and check if it fits in the IMMED field.
340 // Take advantage of the fact that the max unsigned value will rarely
341 // fit into any IMMED field and ignore that case (i.e., cast smaller
342 // unsigned constants to signed).
343 //
Chris Lattner990f2a52001-09-09 23:01:32 +0000344 int64_t intValue;
Vikram S. Adve6e447182001-09-18 12:56:28 +0000345 if (CPV->getType()->isSigned())
346 {
347 intValue = ((ConstPoolSInt*)CPV)->getValue();
348 }
349 else
350 {
351 uint64_t V = ((ConstPoolUInt*)CPV)->getValue();
352 if (V >= INT64_MAX) return opType;
353 intValue = (int64_t)V;
354 }
Chris Lattner990f2a52001-09-09 23:01:32 +0000355
Vikram S. Adve6e447182001-09-18 12:56:28 +0000356 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
357 {
358 opType = MachineOperand::MO_MachineRegister;
359 getMachineRegNum = target.getRegInfo().getZeroRegNum();
360 }
361 else if (canUseImmed &&
362 target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
363 {
364 opType = MachineOperand::MO_SignExtendedImmed;
365 getImmedValue = intValue;
366 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000367
368 return opType;
369}
Vikram S. Adve5b795912001-08-28 23:02:39 +0000370
371
372void
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000373PrintMachineInstructions(const Method *const method)
374{
375 cout << "\n" << method->getReturnType()
376 << " \"" << method->getName() << "\"" << endl;
377
378 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
379 {
380 BasicBlock* bb = *BI;
381 cout << "\n"
382 << (bb->hasName()? bb->getName() : "Label")
383 << " (" << bb << ")" << ":"
384 << endl;
385
386 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
387 for (unsigned i=0; i < mvec.size(); i++)
388 cout << "\t" << *mvec[i] << endl;
389 }
390 cout << endl << "End method \"" << method->getName() << "\""
391 << endl << endl;
392}