lib/Target/Target.td

llvm-svn: 28386
This commit is contained in:
Evan Cheng 2006-05-18 20:42:07 +00:00
parent 8d88fc5ee4
commit d8e2f6ebc1
3 changed files with 40 additions and 18 deletions

View File

@ -76,6 +76,11 @@ const unsigned M_TERMINATOR_FLAG = 1 << 10;
// block. // block.
const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 11; 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 /// TargetOperandInfo - This holds information about one operand of a machine
/// instruction, indicating the register class for register operands, etc. /// 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 /// RegClass - This specifies the register class of the operand if the
/// operand is a register. If not, this contains null. /// operand is a register. If not, this contains null.
const TargetRegisterClass *RegClass; const TargetRegisterClass *RegClass;
unsigned Flags;
/// Currently no other information. /// Currently no other information.
}; };
@ -137,6 +142,13 @@ public:
return get(Opcode).Name; 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 { int getNumOperands(MachineOpCode Opcode) const {
return get(Opcode).numOperands; return get(Opcode).numOperands;
} }
@ -275,6 +287,13 @@ public:
assert(0 && "Target didn't implement insertNoop!"); assert(0 && "Target didn't implement insertNoop!");
abort(); 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 /// hasDelaySlot - Returns true if the specified instruction has a delay slot
/// which must be filled by the code generator. /// which must be filled by the code generator.

View File

@ -229,16 +229,17 @@ static unsigned CountOperands(SDNode *Node) {
static unsigned CreateVirtualRegisters(MachineInstr *MI, static unsigned CreateVirtualRegisters(MachineInstr *MI,
unsigned NumResults, unsigned NumResults,
SSARegMap *RegMap, SSARegMap *RegMap,
const TargetInstrInfo *TII,
const TargetInstrDescriptor &II) { const TargetInstrDescriptor &II) {
// Create the result registers for this node and add the result regs to // Create the result registers for this node and add the result regs to
// the machine instruction. // the machine instruction.
const TargetOperandInfo *OpInfo = II.OpInfo; unsigned ResultReg =
unsigned ResultReg = RegMap->createVirtualRegister(OpInfo[0].RegClass); RegMap->createVirtualRegister(TII->getInstrOperandRegClass(&II, 0));
MI->addRegOperand(ResultReg, MachineOperand::Def); MI->addRegOperand(ResultReg, MachineOperand::Def);
for (unsigned i = 1; i != NumResults; ++i) { for (unsigned i = 1; i != NumResults; ++i) {
assert(OpInfo[i].RegClass && "Isn't a register operand!"); const TargetRegisterClass *RC = TII->getInstrOperandRegClass(&II, i);
MI->addRegOperand(RegMap->createVirtualRegister(OpInfo[i].RegClass), assert(RC && "Isn't a register operand!");
MachineOperand::Def); MI->addRegOperand(RegMap->createVirtualRegister(RC), MachineOperand::Def);
} }
return ResultReg; return ResultReg;
} }
@ -275,9 +276,9 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
// Verify that it is right. // Verify that it is right.
assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
if (II) { if (II) {
assert(II->OpInfo[IIOpNum].RegClass && const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum);
"Don't have operand info for this instruction!"); assert(RC && "Don't have operand info for this instruction!");
assert(RegMap->getRegClass(VReg) == II->OpInfo[IIOpNum].RegClass && assert(RegMap->getRegClass(VReg) == RC &&
"Register class of operand and regclass of use don't agree!"); "Register class of operand and regclass of use don't agree!");
} }
} else if (ConstantSDNode *C = } else if (ConstantSDNode *C =
@ -332,9 +333,9 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
// Verify that it is right. // Verify that it is right.
assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
if (II) { if (II) {
assert(II->OpInfo[IIOpNum].RegClass && const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum);
"Don't have operand info for this instruction!"); assert(RC && "Don't have operand info for this instruction!");
assert(RegMap->getRegClass(VReg) == II->OpInfo[IIOpNum].RegClass && assert(RegMap->getRegClass(VReg) == RC &&
"Register class of operand and regclass of use don't agree!"); "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. // Otherwise, create new virtual registers.
if (NumResults && VRBase == 0) 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 // Emit all of the actual operands of this instruction, adding them to the
// instruction as appropriate. // instruction as appropriate.

View File

@ -139,11 +139,13 @@ void InstrInfoEmitter::run(std::ostream &OS) {
for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) { for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) {
Record *RC = OperandInfo[i]; Record *RC = OperandInfo[i];
// FIXME: We only care about register operands for now. // FIXME: We only care about register operands for now.
if (RC && RC->isSubClassOf("RegisterClass")) { if (RC && RC->isSubClassOf("RegisterClass"))
OS << "{ &" << getQualifiedName(RC) << "RegClass }, "; OS << "{ &" << getQualifiedName(RC) << "RegClass, 0 }, ";
} else { else if (RC && RC->getName() == "ptr_rc")
OS << "{ 0 }, "; // Ptr value whose register class is resolved via callback.
} OS << "{ 0, 1 }, ";
else
OS << "{ 0, 0 }, ";
} }
OS << "};\n"; OS << "};\n";
} }