MachineInstr.h revision 986cc38613e7859ab6c9ab8aa9fc2e686f8c2ab4
1//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the declaration of the MachineInstr class, which is the 11// basic representation for all target dependent machine instructions used by 12// the back end. 13// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_CODEGEN_MACHINEINSTR_H 17#define LLVM_CODEGEN_MACHINEINSTR_H 18 19#include "llvm/ADT/iterator" 20#include "llvm/Support/DataTypes.h" 21#include <vector> 22#include <cassert> 23 24namespace llvm { 25 26class Value; 27class Function; 28class MachineBasicBlock; 29class TargetMachine; 30class GlobalValue; 31 32template <typename T> struct ilist_traits; 33template <typename T> struct ilist; 34 35//===----------------------------------------------------------------------===// 36// class MachineOperand 37// 38// Representation of each machine instruction operand. 39// 40struct MachineOperand { 41 enum MachineOperandType { 42 MO_Register, // Register operand. 43 MO_Immediate, // Immediate Operand 44 MO_MachineBasicBlock, // MachineBasicBlock reference 45 MO_FrameIndex, // Abstract Stack Frame Index 46 MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool 47 MO_JumpTableIndex, // Address of indexed Jump Table for switch 48 MO_ExternalSymbol, // Name of external global symbol 49 MO_GlobalAddress // Address of a global value 50 }; 51 52private: 53 union { 54 GlobalValue *GV; // For MO_GlobalAddress. 55 MachineBasicBlock *MBB; // For MO_MachineBasicBlock. 56 const char *SymbolName; // For MO_ExternalSymbol. 57 unsigned RegNo; // For MO_Register. 58 int64_t immedVal; // For MO_Immediate and MO_*Index. 59 } contents; 60 61 MachineOperandType opType:8; // Discriminate the union. 62 bool IsDef : 1; // True if this is a def, false if this is a use. 63 64 /// offset - Offset to address of global or external, only valid for 65 /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex 66 int offset; 67 68 MachineOperand() {} 69public: 70 MachineOperand(const MachineOperand &M) { 71 *this = M; 72 } 73 74 ~MachineOperand() {} 75 76 static MachineOperand CreateImm(int64_t Val) { 77 MachineOperand Op; 78 Op.opType = MachineOperand::MO_Immediate; 79 Op.contents.immedVal = Val; 80 Op.IsDef = false; 81 Op.offset = 0; 82 return Op; 83 } 84 85 const MachineOperand &operator=(const MachineOperand &MO) { 86 contents = MO.contents; 87 IsDef = MO.IsDef; 88 opType = MO.opType; 89 offset = MO.offset; 90 return *this; 91 } 92 93 /// getType - Returns the MachineOperandType for this operand. 94 /// 95 MachineOperandType getType() const { return opType; } 96 97 /// Accessors that tell you what kind of MachineOperand you're looking at. 98 /// 99 bool isReg() const { return opType == MO_Register; } 100 bool isImm() const { return opType == MO_Immediate; } 101 bool isMBB() const { return opType == MO_MachineBasicBlock; } 102 103 bool isRegister() const { return opType == MO_Register; } 104 bool isImmediate() const { return opType == MO_Immediate; } 105 bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; } 106 bool isFrameIndex() const { return opType == MO_FrameIndex; } 107 bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; } 108 bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; } 109 bool isGlobalAddress() const { return opType == MO_GlobalAddress; } 110 bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } 111 112 int64_t getImm() const { 113 assert(isImm() && "Wrong MachineOperand accessor"); 114 return contents.immedVal; 115 } 116 117 int64_t getImmedValue() const { 118 assert(isImm() && "Wrong MachineOperand accessor"); 119 return contents.immedVal; 120 } 121 MachineBasicBlock *getMachineBasicBlock() const { 122 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 123 return contents.MBB; 124 } 125 void setMachineBasicBlock(MachineBasicBlock *MBB) { 126 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 127 contents.MBB = MBB; 128 } 129 int getFrameIndex() const { 130 assert(isFrameIndex() && "Wrong MachineOperand accessor"); 131 return (int)contents.immedVal; 132 } 133 unsigned getConstantPoolIndex() const { 134 assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); 135 return (unsigned)contents.immedVal; 136 } 137 unsigned getJumpTableIndex() const { 138 assert(isJumpTableIndex() && "Wrong MachineOperand accessor"); 139 return (unsigned)contents.immedVal; 140 } 141 GlobalValue *getGlobal() const { 142 assert(isGlobalAddress() && "Wrong MachineOperand accessor"); 143 return contents.GV; 144 } 145 int getOffset() const { 146 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && 147 "Wrong MachineOperand accessor"); 148 return offset; 149 } 150 const char *getSymbolName() const { 151 assert(isExternalSymbol() && "Wrong MachineOperand accessor"); 152 return contents.SymbolName; 153 } 154 155 bool isUse() const { 156 assert(isRegister() && "Wrong MachineOperand accessor"); 157 return !IsDef; 158 } 159 bool isDef() const { 160 assert(isRegister() && "Wrong MachineOperand accessor"); 161 return IsDef; 162 } 163 void setIsUse() { 164 assert(isRegister() && "Wrong MachineOperand accessor"); 165 IsDef = false; 166 } 167 void setIsDef() { 168 assert(isRegister() && "Wrong MachineOperand accessor"); 169 IsDef = true; 170 } 171 172 /// getReg - Returns the register number. 173 /// 174 unsigned getReg() const { 175 assert(isRegister() && "This is not a register operand!"); 176 return contents.RegNo; 177 } 178 179 /// MachineOperand mutators. 180 /// 181 void setReg(unsigned Reg) { 182 assert(isRegister() && "This is not a register operand!"); 183 contents.RegNo = Reg; 184 } 185 186 void setImmedValue(int64_t immVal) { 187 assert(isImm() && "Wrong MachineOperand mutator"); 188 contents.immedVal = immVal; 189 } 190 void setImm(int64_t immVal) { 191 assert(isImm() && "Wrong MachineOperand mutator"); 192 contents.immedVal = immVal; 193 } 194 195 void setOffset(int Offset) { 196 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() || 197 isJumpTableIndex()) && 198 "Wrong MachineOperand accessor"); 199 offset = Offset; 200 } 201 void setConstantPoolIndex(unsigned Idx) { 202 assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); 203 contents.immedVal = Idx; 204 } 205 206 207 /// ChangeToImmediate - Replace this operand with a new immediate operand of 208 /// the specified value. If an operand is known to be an immediate already, 209 /// the setImmedValue method should be used. 210 void ChangeToImmediate(int64_t ImmVal) { 211 opType = MO_Immediate; 212 contents.immedVal = ImmVal; 213 } 214 215 /// ChangeToRegister - Replace this operand with a new register operand of 216 /// the specified value. If an operand is known to be an register already, 217 /// the setReg method should be used. 218 void ChangeToRegister(unsigned Reg, bool isDef) { 219 opType = MO_Register; 220 contents.RegNo = Reg; 221 IsDef = isDef; 222 } 223 224 friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); 225 226 friend class MachineInstr; 227}; 228 229 230//===----------------------------------------------------------------------===// 231/// MachineInstr - Representation of each machine instruction. 232/// 233class MachineInstr { 234 short Opcode; // the opcode 235 std::vector<MachineOperand> Operands; // the operands 236 MachineInstr* prev, *next; // links for our intrusive list 237 MachineBasicBlock* parent; // pointer to the owning basic block 238 239 // OperandComplete - Return true if it's illegal to add a new operand 240 bool OperandsComplete() const; 241 242 MachineInstr(const MachineInstr&); 243 void operator=(const MachineInstr&); // DO NOT IMPLEMENT 244 245 // Intrusive list support 246 // 247 friend struct ilist_traits<MachineInstr>; 248 249public: 250 /// MachineInstr ctor - This constructor reserve's space for numOperand 251 /// operands. 252 MachineInstr(short Opcode, unsigned numOperands); 253 254 /// MachineInstr ctor - Work exactly the same as the ctor above, except that 255 /// the MachineInstr is created and added to the end of the specified basic 256 /// block. 257 /// 258 MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps); 259 260 ~MachineInstr(); 261 262 const MachineBasicBlock* getParent() const { return parent; } 263 MachineBasicBlock* getParent() { return parent; } 264 265 /// getOpcode - Returns the opcode of this MachineInstr. 266 /// 267 const int getOpcode() const { return Opcode; } 268 269 /// Access to explicit operands of the instruction. 270 /// 271 unsigned getNumOperands() const { return Operands.size(); } 272 273 const MachineOperand& getOperand(unsigned i) const { 274 assert(i < getNumOperands() && "getOperand() out of range!"); 275 return Operands[i]; 276 } 277 MachineOperand& getOperand(unsigned i) { 278 assert(i < getNumOperands() && "getOperand() out of range!"); 279 return Operands[i]; 280 } 281 282 283 /// clone - Create a copy of 'this' instruction that is identical in 284 /// all ways except the the instruction has no parent, prev, or next. 285 MachineInstr* clone() const { return new MachineInstr(*this); } 286 287 /// removeFromParent - This method unlinks 'this' from the containing basic 288 /// block, and returns it, but does not delete it. 289 MachineInstr *removeFromParent(); 290 291 /// eraseFromParent - This method unlinks 'this' from the containing basic 292 /// block and deletes it. 293 void eraseFromParent() { 294 delete removeFromParent(); 295 } 296 297 // 298 // Debugging support 299 // 300 void print(std::ostream &OS, const TargetMachine *TM) const; 301 void dump() const; 302 friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr); 303 304 //===--------------------------------------------------------------------===// 305 // Accessors to add operands when building up machine instructions. 306 // 307 308 /// addRegOperand - Add a register operand. 309 /// 310 void addRegOperand(unsigned Reg, bool IsDef) { 311 MachineOperand &Op = AddNewOperand(); 312 Op.opType = MachineOperand::MO_Register; 313 Op.IsDef = IsDef; 314 Op.contents.RegNo = Reg; 315 Op.offset = 0; 316 } 317 318 /// addImmOperand - Add a zero extended constant argument to the 319 /// machine instruction. 320 /// 321 void addImmOperand(int64_t Val) { 322 MachineOperand &Op = AddNewOperand(); 323 Op.opType = MachineOperand::MO_Immediate; 324 Op.contents.immedVal = Val; 325 Op.offset = 0; 326 } 327 328 void addMachineBasicBlockOperand(MachineBasicBlock *MBB) { 329 MachineOperand &Op = AddNewOperand(); 330 Op.opType = MachineOperand::MO_MachineBasicBlock; 331 Op.contents.MBB = MBB; 332 Op.offset = 0; 333 } 334 335 /// addFrameIndexOperand - Add an abstract frame index to the instruction 336 /// 337 void addFrameIndexOperand(unsigned Idx) { 338 MachineOperand &Op = AddNewOperand(); 339 Op.opType = MachineOperand::MO_FrameIndex; 340 Op.contents.immedVal = Idx; 341 Op.offset = 0; 342 } 343 344 /// addConstantPoolndexOperand - Add a constant pool object index to the 345 /// instruction. 346 /// 347 void addConstantPoolIndexOperand(unsigned Idx, int Offset) { 348 MachineOperand &Op = AddNewOperand(); 349 Op.opType = MachineOperand::MO_ConstantPoolIndex; 350 Op.contents.immedVal = Idx; 351 Op.offset = Offset; 352 } 353 354 /// addJumpTableIndexOperand - Add a jump table object index to the 355 /// instruction. 356 /// 357 void addJumpTableIndexOperand(unsigned Idx) { 358 MachineOperand &Op = AddNewOperand(); 359 Op.opType = MachineOperand::MO_JumpTableIndex; 360 Op.contents.immedVal = Idx; 361 Op.offset = 0; 362 } 363 364 void addGlobalAddressOperand(GlobalValue *GV, int Offset) { 365 MachineOperand &Op = AddNewOperand(); 366 Op.opType = MachineOperand::MO_GlobalAddress; 367 Op.contents.GV = GV; 368 Op.offset = Offset; 369 } 370 371 /// addExternalSymbolOperand - Add an external symbol operand to this instr 372 /// 373 void addExternalSymbolOperand(const char *SymName) { 374 MachineOperand &Op = AddNewOperand(); 375 Op.opType = MachineOperand::MO_ExternalSymbol; 376 Op.contents.SymbolName = SymName; 377 Op.offset = 0; 378 } 379 380 //===--------------------------------------------------------------------===// 381 // Accessors used to modify instructions in place. 382 // 383 384 /// setOpcode - Replace the opcode of the current instruction with a new one. 385 /// 386 void setOpcode(unsigned Op) { Opcode = Op; } 387 388 /// RemoveOperand - Erase an operand from an instruction, leaving it with one 389 /// fewer operand than it started with. 390 /// 391 void RemoveOperand(unsigned i) { 392 Operands.erase(Operands.begin()+i); 393 } 394private: 395 MachineOperand &AddNewOperand() { 396 assert(!OperandsComplete() && 397 "Trying to add an operand to a machine instr that is already done!"); 398 Operands.push_back(MachineOperand()); 399 return Operands.back(); 400 } 401}; 402 403//===----------------------------------------------------------------------===// 404// Debugging Support 405 406std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI); 407std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO); 408 409} // End llvm namespace 410 411#endif 412