Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8de688d
Detect and use zicond in ifconversion on riscv64
am11 May 29, 2026
384207e
Address CR feedback
am11 May 31, 2026
7d5938a
Fix assertion in checked build
am11 Jun 2, 2026
71ff72f
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jun 2, 2026
01055f8
Remove hardcoded size from merged add
am11 Jun 2, 2026
6f3b002
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jun 15, 2026
9df3497
.
am11 Jun 15, 2026
6be71de
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jun 19, 2026
5f5dd46
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 2, 2026
272930d
Address CR feedback
am11 Jul 3, 2026
0a95451
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 3, 2026
261abd0
Update src/coreclr/jit/lowerriscv64.cpp
am11 Jul 3, 2026
095f123
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 13, 2026
a5ef1a2
Merge conflicts
am11 Jul 13, 2026
d383dbb
.
am11 Jul 13, 2026
21f9ad6
Apply format patch
am11 Jul 13, 2026
3899637
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 13, 2026
8c4310a
Remove XOR-with-1 negation folding logic
am11 Jul 13, 2026
aa4f835
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 13, 2026
6d4119b
Check oper before reversing
am11 Jul 13, 2026
161a4ac
Fix merge conflict
am11 Jul 13, 2026
3b803cf
Format
am11 Jul 13, 2026
3497393
.
am11 Jul 13, 2026
501f83f
.
am11 Jul 13, 2026
094ac49
.
am11 Jul 13, 2026
b11fc30
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 13, 2026
ca0db12
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
jakobbotsch Jul 14, 2026
e0f3c7b
Update lower.cpp
am11 Jul 15, 2026
b158587
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 15, 2026
c940739
.
am11 Jul 15, 2026
110fefe
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 15, 2026
69fb6c1
Update src/coreclr/jit/lowerriscv64.cpp
am11 Jul 16, 2026
4d4189f
Merge branch 'main' into feature/riscv64/detect-and-use-zicond
am11 Jul 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableArm64SveSm4, W("EnableArm64Sv
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zba, W("EnableRiscV64Zba"), 1, "Allows RiscV64 Zba hardware intrinsics to be disabled")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zbb, W("EnableRiscV64Zbb"), 1, "Allows RiscV64 Zbb hardware intrinsics to be disabled")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zbs, W("EnableRiscV64Zbs"), 1, "Allows RiscV64 Zbs hardware intrinsics to be disabled")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zicond, W("EnableRiscV64Zicond"), 1, "Allows RiscV64 Zicond hardware intrinsics to be disabled")
#endif

///
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/inc/corinfoinstructionset.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum CORINFO_InstructionSet
InstructionSet_Zba=2,
InstructionSet_Zbb=3,
InstructionSet_Zbs=4,
InstructionSet_Zicond=5,
#endif // TARGET_RISCV64
#ifdef TARGET_AMD64
InstructionSet_X86Base=1,
Expand Down Expand Up @@ -447,6 +448,8 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins
resultflags.RemoveInstructionSet(InstructionSet_Zba);
if (resultflags.HasInstructionSet(InstructionSet_Zbs) && !resultflags.HasInstructionSet(InstructionSet_RiscV64Base))
resultflags.RemoveInstructionSet(InstructionSet_Zbs);
if (resultflags.HasInstructionSet(InstructionSet_Zicond) && !resultflags.HasInstructionSet(InstructionSet_RiscV64Base))
resultflags.RemoveInstructionSet(InstructionSet_Zicond);
#endif // TARGET_RISCV64
#ifdef TARGET_AMD64
if (resultflags.HasInstructionSet(InstructionSet_X86Base) && !resultflags.HasInstructionSet(InstructionSet_X86Base_X64))
Expand Down Expand Up @@ -741,6 +744,8 @@ inline const char *InstructionSetToString(CORINFO_InstructionSet instructionSet)
return "Zbb";
case InstructionSet_Zbs :
return "Zbs";
case InstructionSet_Zicond :
return "Zicond";
#endif // TARGET_RISCV64
#ifdef TARGET_AMD64
case InstructionSet_X86Base :
Expand Down Expand Up @@ -942,6 +947,7 @@ inline CORINFO_InstructionSet InstructionSetFromR2RInstructionSet(ReadyToRunInst
case READYTORUN_INSTRUCTION_Zba: return InstructionSet_Zba;
case READYTORUN_INSTRUCTION_Zbb: return InstructionSet_Zbb;
case READYTORUN_INSTRUCTION_Zbs: return InstructionSet_Zbs;
case READYTORUN_INSTRUCTION_Zicond: return InstructionSet_Zicond;
#endif // TARGET_RISCV64
#ifdef TARGET_AMD64
case READYTORUN_INSTRUCTION_X86Base: return InstructionSet_X86Base;
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

#include <minipal/guid.h>

constexpr GUID JITEEVersionIdentifier = { /* 31a04b06-915e-42a0-bbd2-c9c397677ae5 */
0x31a04b06,
0x915e,
0x42a0,
{0xbb, 0xd2, 0xc9, 0xc3, 0x97, 0x67, 0x7a, 0xe5}
constexpr GUID JITEEVersionIdentifier = { /* c7a85d30-48b8-4d2f-8767-89f520440ded */
0xc7a85d30,
0x48b8,
0x4d2f,
{0x87, 0x67, 0x89, 0xf5, 0x20, 0x44, 0x0d, 0xed}
};

#endif // JIT_EE_VERSIONING_GUID_H
1 change: 1 addition & 0 deletions src/coreclr/inc/readytoruninstructionset.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ enum ReadyToRunInstructionSet
READYTORUN_INSTRUCTION_SveAes=88,
READYTORUN_INSTRUCTION_SveSha3=89,
READYTORUN_INSTRUCTION_SveSm4=90,
READYTORUN_INSTRUCTION_Zicond=91,

};

Expand Down
59 changes: 59 additions & 0 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3150,6 +3150,61 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree)
genProduceReg(tree);
}

