forked from OSchip/llvm-project
parent
8d88fc5ee4
commit
d8e2f6ebc1
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -276,6 +288,13 @@ public:
|
||||||
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.
|
||||||
bool hasDelaySlot(unsigned Opcode) const {
|
bool hasDelaySlot(unsigned Opcode) const {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue