-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[DecoderEmitter] Eliminate DecodeComplete parameter to decodeToMCInst
#159130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DecoderEmitter] Eliminate DecodeComplete parameter to decodeToMCInst
#159130
Conversation
…nst` Currently, the code generated by decoder emitter always set `DeocdeComplete` to false when returning Fail from `decodeToMCInst`. As a result, we can just use the return `DecodeStatus` from `decodeToMCInst` to decide whether to terminate the decoding and return or continue trying.
c91b80d to
88b5445
Compare
|
@llvm/pr-subscribers-llvm-mc Author: Rahul Joshi (jurahul) ChangesCurrently, the code generated by decoder emitter always set Also update the Full diff: https://github.com/llvm/llvm-project/pull/159130.diff 7 Files Affected:
diff --git a/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h b/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
index cae2fbcac1fef..3d10380fa1d46 100644
--- a/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
+++ b/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
@@ -98,11 +98,11 @@ class LLVM_ABI MCDisassembler {
/// from Success->SoftFail ->Fail can be done with a simple
/// bitwise-AND:
///
- /// LEFT & TOP = | Success Unpredictable Fail
- /// --------------+-----------------------------------
- /// Success | Success Unpredictable Fail
- /// Unpredictable | Unpredictable Unpredictable Fail
- /// Fail | Fail Fail Fail
+ /// LEFT & TOP = | Success SoftFail Fail
+ /// --------------+-----------------------------
+ /// Success | Success SoftFail Fail
+ /// SoftFail | SoftFail SoftFail Fail
+ /// Fail | Fail Fail Fail
///
/// An easy way of encoding this is as 0b11, 0b01, 0b00 for
/// Success, SoftFail, Fail respectively.
diff --git a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
index 455089588511f..cc1efd58005b0 100644
--- a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
+++ b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
@@ -71,14 +71,14 @@ def Inst3 : TestInstruction {
let AsmString = "Inst3";
}
-// CHECK-LABEL: DecodeStatus decodeFn_0(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_1(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_2(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_3(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: decodeToMCInst(unsigned Idx, DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
+// CHECK-LABEL: DecodeStatus decodeFn_0(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_1(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_2(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_3(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: decodeToMCInst(unsigned Idx, DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
// CHECK: static constexpr DecodeFnTy decodeFnTable[]
// CHECK-NEXT: decodeFn_0,
// CHECK-NEXT: decodeFn_1,
// CHECK-NEXT: decodeFn_2,
// CHECK-NEXT: decodeFn_3,
-// CHECK: return decodeFnTable[Idx](S, insn, MI, Address, Decoder, DecodeComplete)
+// CHECK: return decodeFnTable[Idx](S, insn, MI, Address, Decoder)
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
index cdb1e327ad07d..98a78e29114c1 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
@@ -41,7 +41,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK: unsigned NumToSkip = *Ptr++;
// CHECK-NEXT: NumToSkip |= (*Ptr++) << 8;
@@ -54,7 +54,7 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: unsigned NumToSkip = *Ptr++;
// CHECK-LARGE-NEXT: NumToSkip |= (*Ptr++) << 8;
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
index 35657ff35c86f..be3bf812fb636 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
@@ -39,8 +39,8 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 19 */ OPC_CheckField, 3, 2, 0,
// CHECK-NEXT: /* 23 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 2, 1, 0,
// CHECK-LARGE-NEXT: /* 4 */ OPC_CheckField, 5, 3, 0,
@@ -51,5 +51,5 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 24 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
index 4ac868dbb51aa..a46bd53cf1702 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
@@ -42,7 +42,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 4, 4, 0,
// CHECK-LARGE-NEXT: /* 4 */ OPC_Scope, 8, 0, 0, // end scope at 16
@@ -51,4 +51,4 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
index ff1a7e33747ba..6be3af6b749aa 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
@@ -40,7 +40,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 17 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 250, 3, 4, 0,
@@ -50,4 +50,4 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 18 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 9aa7d31c62693..acb2fc3b562ae 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -865,7 +865,7 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
"InsnType, uint64_t>;\n";
StringRef DecodeParams =
"DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const "
- "MCDisassembler *Decoder, bool &DecodeComplete";
+ "MCDisassembler *Decoder";
// Print the name of the decode function to OS.
auto PrintDecodeFnName = [&OS, BucketBitWidth](unsigned DecodeIdx) {
@@ -904,7 +904,6 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
OS << "// Handling " << Decoders.size() << " cases.\n";
PrintTemplate();
OS << "decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n";
- OS << " DecodeComplete = true;\n";
if (UseFnTableInDecodeToMCInst) {
// Build a table of function pointers
@@ -918,8 +917,7 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
OS << " };\n";
OS << " if (Idx >= " << Decoders.size() << ")\n";
OS << " llvm_unreachable(\"Invalid decoder index!\");\n";
- OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, "
- "DecodeComplete);\n";
+ OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder);\n";
} else {
OS << " " << TmpTypeDecl;
OS << " TmpType tmp;\n";
@@ -1052,9 +1050,7 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent,
StringRef Decoder = OpInfo.Decoder;
if (!Decoder.empty()) {
OS << Indent << "if (!Check(S, " << Decoder
- << "(MI, tmp, Address, Decoder))) { "
- << (OpInfo.HasCompleteDecoder ? "" : "DecodeComplete = false; ")
- << "return MCDisassembler::Fail; }\n";
+ << "(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }\n";
} else {
OS << Indent << "MI.addOperand(MCOperand::createImm(tmp));\n";
}
@@ -1069,9 +1065,7 @@ static std::string getDecoderString(const InstructionEncoding &Encoding) {
StringRef DecoderMethod = Encoding.getDecoderMethod();
if (!DecoderMethod.empty()) {
OS << Indent << "if (!Check(S, " << DecoderMethod
- << "(MI, insn, Address, Decoder))) { "
- << (Encoding.hasCompleteDecoder() ? "" : "DecodeComplete = false; ")
- << "return MCDisassembler::Fail; }\n";
+ << "(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }\n";
} else {
for (const OperandInfo &Op : Encoding.getOperands())
emitBinaryParser(OS, Indent, Encoding, Op);
@@ -1682,15 +1676,13 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
MI.clear();
- MI.setOpcode(Opc);
- bool DecodeComplete;)";
+ MI.setOpcode(Opc);)";
if (IsVarLenInst) {
OS << "\n unsigned Len = InstrLenTable[Opc];\n"
<< " makeUp(insn, Len);";
}
OS << R"(
- S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm, DecodeComplete);
- assert(DecodeComplete);
+ S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm);
LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
<< ", using decoder " << DecodeIdx << ": "
@@ -1707,18 +1699,15 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
// Perform the decode operation.
MCInst TmpMI;
TmpMI.setOpcode(Opc);
- bool DecodeComplete;
- S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm, DecodeComplete);
+ S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm);
LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
<< ", using decoder " << DecodeIdx << ": ");
- if (DecodeComplete) {
- // Decoding complete.
- LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
+ if (S != MCDisassembler::Fail) {
+ LLVM_DEBUG(dbgs() << (S != MCDisassembler::Success ? "Success\n" : "SoftFail\n"));
MI = TmpMI;
return S;
}
- assert(S == MCDisassembler::Fail);
if (ScopeStack.empty()) {
LLVM_DEBUG(dbgs() << "FAIL, returning FAIL\n");
return MCDisassembler::Fail;
|
|
@llvm/pr-subscribers-tablegen Author: Rahul Joshi (jurahul) ChangesCurrently, the code generated by decoder emitter always set Also update the Full diff: https://github.com/llvm/llvm-project/pull/159130.diff 7 Files Affected:
diff --git a/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h b/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
index cae2fbcac1fef..3d10380fa1d46 100644
--- a/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
+++ b/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
@@ -98,11 +98,11 @@ class LLVM_ABI MCDisassembler {
/// from Success->SoftFail ->Fail can be done with a simple
/// bitwise-AND:
///
- /// LEFT & TOP = | Success Unpredictable Fail
- /// --------------+-----------------------------------
- /// Success | Success Unpredictable Fail
- /// Unpredictable | Unpredictable Unpredictable Fail
- /// Fail | Fail Fail Fail
+ /// LEFT & TOP = | Success SoftFail Fail
+ /// --------------+-----------------------------
+ /// Success | Success SoftFail Fail
+ /// SoftFail | SoftFail SoftFail Fail
+ /// Fail | Fail Fail Fail
///
/// An easy way of encoding this is as 0b11, 0b01, 0b00 for
/// Success, SoftFail, Fail respectively.
diff --git a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
index 455089588511f..cc1efd58005b0 100644
--- a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
+++ b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
@@ -71,14 +71,14 @@ def Inst3 : TestInstruction {
let AsmString = "Inst3";
}
-// CHECK-LABEL: DecodeStatus decodeFn_0(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_1(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_2(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_3(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: decodeToMCInst(unsigned Idx, DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
+// CHECK-LABEL: DecodeStatus decodeFn_0(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_1(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_2(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_3(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: decodeToMCInst(unsigned Idx, DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
// CHECK: static constexpr DecodeFnTy decodeFnTable[]
// CHECK-NEXT: decodeFn_0,
// CHECK-NEXT: decodeFn_1,
// CHECK-NEXT: decodeFn_2,
// CHECK-NEXT: decodeFn_3,
-// CHECK: return decodeFnTable[Idx](S, insn, MI, Address, Decoder, DecodeComplete)
+// CHECK: return decodeFnTable[Idx](S, insn, MI, Address, Decoder)
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
index cdb1e327ad07d..98a78e29114c1 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
@@ -41,7 +41,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK: unsigned NumToSkip = *Ptr++;
// CHECK-NEXT: NumToSkip |= (*Ptr++) << 8;
@@ -54,7 +54,7 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: unsigned NumToSkip = *Ptr++;
// CHECK-LARGE-NEXT: NumToSkip |= (*Ptr++) << 8;
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
index 35657ff35c86f..be3bf812fb636 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
@@ -39,8 +39,8 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 19 */ OPC_CheckField, 3, 2, 0,
// CHECK-NEXT: /* 23 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 2, 1, 0,
// CHECK-LARGE-NEXT: /* 4 */ OPC_CheckField, 5, 3, 0,
@@ -51,5 +51,5 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 24 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
index 4ac868dbb51aa..a46bd53cf1702 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
@@ -42,7 +42,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 4, 4, 0,
// CHECK-LARGE-NEXT: /* 4 */ OPC_Scope, 8, 0, 0, // end scope at 16
@@ -51,4 +51,4 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
index ff1a7e33747ba..6be3af6b749aa 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
@@ -40,7 +40,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 17 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 250, 3, 4, 0,
@@ -50,4 +50,4 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 18 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 9aa7d31c62693..acb2fc3b562ae 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -865,7 +865,7 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
"InsnType, uint64_t>;\n";
StringRef DecodeParams =
"DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const "
- "MCDisassembler *Decoder, bool &DecodeComplete";
+ "MCDisassembler *Decoder";
// Print the name of the decode function to OS.
auto PrintDecodeFnName = [&OS, BucketBitWidth](unsigned DecodeIdx) {
@@ -904,7 +904,6 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
OS << "// Handling " << Decoders.size() << " cases.\n";
PrintTemplate();
OS << "decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n";
- OS << " DecodeComplete = true;\n";
if (UseFnTableInDecodeToMCInst) {
// Build a table of function pointers
@@ -918,8 +917,7 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
OS << " };\n";
OS << " if (Idx >= " << Decoders.size() << ")\n";
OS << " llvm_unreachable(\"Invalid decoder index!\");\n";
- OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, "
- "DecodeComplete);\n";
+ OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder);\n";
} else {
OS << " " << TmpTypeDecl;
OS << " TmpType tmp;\n";
@@ -1052,9 +1050,7 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent,
StringRef Decoder = OpInfo.Decoder;
if (!Decoder.empty()) {
OS << Indent << "if (!Check(S, " << Decoder
- << "(MI, tmp, Address, Decoder))) { "
- << (OpInfo.HasCompleteDecoder ? "" : "DecodeComplete = false; ")
- << "return MCDisassembler::Fail; }\n";
+ << "(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }\n";
} else {
OS << Indent << "MI.addOperand(MCOperand::createImm(tmp));\n";
}
@@ -1069,9 +1065,7 @@ static std::string getDecoderString(const InstructionEncoding &Encoding) {
StringRef DecoderMethod = Encoding.getDecoderMethod();
if (!DecoderMethod.empty()) {
OS << Indent << "if (!Check(S, " << DecoderMethod
- << "(MI, insn, Address, Decoder))) { "
- << (Encoding.hasCompleteDecoder() ? "" : "DecodeComplete = false; ")
- << "return MCDisassembler::Fail; }\n";
+ << "(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }\n";
} else {
for (const OperandInfo &Op : Encoding.getOperands())
emitBinaryParser(OS, Indent, Encoding, Op);
@@ -1682,15 +1676,13 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
MI.clear();
- MI.setOpcode(Opc);
- bool DecodeComplete;)";
+ MI.setOpcode(Opc);)";
if (IsVarLenInst) {
OS << "\n unsigned Len = InstrLenTable[Opc];\n"
<< " makeUp(insn, Len);";
}
OS << R"(
- S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm, DecodeComplete);
- assert(DecodeComplete);
+ S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm);
LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
<< ", using decoder " << DecodeIdx << ": "
@@ -1707,18 +1699,15 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
// Perform the decode operation.
MCInst TmpMI;
TmpMI.setOpcode(Opc);
- bool DecodeComplete;
- S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm, DecodeComplete);
+ S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm);
LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
<< ", using decoder " << DecodeIdx << ": ");
- if (DecodeComplete) {
- // Decoding complete.
- LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
+ if (S != MCDisassembler::Fail) {
+ LLVM_DEBUG(dbgs() << (S != MCDisassembler::Success ? "Success\n" : "SoftFail\n"));
MI = TmpMI;
return S;
}
- assert(S == MCDisassembler::Fail);
if (ScopeStack.empty()) {
LLVM_DEBUG(dbgs() << "FAIL, returning FAIL\n");
return MCDisassembler::Fail;
|
But not when OpInfo.HasCompleteDecoder is false, right? So it seems like this change ought to break some tests...I'm surprised it doesn't. |
As I noted in the other PR, this is not exactly true. It only sets it to false when We should be careful here not to break downstream targets without providing a working replacement. |
Right, I see that either the whole instruction decoder may be incomplete, or only certain operands may be incomplete, in which case other (non-incomplete) operands may fail to decode terminally vs the incomplete operands may bail to decode with an incomplete signal. Yeah, none of the tests seems to break through. Maybe AArch64 does not exercise this case? |
Note, when there is any incomplete decode, we always generate TryDecode and never generate a Decode. So when hasIncompleteDecoder = true, its always TryDecode and there is no need to consider Decode AFAICT. |
Right, but this doesn't make the description less confusing. The statement
is basically not true. There is a path that doesn't set |
|
In the end, I think there is no behavioral difference here. We leave scope (or bail) iff |
| << "(MI, insn, Address, Decoder))) { " | ||
| << (Encoding.hasCompleteDecoder() ? "" : "DecodeComplete = false; ") | ||
| << "return MCDisassembler::Fail; }\n"; | ||
| << "(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop the braces? They were needed before because there could be two statements inside them.
Same above.
| // Decoding complete. | ||
| LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n")); | ||
| if (S != MCDisassembler::Fail) { | ||
| LLVM_DEBUG(dbgs() << (S != MCDisassembler::Success ? "Success\n" : "SoftFail\n")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition is reversed.
Also, PASS/FAIL is printed by most other opcodes, I think we should stick to it. Or change them all to print Success/SoftFail/Fail (in a separate PR).
Wait, I thought this was a no-go based on @jyknight 's comment? in the sense, today, decodeToMCInst returns essentially one of these 3:
Eliminating DecodeComplete would eliminate possibility 2 above. |
From inside decodeToMCInst, yes, it would be indistinguishable from 3. But this function is called from decodeInstruction, which has the opcode (Decode/TryDecode), which can help decide what to do next.
This is |
Right, so for an instruction with say 2 operands, one has |
|
You are right. I confused hasCompleteDecoder flag on an instruction and on operands. It is the operands' flag that makes difference; instruction's flag only affects the chosen opcode. |
|
Thanks. I'll close this. I am trying to work on some scheme to help resolve conflicts without using decoder namespaces. Will follow up on discourse or the other PR. |
|
Closing. |
|
Now I think that Decode is redundant :)
So we could always emit Is my logic flawed? |
|
Right, IIUC decode is just a specialized TryDecode where we know
DecodeComplete is always true.
…On Tue, Sep 16, 2025 at 1:10 PM Sergei Barannikov ***@***.***> wrote:
*s-barannikov* left a comment (llvm/llvm-project#159130)
<#159130 (comment)>
Now I think that Decode is redundant :)
1. In Decode case, decodeToMCInst always returns DecodeComplete set to
true. It is asserted, so I can't be wrong here.
2. If decodeToMCInst returns DecodeComplete set to true, TryDecode
behaves exactly like Decode -- returns the decoded instruction and the
status.
So we could always emit TryDecode. The cost is an additional check for
DecodeComplete, which should be tiny compared to the cost of a decoder
function.
—
Reply to this email directly, view it on GitHub
<#159130 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APRMUB3S3XVQWQMQZXFSLUL3TBVELAVCNFSM6AAAAACGVPDFV6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBQGE4TOOJRHA>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
|
Currently, the code generated by decoder emitter always set
DeocdeCompleteto false when returning Fail fromdecodeToMCInst. As a result, we can just use the returnDecodeStatusfromdecodeToMCInstto decide whether to terminate the decoding and return or continue trying.Also update the
DecodeStatuscombining table documentation to use the term "SoftFail" instead of "Unpredictable".