[llvm] Feature tablegen hwmode bitset access (PR #88377)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 11 03:29:08 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: None (superZWT123)
<details>
<summary>Changes</summary>
---
Patch is 32.26 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/88377.diff
14 Files Affected:
- (modified) llvm/include/llvm/MC/MCSubtargetInfo.h (+17-1)
- (modified) llvm/lib/Target/RISCV/CMakeLists.txt (+1-1)
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+6)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td (+38)
- (modified) llvm/lib/Target/RISCV/RISCVProcessors.td (+1-1)
- (modified) llvm/lib/Target/RISCV/RISCVSubtarget.cpp (+2-2)
- (modified) llvm/lib/Target/RISCV/RISCVSubtarget.h (+1)
- (modified) llvm/test/MC/RISCV/rvzcmop-valid.s (+11-3)
- (added) llvm/test/TableGen/HwModeBitSet.td (+162)
- (modified) llvm/test/TableGen/HwModeEncodeDecode3.td (+60-18)
- (modified) llvm/utils/TableGen/CodeEmitterGen.cpp (+70-23)
- (modified) llvm/utils/TableGen/Common/CodeGenHwModes.cpp (+2)
- (modified) llvm/utils/TableGen/SubtargetEmitter.cpp (+69-8)
``````````diff
diff --git a/llvm/include/llvm/MC/MCSubtargetInfo.h b/llvm/include/llvm/MC/MCSubtargetInfo.h
index f172a799aa3331..70b14665ea9ebd 100644
--- a/llvm/include/llvm/MC/MCSubtargetInfo.h
+++ b/llvm/include/llvm/MC/MCSubtargetInfo.h
@@ -240,7 +240,23 @@ class MCSubtargetInfo {
return ProcFeatures;
}
- virtual unsigned getHwMode() const { return 0; }
+ /// HwMode ID will be stored as bits, allowing users to pull the specific
+ /// HwMode ID (like RegInfo HwMode ID) from the bits as needed. This enables
+ /// users to control multiple features with one hwmode (as previously) or use
+ /// different hwmodes to control different features.
+ enum HwModeType {
+ HwMode_Default, // Return the smallest HwMode ID of current subtarget.
+ HwMode_ValueType, // Return the HwMode ID that controls the ValueType.
+ HwMode_RegInfo, // Return the HwMode ID that controls the RegSizeInfo and
+ // SubRegRange.
+ HwMode_EncodingInfo // Return the HwMode ID that controls the EncodingInfo.
+ };
+
+ virtual unsigned getHwModeSet() const { return 0; }
+
+ virtual unsigned getHwMode(enum HwModeType type = HwMode_Default) const {
+ return 0;
+ }
/// Return the cache size in bytes for the given level of cache.
/// Level is zero-based, so a value of zero means the first level of
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 8715403f3839a6..0d5205f5351ecd 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -7,7 +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)
+tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler --suppress-per-hwmode-duplicates=O1)
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/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 6aadabdf1bc61a..7298526bb36f93 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -640,6 +640,8 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
TRY_TO_DECODE_FEATURE(
RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
"Zcmp table (16-bit Push/Pop & Double Move Instructions)");
+ TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureEncodingTmp), DecoderTable_EncodingTmp16,
+ "For HwMode check");
TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,
"RISCV_C table (16-bit Instruction)");
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 794455aa730400..072649f4610f8d 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1150,15 +1150,21 @@ def Feature32Bit
: SubtargetFeature<"32bit", "IsRV32", "true", "Implements RV32">;
def Feature64Bit
: SubtargetFeature<"64bit", "IsRV64", "true", "Implements RV64">;
+def FeatureEncodingTmp
+ : SubtargetFeature<"TmpE", "IsTmpE", "true", "Implements encoding tmp">;
def IsRV64 : Predicate<"Subtarget->is64Bit()">,
AssemblerPredicate<(all_of Feature64Bit),
"RV64I Base Instruction Set">;
def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
AssemblerPredicate<(all_of (not Feature64Bit)),
"RV32I Base Instruction Set">;
+def IsTmpE : Predicate<"Subtarget->isETmp()">,
+ AssemblerPredicate<(all_of FeatureEncodingTmp),
+ "RV32I Encoding tmp">;
defvar RV32 = DefaultMode;
def RV64 : HwMode<"+64bit", [IsRV64]>;
+def EncodingTmp : HwMode<"+TmpE", [IsRV64]>;
def FeatureRVE
: SubtargetFeature<"e", "IsRVE", "true",
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td
index dd13a07d606d04..23a0a6fb31f00e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td
@@ -11,6 +11,38 @@
//
//===----------------------------------------------------------------------===//
+multiclass tmpEclass<bits<3> imm3> {
+def NAME#commonE : InstructionEncoding {
+ field bits<16> Inst;
+ field bits<16> SoftFail = 0;
+ let Size = 2;
+ bit mayLoad = 0;
+ bit mayStore = 0;
+ bit hasSideEffects = 0;
+ let Inst{1-0} = 0b01;
+ let Inst{6-2} = 0;
+ let Inst{7} = 0b1; //differ
+ let Inst{10-8} = imm3;
+ let Inst{12-11} = 0;
+ let Inst{15-13} = 0b011;
+}
+
+def NAME#specialE : InstructionEncoding {
+ field bits<16> Inst;
+ field bits<16> SoftFail = 0;
+ let Size = 2;
+ bit mayLoad = 0;
+ bit mayStore = 0;
+ bit hasSideEffects = 0;
+ let Inst{1-0} = 0b01;
+ let Inst{6-2} = 0;
+ let Inst{7} = 0b0; //differ
+ let Inst{10-8} = imm3;
+ let Inst{12-11} = 0;
+ let Inst{15-13} = 0b011;
+}
+}
+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class CMOPInst<bits<3> imm3, string opcodestr>
: RVInst16CI<0b011, 0b01, (outs), (ins), opcodestr, ""> {
@@ -18,15 +50,21 @@ class CMOPInst<bits<3> imm3, string opcodestr>
let Inst{7} = 1;
let Inst{10-8} = imm3;
let Inst{12-11} = 0;
+ let EncodingInfos = EncodingByHwMode<[DefaultMode, EncodingTmp],
+ [!cast<InstructionEncoding>(NAME#commonE),
+ !cast<InstructionEncoding>(NAME#specialE)]>;
}
// CMOP1, CMOP5 is used by Zicfiss.
let Predicates = [HasStdExtZcmop, NoHasStdExtZicfiss] in {
+ defm CMOP1 : tmpEclass<0>;
+ defm CMOP5 : tmpEclass<2>;
def CMOP1 : CMOPInst<0, "cmop.1">, Sched<[]>;
def CMOP5 : CMOPInst<2, "cmop.5">, Sched<[]>;
}
foreach n = [3, 7, 9, 11, 13, 15] in {
let Predicates = [HasStdExtZcmop] in
+ defm CMOP # n : tmpEclass<!srl(n, 1)>;
def CMOP # n : CMOPInst<!srl(n, 1), "cmop." # n>, Sched<[]>;
}
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td
index fd6d6078ec238b..cbb199ffb76585 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -60,7 +60,7 @@ def GENERIC_RV32 : RISCVProcessorModel<"generic-rv32",
GenericTuneInfo;
def GENERIC_RV64 : RISCVProcessorModel<"generic-rv64",
NoSchedModel,
- [Feature64Bit]>,
+ [Feature64Bit, FeatureEncodingTmp]>,
GenericTuneInfo;
// Support generic for compatibility with other targets. The triple will be used
// to change to the appropriate rv32/rv64 version.
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index d3236bb07d56d5..b4156df907ee97 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -100,11 +100,11 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
FrameLowering(
initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
- InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
+ InstrInfo(*this), RegInfo(getHwMode(HwMode_RegInfo)), TLInfo(TM, *this) {
CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
Legalizer.reset(new RISCVLegalizerInfo(*this));
- auto *RBI = new RISCVRegisterBankInfo(getHwMode());
+ auto *RBI = new RISCVRegisterBankInfo(getHwMode(HwMode_RegInfo));
RegBankInfo.reset(RBI);
InstSelector.reset(createRISCVInstructionSelector(
*static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 85f8f5f654fe7c..28e9ff4c07f436 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -165,6 +165,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
}
bool is64Bit() const { return IsRV64; }
+ bool isETmp() const { return IsTmpE; }
MVT getXLenVT() const {
return is64Bit() ? MVT::i64 : MVT::i32;
}
diff --git a/llvm/test/MC/RISCV/rvzcmop-valid.s b/llvm/test/MC/RISCV/rvzcmop-valid.s
index c6bb4a15808258..4e0ce25f73efa3 100644
--- a/llvm/test/MC/RISCV/rvzcmop-valid.s
+++ b/llvm/test/MC/RISCV/rvzcmop-valid.s
@@ -1,42 +1,50 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zcmop -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zcmop -show-encoding \
-# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: | FileCheck -check-prefixes=CHECK-ASM-64,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zcmop < %s \
-# RUN: | llvm-objdump --mattr=+zcmop -d -r - \
+# RUN: | llvm-objdump --triple=riscv32 --mattr=+zcmop -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zcmop < %s \
-# RUN: | llvm-objdump --mattr=+zcmop -d -r - \
+# RUN: | llvm-objdump --triple=riscv64 --mattr=+zcmop -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# CHECK-ASM-AND-OBJ: cmop.1
# CHECK-ASM: encoding: [0x81,0x60]
+# CHECK-ASM-64: encoding: [0x01,0x60]
cmop.1
# CHECK-ASM-AND-OBJ: cmop.3
# CHECK-ASM: encoding: [0x81,0x61]
+# CHECK-ASM-64: encoding: [0x01,0x61]
cmop.3
# CHECK-ASM-AND-OBJ: cmop.5
# CHECK-ASM: encoding: [0x81,0x62]
+# CHECK-ASM-64: encoding: [0x01,0x62]
cmop.5
# CHECK-ASM-AND-OBJ: cmop.7
# CHECK-ASM: encoding: [0x81,0x63]
+# CHECK-ASM-64: encoding: [0x01,0x63]
cmop.7
# CHECK-ASM-AND-OBJ: cmop.9
# CHECK-ASM: encoding: [0x81,0x64]
+# CHECK-ASM-64: encoding: [0x01,0x64]
cmop.9
# CHECK-ASM-AND-OBJ: cmop.11
# CHECK-ASM: encoding: [0x81,0x65]
+# CHECK-ASM-64: encoding: [0x01,0x65]
cmop.11
# CHECK-ASM-AND-OBJ: cmop.13
# CHECK-ASM: encoding: [0x81,0x66]
+# CHECK-ASM-64: encoding: [0x01,0x66]
cmop.13
# CHECK-ASM-AND-OBJ: cmop.15
# CHECK-ASM: encoding: [0x81,0x67]
+# CHECK-ASM-64: encoding: [0x01,0x67]
cmop.15
diff --git a/llvm/test/TableGen/HwModeBitSet.td b/llvm/test/TableGen/HwModeBitSet.td
new file mode 100644
index 00000000000000..c642906f6f4a88
--- /dev/null
+++ b/llvm/test/TableGen/HwModeBitSet.td
@@ -0,0 +1,162 @@
+// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-REG
+// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-SUBTARGET
+
+include "llvm/Target/Target.td"
+
+def TestTargetInstrInfo : InstrInfo;
+
+def TestTarget : Target {
+ let InstructionSet = TestTargetInstrInfo;
+}
+
+def TestMode : HwMode<"+feat", []>;
+def TestMode1 : HwMode<"+feat1", []>;
+def TestMode2 : HwMode<"+feat2", []>;
+
+class MyReg<string n>
+ : Register<n> {
+ let Namespace = "Test";
+}
+
+class MyClass<int size, list<ValueType> types, dag registers>
+ : RegisterClass<"Test", types, size, registers> {
+ let Size = size;
+}
+
+def X0 : MyReg<"x0">;
+def X1 : MyReg<"x1">;
+def X2 : MyReg<"x2">;
+def X3 : MyReg<"x3">;
+def X4 : MyReg<"x4">;
+def X5 : MyReg<"x5">;
+def X6 : MyReg<"x6">;
+def X7 : MyReg<"x7">;
+def X8 : MyReg<"x8">;
+def X9 : MyReg<"x9">;
+def X10 : MyReg<"x10">;
+def X11 : MyReg<"x11">;
+def X12 : MyReg<"x12">;
+def X13 : MyReg<"x13">;
+def X14 : MyReg<"x14">;
+def X15 : MyReg<"x15">;
+
+def ValueModeVT : ValueTypeByHwMode<[DefaultMode, TestMode, TestMode1],
+ [i32, i64, f32]>;
+
+let RegInfos = RegInfoByHwMode<[DefaultMode, TestMode],
+ [RegInfo<32,32,32>, RegInfo<64,64,64>]> in
+def XRegs : MyClass<32, [ValueModeVT], (sequence "X%u", 0, 15)>;
+
+def sub_even : SubRegIndex<32> {
+ let SubRegRanges = SubRegRangeByHwMode<[DefaultMode, TestMode],
+ [SubRegRange<32>, SubRegRange<64>]>;
+}
+def sub_odd : SubRegIndex<32, 32> {
+ let SubRegRanges = SubRegRangeByHwMode<[DefaultMode, TestMode],
+ [SubRegRange<32, 32>, SubRegRange<64, 64>]>;
+}
+
+def XPairs : RegisterTuples<[sub_even, sub_odd],
+ [(decimate (rotl XRegs, 0), 2),
+ (decimate (rotl XRegs, 1), 2)]>;
+
+let RegInfos = RegInfoByHwMode<[DefaultMode, TestMode],
+ [RegInfo<64,64,32>, RegInfo<128,128,64>]> in
+def XPairsClass : MyClass<64, [untyped], (add XPairs)>;
+
+// Modes who are not controlling Register related features will be manipulated
+// the same as DefaultMode.
+// CHECK-REG-LABEL: RegisterClass XRegs:
+// CHECK-REG: SpillSize: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 }
+// CHECK-REG: SpillAlignment: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 }
+// CHECK-REG: Regs: X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+
+// CHECK-REG-LABEL: RegisterClass XPairsClass:
+// CHECK-REG: SpillSize: { Default:64 TestMode:128 TestMode1:64 TestMode2:64 }
+// CHECK-REG: SpillAlignment: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 }
+// CHECK-REG: CoveredBySubRegs: 1
+// CHECK-REG: Regs: X0_X1 X2_X3 X4_X5 X6_X7 X8_X9 X10_X11 X12_X13 X14_X15
+
+// CHECK-REG-LABEL: SubRegIndex sub_even:
+// CHECK-REG: Offset: { Default:0 TestMode:0 TestMode1:0 TestMode2:0 }
+// CHECK-REG: Size: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 }
+// CHECK-REG-LABEL: SubRegIndex sub_odd:
+// CHECK-REG: Offset: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 }
+// CHECK-REG: Size: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 }
+
+//============================================================================//
+//--------------------- Encoding/Decoding parts ------------------------------//
+//============================================================================//
+def fooTypeEncDefault : InstructionEncoding {
+ let Size = 8;
+ field bits<64> SoftFail = 0;
+ bits<64> Inst;
+ bits<8> factor;
+ let Inst{7...0} = factor;
+ let Inst{3...2} = 0b10;
+ let Inst{1...0} = 0b00;
+}
+
+def fooTypeEncA : InstructionEncoding {
+ let Size = 4;
+ field bits<32> SoftFail = 0;
+ bits<32> Inst;
+ bits<8> factor;
+ let Inst{7...0} = factor;
+ let Inst{3...2} = 0b11;
+ let Inst{1...0} = 0b00;
+}
+
+
+def foo : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$factor);
+ let EncodingInfos = EncodingByHwMode<
+ [TestMode2, DefaultMode], [fooTypeEncA, fooTypeEncDefault]
+ >;
+ let AsmString = "foo $factor";
+}
+
+// CHECK-SUBTARGET-LABEL: unsigned TestTargetGenSubtargetInfo::getHwModeSet() const {
+// CHECK-SUBTARGET: unsigned Modes = 0;
+// CHECK-SUBTARGET: if (checkFeatures("+feat")) Modes |= (1 << 0);
+// CHECK-SUBTARGET: if (checkFeatures("+feat1")) Modes |= (1 << 1);
+// CHECK-SUBTARGET: if (checkFeatures("+feat2")) Modes |= (1 << 2);
+// CHECK-SUBTARGET: return Modes;
+// CHECK-SUBTARGET: }
+// CHECK-SUBTARGET-LABEL: unsigned TestTargetGenSubtargetInfo::getHwMode(enum HwModeType type) const {
+// CHECK-SUBTARGET: unsigned Modes = getHwModeSet();
+// CHECK-SUBTARGET: if(!Modes)
+// CHECK-SUBTARGET: return Modes;
+// CHECK-SUBTARGET: switch (type) {
+// CHECK-SUBTARGET: case HwMode_Default:
+// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1;
+// CHECK-SUBTARGET: break;
+// CHECK-SUBTARGET: case HwMode_ValueType: {
+// CHECK-SUBTARGET: Modes &= 3;
+// CHECK-SUBTARGET: if (!Modes)
+// CHECK-SUBTARGET: return Modes;
+// CHECK-SUBTARGET: if (!llvm::has_single_bit<unsigned>(Modes))
+// CHECK-SUBTARGET: llvm_unreachable("Two or more HwModes for ValueType were found!");
+// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1;
+// CHECK-SUBTARGET: }
+// CHECK-SUBTARGET: case HwMode_RegInfo: {
+// CHECK-SUBTARGET: Modes &= 1;
+// CHECK-SUBTARGET: if (!Modes)
+// CHECK-SUBTARGET: return Modes;
+// CHECK-SUBTARGET: if (!llvm::has_single_bit<unsigned>(Modes))
+// CHECK-SUBTARGET: llvm_unreachable("Two or more HwModes for RegInfo were found!");
+// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1;
+// CHECK-SUBTARGET: }
+// CHECK-SUBTARGET: case HwMode_EncodingInfo: {
+// CHECK-SUBTARGET: Modes &= 4;
+// CHECK-SUBTARGET: if (!Modes)
+// CHECK-SUBTARGET: return Modes;
+// CHECK-SUBTARGET: if (!llvm::has_single_bit<unsigned>(Modes))
+// CHECK-SUBTARGET: llvm_unreachable("Two or more HwModes for Encoding were found!");
+// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1;
+// CHECK-SUBTARGET: }
+// CHECK-SUBTARGET: }
+// CHECK-SUBTARGET: return 0; // should not get here
+// CHECK-SUBTARGET: }
+
diff --git a/llvm/test/TableGen/HwModeEncodeDecode3.td b/llvm/test/TableGen/HwModeEncodeDecode3.td
index 8e0266b2c55af9..bc65d4a1d40d3b 100644
--- a/llvm/test/TableGen/HwModeEncodeDecode3.td
+++ b/llvm/test/TableGen/HwModeEncodeDecode3.td
@@ -160,15 +160,22 @@ def unrelated: Instruction {
// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:baz
// DECODER-SUPPRESS-O2-NOT: Opcode: bar
-// ENCODER-LABEL: static const uint64_t InstBits_DefaultMode[] = {
+// For 'bar' and 'unrelated', we didn't assign any hwmodes for them,
+// they should keep the same in the following three tables.
+// For 'foo' we assigned three hwmodes(includes 'DefaultMode')
+// it's encodings should be different in the following three tables.
+// For 'baz' we only assigned ModeB for it, to avoid empty encoding
+// we assigned the encoding of ModeB to ModeA and DefaultMode(Even though
+// they will not be used).
+// ENCODER-LABEL: static const uint64_t InstBits[] = {
// ENCODER: UINT64_C(2), // bar
-// ENCODER: UINT64_C(0), // baz
+// ENCODER: UINT64_C(12), // baz
// ENCODER: UINT64_C(8), // foo
// ENCODER: UINT64_C(2), // unrelated
// ENCODER-LABEL: static const uint64_t InstBits_ModeA[] = {
// ENCODER: UINT64_C(2), // bar
-// ENCODER: UINT64_C(0), // baz
+// ENCODER: UINT64_C(12), // baz
// ENCODER: UINT64_C(12), // foo
// ENCODER: UINT64_C(2), // unrelated
@@ -178,18 +185,53 @@ def unrelated: Instruction {
// ENCODER: UINT64_C(3), // foo
// ENCODER: UINT64_C(2), // unrelated
-// ENCODER: unsigned HwMode = STI.getHwMode();
-// ENCODER: switch (HwMode) {
-// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break;
-// ENCODER: case 0: InstBits = InstBits_DefaultMode; break;
-// ENCODER: case 1: InstBits = InstBits_ModeA; break;
-// ENCODER: case 2: InstBits = InstBits_ModeB; break;
-// ENCODER: };
-
-// ENCODER: case ::foo: {
-// ENCODER: switch (HwMode) {
-// ENCODER: default: llvm_unreachable("Unhandled HwMode");
-// ENCODER: case 0: {
-// ENCODER: case 1: {
-// ENCODER: case 2: {
-
+// ENCODER-LABEL: case ::bar:
+// ENCODER-LABEL: case ::unrelated:
+// ENCODER-NOT: getHwMode
+// ENCODER-LABEL: case ::baz: {
+// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo);
+// ENCODER: HwMode &= 2;
+// ENCODER: switch (HwMode) {
+// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break;
+// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break;
+// ENCODER: };
+// ENCODER: Value = InstBitsByHw[opcode];
+// ENCODER: switch (HwMode) {
+// ENCODER: default: llvm_unreachable("Unhandled HwMode");
+// ENCODER: case 2: {
+// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
+// ENCODER: op &= UINT64_C(240);
+// ENCODER: Value |= op;
+// ENCODER: break;
+// ENCODER: }
+// ENCODER-LABEL: case ::foo: {
+// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMod...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/88377
More information about the llvm-commits
mailing list