mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-30 09:01:19 +00:00
Rework C translation.
This commit is contained in:
parent
37ada75258
commit
fe28fc2014
@ -74,11 +74,9 @@ We use the following emitter backends
|
||||
|
||||
## Developer notes
|
||||
|
||||
- If you find C++ code within the generated files check the `.td` files again.
|
||||
You can replace any C++ code except calls to template functions (those are used by `auto-sync's` `TemplateCollector`).
|
||||
If the `PrinterCapstone` is used the calls to template functions are patched in `PrinterCapstone::resolveTemplateCall()`.
|
||||
Syntax to define C++ code in `.td` files is `[{ code }]`
|
||||
Also see: TableGen syntax for [TokCode](https://llvm.org/docs/TableGen/ProgRef.html#grammar-token-tokcode) (usually used for code snippets).
|
||||
- If you find C++ code within the generated files you need to extend `PrinterCapstone::translateToC()`.
|
||||
If this still doesn't fix the problem, the code snipped wasn't passed through `translateToC()` before emitting.
|
||||
So you need to figure out where this specific code snipped is printed and add `translateToC()`.
|
||||
|
||||
- If the mapping files miss operand types or access information, then the `.td` files are incomplete (happens surprisingly often).
|
||||
You need to search for the instruction or operands with missing or incorrect values and fix them.
|
||||
|
@ -76,10 +76,10 @@ def sve_logical_imm8 : Operand<i64> {
|
||||
let PrintMethod = "printLogicalImm<int8_t>";
|
||||
|
||||
let MCOperandPredicate = [{
|
||||
if (!MCOperand_isImm(MCOp))
|
||||
if (!MCOp.isImm())
|
||||
return false;
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOperand_getImm(MCOp), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements_int8_t(Val);
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm()), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements<int8_t>(Val);
|
||||
}];
|
||||
}
|
||||
|
||||
@ -88,10 +88,10 @@ def sve_logical_imm16 : Operand<i64> {
|
||||
let PrintMethod = "printLogicalImm<int16_t>";
|
||||
|
||||
let MCOperandPredicate = [{
|
||||
if (!MCOperand_isImm(MCOp))
|
||||
if (!MCOp.isImm())
|
||||
return false;
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOperand_getImm(MCOp), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements_int16_t(Val);
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm()), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements<int16_t>(Val);
|
||||
}];
|
||||
}
|
||||
|
||||
@ -100,9 +100,9 @@ def sve_logical_imm32 : Operand<i64> {
|
||||
let PrintMethod = "printLogicalImm<int32_t>";
|
||||
|
||||
let MCOperandPredicate = [{
|
||||
if (!MCOperand_isImm(MCOp))
|
||||
if (!MCOp.isImm())
|
||||
return false;
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOperand_getImm(MCOp), 64);
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm()), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements<int32_t>(Val);
|
||||
}];
|
||||
}
|
||||
@ -118,9 +118,9 @@ def sve_preferred_logical_imm16 : Operand<i64> {
|
||||
let PrintMethod = "printSVELogicalImm<int16_t>";
|
||||
|
||||
let MCOperandPredicate = [{
|
||||
if (!MCOperand_isImm(MCOp))
|
||||
if (!MCOp.isImm())
|
||||
return false;
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOperand_getImm(MCOp), 64);
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm()), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements<int16_t>(Val) &&
|
||||
AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
|
||||
}];
|
||||
@ -131,9 +131,9 @@ def sve_preferred_logical_imm32 : Operand<i64> {
|
||||
let PrintMethod = "printSVELogicalImm<int32_t>";
|
||||
|
||||
let MCOperandPredicate = [{
|
||||
if (!MCOperand_isImm(MCOp))
|
||||
if (!MCOp.isImm())
|
||||
return false;
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOperand_getImm(MCOp), 64);
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm()), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements<int32_t>(Val) &&
|
||||
AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
|
||||
}];
|
||||
@ -144,9 +144,9 @@ def sve_preferred_logical_imm64 : Operand<i64> {
|
||||
let PrintMethod = "printSVELogicalImm<int64_t>";
|
||||
|
||||
let MCOperandPredicate = [{
|
||||
if (!MCOperand_isImm(MCOp))
|
||||
if (!MCOp.isImm())
|
||||
return false;
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOperand_getImm(MCOp), 64);
|
||||
int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm()), 64);
|
||||
return AArch64_AM::isSVEMaskOfIdenticalElements<int64_t>(Val) &&
|
||||
AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
|
||||
}];
|
||||
|
@ -57,7 +57,7 @@ std::string AsmWriterOperand::getCode(bool PassSubtarget) const {
|
||||
|
||||
if (Str.find("<") != std::string::npos &&
|
||||
LangCS)
|
||||
Result = PrinterCapstone::resolveTemplateCall(Result) + "(MI";
|
||||
Result = PrinterCapstone::translateToC(Result) + "(MI";
|
||||
else
|
||||
Result = Result + "(MI";
|
||||
|
||||
|
@ -1012,7 +1012,7 @@ public:
|
||||
bool Newline = true,
|
||||
bool UndefAtEnd = false) const override;
|
||||
|
||||
static std::string resolveTemplateCall(std::string const &Dec);
|
||||
static std::string translateToC(std::string const &Dec);
|
||||
|
||||
//------------------------
|
||||
// Backend: RegisterInfo
|
||||
|
@ -618,15 +618,38 @@ void PrinterCapstone::regInfoEmitIsConstantPhysReg(
|
||||
std::deque<CodeGenRegister> const &Regs,
|
||||
std::string const &ClassName) const {}
|
||||
|
||||
std::string PrinterCapstone::resolveTemplateCall(std::string const &Dec) {
|
||||
unsigned long const B = Dec.find_first_of("<");
|
||||
unsigned long const E = Dec.find(">");
|
||||
void patchQualifier(std::string &Code) {
|
||||
while (Code.find("::") != std::string::npos)
|
||||
Code = Regex("::").sub("_", Code);
|
||||
}
|
||||
|
||||
void patchNullptr(std::string &Code) {
|
||||
while (Code.find("nullptr") != std::string::npos)
|
||||
Code = Regex("nullptr").sub("NULL", Code);
|
||||
}
|
||||
|
||||
void patchIsGetImmReg(std::string &Code) {
|
||||
Regex Pattern = Regex("[a-zA-Z0-9_]+\\.(get|is)(Imm|Reg)\\(\\)");
|
||||
SmallVector<StringRef> Matches;
|
||||
while (Pattern.match(Code, &Matches)) {
|
||||
StringRef Match = Matches[0];
|
||||
StringRef Op = Match.split(".").first;
|
||||
StringRef Func = Match.split(".").second.trim(")");
|
||||
Code = Code.replace(Code.find(Match), Match.size(),
|
||||
"MCOperand_" + Func.str() + Op.str() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
void patchTemplateArgs(std::string &Code) {
|
||||
unsigned long const B = Code.find_first_of("<");
|
||||
unsigned long const E = Code.find(">");
|
||||
if (B == std::string::npos) {
|
||||
// No template
|
||||
return Dec;
|
||||
return;
|
||||
}
|
||||
std::string const &DecName = Dec.substr(0, B);
|
||||
std::string Args = Dec.substr(B + 1, E - B - 1);
|
||||
std::string const &DecName = Code.substr(0, B);
|
||||
std::string Args = Code.substr(B + 1, E - B - 1);
|
||||
std::string Rest = Code.substr(E + 1);
|
||||
while ((Args.find("true") != std::string::npos) ||
|
||||
(Args.find("false") != std::string::npos) ||
|
||||
(Args.find(",") != std::string::npos) ||
|
||||
@ -636,8 +659,16 @@ std::string PrinterCapstone::resolveTemplateCall(std::string const &Dec) {
|
||||
Args = Regex(" *, *").sub("_", Args);
|
||||
Args = Regex("'").sub("", Args);
|
||||
}
|
||||
std::string Decoder = DecName + "_" + Args;
|
||||
return Decoder;
|
||||
Code = DecName + "_" + Args + Rest;
|
||||
}
|
||||
|
||||
std::string PrinterCapstone::translateToC(std::string const &Code) {
|
||||
std::string PatchedCode(Code);
|
||||
patchQualifier(PatchedCode);
|
||||
patchNullptr(PatchedCode);
|
||||
patchIsGetImmReg(PatchedCode);
|
||||
patchTemplateArgs(PatchedCode);
|
||||
return PatchedCode;
|
||||
}
|
||||
|
||||
void PrinterCapstone::decoderEmitterEmitOpDecoder(raw_ostream &DecoderOS,
|
||||
@ -645,7 +676,7 @@ void PrinterCapstone::decoderEmitterEmitOpDecoder(raw_ostream &DecoderOS,
|
||||
unsigned const Indent = 4;
|
||||
DecoderOS.indent(Indent) << GuardPrefix;
|
||||
if (Op.Decoder.find("<") != std::string::npos) {
|
||||
DecoderOS << resolveTemplateCall(Op.Decoder);
|
||||
DecoderOS << translateToC(Op.Decoder);
|
||||
} else {
|
||||
DecoderOS << Op.Decoder;
|
||||
}
|
||||
@ -659,7 +690,7 @@ void PrinterCapstone::decoderEmitterEmitOpBinaryParser(
|
||||
raw_ostream &DecOS, const OperandInfo &OpInfo) const {
|
||||
unsigned const Indent = 4;
|
||||
const std::string &Decoder = (OpInfo.Decoder.find("<") != std::string::npos)
|
||||
? resolveTemplateCall(OpInfo.Decoder)
|
||||
? translateToC(OpInfo.Decoder)
|
||||
: OpInfo.Decoder;
|
||||
|
||||
bool const UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;
|
||||
@ -1686,8 +1717,10 @@ void PrinterCapstone::asmWriterEmitPrintAliasOp(
|
||||
<< " break;\n";
|
||||
|
||||
for (unsigned I = 0; I < PrintMethods.size(); ++I) {
|
||||
OS << " case " << I << ":\n"
|
||||
<< " " << PrintMethods[I].first << "(MI, "
|
||||
OS << " case " << I << ":\n";
|
||||
std::string PrintMethod =
|
||||
PrinterCapstone::translateToC(PrintMethods[I].first);
|
||||
OS << " " << PrintMethod << "(MI, "
|
||||
<< (PrintMethods[I].second ? "Address, " : "") << "OpIdx, "
|
||||
<< "OS);\n"
|
||||
<< " break;\n";
|
||||
@ -1713,8 +1746,9 @@ void PrinterCapstone::asmWriterEmitPrintMC(
|
||||
for (unsigned I = 0; I < MCOpPredicates.size(); ++I) {
|
||||
StringRef const MCOpPred =
|
||||
MCOpPredicates[I]->getValueAsString("MCOperandPredicate");
|
||||
OS << " case " << I + 1 << ": {\n"
|
||||
<< MCOpPred.data() << "\n"
|
||||
OS << " case " << I + 1 << ": {\n";
|
||||
std::string PrintMethod = PrinterCapstone::translateToC(MCOpPred.data());
|
||||
OS << PrintMethod << "\n"
|
||||
<< " }\n";
|
||||
}
|
||||
OS << " }\n"
|
||||
@ -2796,7 +2830,7 @@ void printOpPrintGroupEnum(StringRef const &TargetName,
|
||||
|
||||
for (const CGIOperandList::OperandInfo &Op : CGI->Operands) {
|
||||
std::string OpGroup =
|
||||
PrinterCapstone::resolveTemplateCall(Op.PrinterMethodName).substr(5);
|
||||
PrinterCapstone::translateToC(Op.PrinterMethodName).substr(5);
|
||||
if (OpGroups.find(OpGroup) != OpGroups.end())
|
||||
continue;
|
||||
OpGroupEnum.indent(2) << TargetName + "_OP_GROUP_" + OpGroup + " = "
|
||||
|
Loading…
Reference in New Issue
Block a user