//------------------------------------------------------------------------
// genCodeForSelect: Produce branch-free code for a GT_SELECT node using Zicond.
//
// SELECT(cond, trueVal, falseVal) =>
// czero.nez tmp, falseVal, cond ; tmp = (cond != 0) ? 0 : falseVal
// czero.eqz dst, trueVal, cond ; dst = (cond == 0) ? 0 : trueVal
// or dst, dst, tmp
//
// Degenerate cases (one operand is the zero register) collapse to a single czero.
//
// Arguments:
// tree - the GT_SELECT node
//
void CodeGen::genCodeForSelect(GenTreeOp* tree)
{
assert(tree->OperIs(GT_SELECT));
assert(m_compiler->compOpportunisticallyDependsOn(InstructionSet_Zicond));
assert(varTypeIsIntegralOrI(tree));

GenTreeConditional* sel = tree->AsConditional();
GenTree* cond = sel->gtCond;
GenTree* trueVal = sel->gtOp1;
GenTree* falseVal = sel->gtOp2;

genConsumeRegs(cond);
genConsumeRegs(trueVal);
genConsumeRegs(falseVal);

regNumber targetReg = tree->GetRegNum();
regNumber condReg = cond->GetRegNum();
regNumber trueReg = trueVal->isContained() ? REG_ZERO : trueVal->GetRegNum();
regNumber falseReg = falseVal->isContained() ? REG_ZERO : falseVal->GetRegNum();

emitter* emit = GetEmitter();
emitAttr attr = emitActualTypeSize(tree);

if (falseReg == REG_ZERO)
{
emit->emitIns_R_R_R(INS_czero_eqz, attr, targetReg, trueReg, condReg);
}
else if (trueReg == REG_ZERO)
{
emit->emitIns_R_R_R(INS_czero_nez, attr, targetReg, falseReg, condReg);
}
else
{
regNumber tmpReg = internalRegisters.Extract(tree);
Comment thread
am11 marked this conversation as resolved.
Outdated
emit->emitIns_R_R_R(INS_czero_nez, attr, tmpReg, falseReg, condReg);
emit->emitIns_R_R_R(INS_czero_eqz, attr, targetReg, trueReg, condReg);
emit->emitIns_R_R_R(INS_or, attr, targetReg, targetReg, tmpReg);
Comment thread
am11 marked this conversation as resolved.
Outdated
}

genProduceReg(tree);
}

//------------------------------------------------------------------------
// genCodeForJumpCompare: Generates code for jmpCompare statement.
//
Expand Down Expand Up @@ -3940,6 +3995,10 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
genCodeForCompare(treeNode->AsOp());
break;

case GT_SELECT:
genCodeForSelect(treeNode->AsOp());
break;

