Rework C translation.

This commit is contained in:
Rot127 2023-05-30 08:06:12 -05:00
parent 37ada75258
commit fe28fc2014
No known key found for this signature in database
GPG Key ID: 3812B8258810AF67
5 changed files with 68 additions and 36 deletions

View File

@ -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.

View File

@ -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);
}];

View File

@ -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";

View File

@ -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

View File

@ -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 + " = "