/// MachineInstr - Representation of each machine instruction.
///
class MachineInstr {
- short Opcode; // the opcode
+ const TargetInstrDescriptor *TID; // Instruction descriptor.
unsigned short NumImplicitOps; // Number of implicit operands (which
// are determined at construction time).
public:
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
- /// opcode 0 and no operands.
+ /// TID NULL and no operands.
MachineInstr();
/// MachineInstr ctor - This constructor create a MachineInstr and add the
const MachineBasicBlock* getParent() const { return parent; }
MachineBasicBlock* getParent() { return parent; }
+
+ /// getInstrDescriptor - Returns the target instruction descriptor of this
+ /// MachineInstr.
+ const TargetInstrDescriptor *getInstrDescriptor() const { return TID; }
/// getOpcode - Returns the opcode of this MachineInstr.
///
- const int getOpcode() const { return Opcode; }
+ const int getOpcode() const;
/// Access to explicit operands of the instruction.
///
// Accessors used to modify instructions in place.
//
- /// setOpcode - Replace the opcode of the current instruction with a new one.
+ /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of
+ /// the current instruction with a new one.
///
- void setOpcode(unsigned Op) { Opcode = Op; }
+ void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; }
/// RemoveOperand - Erase an operand from an instruction, leaving it with one
/// fewer operand than it started with.
/// addImplicitDefUseOperands - Add all implicit def and use operands to
/// this instruction.
- void addImplicitDefUseOperands(const TargetInstrDescriptor &TID);
+ void addImplicitDefUseOperands();
};
//===----------------------------------------------------------------------===//
#include <iostream>
using namespace llvm;
-// Global variable holding an array of descriptors for machine instructions.
-// The actual object needs to be created separately for each target machine.
-// This variable is initialized and reset by class TargetInstrInfo.
-//
-// FIXME: This should be a property of the target so that more than one target
-// at a time can be active...
-//
-namespace llvm {
- extern const TargetInstrDescriptor *TargetInstrDescriptors;
-}
-
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
-/// opcode 0 and no operands.
+/// TID NULL and no operands.
MachineInstr::MachineInstr()
- : Opcode(0), NumImplicitOps(0), parent(0) {
+ : TID(0), NumImplicitOps(0), parent(0) {
// Make sure that we get added to a machine basicblock
LeakDetector::addGarbageObject(this);
}
-void MachineInstr::addImplicitDefUseOperands(const TargetInstrDescriptor &TID) {
- if (TID.ImplicitDefs)
- for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) {
+void MachineInstr::addImplicitDefUseOperands() {
+ if (TID->ImplicitDefs)
+ for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) {
MachineOperand Op;
Op.opType = MachineOperand::MO_Register;
Op.IsDef = true;
Op.offset = 0;
Operands.push_back(Op);
}
- if (TID.ImplicitUses)
- for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) {
+ if (TID->ImplicitUses)
+ for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) {
MachineOperand Op;
Op.opType = MachineOperand::MO_Register;
Op.IsDef = false;
/// implicit operands. It reserves space for number of operands specified by
/// TargetInstrDescriptor or the numOperands if it is not zero. (for
/// instructions with variable number of operands).
-MachineInstr::MachineInstr(const TargetInstrDescriptor &TID)
- : Opcode(TID.Opcode), NumImplicitOps(0), parent(0) {
- if (TID.ImplicitDefs)
- for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs)
+MachineInstr::MachineInstr(const TargetInstrDescriptor &tid)
+ : TID(&tid), NumImplicitOps(0), parent(0) {
+ if (TID->ImplicitDefs)
+ for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs)
NumImplicitOps++;
- if (TID.ImplicitUses)
- for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses)
+ if (TID->ImplicitUses)
+ for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses)
NumImplicitOps++;
- Operands.reserve(NumImplicitOps + TID.numOperands);
- addImplicitDefUseOperands(TID);
+ Operands.reserve(NumImplicitOps + TID->numOperands);
+ addImplicitDefUseOperands();
// Make sure that we get added to a machine basicblock
LeakDetector::addGarbageObject(this);
}
/// MachineInstr is created and added to the end of the specified basic block.
///
MachineInstr::MachineInstr(MachineBasicBlock *MBB,
- const TargetInstrDescriptor &TID)
- : Opcode(TID.Opcode), NumImplicitOps(0), parent(0) {
+ const TargetInstrDescriptor &tid)
+ : TID(&tid), NumImplicitOps(0), parent(0) {
assert(MBB && "Cannot use inserting ctor with null basic block!");
- if (TID.ImplicitDefs)
- for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs)
+ if (TID->ImplicitDefs)
+ for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs)
NumImplicitOps++;
- if (TID.ImplicitUses)
- for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses)
+ if (TID->ImplicitUses)
+ for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses)
NumImplicitOps++;
- Operands.reserve(NumImplicitOps + TID.numOperands);
- addImplicitDefUseOperands(TID);
+ Operands.reserve(NumImplicitOps + TID->numOperands);
+ addImplicitDefUseOperands();
// Make sure that we get added to a machine basicblock
LeakDetector::addGarbageObject(this);
MBB->push_back(this); // Add instruction to end of basic block!
/// MachineInstr ctor - Copies MachineInstr arg exactly
///
MachineInstr::MachineInstr(const MachineInstr &MI) {
- Opcode = MI.getOpcode();
+ TID = MI.getInstrDescriptor();
NumImplicitOps = MI.NumImplicitOps;
Operands.reserve(MI.getNumOperands());
LeakDetector::removeGarbageObject(this);
}
+/// getOpcode - Returns the opcode of this MachineInstr.
+///
+const int MachineInstr::getOpcode() const {
+ return TID->Opcode;
+}
+
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, and returns it, but does not delete it.
MachineInstr *MachineInstr::removeFromParent() {
/// OperandComplete - Return true if it's illegal to add a new operand
///
bool MachineInstr::OperandsComplete() const {
- unsigned short NumOperands = TargetInstrDescriptors[Opcode].numOperands;
- if ((TargetInstrDescriptors[Opcode].Flags & M_VARIABLE_OPS) == 0 &&
+ unsigned short NumOperands = TID->numOperands;
+ if ((TID->Flags & M_VARIABLE_OPS) == 0 &&
getNumOperands()-NumImplicitOps >= NumOperands)
return true; // Broken: we have all the operands of this instruction!
return false;
++StartOp; // Don't print this operand again!
}
- // Must check if Target machine is not null because machine BB could not
- // be attached to a Machine function yet
- if (TM)
- OS << TM->getInstrInfo()->getName(getOpcode());
+ if (TID)
+ OS << TID->Name;
for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
const MachineOperand& mop = getOperand(i);
// Otherwise, print it out in the "raw" format without symbolic register names
// and such.
- os << TargetInstrDescriptors[MI.getOpcode()].Name;
+ os << MI.getInstrDescriptor()->Name;
for (unsigned i = 0, N = MI.getNumOperands(); i < N; i++) {
os << "\t" << MI.getOperand(i);