mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Allow targets to optionally specify custom binary encoder functions for
operand values. This is useful for operands which require additional trickery to encode into the instruction. For example, the ARM shifted immediate and shifted register operands. llvm-svn: 116353
This commit is contained in:
parent
33a26354c1
commit
394bc160f9
@ -154,7 +154,6 @@ void CodeEmitterGen::run(raw_ostream &o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gotOp) {
|
if (!gotOp) {
|
||||||
|
|
||||||
// If the operand matches by name, reference according to that
|
// If the operand matches by name, reference according to that
|
||||||
// operand number. Non-matching operands are assumed to be in
|
// operand number. Non-matching operands are assumed to be in
|
||||||
// order.
|
// order.
|
||||||
@ -171,10 +170,26 @@ void CodeEmitterGen::run(raw_ostream &o) {
|
|||||||
++NumberedOp;
|
++NumberedOp;
|
||||||
OpIdx = NumberedOp++;
|
OpIdx = NumberedOp++;
|
||||||
}
|
}
|
||||||
|
std::pair<unsigned, unsigned> SO = CGI.getSubOperandNumber(OpIdx);
|
||||||
|
std::string &EncoderMethodName =
|
||||||
|
CGI.OperandList[SO.first].EncoderMethodName;
|
||||||
|
|
||||||
|
// If the source operand has a custom encoder, use it. This will
|
||||||
|
// get the encoding for all of the suboperands.
|
||||||
|
if (!EncoderMethodName.empty()) {
|
||||||
|
// A custom encoder has all of the information for the
|
||||||
|
// sub-operands, if there are more than one, so only
|
||||||
|
// query the encoder once per source operand.
|
||||||
|
if (SO.second == 0) {
|
||||||
|
Case += " // op: " + VarName + "\n"
|
||||||
|
+ " op = " + EncoderMethodName + "(MI, "
|
||||||
|
+ utostr(OpIdx) + ");\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Case += " // op: " + VarName + "\n"
|
Case += " // op: " + VarName + "\n"
|
||||||
+ " op = getMachineOpValue(MI, MI.getOperand("
|
+ " op = getMachineOpValue(MI, MI.getOperand("
|
||||||
+ utostr(OpIdx) + "));\n";
|
+ utostr(OpIdx) + "));\n";
|
||||||
|
}
|
||||||
gotOp = true;
|
gotOp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,10 +166,14 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
|
|||||||
|
|
||||||
Record *Rec = Arg->getDef();
|
Record *Rec = Arg->getDef();
|
||||||
std::string PrintMethod = "printOperand";
|
std::string PrintMethod = "printOperand";
|
||||||
|
std::string EncoderMethod;
|
||||||
unsigned NumOps = 1;
|
unsigned NumOps = 1;
|
||||||
DagInit *MIOpInfo = 0;
|
DagInit *MIOpInfo = 0;
|
||||||
if (Rec->isSubClassOf("Operand")) {
|
if (Rec->isSubClassOf("Operand")) {
|
||||||
PrintMethod = Rec->getValueAsString("PrintMethod");
|
PrintMethod = Rec->getValueAsString("PrintMethod");
|
||||||
|
// If there is an explicit encoder method, use it.
|
||||||
|
if (Rec->getValue("EncoderMethod"))
|
||||||
|
EncoderMethod = Rec->getValueAsString("EncoderMethod");
|
||||||
MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
|
MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
|
||||||
|
|
||||||
// Verify that MIOpInfo has an 'ops' root value.
|
// Verify that MIOpInfo has an 'ops' root value.
|
||||||
@ -204,7 +208,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
|
|||||||
throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
|
throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
|
||||||
" has the same name as a previous operand!";
|
" has the same name as a previous operand!";
|
||||||
|
|
||||||
OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod,
|
OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
|
||||||
MIOperandNo, NumOps, MIOpInfo));
|
MIOperandNo, NumOps, MIOpInfo));
|
||||||
MIOperandNo += NumOps;
|
MIOperandNo += NumOps;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,10 @@ namespace llvm {
|
|||||||
/// the asmprinter.
|
/// the asmprinter.
|
||||||
std::string PrinterMethodName;
|
std::string PrinterMethodName;
|
||||||
|
|
||||||
|
/// EncoderMethodName - The method used to get the machine operand value
|
||||||
|
/// for binary encoding. "getMachineOpValue" by default.
|
||||||
|
std::string EncoderMethodName;
|
||||||
|
|
||||||
/// MIOperandNo - Currently (this is meant to be phased out), some logical
|
/// MIOperandNo - Currently (this is meant to be phased out), some logical
|
||||||
/// operands correspond to multiple MachineInstr operands. In the X86
|
/// operands correspond to multiple MachineInstr operands. In the X86
|
||||||
/// target for example, one address operand is represented as 4
|
/// target for example, one address operand is represented as 4
|
||||||
@ -101,9 +105,10 @@ namespace llvm {
|
|||||||
std::vector<ConstraintInfo> Constraints;
|
std::vector<ConstraintInfo> Constraints;
|
||||||
|
|
||||||
OperandInfo(Record *R, const std::string &N, const std::string &PMN,
|
OperandInfo(Record *R, const std::string &N, const std::string &PMN,
|
||||||
unsigned MION, unsigned MINO, DagInit *MIOI)
|
const std::string &EMN, unsigned MION, unsigned MINO,
|
||||||
: Rec(R), Name(N), PrinterMethodName(PMN), MIOperandNo(MION),
|
DagInit *MIOI)
|
||||||
MINumOperands(MINO), MIOperandInfo(MIOI) {}
|
: Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
|
||||||
|
MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// NumDefs - Number of def operands declared, this is the number of
|
/// NumDefs - Number of def operands declared, this is the number of
|
||||||
|
Loading…
Reference in New Issue
Block a user