case GT_JCMP:
genCodeForJumpCompare(treeNode->AsOpCC());
break;
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6215,6 +6215,11 @@ int Compiler::compCompileAfterInit(CORINFO_MODULE_HANDLE classPtr,
{
instructionSetFlags.AddInstructionSet(InstructionSet_Zbb);
}

if (JitConfig.EnableRiscV64Zicond() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Zicond);
}
#endif

// These calls are important and explicitly ordered to ensure that the flags are correct in
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10698,6 +10698,7 @@ class Compiler
}
#endif // DEBUG

public:
bool notifyInstructionSetUsage(CORINFO_InstructionSet isa, bool supported) const;

// Answer the question: Is a particular ISA allowed to be used implicitly by optimizations?
Expand Down Expand Up @@ -10741,6 +10742,7 @@ class Compiler
return opts.compSupportsISA.HasInstructionSet(isa);
}

private:
#ifdef DEBUG
//------------------------------------------------------------------------
// canUseEvexEncodingDebugOnly - Answer the question: Is Evex encoding supported on this target.
Expand Down
17 changes: 16 additions & 1 deletion src/coreclr/jit/emitriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ void emitter::emitIns_R_R_R(
(INS_fadd_d <= ins && ins <= INS_fmax_d) || (INS_feq_s <= ins && ins <= INS_fle_s) ||
(INS_feq_d <= ins && ins <= INS_fle_d) || (INS_lr_w <= ins && ins <= INS_amomaxu_d) ||
(INS_sh1add <= ins && ins <= INS_sh3add_uw) || (INS_rol <= ins && ins <= INS_maxu) ||
(INS_bset <= ins && ins <= INS_binv))
(INS_bset <= ins && ins <= INS_binv) || (INS_czero_eqz <= ins && ins <= INS_czero_nez))
{
#ifdef DEBUG
switch (ins)
Expand Down Expand Up @@ -962,6 +962,9 @@ void emitter::emitIns_R_R_R(
case INS_bclr:
case INS_bext:
case INS_binv:

case INS_czero_eqz:
case INS_czero_nez:
break;
default:
NYI_RISCV64("illegal ins within emitIns_R_R_R!");
Expand Down Expand Up @@ -4041,6 +4044,18 @@ void emitter::emitDispInsName(
return emitDispIllegalInstruction(code);
printf("binv %s, %s, %s\n", rd, rs1, rs2);
return;
case 0b0000111:
switch (opcode3)
{
case 0b101:
printf("czero.eqz %s, %s, %s\n", rd, rs1, rs2);
return;
case 0b111:
printf("czero.nez %s, %s, %s\n", rd, rs1, rs2);
return;
default:
return emitDispIllegalInstruction(code);
}
default:
return emitDispIllegalInstruction(code);
}
Expand Down
34 changes: 32 additions & 2 deletions src/coreclr/jit/ifconversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,38 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget)
#ifdef TARGET_RISCV64
if (select->OperIs(GT_SELECT))
{
JITDUMP("Skipping if-conversion that could not be optimized to ordinary operations\n");
return true;
// Without Zicond, riscv64 has no native lowering for GT_SELECT - the
// branchy form is kept. With Zicond the SELECT is lowered to a
// czero.{eqz,nez}/or sequence, but only for integer-typed selects.
bool canCodegenSelect = m_compiler->compOpportunisticallyDependsOn(InstructionSet_Zicond) &&
varTypeIsIntegralOrI(select->TypeGet());
if (!canCodegenSelect)
{
JITDUMP("Skipping if-conversion that could not be optimized to ordinary operations\n");
return true;
}

// RISC-V has no flag register, so any branchless SELECT must first materialize
// the condition into a 0/1 register before the czero/or sequence (>=5 insns).
Comment thread
jakobbotsch marked this conversation as resolved.
// When one arm is a no-op (read of an existing local) and the other is a small
// immediate, the branchy form fits in ~2 insns (branch + addi), so keep it.
Comment thread
jakobbotsch marked this conversation as resolved.
GenTreeConditional* sel = select->AsConditional();
GenTree* selTrue = sel->gtOp1;
GenTree* selFalse = sel->gtOp2;

auto isLocalNoOp = [](GenTree* n) {
return n->OperIs(GT_LCL_VAR);
};
auto isSmallImm = [](GenTree* n) {
return n->IsIntegralConst() && (n->AsIntConCommon()->IntegralValue() >= -2048) &&
(n->AsIntConCommon()->IntegralValue() <= 2047);
};
Comment thread
am11 marked this conversation as resolved.

if ((isLocalNoOp(selTrue) && isSmallImm(selFalse)) || (isSmallImm(selTrue) && isLocalNoOp(selFalse)))
{
JITDUMP("Skipping if-conversion: branchy form fits in ~2 insns; Zicond would need 5+\n");
return true;
}
}
#endif

Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/jit/instrsriscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@ INST(bclri, "bclri", 0, 0x48001013)
INST(bexti, "bexti", 0, 0x48005013)
INST(binvi, "binvi", 0, 0x68001013)

// Zicond (RV32 + RV64)
//// R_R_R
INST(czero_eqz, "czero.eqz", 0, 0x0e005033)
INST(czero_nez, "czero.nez", 0, 0x0e007033)

// RVC
INST(c_mv, "c.mv", 0, 0x00008002)
INST(c_add, "c.add", 0, 0x00009002)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ RELEASE_CONFIG_INTEGER(EnableArm64SveSm4, "EnableArm64SveSm4",
RELEASE_CONFIG_INTEGER(EnableRiscV64Zba, "EnableRiscV64Zba", 1) // Allows RiscV64 Zba hardware intrinsics to be disabled
RELEASE_CONFIG_INTEGER(EnableRiscV64Zbb, "EnableRiscV64Zbb", 1) // Allows RiscV64 Zbb hardware intrinsics to be disabled
RELEASE_CONFIG_INTEGER(EnableRiscV64Zbs, "EnableRiscV64Zbs", 1) // Allows RiscV64 Zbs hardware intrinsics to be disabled
RELEASE_CONFIG_INTEGER(EnableRiscV64Zicond, "EnableRiscV64Zicond", 1) // Allows RiscV64 Zicond hardware intrinsics to be disabled
#endif

RELEASE_CONFIG_INTEGER(EnableEmbeddedBroadcast, "EnableEmbeddedBroadcast", 1) // Allows embedded broadcasts to be disabled
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4805,8 +4805,9 @@ GenTree* Lowering::LowerSelect(GenTreeConditional* select)
// TODO-CQ: If we allowed multiple nodes to consume the same CPU flags then
// we could do this on x86. We currently disable if-conversion for TYP_LONG
// on 32-bit architectures because of this.
GenCondition selectCond;
GenTreeOpCC* newSelect = nullptr;
#if !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64)
GenCondition selectCond;
if (((select->gtFlags & GTF_SET_FLAGS) == 0) && TryLowerConditionToFlagsNode(select, cond, &selectCond))
Comment thread
am11 marked this conversation as resolved.
Outdated
{
select->SetOper(GT_SELECTCC);
Expand All @@ -4818,6 +4819,7 @@ GenTree* Lowering::LowerSelect(GenTreeConditional* select)
JITDUMP("\n");
}
else
#endif
{
ContainCheckSelect(select);
}
Expand Down
56 changes: 55 additions & 1 deletion src/coreclr/jit/lowerriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,61 @@ void Lowering::ContainCheckCompare(GenTreeOp* cmp)
//
void Lowering::ContainCheckSelect(GenTreeOp* node)
{
noway_assert(!"GT_SELECT nodes are not supported on riscv64");
assert(node->OperIs(GT_SELECT));
// GT_SELECT is only produced/codegen'd on riscv64 when Zicond is available; integer-only.
assert(m_compiler->compOpportunisticallyDependsOn(InstructionSet_Zicond));
assert(varTypeIsIntegralOrI(node));

GenTreeConditional* sel = node->AsConditional();

// czero.{eqz,nez} encode both polarities, so reversed relops (GE/LE and unsigned
// EQ/NE-with-zero) that would otherwise emit slt+xori can have the trailing xori
// dropped by swapping the SELECT arms and using the un-reversed compare directly.
GenTree* cond = sel->gtCond;
if (cond->OperIsCompare())
{
GenTreeOp* relop = cond->AsOp();
genTreeOps oper = relop->OperGet();
// genCodeForCompare reverses GE/LE into LT/GT and emits a trailing xori; it
// also rewrites unsigned EQ(x,0)/NE(x,0) into LE/GT and reverses again. Both
// patterns end up materializing the negation as xori reg, reg, 1.
Comment thread
am11 marked this conversation as resolved.
Outdated
bool relopIsReversed = oper == GT_GE || oper == GT_LE;
if (!relopIsReversed && relop->OperIs(GT_EQ, GT_NE))
Comment thread
am11 marked this conversation as resolved.
Outdated
{
GenTree* relopOp2 = relop->gtGetOp2();
relopIsReversed = oper == GT_EQ && relopOp2->IsIntegralConst(0) && relopOp2->isContained();
Comment thread
am11 marked this conversation as resolved.
Outdated
}
LIR::Use condUse;
if (relopIsReversed && BlockRange().TryGetUse(cond, &condUse) && (condUse.User() == sel))
{
relop->SetOper(GenTree::ReverseRelop(oper));
std::swap(sel->gtOp1, sel->gtOp2);
}
}
// Also fold an explicit XOR-with-1 negation produced by other lowerings.
else if (cond->OperIs(GT_XOR))
Comment thread
jakobbotsch marked this conversation as resolved.
Outdated
{
GenTree* xorLhs = cond->AsOp()->gtGetOp1();
GenTree* xorRhs = cond->AsOp()->gtGetOp2();
LIR::Use condUse;
if (xorRhs->IsIntegralConst(1) && xorLhs->OperIsCompare() && BlockRange().TryGetUse(cond, &condUse) &&
(condUse.User() == sel))
Comment thread
am11 marked this conversation as resolved.
Outdated
{
sel->gtCond = xorLhs;
std::swap(sel->gtOp1, sel->gtOp2);
BlockRange().Remove(xorRhs);
BlockRange().Remove(cond);
}
Comment thread
am11 marked this conversation as resolved.
}

// czero.{eqz,nez} take a register source and a register condition, so the only
// contained form is an integral-zero operand that can be expressed via REG_ZERO.
GenTree* op1 = sel->gtOp1;
GenTree* op2 = sel->gtOp2;
if (op1->IsIntegralConst(0) && !op1->AsIntCon()->ImmedValNeedsReloc(m_compiler))
MakeSrcContained(node, op1);
Comment thread
am11 marked this conversation as resolved.
if (op2->IsIntegralConst(0) && !op2->AsIntCon()->ImmedValNeedsReloc(m_compiler))
MakeSrcContained(node, op2);
}

//------------------------------------------------------------------------
Expand Down
13 changes: 13 additions & 0 deletions src/coreclr/jit/lsrariscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,19 @@ int LinearScan::BuildNode(GenTree* tree)
srcCount = BuildCmp(tree);
break;

case GT_SELECT:
{
GenTreeConditional* sel = tree->AsConditional();
srcCount = BuildOperandUses(sel->gtCond);
srcCount += BuildOperandUses(sel->gtOp1);
srcCount += BuildOperandUses(sel->gtOp2);
buildInternalIntRegisterDefForNode(tree);
Comment thread
am11 marked this conversation as resolved.
Outdated
assert(dstCount == 1);
BuildDef(tree);
buildInternalRegisterUses();
}
break;

case GT_CKFINITE:
srcCount = 1;
assert(dstCount == 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ private static class RiscV64IntrinsicConstants
public const int Zba = (1 << 0);
public const int Zbb = (1 << 1);
public const int Zbs = (1 << 2);
public const int Zicond = (1 << 3);

public static void AddToBuilder(InstructionSetSupportBuilder builder, int flags)
{
Expand All @@ -333,6 +334,8 @@ public static void AddToBuilder(InstructionSetSupportBuilder builder, int flags)
builder.AddSupportedInstructionSet("zbb");
if ((flags & Zbs) != 0)
builder.AddSupportedInstructionSet("zbs");
if ((flags & Zicond) != 0)
builder.AddSupportedInstructionSet("zicond");
}

public static int FromInstructionSet(InstructionSet instructionSet)
Expand All @@ -346,6 +349,7 @@ public static int FromInstructionSet(InstructionSet instructionSet)
InstructionSet.RiscV64_Zba => Zba,
InstructionSet.RiscV64_Zbb => Zbb,
InstructionSet.RiscV64_Zbs => Zbs,
InstructionSet.RiscV64_Zicond => Zicond,

_ => throw new NotSupportedException(((InstructionSet_RiscV64)instructionSet).ToString())
};
Expand Down
Loading
Loading