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

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 2 07:38:43 PDT 2025


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

>From ae24279533736da279301a884a926b906778bd21 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Tue, 1 Jul 2025 09:47:10 -0700
Subject: [PATCH 1/2] [TableGen][DecoderEmitter] Add option to emit
 type-specialized `decodeToMCInst`

---
 llvm/lib/Target/AArch64/CMakeLists.txt   |   3 +-
 llvm/lib/Target/AMDGPU/CMakeLists.txt    |   5 +-
 llvm/lib/Target/ARC/CMakeLists.txt       |   4 +-
 llvm/lib/Target/ARM/CMakeLists.txt       |   4 +-
 llvm/lib/Target/AVR/CMakeLists.txt       |   3 +-
 llvm/lib/Target/BPF/CMakeLists.txt       |   3 +-
 llvm/lib/Target/CSKY/CMakeLists.txt      |   3 +-
 llvm/lib/Target/Hexagon/CMakeLists.txt   |   3 +-
 llvm/lib/Target/Lanai/CMakeLists.txt     |   3 +-
 llvm/lib/Target/LoongArch/CMakeLists.txt |   3 +-
 llvm/lib/Target/MSP430/CMakeLists.txt    |   3 +-
 llvm/lib/Target/Mips/CMakeLists.txt      |   3 +-
 llvm/lib/Target/PowerPC/CMakeLists.txt   |   3 +-
 llvm/lib/Target/RISCV/CMakeLists.txt     |   4 +-
 llvm/lib/Target/Sparc/CMakeLists.txt     |   3 +-
 llvm/lib/Target/SystemZ/CMakeLists.txt   |   3 +-
 llvm/lib/Target/VE/CMakeLists.txt        |   3 +-
 llvm/lib/Target/XCore/CMakeLists.txt     |   4 +-
 llvm/lib/Target/Xtensa/CMakeLists.txt    |   3 +-
 llvm/test/TableGen/VarLenDecoder.td      |  13 +-
 llvm/utils/TableGen/DecoderEmitter.cpp   | 187 ++++++++++++++++++-----
 21 files changed, 202 insertions(+), 61 deletions(-)

diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt
index 66136a464f05d..98cc8693144f0 100644
--- a/llvm/lib/Target/AArch64/CMakeLists.txt
+++ b/llvm/lib/Target/AArch64/CMakeLists.txt
@@ -7,7 +7,8 @@ tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
 tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
 tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
 tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel)
 tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM AArch64GenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner
diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt
index e3519f192137c..6254750c10c3c 100644
--- a/llvm/lib/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt
@@ -6,7 +6,10 @@ tablegen(LLVM AMDGPUGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM AMDGPUGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM AMDGPUGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM AMDGPUGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM AMDGPUGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM AMDGPUGenDisassemblerTables.inc -gen-disassembler
+         -non-templated-decode-to-mcinst-type-spec=uint32_t:=32
+         -non-templated-decode-to-mcinst-type-spec=uint64_t:=64
+         -non-templated-decode-to-mcinst-type-spec=DecoderUInt128:=96,128)
 tablegen(LLVM AMDGPUGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM AMDGPUGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM AMDGPUGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/lib/Target/ARC/CMakeLists.txt b/llvm/lib/Target/ARC/CMakeLists.txt
index 196cc31cc5080..e6656576fbcc3 100644
--- a/llvm/lib/Target/ARC/CMakeLists.txt
+++ b/llvm/lib/Target/ARC/CMakeLists.txt
@@ -5,7 +5,9 @@ set(LLVM_TARGET_DEFINITIONS ARC.td)
 tablegen(LLVM ARCGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM ARCGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM ARCGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM ARCGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM ARCGenDisassemblerTables.inc -gen-disassembler
+         -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32
+         -non-templated-decode-to-mcinst-type-spec=uint64_t:=48,64)
 tablegen(LLVM ARCGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM ARCGenRegisterInfo.inc -gen-register-info)
 tablegen(LLVM ARCGenSDNodeInfo.inc -gen-sd-node-info)
diff --git a/llvm/lib/Target/ARM/CMakeLists.txt b/llvm/lib/Target/ARM/CMakeLists.txt
index a39629bd8aeb0..718a084ec6388 100644
--- a/llvm/lib/Target/ARM/CMakeLists.txt
+++ b/llvm/lib/Target/ARM/CMakeLists.txt
@@ -6,7 +6,9 @@ tablegen(LLVM ARMGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM ARMGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM ARMGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM ARMGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler
+         -non-templated-decode-to-mcinst-type-spec=uint16_t:=16
+         -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
 tablegen(LLVM ARMGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM ARMGenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM ARMGenInstrInfo.inc -gen-instr-info)
diff --git a/llvm/lib/Target/AVR/CMakeLists.txt b/llvm/lib/Target/AVR/CMakeLists.txt
index 781dac02c7083..a2da85d77a325 100644
--- a/llvm/lib/Target/AVR/CMakeLists.txt
+++ b/llvm/lib/Target/AVR/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM AVRGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM AVRGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM AVRGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM AVRGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM AVRGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM AVRGenDisassemblerTables.inc -gen-disassembler
+         -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32)
 tablegen(LLVM AVRGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM AVRGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM AVRGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/BPF/CMakeLists.txt b/llvm/lib/Target/BPF/CMakeLists.txt
index eade4cacb7100..6a609d645dfa1 100644
--- a/llvm/lib/Target/BPF/CMakeLists.txt
+++ b/llvm/lib/Target/BPF/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM BPFGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM BPFGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM BPFGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM BPFGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM BPFGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM BPFGenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint64_t:=64)
 tablegen(LLVM BPFGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM BPFGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM BPFGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/CSKY/CMakeLists.txt b/llvm/lib/Target/CSKY/CMakeLists.txt
index 4b900bc99c271..eadf0169edef1 100644
--- a/llvm/lib/Target/CSKY/CMakeLists.txt
+++ b/llvm/lib/Target/CSKY/CMakeLists.txt
@@ -7,7 +7,8 @@ tablegen(LLVM CSKYGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM CSKYGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM CSKYGenCompressInstEmitter.inc -gen-compress-inst-emitter)
 tablegen(LLVM CSKYGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM CSKYGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM CSKYGenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32)
 tablegen(LLVM CSKYGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM CSKYGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM CSKYGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/lib/Target/Hexagon/CMakeLists.txt b/llvm/lib/Target/Hexagon/CMakeLists.txt
index d758260a8ab5d..be2bc89155612 100644
--- a/llvm/lib/Target/Hexagon/CMakeLists.txt
+++ b/llvm/lib/Target/Hexagon/CMakeLists.txt
@@ -7,7 +7,8 @@ tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
 tablegen(LLVM HexagonGenDFAPacketizer.inc -gen-dfa-packetizer)
-tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
 tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/Lanai/CMakeLists.txt b/llvm/lib/Target/Lanai/CMakeLists.txt
index 4a628e13fc177..dfb0c93e1a5e3 100644
--- a/llvm/lib/Target/Lanai/CMakeLists.txt
+++ b/llvm/lib/Target/Lanai/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM LanaiGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM LanaiGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM LanaiGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM LanaiGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM LanaiGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM LanaiGenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
 tablegen(LLVM LanaiGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LanaiGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM LanaiGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index 0f674b1b0fa9e..c851f5c2fc1da 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -5,7 +5,8 @@ set(LLVM_TARGET_DEFINITIONS LoongArch.td)
 tablegen(LLVM LoongArchGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM LoongArchGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM LoongArchGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM LoongArchGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM LoongArchGenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
 tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter)
diff --git a/llvm/lib/Target/MSP430/CMakeLists.txt b/llvm/lib/Target/MSP430/CMakeLists.txt
index 4081d3472fd78..f10c8192e7df0 100644
--- a/llvm/lib/Target/MSP430/CMakeLists.txt
+++ b/llvm/lib/Target/MSP430/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM MSP430GenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM MSP430GenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM MSP430GenCallingConv.inc -gen-callingconv)
 tablegen(LLVM MSP430GenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint64_t:=16,32,48)
 tablegen(LLVM MSP430GenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM MSP430GenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM MSP430GenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt
index 21d1765107ae6..2516d00706a91 100644
--- a/llvm/lib/Target/Mips/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM MipsGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM MipsGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM MipsGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM MipsGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM MipsGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM MipsGenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32)
 tablegen(LLVM MipsGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM MipsGenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM MipsGenPostLegalizeGICombiner.inc -gen-global-isel-combiner
diff --git a/llvm/lib/Target/PowerPC/CMakeLists.txt b/llvm/lib/Target/PowerPC/CMakeLists.txt
index 3808a26a0b92a..136db0634eb93 100644
--- a/llvm/lib/Target/PowerPC/CMakeLists.txt
+++ b/llvm/lib/Target/PowerPC/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM PPCGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM PPCGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM PPCGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM PPCGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM PPCGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM PPCGenDisassemblerTables.inc -gen-disassembler
+               -non-templated-decode-to-mcinst-type-spec=uint64_t:=32,64)
 tablegen(LLVM PPCGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM PPCGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM PPCGenMCCodeEmitter.inc -gen-emitter)
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index e32d6eab3b977..9df6701387d43 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -7,7 +7,9 @@ tablegen(LLVM RISCVGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter)
 tablegen(LLVM RISCVGenMacroFusion.inc -gen-macro-fusion-pred)
 tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler
+              -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32
+              -non-templated-decode-to-mcinst-type-spec=uint64_t:=48)
 tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/lib/Target/Sparc/CMakeLists.txt b/llvm/lib/Target/Sparc/CMakeLists.txt
index f682719ac483f..6334dbbc6cc1a 100644
--- a/llvm/lib/Target/Sparc/CMakeLists.txt
+++ b/llvm/lib/Target/Sparc/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM SparcGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler
+               -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
 tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/SystemZ/CMakeLists.txt b/llvm/lib/Target/SystemZ/CMakeLists.txt
index 0d8f3eac6ee4f..1caeef468f3fb 100644
--- a/llvm/lib/Target/SystemZ/CMakeLists.txt
+++ b/llvm/lib/Target/SystemZ/CMakeLists.txt
@@ -7,7 +7,8 @@ tablegen(LLVM SystemZGenGNUAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM SystemZGenHLASMAsmWriter.inc -gen-asm-writer -asmwriternum=1)
 tablegen(LLVM SystemZGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM SystemZGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler
+               -non-templated-decode-to-mcinst-type-spec=uint64_t:=16,32,48)
 tablegen(LLVM SystemZGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM SystemZGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM SystemZGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/VE/CMakeLists.txt b/llvm/lib/Target/VE/CMakeLists.txt
index d1bb4f32fcba7..6b83a3e7ae28e 100644
--- a/llvm/lib/Target/VE/CMakeLists.txt
+++ b/llvm/lib/Target/VE/CMakeLists.txt
@@ -4,7 +4,8 @@ set(LLVM_TARGET_DEFINITIONS VE.td)
 
 tablegen(LLVM VEGenRegisterInfo.inc -gen-register-info)
 tablegen(LLVM VEGenInstrInfo.inc -gen-instr-info)
-tablegen(LLVM VEGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM VEGenDisassemblerTables.inc -gen-disassembler
+               -non-templated-decode-to-mcinst-type-spec=uint64_t:=64)
 tablegen(LLVM VEGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM VEGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM VEGenAsmMatcher.inc -gen-asm-matcher)
diff --git a/llvm/lib/Target/XCore/CMakeLists.txt b/llvm/lib/Target/XCore/CMakeLists.txt
index f411c658b43b0..3b5bf848d8144 100644
--- a/llvm/lib/Target/XCore/CMakeLists.txt
+++ b/llvm/lib/Target/XCore/CMakeLists.txt
@@ -5,7 +5,9 @@ set(LLVM_TARGET_DEFINITIONS XCore.td)
 tablegen(LLVM XCoreGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM XCoreGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM XCoreGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM XCoreGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM XCoreGenDisassemblerTables.inc -gen-disassembler
+          -non-templated-decode-to-mcinst-type-spec=uint16_t:=16
+          -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
 tablegen(LLVM XCoreGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM XCoreGenRegisterInfo.inc -gen-register-info)
 tablegen(LLVM XCoreGenSDNodeInfo.inc -gen-sd-node-info)
diff --git a/llvm/lib/Target/Xtensa/CMakeLists.txt b/llvm/lib/Target/Xtensa/CMakeLists.txt
index 4fc1ba6dfa650..9c825b5d880c7 100644
--- a/llvm/lib/Target/Xtensa/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/CMakeLists.txt
@@ -6,7 +6,8 @@ tablegen(LLVM XtensaGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM XtensaGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM XtensaGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM XtensaGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler
+               -non-templated-decode-to-mcinst-type-spec=uint64_t:=16,24)
 tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM XtensaGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/test/TableGen/VarLenDecoder.td b/llvm/test/TableGen/VarLenDecoder.td
index 06ff62294a196..2359bd2c15145 100644
--- a/llvm/test/TableGen/VarLenDecoder.td
+++ b/llvm/test/TableGen/VarLenDecoder.td
@@ -61,11 +61,7 @@ def FOO32 : MyVarInst<MemOp32> {
 // CHECK-LARGE-NEXT: /* 14 */      MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
 // CHECK-LARGE-NEXT: /* 18 */      MCD::OPC_Fail,
 
-// Instruction length table
-// CHECK: 27,
-// CHECK-NEXT: 43,
-// CHECK-NEXT: };
-
+// CHECK-LABEL: decodeToMCInst
 // CHECK:      case 0:
 // CHECK-NEXT: tmp = fieldFromInstruction(insn, 8, 3);
 // CHECK-NEXT: if (!Check(S, DecodeRegClassRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
@@ -85,6 +81,13 @@ def FOO32 : MyVarInst<MemOp32> {
 // CHECK-NEXT: MI.addOperand(MCOperand::createImm(tmp));
 // CHECK-NEXT: return S;
 
+// Instruction length table
+// CHECK-LABEL: InstrLenTable
+// CHECK: 27,
+// CHECK-NEXT: 43,
+// CHECK-NEXT: };
+
+// CHECK-LABEL: decodeInstruction
 // CHECK-LABEL: case MCD::OPC_ExtractField: {
 // CHECK: makeUp(insn, Start + Len);
 
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index d582309a6fd4a..ae3f072601014 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -23,6 +23,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
@@ -92,6 +93,22 @@ static cl::opt<bool> UseFnTableInDecodeToMCInst(
         "of the generated code."),
     cl::init(false), cl::cat(DisassemblerEmitterCat));
 
+// Option to generate a non-templated version of `decodeToMCInst`. The
+// templated `decodeToMCInst` is templated on `InsnType` and a given `InsnType`
+// can target instructions with one or more Bitwidths. So the option to
+// generate a non-templated `decodeToMCInst` is a typespec of the form
+// type::=list-of-sizes.
+
+// For example, for the AMDGPU target, the type `DecoderUInt128` is used for
+// both 96 and 128 bit instructions. So the generated non-templated
+// `decodeToMCInst` will support decoding both these instruction Bitwidths and
+// the option will be DecoderUInt128::=96,128
+static cl::list<std::string> DecodeToMCInstTypeSpecs(
+    "non-templated-decode-to-mcinst-type-spec",
+    cl::desc("list of C++ types and associated bitwidths to used to generate "
+             "non-templated `decodeToMCInst`."),
+    cl::cat(DisassemblerEmitterCat));
+
 STATISTIC(NumEncodings, "Number of encodings considered");
 STATISTIC(NumEncodingsLackingDisasm,
           "Number of encodings without disassembler info");
@@ -234,7 +251,7 @@ class DecoderEmitter {
   void emitPredicateFunction(formatted_raw_ostream &OS,
                              PredicateSet &Predicates, indent Indent) const;
   void emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
-                           indent Indent) const;
+                           StringRef SpecializedInsnType, indent Indent) const;
 
   // run - Output the code emitter
   void run(raw_ostream &o);
@@ -1068,24 +1085,35 @@ void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
 
 void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
                                          DecoderSet &Decoders,
+                                         StringRef SpecializedInsnType,
                                          indent Indent) const {
+  auto emitTemplate = [&OS, SpecializedInsnType, &Indent] {
+    if (SpecializedInsnType.empty())
+      OS << Indent << "template <typename InsnType>\n";
+  };
+
+  StringRef InsnType =
+      SpecializedInsnType.empty() ? "InsnType" : SpecializedInsnType;
+
   // The decoder function is just a big switch statement or a table of function
   // pointers based on the input decoder index.
 
   // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
   // It would be better for emitBinaryParser to use a 64-bit tmp whenever
   // possible but fall back to an InsnType-sized tmp for truly large fields.
-  StringRef TmpTypeDecl =
-      "using TmpType = std::conditional_t<std::is_integral<InsnType>::value, "
-      "InsnType, uint64_t>;\n";
-  StringRef DecodeParams =
-      "DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const "
-      "MCDisassembler *Decoder, bool &DecodeComplete";
+  auto TmpTypeDecl = formatv(
+      "using TmpType = std::conditional_t<std::is_integral<{0}>::value, {0}, "
+      "uint64_t>;\n",
+      InsnType);
+  auto DecodeParams =
+      formatv("DecodeStatus S, {} insn, MCInst &MI, uint64_t Address, const "
+              "MCDisassembler *Decoder, bool &DecodeComplete",
+              InsnType);
 
   if (UseFnTableInDecodeToMCInst) {
     // Emit a function for each case first.
     for (const auto &[Index, Decoder] : enumerate(Decoders)) {
-      OS << Indent << "template <typename InsnType>\n";
+      emitTemplate();
       OS << Indent << "DecodeStatus decodeFn" << Index << "(" << DecodeParams
          << ") {\n";
       Indent += 2;
@@ -1099,7 +1127,7 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
   }
 
   OS << Indent << "// Handling " << Decoders.size() << " cases.\n";
-  OS << Indent << "template <typename InsnType>\n";
+  emitTemplate();
   OS << Indent << "static DecodeStatus decodeToMCInst(unsigned Idx, "
      << DecodeParams << ") {\n";
   Indent += 2;
@@ -2538,6 +2566,70 @@ handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
   }
 }
 
+// Result of parsing a single `non-templated-decode-to-mcinst-type-spec` option.
+using BitwidthSet = SmallSet<unsigned, 4>;
+struct NonTemplatedTypeSpec {
+  StringRef Type;
+  BitwidthSet Bitwidths;
+};
+
+static SmallVector<NonTemplatedTypeSpec>
+parseNonTemplatedTypeSpec(BitwidthSet &InstrBitwidths) {
+  SmallVector<NonTemplatedTypeSpec> Parsed;
+  if (DecodeToMCInstTypeSpecs.empty()) {
+    // If no `non-templated-decode-to-mcinst-type-spec` option is specified,
+    // create a type-spec with empty values, which will trigger generation of
+    // a templated `decodeToMCInst`.
+    Parsed.emplace_back();
+    return Parsed;
+  }
+
+  Parsed.reserve(DecodeToMCInstTypeSpecs.size());
+  BitwidthSet OptionBitwidths;
+
+  for (StringRef TypeSpec : DecodeToMCInstTypeSpecs) {
+    BitwidthSet Bitwidths;
+    // Each `non-templated-decode-to-mcinst-type-spec` is of the form
+    // <type>:=<list of bitwidths>. Note, <type> can in general be a templated
+    // type, so using the token ":=" as a separator to allow many general C++
+    // types here.
+    auto [Type, ListOfBitWidths] = TypeSpec.split(":=");
+    if (Type.empty())
+      PrintFatalError("Invalid typespec: " + TypeSpec);
+
+    for (StringRef BwStr : split(ListOfBitWidths, ',')) {
+      unsigned Bitwidth;
+      if (BwStr.getAsInteger(10, Bitwidth))
+        PrintFatalError("Invalid bitwidth: " + BwStr + " in typespec " +
+                        TypeSpec);
+
+      if (!OptionBitwidths.insert(Bitwidth).second)
+        PrintFatalError("Bitwidth " + Twine(Bitwidth) + " already specified.");
+
+      if (!InstrBitwidths.contains(Bitwidth))
+        PrintFatalError(Twine("No instruction of Bitwidth ") + Twine(Bitwidth) +
+                        " supported.");
+
+      InstrBitwidths.erase(Bitwidth);
+      Bitwidths.insert(Bitwidth);
+    }
+
+    if (Bitwidths.empty())
+      PrintFatalError("No bitwidth specified in typespec " + TypeSpec);
+
+    Parsed.emplace_back(NonTemplatedTypeSpec{Type, Bitwidths});
+  }
+
+  if (!InstrBitwidths.empty()) {
+    PrintFatalError([&InstrBitwidths](raw_ostream &OS) {
+      OS << "Bitwidth(s) ";
+      llvm::interleaveComma(InstrBitwidths, OS);
+      OS << " missing in `non-templated-decode-to-mcinst-type-spec` options.";
+    });
+  }
+  return Parsed;
+}
+
 // Emits disassembler code for instruction decoding.
 void DecoderEmitter::run(raw_ostream &o) {
   formatted_raw_ostream OS(o);
@@ -2649,35 +2741,59 @@ namespace {
     }
   }
 
+  // Collect all allowed Bitwidths for instructions.
+  BitwidthSet InstrBitwidths;
+  for (const auto &[NSAndByteSize, _] : OpcMap) {
+    const unsigned Bitwidth = 8 * NSAndByteSize.second;
+    InstrBitwidths.insert(Bitwidth);
+  }
+  SmallVector<NonTemplatedTypeSpec> NonTemplatedTypeSpecs =
+      parseNonTemplatedTypeSpec(InstrBitwidths);
+
   DecoderTableInfo TableInfo;
   unsigned OpcodeMask = 0;
-  for (const auto &[NSAndByteSize, EncodingIDs] : OpcMap) {
-    const std::string &DecoderNamespace = NSAndByteSize.first;
-    const unsigned BitWidth = 8 * NSAndByteSize.second;
-    // Emit the decoder for this namespace+width combination.
-    FilterChooser FC(NumberedEncodings, EncodingIDs, Operands,
-                     IsVarLenInst ? MaxInstLen : BitWidth, this);
-
-    // The decode table is cleared for each top level decoder function. The
-    // predicates and decoders themselves, however, are shared across all
-    // decoders to give more opportunities for uniqueing.
-    TableInfo.Table.clear();
-    TableInfo.FixupStack.clear();
-    TableInfo.FixupStack.emplace_back();
-    FC.emitTableEntries(TableInfo);
-    // Any NumToSkip fixups in the top level scope can resolve to the
-    // OPC_Fail at the end of the table.
-    assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
-    // Resolve any NumToSkip fixups in the current scope.
-    resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
-                       TableInfo.Table.size());
-    TableInfo.FixupStack.clear();
+  for (const auto &[NTType, NTBitwidths] : NonTemplatedTypeSpecs) {
+    // Reset the Decoders for each non-templated type.
+    TableInfo.Decoders.clear();
+
+    for (const auto &[NSAndByteSize, EncodingIDs] : OpcMap) {
+      const std::string &DecoderNamespace = NSAndByteSize.first;
+      const unsigned InstrBitwidth =
+          IsVarLenInst ? MaxInstLen : 8 * NSAndByteSize.second;
+
+      // Only handle instruction of the non-templated bitwidth size when
+      // non-templated bitwidth option is enabled.
+      if (!NTBitwidths.empty() && !NTBitwidths.contains(InstrBitwidth))
+        continue;
+
+      // Emit the decoder for this namespace+width combination.
+      FilterChooser FC(NumberedEncodings, EncodingIDs, Operands,
+                       IsVarLenInst ? MaxInstLen : InstrBitwidth, this);
+
+      // The decode table is cleared for each top level decoder function. The
+      // predicates and decoders themselves, however, are shared across all
+      // decoders to give more opportunities for uniqueing.
+      TableInfo.Table.clear();
+      TableInfo.FixupStack.clear();
+      TableInfo.FixupStack.emplace_back();
+      FC.emitTableEntries(TableInfo);
+      // Any NumToSkip fixups in the top level scope can resolve to the
+      // OPC_Fail at the end of the table.
+      assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
+      // Resolve any NumToSkip fixups in the current scope.
+      resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
+                         TableInfo.Table.size());
+      TableInfo.FixupStack.clear();
 
-    TableInfo.Table.push_back(MCD::OPC_Fail);
+      TableInfo.Table.push_back(MCD::OPC_Fail);
 
-    // Print the table to the output stream.
-    OpcodeMask |= emitTable(OS, TableInfo.Table, indent(0), FC.getBitWidth(),
-                            DecoderNamespace, EncodingIDs);
+      // Print the table to the output stream.
+      OpcodeMask |= emitTable(OS, TableInfo.Table, indent(0), FC.getBitWidth(),
+                              DecoderNamespace, EncodingIDs);
+    }
+
+    // Emit the decoder function for this BitWidth.
+    emitDecoderFunction(OS, TableInfo.Decoders, NTType, indent(0));
   }
 
   // For variable instruction, we emit a instruction length table
@@ -2694,9 +2810,6 @@ namespace {
   if (HasCheckPredicate)
     emitPredicateFunction(OS, TableInfo.Predicates, indent(0));
 
-  // Emit the decoder function.
-  emitDecoderFunction(OS, TableInfo.Decoders, indent(0));
-
   // Emit the main entry point for the decoder, decodeInstruction().
   emitDecodeInstruction(OS, IsVarLenInst, OpcodeMask);
 

>From 04366eedc71984255b2792be4ff32babd33f3668 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 2 Jul 2025 06:53:54 -0700
Subject: [PATCH 2/2] Review feedback

---
 llvm/include/llvm/TableGen/Record.h      |   2 +
 llvm/include/llvm/Target/Target.td       |  19 ++++
 llvm/lib/TableGen/Record.cpp             |  43 +++++-----
 llvm/lib/Target/AArch64/AArch64.td       |   6 +-
 llvm/lib/Target/AArch64/CMakeLists.txt   |   3 +-
 llvm/lib/Target/AMDGPU/CMakeLists.txt    |   5 +-
 llvm/lib/Target/ARC/CMakeLists.txt       |   4 +-
 llvm/lib/Target/ARM/CMakeLists.txt       |   4 +-
 llvm/lib/Target/AVR/CMakeLists.txt       |   3 +-
 llvm/lib/Target/BPF/CMakeLists.txt       |   3 +-
 llvm/lib/Target/CSKY/CMakeLists.txt      |   3 +-
 llvm/lib/Target/Hexagon/CMakeLists.txt   |   3 +-
 llvm/lib/Target/Lanai/CMakeLists.txt     |   3 +-
 llvm/lib/Target/LoongArch/CMakeLists.txt |   3 +-
 llvm/lib/Target/MSP430/CMakeLists.txt    |   3 +-
 llvm/lib/Target/Mips/CMakeLists.txt      |   3 +-
 llvm/lib/Target/PowerPC/CMakeLists.txt   |   3 +-
 llvm/lib/Target/RISCV/CMakeLists.txt     |   4 +-
 llvm/lib/Target/RISCV/RISCV.td           |   4 +
 llvm/lib/Target/Sparc/CMakeLists.txt     |   3 +-
 llvm/lib/Target/SystemZ/CMakeLists.txt   |   3 +-
 llvm/lib/Target/VE/CMakeLists.txt        |   3 +-
 llvm/lib/Target/XCore/CMakeLists.txt     |   4 +-
 llvm/lib/Target/Xtensa/CMakeLists.txt    |   3 +-
 llvm/utils/TableGen/DecoderEmitter.cpp   | 105 +++++++++++------------
 25 files changed, 120 insertions(+), 122 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 5849344bcb0b5..306988cd0fc53 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -803,6 +803,8 @@ class ListInit final : public TypedInit,
   size_t size() const { return NumElements; }
   bool empty() const { return NumElements == 0; }
 
+  std::vector<int64_t> getAsListOfInts() const;
+
   const Init *getBit(unsigned Bit) const override {
     llvm_unreachable("Illegal bit reference off list");
   }
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index ce9a2b2751968..e2e711baaede2 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -1158,6 +1158,25 @@ class InstrInfo {
   //
   // This option is a temporary migration help. It will go away.
   bit guessInstructionProperties = true;
+
+  // These properties, when set, opt into the non-templated variants of
+  // `decodeToMCInst` generated by TableGen DecoderEmitter backend. Using this
+  // option helps reduce the code size of the generated code as compared to the
+  // templated `decodeToMCInst` that is generated by default.
+  // For each index `I`, InsnCPPTypes[I] is a C++ type that will be used to
+  // generate a non-templated `decodeToMCInst`, and InstBitwidths[I] is a list
+  // instruction bitwidth(s) whose decoders will be included in the generated
+  // code.
+  list<string> InsnCPPTypes = [];
+  list<list<int>> InsnBitwidths = [];
+  assert !eq(!size(InsnCPPTypes), !size(InsnBitwidths)),
+     "The InsnCPPTypes and InsnBitwidths lists must be the same length";
+
+  // Make sure the InstCPPTypes, if not empty, does not contain empty strings.
+  assert !or(!empty(InsnCPPTypes), !empty(!filter(e, InsnCPPTypes, !empty(e)))),
+     "Entries in InstCPPTypes cannot be empty";
+
+  // Make sure that InsnBitwidths, if not empty, does not contain empty list.
 }
 
 // Standard Pseudo Instructions.
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 7f2ed77a74099..69f6fa6edb49b 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -804,6 +804,15 @@ std::string ListInit::getAsString() const {
   return Result + "]";
 }
 
+std::vector<int64_t> ListInit::getAsListOfInts() const {
+  if (!isa<IntRecTy>(getElementType()))
+    PrintFatalError("List does not contain integer values");
+  std::vector<int64_t> Ints;
+  for (const Init *I : getElements())
+    Ints.push_back(cast<IntInit>(I)->getValue());
+  return Ints;
+}
+
 const Init *OpInit::getBit(unsigned Bit) const {
   if (getType() == BitRecTy::get(getRecordKeeper()))
     return this;
@@ -3119,32 +3128,26 @@ int64_t Record::getValueAsInt(StringRef FieldName) const {
 std::vector<int64_t>
 Record::getValueAsListOfInts(StringRef FieldName) const {
   const ListInit *List = getValueAsListInit(FieldName);
-  std::vector<int64_t> Ints;
-  for (const Init *I : List->getElements()) {
-    if (const auto *II = dyn_cast<IntInit>(I))
-      Ints.push_back(II->getValue());
-    else
-      PrintFatalError(getLoc(),
-                      Twine("Record `") + getName() + "', field `" + FieldName +
-                          "' exists but does not have a list of ints value: " +
-                          I->getAsString());
-  }
-  return Ints;
+  if (!isa<IntRecTy>(List->getElementType()))
+    PrintFatalError(getLoc(),
+                    Twine("Record `") + getName() + "', field `" + FieldName +
+                        "' exists but does not have a list of ints value: " +
+                        List->getAsString());
+  return List->getAsListOfInts();
 }
 
 std::vector<StringRef>
 Record::getValueAsListOfStrings(StringRef FieldName) const {
   const ListInit *List = getValueAsListInit(FieldName);
+  if (!isa<StringRecTy>(List->getElementType()))
+    PrintFatalError(getLoc(),
+                    Twine("Record `") + getName() + "', field `" + FieldName +
+                        "' exists but does not have a list of string value: " +
+                        List->getAsString());
+
   std::vector<StringRef> Strings;
-  for (const Init *I : List->getElements()) {
-    if (const auto *SI = dyn_cast<StringInit>(I))
-      Strings.push_back(SI->getValue());
-    else
-      PrintFatalError(getLoc(),
-                      Twine("Record `") + getName() + "', field `" + FieldName +
-                          "' exists but does not have a list of strings value: " +
-                          I->getAsString());
-  }
+  for (const Init *I : List->getElements())
+    Strings.push_back(cast<StringInit>(I)->getValue());
   return Strings;
 }
 
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 25cdcae4e41de..670027d59acde 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -40,7 +40,11 @@ include "AArch64SchedPredExynos.td"
 include "AArch64SchedPredNeoverse.td"
 include "AArch64Combine.td"
 
-def AArch64InstrInfo : InstrInfo;
+def AArch64InstrInfo : InstrInfo {
+  // Opt-in into non-templated code for instruction decoder.
+  let InsnCPPTypes = ["uint32_t"];
+  let InsnBitwidths = [[32]];
+}
 
 //===----------------------------------------------------------------------===//
 // Named operands for MRS/MSR/TLBI/...
diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt
index 98cc8693144f0..66136a464f05d 100644
--- a/llvm/lib/Target/AArch64/CMakeLists.txt
+++ b/llvm/lib/Target/AArch64/CMakeLists.txt
@@ -7,8 +7,7 @@ tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
 tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
 tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
+tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel)
 tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM AArch64GenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner
diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt
index 6254750c10c3c..e3519f192137c 100644
--- a/llvm/lib/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt
@@ -6,10 +6,7 @@ tablegen(LLVM AMDGPUGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM AMDGPUGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM AMDGPUGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM AMDGPUGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM AMDGPUGenDisassemblerTables.inc -gen-disassembler
-         -non-templated-decode-to-mcinst-type-spec=uint32_t:=32
-         -non-templated-decode-to-mcinst-type-spec=uint64_t:=64
-         -non-templated-decode-to-mcinst-type-spec=DecoderUInt128:=96,128)
+tablegen(LLVM AMDGPUGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM AMDGPUGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM AMDGPUGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM AMDGPUGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/lib/Target/ARC/CMakeLists.txt b/llvm/lib/Target/ARC/CMakeLists.txt
index e6656576fbcc3..196cc31cc5080 100644
--- a/llvm/lib/Target/ARC/CMakeLists.txt
+++ b/llvm/lib/Target/ARC/CMakeLists.txt
@@ -5,9 +5,7 @@ set(LLVM_TARGET_DEFINITIONS ARC.td)
 tablegen(LLVM ARCGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM ARCGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM ARCGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM ARCGenDisassemblerTables.inc -gen-disassembler
-         -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32
-         -non-templated-decode-to-mcinst-type-spec=uint64_t:=48,64)
+tablegen(LLVM ARCGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM ARCGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM ARCGenRegisterInfo.inc -gen-register-info)
 tablegen(LLVM ARCGenSDNodeInfo.inc -gen-sd-node-info)
diff --git a/llvm/lib/Target/ARM/CMakeLists.txt b/llvm/lib/Target/ARM/CMakeLists.txt
index 718a084ec6388..a39629bd8aeb0 100644
--- a/llvm/lib/Target/ARM/CMakeLists.txt
+++ b/llvm/lib/Target/ARM/CMakeLists.txt
@@ -6,9 +6,7 @@ tablegen(LLVM ARMGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM ARMGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM ARMGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM ARMGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler
-         -non-templated-decode-to-mcinst-type-spec=uint16_t:=16
-         -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
+tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM ARMGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM ARMGenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM ARMGenInstrInfo.inc -gen-instr-info)
diff --git a/llvm/lib/Target/AVR/CMakeLists.txt b/llvm/lib/Target/AVR/CMakeLists.txt
index a2da85d77a325..781dac02c7083 100644
--- a/llvm/lib/Target/AVR/CMakeLists.txt
+++ b/llvm/lib/Target/AVR/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM AVRGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM AVRGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM AVRGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM AVRGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM AVRGenDisassemblerTables.inc -gen-disassembler
-         -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32)
+tablegen(LLVM AVRGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM AVRGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM AVRGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM AVRGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/BPF/CMakeLists.txt b/llvm/lib/Target/BPF/CMakeLists.txt
index 6a609d645dfa1..eade4cacb7100 100644
--- a/llvm/lib/Target/BPF/CMakeLists.txt
+++ b/llvm/lib/Target/BPF/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM BPFGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM BPFGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM BPFGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM BPFGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM BPFGenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint64_t:=64)
+tablegen(LLVM BPFGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM BPFGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM BPFGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM BPFGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/CSKY/CMakeLists.txt b/llvm/lib/Target/CSKY/CMakeLists.txt
index eadf0169edef1..4b900bc99c271 100644
--- a/llvm/lib/Target/CSKY/CMakeLists.txt
+++ b/llvm/lib/Target/CSKY/CMakeLists.txt
@@ -7,8 +7,7 @@ tablegen(LLVM CSKYGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM CSKYGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM CSKYGenCompressInstEmitter.inc -gen-compress-inst-emitter)
 tablegen(LLVM CSKYGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM CSKYGenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32)
+tablegen(LLVM CSKYGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM CSKYGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM CSKYGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM CSKYGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/lib/Target/Hexagon/CMakeLists.txt b/llvm/lib/Target/Hexagon/CMakeLists.txt
index be2bc89155612..d758260a8ab5d 100644
--- a/llvm/lib/Target/Hexagon/CMakeLists.txt
+++ b/llvm/lib/Target/Hexagon/CMakeLists.txt
@@ -7,8 +7,7 @@ tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
 tablegen(LLVM HexagonGenDFAPacketizer.inc -gen-dfa-packetizer)
-tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
+tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/Lanai/CMakeLists.txt b/llvm/lib/Target/Lanai/CMakeLists.txt
index dfb0c93e1a5e3..4a628e13fc177 100644
--- a/llvm/lib/Target/Lanai/CMakeLists.txt
+++ b/llvm/lib/Target/Lanai/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM LanaiGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM LanaiGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM LanaiGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM LanaiGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM LanaiGenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
+tablegen(LLVM LanaiGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM LanaiGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LanaiGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM LanaiGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index c851f5c2fc1da..0f674b1b0fa9e 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -5,8 +5,7 @@ set(LLVM_TARGET_DEFINITIONS LoongArch.td)
 tablegen(LLVM LoongArchGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM LoongArchGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM LoongArchGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM LoongArchGenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
+tablegen(LLVM LoongArchGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter)
diff --git a/llvm/lib/Target/MSP430/CMakeLists.txt b/llvm/lib/Target/MSP430/CMakeLists.txt
index f10c8192e7df0..4081d3472fd78 100644
--- a/llvm/lib/Target/MSP430/CMakeLists.txt
+++ b/llvm/lib/Target/MSP430/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM MSP430GenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM MSP430GenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM MSP430GenCallingConv.inc -gen-callingconv)
 tablegen(LLVM MSP430GenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint64_t:=16,32,48)
+tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM MSP430GenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM MSP430GenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM MSP430GenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt
index 2516d00706a91..21d1765107ae6 100644
--- a/llvm/lib/Target/Mips/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM MipsGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM MipsGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM MipsGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM MipsGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM MipsGenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32)
+tablegen(LLVM MipsGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM MipsGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM MipsGenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM MipsGenPostLegalizeGICombiner.inc -gen-global-isel-combiner
diff --git a/llvm/lib/Target/PowerPC/CMakeLists.txt b/llvm/lib/Target/PowerPC/CMakeLists.txt
index 136db0634eb93..3808a26a0b92a 100644
--- a/llvm/lib/Target/PowerPC/CMakeLists.txt
+++ b/llvm/lib/Target/PowerPC/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM PPCGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM PPCGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM PPCGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM PPCGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM PPCGenDisassemblerTables.inc -gen-disassembler
-               -non-templated-decode-to-mcinst-type-spec=uint64_t:=32,64)
+tablegen(LLVM PPCGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM PPCGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM PPCGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM PPCGenMCCodeEmitter.inc -gen-emitter)
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 9df6701387d43..e32d6eab3b977 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -7,9 +7,7 @@ tablegen(LLVM RISCVGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter)
 tablegen(LLVM RISCVGenMacroFusion.inc -gen-macro-fusion-pred)
 tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler
-              -non-templated-decode-to-mcinst-type-spec=uint32_t:=16,32
-              -non-templated-decode-to-mcinst-type-spec=uint64_t:=48)
+tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index b24d8637cb27f..b3ce392d27a17 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -85,6 +85,10 @@ include "RISCVPfmCounters.td"
 
 def RISCVInstrInfo : InstrInfo {
   let guessInstructionProperties = 0;
+
+  // Opt-in into non-templated code for instruction decoder.
+  let InsnCPPTypes = ["uint64_t"];
+  let InsnBitwidths = [[16, 32, 48]];
 }
 
 def RISCVAsmParser : AsmParser {
diff --git a/llvm/lib/Target/Sparc/CMakeLists.txt b/llvm/lib/Target/Sparc/CMakeLists.txt
index 6334dbbc6cc1a..f682719ac483f 100644
--- a/llvm/lib/Target/Sparc/CMakeLists.txt
+++ b/llvm/lib/Target/Sparc/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM SparcGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler
-               -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
+tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/SystemZ/CMakeLists.txt b/llvm/lib/Target/SystemZ/CMakeLists.txt
index 1caeef468f3fb..0d8f3eac6ee4f 100644
--- a/llvm/lib/Target/SystemZ/CMakeLists.txt
+++ b/llvm/lib/Target/SystemZ/CMakeLists.txt
@@ -7,8 +7,7 @@ tablegen(LLVM SystemZGenGNUAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM SystemZGenHLASMAsmWriter.inc -gen-asm-writer -asmwriternum=1)
 tablegen(LLVM SystemZGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM SystemZGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler
-               -non-templated-decode-to-mcinst-type-spec=uint64_t:=16,32,48)
+tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM SystemZGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM SystemZGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM SystemZGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/VE/CMakeLists.txt b/llvm/lib/Target/VE/CMakeLists.txt
index 6b83a3e7ae28e..d1bb4f32fcba7 100644
--- a/llvm/lib/Target/VE/CMakeLists.txt
+++ b/llvm/lib/Target/VE/CMakeLists.txt
@@ -4,8 +4,7 @@ set(LLVM_TARGET_DEFINITIONS VE.td)
 
 tablegen(LLVM VEGenRegisterInfo.inc -gen-register-info)
 tablegen(LLVM VEGenInstrInfo.inc -gen-instr-info)
-tablegen(LLVM VEGenDisassemblerTables.inc -gen-disassembler
-               -non-templated-decode-to-mcinst-type-spec=uint64_t:=64)
+tablegen(LLVM VEGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM VEGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM VEGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM VEGenAsmMatcher.inc -gen-asm-matcher)
diff --git a/llvm/lib/Target/XCore/CMakeLists.txt b/llvm/lib/Target/XCore/CMakeLists.txt
index 3b5bf848d8144..f411c658b43b0 100644
--- a/llvm/lib/Target/XCore/CMakeLists.txt
+++ b/llvm/lib/Target/XCore/CMakeLists.txt
@@ -5,9 +5,7 @@ set(LLVM_TARGET_DEFINITIONS XCore.td)
 tablegen(LLVM XCoreGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM XCoreGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM XCoreGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM XCoreGenDisassemblerTables.inc -gen-disassembler
-          -non-templated-decode-to-mcinst-type-spec=uint16_t:=16
-          -non-templated-decode-to-mcinst-type-spec=uint32_t:=32)
+tablegen(LLVM XCoreGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM XCoreGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM XCoreGenRegisterInfo.inc -gen-register-info)
 tablegen(LLVM XCoreGenSDNodeInfo.inc -gen-sd-node-info)
diff --git a/llvm/lib/Target/Xtensa/CMakeLists.txt b/llvm/lib/Target/Xtensa/CMakeLists.txt
index 9c825b5d880c7..4fc1ba6dfa650 100644
--- a/llvm/lib/Target/Xtensa/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM XtensaGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM XtensaGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM XtensaGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM XtensaGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler
-               -non-templated-decode-to-mcinst-type-spec=uint64_t:=16,24)
+tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM XtensaGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index ae3f072601014..7656baddccba1 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -93,22 +93,6 @@ static cl::opt<bool> UseFnTableInDecodeToMCInst(
         "of the generated code."),
     cl::init(false), cl::cat(DisassemblerEmitterCat));
 
-// Option to generate a non-templated version of `decodeToMCInst`. The
-// templated `decodeToMCInst` is templated on `InsnType` and a given `InsnType`
-// can target instructions with one or more Bitwidths. So the option to
-// generate a non-templated `decodeToMCInst` is a typespec of the form
-// type::=list-of-sizes.
-
-// For example, for the AMDGPU target, the type `DecoderUInt128` is used for
-// both 96 and 128 bit instructions. So the generated non-templated
-// `decodeToMCInst` will support decoding both these instruction Bitwidths and
-// the option will be DecoderUInt128::=96,128
-static cl::list<std::string> DecodeToMCInstTypeSpecs(
-    "non-templated-decode-to-mcinst-type-spec",
-    cl::desc("list of C++ types and associated bitwidths to used to generate "
-             "non-templated `decodeToMCInst`."),
-    cl::cat(DisassemblerEmitterCat));
-
 STATISTIC(NumEncodings, "Number of encodings considered");
 STATISTIC(NumEncodingsLackingDisasm,
           "Number of encodings without disassembler info");
@@ -233,6 +217,14 @@ struct EncodingIDAndOpcode {
 using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
 using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>;
 
+// Result of parsing the `InsnCPPTypes` and `InstBitwidths` fields in the Target
+// instruction set.
+using BitwidthSet = SmallSet<unsigned, 4>;
+struct NonTemplatedInsnType {
+  StringRef CPPType;
+  BitwidthSet Bitwidths;
+};
+
 class DecoderEmitter {
   const RecordKeeper &RK;
   std::vector<EncodingAndInst> NumberedEncodings;
@@ -257,6 +249,8 @@ class DecoderEmitter {
   void run(raw_ostream &o);
 
 private:
+  SmallVector<NonTemplatedInsnType>
+  parseNonTemplatedInsnTypes(BitwidthSet &InstrBitwidths);
   CodeGenTarget Target;
 
 public:
@@ -2565,66 +2559,63 @@ handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
     break;
   }
 }
+SmallVector<NonTemplatedInsnType>
+DecoderEmitter::parseNonTemplatedInsnTypes(BitwidthSet &InstrBitwidths) {
+  SmallVector<NonTemplatedInsnType> Parsed;
 
-// Result of parsing a single `non-templated-decode-to-mcinst-type-spec` option.
-using BitwidthSet = SmallSet<unsigned, 4>;
-struct NonTemplatedTypeSpec {
-  StringRef Type;
-  BitwidthSet Bitwidths;
-};
+  const Record *InstructionSet = Target.getInstructionSet();
+  std::vector<StringRef> InsnCPPTypes =
+      InstructionSet->getValueAsListOfStrings("InsnCPPTypes");
 
-static SmallVector<NonTemplatedTypeSpec>
-parseNonTemplatedTypeSpec(BitwidthSet &InstrBitwidths) {
-  SmallVector<NonTemplatedTypeSpec> Parsed;
-  if (DecodeToMCInstTypeSpecs.empty()) {
-    // If no `non-templated-decode-to-mcinst-type-spec` option is specified,
+  if (InsnCPPTypes.empty()) {
+    // If no `InsnCPPTypes` is specified in the instruction info,
     // create a type-spec with empty values, which will trigger generation of
     // a templated `decodeToMCInst`.
     Parsed.emplace_back();
     return Parsed;
   }
 
-  Parsed.reserve(DecodeToMCInstTypeSpecs.size());
+  // Use field locations for error reporting.
+  SMLoc CPPTypesLoc = InstructionSet->getFieldLoc("InsnCPPTypes");
+  SMLoc BitwidthsLoc = InstructionSet->getFieldLoc("InsnBitwidths");
+
+  const ListInit *InsnBitwidths =
+      InstructionSet->getValueAsListInit("InsnBitwidths");
+
+  Parsed.reserve(InsnCPPTypes.size());
   BitwidthSet OptionBitwidths;
 
-  for (StringRef TypeSpec : DecodeToMCInstTypeSpecs) {
+  for (const auto &[CPPType, BWL] :
+       zip_equal(InsnCPPTypes, InsnBitwidths->getElements())) {
     BitwidthSet Bitwidths;
-    // Each `non-templated-decode-to-mcinst-type-spec` is of the form
-    // <type>:=<list of bitwidths>. Note, <type> can in general be a templated
-    // type, so using the token ":=" as a separator to allow many general C++
-    // types here.
-    auto [Type, ListOfBitWidths] = TypeSpec.split(":=");
-    if (Type.empty())
-      PrintFatalError("Invalid typespec: " + TypeSpec);
-
-    for (StringRef BwStr : split(ListOfBitWidths, ',')) {
-      unsigned Bitwidth;
-      if (BwStr.getAsInteger(10, Bitwidth))
-        PrintFatalError("Invalid bitwidth: " + BwStr + " in typespec " +
-                        TypeSpec);
-
+    if (CPPType.empty())
+      PrintFatalError(CPPTypesLoc,
+                      "CPP Type cannot be empty in `InsnCPPTypes`");
+    const auto *BitwidthList = dyn_cast<ListInit>(BWL);
+    if (!BitwidthList || BitwidthList->empty())
+      PrintFatalError(BitwidthsLoc,
+                      "No bitwidths specified for InsnCPPType : " + CPPType);
+
+    for (int64_t Bitwidth : BitwidthList->getAsListOfInts()) {
       if (!OptionBitwidths.insert(Bitwidth).second)
-        PrintFatalError("Bitwidth " + Twine(Bitwidth) + " already specified.");
+        PrintFatalError(BitwidthsLoc,
+                        "Bitwidth " + Twine(Bitwidth) + " already specified.");
 
       if (!InstrBitwidths.contains(Bitwidth))
-        PrintFatalError(Twine("No instruction of Bitwidth ") + Twine(Bitwidth) +
-                        " supported.");
-
+        PrintFatalError(BitwidthsLoc, "No instruction of bitwidth " +
+                                          Twine(Bitwidth) + " supported.");
       InstrBitwidths.erase(Bitwidth);
       Bitwidths.insert(Bitwidth);
     }
-
-    if (Bitwidths.empty())
-      PrintFatalError("No bitwidth specified in typespec " + TypeSpec);
-
-    Parsed.emplace_back(NonTemplatedTypeSpec{Type, Bitwidths});
+    Parsed.emplace_back(NonTemplatedInsnType{CPPType, Bitwidths});
   }
 
   if (!InstrBitwidths.empty()) {
+    // FIXME: Add PrintFatalError that accepts a location and a function_ref.
     PrintFatalError([&InstrBitwidths](raw_ostream &OS) {
       OS << "Bitwidth(s) ";
-      llvm::interleaveComma(InstrBitwidths, OS);
-      OS << " missing in `non-templated-decode-to-mcinst-type-spec` options.";
+      interleaveComma(InstrBitwidths, OS);
+      OS << " missing in `InsnBitwidths`";
     });
   }
   return Parsed;
@@ -2747,12 +2738,12 @@ namespace {
     const unsigned Bitwidth = 8 * NSAndByteSize.second;
     InstrBitwidths.insert(Bitwidth);
   }
-  SmallVector<NonTemplatedTypeSpec> NonTemplatedTypeSpecs =
-      parseNonTemplatedTypeSpec(InstrBitwidths);
+  SmallVector<NonTemplatedInsnType> NonTemplatedInsnTypes =
+      parseNonTemplatedInsnTypes(InstrBitwidths);
 
   DecoderTableInfo TableInfo;
   unsigned OpcodeMask = 0;
-  for (const auto &[NTType, NTBitwidths] : NonTemplatedTypeSpecs) {
+  for (const auto &[NTType, NTBitwidths] : NonTemplatedInsnTypes) {
     // Reset the Decoders for each non-templated type.
     TableInfo.Decoders.clear();
 



More information about the llvm-commits mailing list