mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Instructions with variable operands (variable_ops) can have a number required
operands. e.g. def CALL32r : I<0xFF, MRM2r, (ops GR32:$dst, variable_ops), "call {*}$dst", [(X86call GR32:$dst)]>; TableGen should emit operand informations for the "required" operands. Added a target instruction info flag M_VARIABLE_OPS to indicate the target instruction may have more operands in addition to the minimum required operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28791 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d7c2c86239
commit
8d3af5e7d0
@ -76,6 +76,10 @@ 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;
|
||||||
|
|
||||||
|
// M_VARIABLE_OPS - Set if this instruction can have a variable number of extra
|
||||||
|
// operands in addition to the minimum number operands specified.
|
||||||
|
const unsigned M_VARIABLE_OPS = 1 << 12;
|
||||||
|
|
||||||
// Machine operand flags
|
// Machine operand flags
|
||||||
// M_LOOK_UP_PTR_REG_CLASS - Set if this operand is a pointer value and it
|
// 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.
|
// requires a callback to look up its register class.
|
||||||
@ -97,7 +101,7 @@ public:
|
|||||||
class TargetInstrDescriptor {
|
class TargetInstrDescriptor {
|
||||||
public:
|
public:
|
||||||
const char * Name; // Assembly language mnemonic for the opcode.
|
const char * Name; // Assembly language mnemonic for the opcode.
|
||||||
int numOperands; // Number of args; -1 if variable #args
|
unsigned numOperands; // Num of args (may be more if variable_ops).
|
||||||
InstrSchedClass schedClass; // enum identifying instr sched class
|
InstrSchedClass schedClass; // enum identifying instr sched class
|
||||||
unsigned Flags; // flags identifying machine instr class
|
unsigned Flags; // flags identifying machine instr class
|
||||||
unsigned TSFlags; // Target Specific Flag values
|
unsigned TSFlags; // Target Specific Flag values
|
||||||
@ -144,6 +148,11 @@ public:
|
|||||||
|
|
||||||
const TargetRegisterClass
|
const TargetRegisterClass
|
||||||
*getInstrOperandRegClass(const TargetInstrDescriptor *II, unsigned Op) const {
|
*getInstrOperandRegClass(const TargetInstrDescriptor *II, unsigned Op) const {
|
||||||
|
if (Op >= II->numOperands) {
|
||||||
|
if (II->Flags & M_VARIABLE_OPS)
|
||||||
|
return NULL;
|
||||||
|
assert(false && "Invalid operand # of instruction");
|
||||||
|
}
|
||||||
const TargetOperandInfo &toi = II->OpInfo[Op];
|
const TargetOperandInfo &toi = II->OpInfo[Op];
|
||||||
return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS)
|
return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS)
|
||||||
? getPointerRegClass() : toi.RegClass;
|
? getPointerRegClass() : toi.RegClass;
|
||||||
@ -212,6 +221,10 @@ public:
|
|||||||
return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION;
|
return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasVariableOperands(MachineOpCode Opcode) const {
|
||||||
|
return get(Opcode).Flags & M_VARIABLE_OPS;
|
||||||
|
}
|
||||||
|
|
||||||
/// Return true if the instruction is a register to register move
|
/// Return true if the instruction is a register to register move
|
||||||
/// and leave the source and dest operands in the passed parameters.
|
/// and leave the source and dest operands in the passed parameters.
|
||||||
virtual bool isMoveInstr(const MachineInstr& MI,
|
virtual bool isMoveInstr(const MachineInstr& MI,
|
||||||
|
@ -91,7 +91,8 @@ MachineInstr *MachineInstr::removeFromParent() {
|
|||||||
///
|
///
|
||||||
bool MachineInstr::OperandsComplete() const {
|
bool MachineInstr::OperandsComplete() const {
|
||||||
int NumOperands = TargetInstrDescriptors[Opcode].numOperands;
|
int NumOperands = TargetInstrDescriptors[Opcode].numOperands;
|
||||||
if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
|
if ((TargetInstrDescriptors[Opcode].Flags & M_VARIABLE_OPS) == 0 &&
|
||||||
|
getNumOperands() >= (unsigned)NumOperands)
|
||||||
return true; // Broken: we have all the operands of this instruction!
|
return true; // Broken: we have all the operands of this instruction!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +358,8 @@ void ScheduleDAG::EmitNode(SDNode *Node,
|
|||||||
unsigned NodeOperands = CountOperands(Node);
|
unsigned NodeOperands = CountOperands(Node);
|
||||||
unsigned NumMIOperands = NodeOperands + NumResults;
|
unsigned NumMIOperands = NodeOperands + NumResults;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert((unsigned(II.numOperands) == NumMIOperands || II.numOperands == -1)&&
|
assert((unsigned(II.numOperands) == NumMIOperands ||
|
||||||
|
(II.Flags & M_VARIABLE_OPS)) &&
|
||||||
"#operands for dag node doesn't match .td file!");
|
"#operands for dag node doesn't match .td file!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -64,9 +64,6 @@ void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses,
|
|||||||
|
|
||||||
static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) {
|
static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) {
|
||||||
std::vector<Record*> Result;
|
std::vector<Record*> Result;
|
||||||
if (Inst.hasVariableNumberOfOperands)
|
|
||||||
return Result; // No info for variable operand instrs.
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
|
||||||
if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) {
|
if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) {
|
||||||
Result.push_back(Inst.OperandList[i].Rec);
|
Result.push_back(Inst.OperandList[i].Rec);
|
||||||
@ -170,15 +167,13 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
|||||||
std::map<std::vector<Record*>, unsigned> &EmittedLists,
|
std::map<std::vector<Record*>, unsigned> &EmittedLists,
|
||||||
std::map<std::vector<Record*>, unsigned> &OpInfo,
|
std::map<std::vector<Record*>, unsigned> &OpInfo,
|
||||||
std::ostream &OS) {
|
std::ostream &OS) {
|
||||||
int NumOperands;
|
int MinOperands;
|
||||||
if (Inst.hasVariableNumberOfOperands)
|
if (!Inst.OperandList.empty())
|
||||||
NumOperands = -1;
|
|
||||||
else if (!Inst.OperandList.empty())
|
|
||||||
// Each logical operand can be multiple MI operands.
|
// Each logical operand can be multiple MI operands.
|
||||||
NumOperands = Inst.OperandList.back().MIOperandNo +
|
MinOperands = Inst.OperandList.back().MIOperandNo +
|
||||||
Inst.OperandList.back().MINumOperands;
|
Inst.OperandList.back().MINumOperands;
|
||||||
else
|
else
|
||||||
NumOperands = 0;
|
MinOperands = 0;
|
||||||
|
|
||||||
OS << " { \"";
|
OS << " { \"";
|
||||||
if (Inst.Name.empty())
|
if (Inst.Name.empty())
|
||||||
@ -189,7 +184,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
|||||||
unsigned ItinClass = !IsItineraries ? 0 :
|
unsigned ItinClass = !IsItineraries ? 0 :
|
||||||
ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName());
|
ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName());
|
||||||
|
|
||||||
OS << "\",\t" << NumOperands << ", " << ItinClass
|
OS << "\",\t" << MinOperands << ", " << ItinClass
|
||||||
<< ", 0";
|
<< ", 0";
|
||||||
|
|
||||||
// Try to determine (from the pattern), if the instruction is a store.
|
// Try to determine (from the pattern), if the instruction is a store.
|
||||||
@ -224,6 +219,8 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
|||||||
if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG";
|
if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG";
|
||||||
if (Inst.usesCustomDAGSchedInserter)
|
if (Inst.usesCustomDAGSchedInserter)
|
||||||
OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION";
|
OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION";
|
||||||
|
if (Inst.hasVariableNumberOfOperands)
|
||||||
|
OS << "|M_VARIABLE_OPS";
|
||||||
OS << ", 0";
|
OS << ", 0";
|
||||||
|
|
||||||
// Emit all of the target-specific flags...
|
// Emit all of the target-specific flags...
|
||||||
|
Loading…
Reference in New Issue
Block a user