[llvm] [TableGen][DecoderEmitter] Add option to emit type-specialized `decodeToMCInst` (PR #146593)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 1 15:56:00 PDT 2025


topperc wrote:

> Repeating the type per-instruction record might be redundant (and we would need more verification as well to verify for a given size, all insts of that size have the C++ type specified and its consistent). One option is to add a new InstructionTypeAndSize class that records this information, and DecoderEmitter can use that if its present else fall back to templated code. Something like
> 
> ```
> class InstructionDecoderTypeAndSize<string CPPType, list<int> Bitwidths> {
> }
> 
> class InstructionDecoderTypeAndSizes<list<InstructionDecoderTypeAndSize>> {
> }
> ```
> 
> and a particular backend can define a single record of type InstructionDecoderTypeAndSizes<> which the DecoderEmitter will use. This is essentially encoding the command line option as a record.
> 
> ```
> // RISCV.td
> // Opt-in to non-templated deocder code.
> def : InstructionDecoderTypeAndSizes<[
>                 InstructionDecoderTypeAndSize<"uint64_t", [48]>,
>                 InstructionDecoderTypeAndSize<"uint32_t", [16,32]>]>;
> ```
> 
> or more simply
> 
> ```
> class InstructionDecoderTypeAndSizes<list<string> CPPTypes, list<list<int>> Bitwidths> {
> }
> 
> def : InstructionDecoderTypeAndSizes<
>            [ "uint32_t", uint64_t"],
>            [ [16,32],    [64]     ]>;
> ```

RISCV uses a common base class for each of the 3 instruction sizes. Other targets may be similar.

```
class RVInst<dag outs, dag ins, string opcodestr, string argstr,                 
             list<dag> pattern, InstFormat format>                               
    : RVInstCommon<outs, ins, opcodestr, argstr, pattern, format> {              
  field bits<32> Inst;                                                           
  // SoftFail is a field the disassembler can use to provide a way for           
  // instructions to not match without killing the whole decode process. It is   
  // mainly used for ARM, but Tablegen expects this field to exist or it fails   
  // to build the decode table.                                                  
  field bits<32> SoftFail = 0;                                                   
  let Size = 4;                                                                  
}                                                                                
                                                                                 
class RVInst48<dag outs, dag ins, string opcodestr, string argstr,               
               list<dag> pattern, InstFormat format>                             
    : RVInstCommon<outs, ins, opcodestr, argstr, pattern, format> {              
  field bits<48> Inst;                                                           
  field bits<48> SoftFail = 0;                                                   
  let Size = 6;                                                                  
}                                                                                
                                                                                 
class RVInst64<dag outs, dag ins, string opcodestr, string argstr,               
               list<dag> pattern, InstFormat format>                             
    : RVInstCommon<outs, ins, opcodestr, argstr, pattern, format> {              
  field bits<64> Inst;                                                           
  field bits<64> SoftFail = 0;                                                   
  let Size = 8;                                                                  
}
```

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


More information about the llvm-commits mailing list