diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 04f07abce60..b5bb25a4b3a 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -88,9 +88,20 @@ private: char flags; // see bit field definitions above int regNum; // register number for an explicit register // will be set for a value after reg allocation +private: + MachineOperand() + : immedVal(0), opType(MO_VirtualRegister), flags(0), regNum(-1) {} + MachineOperand(int64_t ImmVal, MachineOperandType OpTy) + : immedVal(ImmVal), opType(OpTy), flags(0), regNum(-1) {} + MachineOperand(int Reg, MachineOperandType OpTy, bool isDef = false) + : immedVal(0), opType(OpTy), flags(isDef ? DEFFLAG : 0), regNum(Reg) {} + MachineOperand(Value *V, MachineOperandType OpTy, + bool isDef = false, bool isDNU = false) + : value(V), opType(OpTy), regNum(-1) { + flags = (isDef ? DEFFLAG : 0) | (isDNU ? DEFUSEFLAG : 0); + } + public: - MachineOperand() : immedVal(0), opType(MO_VirtualRegister), - flags(0), regNum(-1) {} MachineOperand(const MachineOperand &M) : immedVal(M.immedVal), opType(M.opType), flags(M.flags), regNum(M.regNum) { } @@ -210,21 +221,26 @@ class MachineInstr : public Annotable, // MachineInstrs are annotable // regsUsed - all machine registers used for this instruction, including regs // used to save values across the instruction. This is a bitset of registers. std::vector regsUsed; + + // OperandComplete - Return true if it's illegal to add a new operand + bool OperandsComplete() const; public: - /*ctor*/ MachineInstr (MachineOpCode _opCode, - OpCodeMask _opCodeMask = 0); - /*ctor*/ MachineInstr (MachineOpCode _opCode, - unsigned numOperands, - OpCodeMask _opCodeMask = 0); - inline ~MachineInstr () {} + MachineInstr(MachineOpCode Opcode, OpCodeMask OpcodeMask = 0); + MachineInstr(MachineOpCode Opcode, unsigned numOperands, OpCodeMask Mask = 0); + + /// MachineInstr ctor - This constructor only does a _reserve_ of the + /// operands, not a resize for them. It is expected that if you use this that + /// you call add* methods below to fill up the operands, instead of the Set + /// methods. + /// + MachineInstr(MachineOpCode Opcode, unsigned numOperands, bool XX, bool YY); // // Support to rewrite a machine instruction in place: for now, simply // replace() and then set new operands with Set.*Operand methods below. // - void replace (MachineOpCode _opCode, - unsigned numOperands, - OpCodeMask _opCodeMask = 0x0); + void replace(MachineOpCode Opcode, unsigned numOperands, + OpCodeMask Mask = 0x0); // // The opcode. @@ -327,6 +343,67 @@ public: int64_t intValue); void SetMachineOperandReg(unsigned i, int regNum, bool isDef=false); + //===--------------------------------------------------------------------===// + // Accessors to add operands when building up machine instructions + // + + /// addRegOperand - Add a MO_VirtualRegister operand to the end of the + /// operands list... + /// + void addRegOperand(Value *V, bool isDef=false, bool isDefAndUse=false) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(V, MachineOperand::MO_VirtualRegister, + isDef, isDefAndUse)); + } + + /// addRegOperand - Add a symbolic virtual register reference... + /// + void addRegOperand(int reg) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(reg, MachineOperand::MO_VirtualRegister)); + } + + /// addPCDispOperand - Add a PC relative displacement operand to the MI + /// + void addPCDispOperand(Value *V) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(V, MachineOperand::MO_PCRelativeDisp)); + } + + /// addMachineRegOperand - Add a virtual register operand to this MachineInstr + /// + void addMachineRegOperand(int reg, bool isDef=false) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister, + isDef)); + insertUsedReg(reg); + } + + /// addZeroExtImmOperand - Add a zero extended constant argument to the + /// machine instruction. + /// + void addZeroExtImmOperand(int64_t intValue) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(intValue, + MachineOperand::MO_UnextendedImmed)); + } + + /// addSignExtImmOperand - Add a zero extended constant argument to the + /// machine instruction. + /// + void addSignExtImmOperand(int64_t intValue) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(intValue, + MachineOperand::MO_SignExtendedImmed)); + } + + unsigned substituteValue(const Value* oldVal, Value* newVal, bool defsOnly = true); diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index c3c5ca8fead..2a1893cc3d0 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -11,41 +11,42 @@ using std::cerr; // Constructor for instructions with fixed #operands (nearly all) MachineInstr::MachineInstr(MachineOpCode _opCode, OpCodeMask _opCodeMask) - : opCode(_opCode), - opCodeMask(_opCodeMask), - operands(TargetInstrDescriptors[_opCode].numOperands) -{ + : opCode(_opCode), opCodeMask(_opCodeMask), + operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()) { assert(TargetInstrDescriptors[_opCode].numOperands >= 0); } // Constructor for instructions with variable #operands -MachineInstr::MachineInstr(MachineOpCode _opCode, - unsigned numOperands, - OpCodeMask _opCodeMask) - : opCode(_opCode), - opCodeMask(_opCodeMask), - operands(numOperands) -{ +MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands, + OpCodeMask OpCodeMask) + : opCode(OpCode), opCodeMask(OpCodeMask), + operands(numOperands, MachineOperand()) { } +// OperandComplete - Return true if it's illegal to add a new operand +bool MachineInstr::OperandsComplete() const { + int NumOperands = TargetInstrDescriptors[opCode].numOperands; + if (NumOperands >= 0 && operands.size() >= (unsigned)NumOperands) + return true; // Broken! + return false; +} + + // // Support for replacing opcode and operands of a MachineInstr in place. // This only resets the size of the operand vector and initializes it. // The new operands must be set explicitly later. // -void -MachineInstr::replace(MachineOpCode _opCode, - unsigned numOperands, - OpCodeMask _opCodeMask) -{ - opCode = _opCode; - opCodeMask = _opCodeMask; +void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands, + OpCodeMask Mask) { + opCode = Opcode; + opCodeMask = Mask; operands.clear(); - operands.resize(numOperands); + operands.resize(numOperands, MachineOperand()); } void -MachineInstr::SetMachineOperandVal(unsigned int i, +MachineInstr::SetMachineOperandVal(unsigned i, MachineOperand::MachineOperandType opType, Value* V, bool isdef,