[llvm] [LLVM][MC] Introduce `OrFail` variants of MCD ops (PR #138614)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Sat May 31 06:23:27 PDT 2025


================
@@ -10,24 +10,29 @@
 #ifndef LLVM_MC_MCDECODEROPS_H
 #define LLVM_MC_MCDECODEROPS_H
 
-namespace llvm {
+namespace llvm::MCD {
 
-namespace MCD {
 // Disassembler state machine opcodes.
+// nts_t is either uint16_t or uint24_t based on whether large decoder table is
+// enabled.
 enum DecoderOps {
-  OPC_ExtractField = 1, // OPC_ExtractField(uleb128 Start, uint8_t Len)
-  OPC_FilterValue,      // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
-  OPC_CheckField,       // OPC_CheckField(uleb128 Start, uint8_t Len,
-                        //                uleb128 Val, uint16_t NumToSkip)
-  OPC_CheckPredicate,   // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
-  OPC_Decode,           // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
-  OPC_TryDecode,        // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
-                        //               uint16_t NumToSkip)
-  OPC_SoftFail,         // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
-  OPC_Fail              // OPC_Fail()
+  OPC_ExtractField = 1,     // OPC_ExtractField(uleb128 Start, uint8_t Len)
+  OPC_FilterValue,          // OPC_FilterValue(uleb128 Val, nts_t NumToSkip)
+  OPC_FilterValueOrFail,    // OPC_FilterValueOrFail(uleb128 Val)
+  OPC_CheckField,           // OPC_CheckField(uleb128 Start, uint8_t Len,
+                            //                uleb128 Val, nts_t NumToSkip)
+  OPC_CheckFieldOrFail,     // OPC_CheckFieldOrFail(uleb128 Start, uint8_t Len,
+                            //                uleb128 Val)
+  OPC_CheckPredicate,       // OPC_CheckPredicate(uleb128 PIdx, nts_t NumToSkip)
+  OPC_CheckPredicateOrFail, // OPC_CheckPredicateOrFail(uleb128 PIdx)
+  OPC_Decode,               // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+  OPC_TryDecode,            // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
+                            //               nts_t NumToSkip)
+  OPC_TryDecodeOrFail,      // OPC_TryDecodeOrFail(uleb128 Opcode, uleb128 DIdx)
----------------
jurahul wrote:

There seems to be a subtle difference between two. See this comment in the file (~line 1488):

>  // Produce OPC_Decode or OPC_TryDecode opcode based on the information
  // whether the instruction decoder is complete or not. If it is complete
  // then it handles all possible values of remaining variable/unfiltered bits
  // and for any value can determine if the bitpattern is a valid instruction
  // or not. This means OPC_Decode will be the final step in the decoding
  // process. If it is not complete, then the Fail return code from the
  // decoder method indicates that additional processing should be done to see
  // if there is any other instruction that also matches the bitpattern and
  // can decode it.

So OPC_Decode is generated when we know that decoding will be complete, and hence that case just asserts that in the code:

```
      S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, DecodeComplete);
      assert(DecodeComplete);
```
and OPC_Decode is always the terminal step and does not have `NumToSkip` encoded.

OPC_TryDecode is generated when we know that we do not have a complete decoder, so it attempts to decode and if decoding is complete, it returns, else continues to the encoded `NumToSkip` address. 

In general, here I am defining an `OrFail` variant only for ops that have an associated `NumToSkip` encoding, and since OPC_Decode does not have one, it seems inconsistent to rename TryDecodeOrFail to DecodeOrFail. So I propose we keep the TryDecodeOrFail name.


https://github.com/llvm/llvm-project/pull/138614


More information about the llvm-commits mailing list