diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h index 625f5c217097..9e49a975bc11 100644 --- a/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/llvm/include/llvm/Target/TargetInstrInfo.h @@ -76,6 +76,11 @@ const unsigned M_TERMINATOR_FLAG = 1 << 10; // block. const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 11; +// Machine operand flags +// M_LOOK_UP_PTR_REG_CLASS - Set if this operand is a pointer value and it +// requires a callback to look up its register class. +const unsigned M_LOOK_UP_PTR_REG_CLASS = 1 << 0; + /// TargetOperandInfo - This holds information about one operand of a machine /// instruction, indicating the register class for register operands, etc. /// @@ -84,7 +89,7 @@ public: /// RegClass - This specifies the register class of the operand if the /// operand is a register. If not, this contains null. const TargetRegisterClass *RegClass; - + unsigned Flags; /// Currently no other information. }; @@ -137,6 +142,13 @@ public: return get(Opcode).Name; } + const TargetRegisterClass + *getInstrOperandRegClass(const TargetInstrDescriptor *II, unsigned Op) const { + const TargetOperandInfo &toi = II->OpInfo[Op]; + return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS) + ? getPointerRegClass() : toi.RegClass; + } + int getNumOperands(MachineOpCode Opcode) const { return get(Opcode).numOperands; } @@ -275,6 +287,13 @@ public: assert(0 && "Target didn't implement insertNoop!"); abort(); } + + /// getPointerRegClass - Returns a TargetRegisterClass used for pointer + /// values. + virtual const TargetRegisterClass *getPointerRegClass() const { + assert(0 && "Target didn't implement getPointerRegClass!"); + abort(); + } /// hasDelaySlot - Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 523062053d88..cfe5e6b0767d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -229,16 +229,17 @@ static unsigned CountOperands(SDNode *Node) { static unsigned CreateVirtualRegisters(MachineInstr *MI, unsigned NumResults, SSARegMap *RegMap, + const TargetInstrInfo *TII, const TargetInstrDescriptor &II) { // Create the result registers for this node and add the result regs to // the machine instruction. - const TargetOperandInfo *OpInfo = II.OpInfo; - unsigned ResultReg = RegMap->createVirtualRegister(OpInfo[0].RegClass); + unsigned ResultReg = + RegMap->createVirtualRegister(TII->getInstrOperandRegClass(&II, 0)); MI->addRegOperand(ResultReg, MachineOperand::Def); for (unsigned i = 1; i != NumResults; ++i) { - assert(OpInfo[i].RegClass && "Isn't a register operand!"); - MI->addRegOperand(RegMap->createVirtualRegister(OpInfo[i].RegClass), - MachineOperand::Def); + const TargetRegisterClass *RC = TII->getInstrOperandRegClass(&II, i); + assert(RC && "Isn't a register operand!"); + MI->addRegOperand(RegMap->createVirtualRegister(RC), MachineOperand::Def); } return ResultReg; } @@ -275,9 +276,9 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, // Verify that it is right. assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); if (II) { - assert(II->OpInfo[IIOpNum].RegClass && - "Don't have operand info for this instruction!"); - assert(RegMap->getRegClass(VReg) == II->OpInfo[IIOpNum].RegClass && + const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum); + assert(RC && "Don't have operand info for this instruction!"); + assert(RegMap->getRegClass(VReg) == RC && "Register class of operand and regclass of use don't agree!"); } } else if (ConstantSDNode *C = @@ -332,9 +333,9 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, // Verify that it is right. assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); if (II) { - assert(II->OpInfo[IIOpNum].RegClass && - "Don't have operand info for this instruction!"); - assert(RegMap->getRegClass(VReg) == II->OpInfo[IIOpNum].RegClass && + const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum); + assert(RC && "Don't have operand info for this instruction!"); + assert(RegMap->getRegClass(VReg) == RC && "Register class of operand and regclass of use don't agree!"); } } @@ -387,7 +388,7 @@ void ScheduleDAG::EmitNode(SDNode *Node, // Otherwise, create new virtual registers. if (NumResults && VRBase == 0) - VRBase = CreateVirtualRegisters(MI, NumResults, RegMap, II); + VRBase = CreateVirtualRegisters(MI, NumResults, RegMap, TII, II); // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index a713bc330d73..66d17cb86bb8 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -139,11 +139,13 @@ void InstrInfoEmitter::run(std::ostream &OS) { for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) { Record *RC = OperandInfo[i]; // FIXME: We only care about register operands for now. - if (RC && RC->isSubClassOf("RegisterClass")) { - OS << "{ &" << getQualifiedName(RC) << "RegClass }, "; - } else { - OS << "{ 0 }, "; - } + if (RC && RC->isSubClassOf("RegisterClass")) + OS << "{ &" << getQualifiedName(RC) << "RegClass, 0 }, "; + else if (RC && RC->getName() == "ptr_rc") + // Ptr value whose register class is resolved via callback. + OS << "{ 0, 1 }, "; + else + OS << "{ 0, 0 }, "; } OS << "};\n"; }