MachineInstr.h revision 68498cefe602bf5364168b4acd0bd5806cdd72ec
1// $Id$ -*-c++-*- 2//*************************************************************************** 3// File: 4// MachineInstr.h 5// 6// Purpose: 7// 8// 9// Strategy: 10// 11// History: 12// 7/2/01 - Vikram Adve - Created 13//**************************************************************************/ 14 15#ifndef LLVM_CODEGEN_MACHINEINSTR_H 16#define LLVM_CODEGEN_MACHINEINSTR_H 17 18#include "llvm/CodeGen/InstrForest.h" 19#include "llvm/Tools/DataTypes.h" 20#include "llvm/Support/Unique.h" 21#include "llvm/CodeGen/TargetMachine.h" 22 23//--------------------------------------------------------------------------- 24// class MachineOperand 25// 26// Purpose: 27// Representation of each machine instruction operand. 28// This class is designed so that you can allocate a vector of operands 29// first and initialize each one later. 30// 31// E.g, for this VM instruction: 32// ptr = alloca type, numElements 33// we generate 2 machine instructions on the SPARC: 34// 35// mul Constant, Numelements -> Reg 36// add %sp, Reg -> Ptr 37// 38// Each instruction has 3 operands, listed above. Of those: 39// - Reg, NumElements, and Ptr are of operand type MO_Register. 40// - Constant is of operand type MO_SignExtendedImmed on the SPARC. 41// 42// For the register operands, the virtual register type is as follows: 43// 44// - Reg will be of virtual register type MO_MInstrVirtualReg. The field 45// MachineInstr* minstr will point to the instruction that computes reg. 46// 47// - %sp will be of virtual register type MO_MachineReg. 48// The field regNum identifies the machine register. 49// 50// - NumElements will be of virtual register type MO_VirtualReg. 51// The field Value* value identifies the value. 52// 53// - Ptr will also be of virtual register type MO_VirtualReg. 54// Again, the field Value* value identifies the value. 55// 56//--------------------------------------------------------------------------- 57 58class MachineOperand { 59public: 60 friend ostream& operator<<(ostream& os, const MachineOperand& mop); 61 62public: 63 enum MachineOperandType { 64 MO_Register, 65 MO_CCRegister, 66 MO_SignExtendedImmed, 67 MO_UnextendedImmed, 68 MO_PCRelativeDisp, 69 }; 70 71 enum VirtualRegisterType { 72 MO_VirtualReg, // virtual register for *value 73 MO_MachineReg // pre-assigned machine register `regNum' 74 }; 75 76 MachineOperandType machineOperandType; 77 78 VirtualRegisterType vregType; 79 80 Value* value; // BasicBlockVal for a label operand. 81 // ConstantVal for a non-address immediate. 82 // Virtual register for a register operand. 83 84 unsigned int regNum; // register number for an explicit register 85 86 int64_t immedVal; // constant value for an explicit constant 87 88 /*ctor*/ MachineOperand (); 89 /*ctor*/ MachineOperand (MachineOperandType operandType, 90 Value* _val); 91 /*copy ctor*/ MachineOperand (const MachineOperand&); 92 /*dtor*/ ~MachineOperand () {} 93 94 // These functions are provided so that a vector of operands can be 95 // statically allocated and individual ones can be initialized later. 96 // 97 void Initialize (MachineOperandType operandType, 98 Value* _val); 99 void InitializeConst (MachineOperandType operandType, 100 int64_t intValue); 101 void InitializeReg (unsigned int regNum); 102}; 103 104 105inline 106MachineOperand::MachineOperand() 107 : machineOperandType(MO_Register), 108 vregType(MO_VirtualReg), 109 value(NULL), 110 regNum(0), 111 immedVal(0) 112{} 113 114inline 115MachineOperand::MachineOperand(MachineOperandType operandType, 116 Value* _val) 117 : machineOperandType(operandType), 118 vregType(MO_VirtualReg), 119 value(_val), 120 regNum(0), 121 immedVal(0) 122{} 123 124inline 125MachineOperand::MachineOperand(const MachineOperand& mo) 126 : machineOperandType(mo.machineOperandType), 127 vregType(mo.vregType), 128 value(mo.value), 129 regNum(mo.regNum), 130 immedVal(mo.immedVal) 131{ 132} 133 134inline void 135MachineOperand::Initialize(MachineOperandType operandType, 136 Value* _val) 137{ 138 machineOperandType = operandType; 139 value = _val; 140} 141 142inline void 143MachineOperand::InitializeConst(MachineOperandType operandType, 144 int64_t intValue) 145{ 146 machineOperandType = operandType; 147 value = NULL; 148 immedVal = intValue; 149} 150 151inline void 152MachineOperand::InitializeReg(unsigned int _regNum) 153{ 154 machineOperandType = MO_Register; 155 vregType = MO_MachineReg; 156 value = NULL; 157 regNum = _regNum; 158} 159 160 161//--------------------------------------------------------------------------- 162// class MachineInstr 163// 164// Purpose: 165// Representation of each machine instruction. 166// 167// MachineOpCode must be an enum, defined separately for each target. 168// E.g., It is defined in SparcInstructionSelection.h for the SPARC. 169// The array MachineInstrInfo TargetMachineInstrInfo[] objects 170// (indexed by opCode) provides information about each target instruction. 171// 172// opCodeMask is used to record variants of an instruction. 173// E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants): 174// ANNUL: if 1: Annul delay slot instruction. 175// PREDICT-NOT-TAKEN: if 1: predict branch not taken. 176// Instead of creating 4 different opcodes for BNZ, we create a single 177// opcode and set bits in opCodeMask for each of these flags. 178//--------------------------------------------------------------------------- 179 180class MachineInstr : public Unique { 181private: 182 MachineOpCode opCode; 183 OpCodeMask opCodeMask; // extra bits for variants of an opcode 184 vector<MachineOperand> operands; // operand 0 is the result 185 186public: 187 /*ctor*/ MachineInstr (MachineOpCode _opCode, 188 OpCodeMask _opCodeMask = 0x0); 189 190 /*dtor*/ virtual ~MachineInstr (); 191 192 const MachineOpCode getOpCode () const; 193 194 unsigned int getNumOperands () const; 195 196 const MachineOperand& getOperand (unsigned int i) const; 197 198 void dump (unsigned int indent = 0); 199 200public: 201 friend ostream& operator<<(ostream& os, const MachineInstr& minstr); 202 203public: 204 // Access to set the operands when building the machine instruction 205 void SetMachineOperand(unsigned int i, 206 MachineOperand::MachineOperandType operandType, 207 Value* _val); 208 void SetMachineOperand(unsigned int i, 209 MachineOperand::MachineOperandType operandType, 210 int64_t intValue); 211 void SetMachineOperand(unsigned int i, 212 unsigned int regNum); 213}; 214 215inline const MachineOpCode 216MachineInstr::getOpCode() const 217{ 218 return opCode; 219} 220 221inline unsigned int 222MachineInstr::getNumOperands() const 223{ 224 assert(operands.size() == TargetMachineInstrInfo[opCode].numOperands); 225 return operands.size(); 226} 227 228inline const MachineOperand& 229MachineInstr::getOperand(unsigned int i) const 230{ 231 return operands[i]; 232} 233 234 235//--------------------------------------------------------------------------- 236// class MachineInstructionsForVMInstr 237// 238// Purpose: 239// Representation of the sequence of machine instructions created 240// for a single VM instruction. Additionally records any temporary 241// "values" used as intermediate values in this sequence. 242// Note that such values should be treated as pure SSA values with 243// no interpretation of their operands (i.e., as a TmpInstruction object 244// which actually represents such a value). 245// 246//--------------------------------------------------------------------------- 247 248class MachineCodeForVMInstr: public vector<MachineInstr*> 249{ 250private: 251 vector<Value*> tempVec; 252 253public: 254 /*ctor*/ MachineCodeForVMInstr () {} 255 /*ctor*/ ~MachineCodeForVMInstr (); 256 257 const vector<Value*>& 258 getTempValues () const { return tempVec; } 259 260 void addTempValue (Value* val) 261 { tempVec.push_back(val); } 262 263 // dropAllReferences() - This function drops all references within 264 // temporary (hidden) instructions created in implementing the original 265 // VM intruction. This ensures there are no remaining "uses" within 266 // these hidden instructions, before the values of a method are freed. 267 // 268 // Make this inline because it has to be called from class Instruction 269 // and inlining it avoids a serious circurality in link order. 270 inline void dropAllReferences() { 271 for (unsigned i=0, N=tempVec.size(); i < N; i++) 272 if (tempVec[i]->getValueType() == Value::InstructionVal) 273 ((Instruction*) tempVec[i])->dropAllReferences(); 274 } 275}; 276 277inline 278MachineCodeForVMInstr::~MachineCodeForVMInstr() 279{ 280 // Free the Value objects created to hold intermediate values 281 for (unsigned i=0, N=tempVec.size(); i < N; i++) 282 delete tempVec[i]; 283 284 // Free the MachineInstr objects allocated, if any. 285 for (unsigned i=0, N=this->size(); i < N; i++) 286 delete (*this)[i]; 287} 288 289//--------------------------------------------------------------------------- 290// Target-independent utility routines for creating machine instructions 291//--------------------------------------------------------------------------- 292 293 294//------------------------------------------------------------------------ 295// Function Set2OperandsFromInstr 296// Function Set3OperandsFromInstr 297// 298// For the common case of 2- and 3-operand arithmetic/logical instructions, 299// set the m/c instr. operands directly from the VM instruction's operands. 300// Check whether the first or second operand is 0 and can use a dedicated 301// "0" register. 302// Check whether the second operand should use an immediate field or register. 303// (First and third operands are never immediates for such instructions.) 304// 305// Arguments: 306// canDiscardResult: Specifies that the result operand can be discarded 307// by using the dedicated "0" 308// 309// op1position, op2position and resultPosition: Specify in which position 310// in the machine instruction the 3 operands (arg1, arg2 311// and result) should go. 312// 313// RETURN VALUE: unsigned int flags, where 314// flags & 0x01 => operand 1 is constant and needs a register 315// flags & 0x02 => operand 2 is constant and needs a register 316//------------------------------------------------------------------------ 317 318void Set2OperandsFromInstr (MachineInstr* minstr, 319 InstructionNode* vmInstrNode, 320 const TargetMachine& targetMachine, 321 bool canDiscardResult = false, 322 int op1Position = 0, 323 int resultPosition = 1); 324 325void Set3OperandsFromInstr (MachineInstr* minstr, 326 InstructionNode* vmInstrNode, 327 const TargetMachine& targetMachine, 328 bool canDiscardResult = false, 329 int op1Position = 0, 330 int op2Position = 1, 331 int resultPosition = 2); 332 333MachineOperand::MachineOperandType 334 ChooseRegOrImmed(Value* val, 335 MachineOpCode opCode, 336 const TargetMachine& targetMachine, 337 bool canUseImmed, 338 MachineOperand::VirtualRegisterType& getVRegType, 339 unsigned int& getMachineRegNum, 340 int64_t& getImmedValue); 341 342ostream& operator<<(ostream& os, const MachineInstr& minstr); 343 344 345ostream& operator<<(ostream& os, const MachineOperand& mop); 346 347 348//**************************************************************************/ 349 350#endif 351