blob: 7224ead39997ecb1d448fcd6e430e8894470154c [file]
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// RiscV 64 bit G instruction decoder.
decoder RiscV64G {
opcode_enum = "isa64::OpcodeEnum";
includes {
#include "riscv/riscv64g_decoder.h"
}
namespace mpact::sim::riscv::encoding64;
RiscVGInst32;
RiscVCInst16;
};
#include "riscv_format32.bin_fmt"
#include "riscv_format16.bin_fmt"
instruction group RiscVGInst32 = {RiscVGInstBase32, RiscVGHints32};
instruction group RiscVGInstBase32[32] : Inst32Format {
lui : UType : opcode == 0b011'0111;
auipc : UType : opcode == 0b001'0111;
jal : JType : rd != 0, opcode == 0b110'1111;
j : JType : rd == 0, opcode == 0b110'1111;
jalr : IType : rd != 0, func3 == 0b000, opcode == 0b110'0111;
jr : IType : rd == 0, func3 == 0b000, opcode == 0b110'0111;
beq : BType : func3 == 0b000, opcode == 0b110'0011;
bne : BType : func3 == 0b001, opcode == 0b110'0011;
blt : BType : func3 == 0b100, opcode == 0b110'0011;
bge : BType : func3 == 0b101, opcode == 0b110'0011;
bltu : BType : func3 == 0b110, opcode == 0b110'0011;
bgeu : BType : func3 == 0b111, opcode == 0b110'0011;
lb : BType : func3 == 0b000, opcode == 0b000'0011;
ld : BType : func3 == 0b011, opcode == 0b000'0011;
lh : BType : func3 == 0b001, opcode == 0b000'0011;
lw : BType : func3 == 0b010, opcode == 0b000'0011;
lwu : BType : func3 == 0b110, opcode == 0b000'0011;
lbu : BType : func3 == 0b100, opcode == 0b000'0011;
lhu : BType : func3 == 0b101, opcode == 0b000'0011;
sb : SType : func3 == 0b000, opcode == 0b010'0011;
sh : SType : func3 == 0b001, opcode == 0b010'0011;
sw : SType : func3 == 0b010, opcode == 0b010'0011;
sd : SType : func3 == 0b011, opcode == 0b010'0011;
addi : IType : func3 == 0b000, opcode == 0b001'0011;
nop : IType : func3 == 0b000, opcode == 0b001'0011, rd == 0, imm12 == 0, rs1 == 0;
addiw : IType : func3 == 0b000, opcode == 0b001'1011;
slti : IType : func3 == 0b010, opcode == 0b001'0011;
sltiu : IType : func3 == 0b011, opcode == 0b001'0011;
xori : IType : func3 == 0b100, opcode == 0b001'0011;
ori : IType : func3 == 0b110, opcode == 0b001'0011;
andi : IType : func3 == 0b111, opcode == 0b001'0011;
slli : RSType : func6 == 0b000'000, func3==0b001, opcode == 0b001'0011;
srli : RSType : func6 == 0b000'000, func3==0b101, opcode == 0b001'0011;
srai : RSType : func6 == 0b010'000, func3==0b101, opcode == 0b001'0011;
slliw : RType : func7 == 0b000'0000, func3==0b001, opcode == 0b001'1011;
srliw : RType : func7 == 0b000'0000, func3==0b101, opcode == 0b001'1011;
sraiw : RType : func7 == 0b010'0000, func3==0b101, opcode == 0b001'1011;
add : RType : func7 == 0b000'0000, func3==0b000, rd != 0, opcode == 0b011'0011;
addw : RType : func7 == 0b000'0000, func3==0b000, opcode == 0b011'1011;
sub : RType : func7 == 0b010'0000, func3==0b000, opcode == 0b011'0011;
subw : RType : func7 == 0b010'0000, func3==0b000, opcode == 0b011'1011;
sll : RType : func7 == 0b000'0000, func3==0b001, opcode == 0b011'0011;
sllw : RType : func7 == 0b000'0000, func3==0b001, opcode == 0b011'1011;
slt : RType : func7 == 0b000'0000, func3==0b010, opcode == 0b011'0011;
sltu : RType : func7 == 0b000'0000, func3==0b011, opcode == 0b011'0011;
xor : RType : func7 == 0b000'0000, func3==0b100, opcode == 0b011'0011;
srl : RType : func7 == 0b000'0000, func3==0b101, opcode == 0b011'0011;
srlw : RType : func7 == 0b000'0000, func3==0b101, opcode == 0b011'1011;
sra : RType : func7 == 0b010'0000, func3==0b101, opcode == 0b011'0011;
sraw : RType : func7 == 0b010'0000, func3==0b101, opcode == 0b011'1011;
or : RType : func7 == 0b000'0000, func3==0b110, opcode == 0b011'0011;
and : RType : func7 == 0b000'0000, func3==0b111, opcode == 0b011'0011;
fence : Fence : fm == 0b0000, succ != 0b0000, func3 == 0b000, opcode == 0b000'1111;
fence_tso : Fence : fm == 0b1000, pred == 0b0011, succ == 0b0011, func3 == 0b000, opcode == 0b000'1111;
ecall : Inst32Format : bits == 0b0000'0000'0000'00000'000'00000, opcode == 0b111'0011;
ebreak : Inst32Format : bits == 0b0000'0000'0001'00000'000'00000, opcode == 0b111'0011;
// RiscV32 Instruction fence.
fencei : IType : func3 == 001, opcode == 0b000'1111;
// RiscV32 multiply divide.
mul : RType : func7 == 0b000'0001, func3 == 0b000, opcode == 0b011'0011;
mulh : RType : func7 == 0b000'0001, func3 == 0b001, opcode == 0b011'0011;
mulhsu : RType : func7 == 0b000'0001, func3 == 0b010, opcode == 0b011'0011;
mulhu : RType : func7 == 0b000'0001, func3 == 0b011, opcode == 0b011'0011;
div : RType : func7 == 0b000'0001, func3 == 0b100, opcode == 0b011'0011;
divu : RType : func7 == 0b000'0001, func3 == 0b101, opcode == 0b011'0011;
rem : RType : func7 == 0b000'0001, func3 == 0b110, opcode == 0b011'0011;
remu : RType : func7 == 0b000'0001, func3 == 0b111, opcode == 0b011'0011;
// RiscV64 multiply divide.
mulw : RType : func7 == 0b000'0001, func3 == 0b000, opcode == 0b011'1011;
divw : RType : func7 == 0b000'0001, func3 == 0b100, opcode == 0b011'1011;
divuw : RType : func7 == 0b000'0001, func3 == 0b101, opcode == 0b011'1011;
remw : RType : func7 == 0b000'0001, func3 == 0b110, opcode == 0b011'1011;
remuw : RType : func7 == 0b000'0001, func3 == 0b111, opcode == 0b011'1011;
// RiscV32 atomic instructions.
lrw : AType : func5 == 0b0'0010, rs2 == 0, func3 == 0b010, opcode == 0b010'1111;
scw : AType : func5 == 0b0'0011, func3 == 0b010, opcode == 0b010'1111;
amoswapw : AType : func5 == 0b0'0001, func3 == 0b010, opcode == 0b010'1111;
amoaddw : AType : func5 == 0b0'0000, func3 == 0b010, opcode == 0b010'1111;
amoxorw : AType : func5 == 0b0'0100, func3 == 0b010, opcode == 0b010'1111;
amoandw : AType : func5 == 0b0'1100, func3 == 0b010, opcode == 0b010'1111;
amoorw : AType : func5 == 0b0'1000, func3 == 0b010, opcode == 0b010'1111;
amominw : AType : func5 == 0b1'0000, func3 == 0b010, opcode == 0b010'1111;
amomaxw : AType : func5 == 0b1'0100, func3 == 0b010, opcode == 0b010'1111;
amominuw : AType : func5 == 0b1'1000, func3 == 0b010, opcode == 0b010'1111;
amomaxuw : AType : func5 == 0b1'1100, func3 == 0b010, opcode == 0b010'1111;
// RiscV64 atomic instructions
lrd : AType : func5 == 0b0'0010, rs2 == 0, func3 == 0b011, opcode == 0b010'1111;
scd : AType : func5 == 0b0'0011, func3 == 0b011, opcode == 0b010'1111;
amoswapd : AType : func5 == 0b0'0001, func3 == 0b011, opcode == 0b010'1111;
amoaddd : AType : func5 == 0b0'0000, func3 == 0b011, opcode == 0b010'1111;
amoxord : AType : func5 == 0b0'0100, func3 == 0b011, opcode == 0b010'1111;
amoandd : AType : func5 == 0b0'1100, func3 == 0b011, opcode == 0b010'1111;
amoord : AType : func5 == 0b0'1000, func3 == 0b011, opcode == 0b010'1111;
amomind : AType : func5 == 0b1'0000, func3 == 0b011, opcode == 0b010'1111;
amomaxd : AType : func5 == 0b1'0100, func3 == 0b011, opcode == 0b010'1111;
amominud : AType : func5 == 0b1'1000, func3 == 0b011, opcode == 0b010'1111;
amomaxud : AType : func5 == 0b1'1100, func3 == 0b011, opcode == 0b010'1111;
// RiscV32 single precision floating point instructions.
flw : IType : func3 == 0b010, opcode == 0b000'0111;
fsw : SType : func3 == 0b010, opcode == 0b010'0111;
fmadd_s : R4Type : func2 == 0b00, opcode == 0b100'0011;
fmsub_s : R4Type : func2 == 0b00, opcode == 0b100'0111;
fnmsub_s : R4Type : func2 == 0b00, opcode == 0b100'1011;
fnmadd_s : R4Type : func2 == 0b00, opcode == 0b100'1111;
fadd_s : RType : func7 == 0b000'0000, opcode == 0b101'0011;
fsub_s : RType : func7 == 0b000'0100, opcode == 0b101'0011;
fmul_s : RType : func7 == 0b000'1000, opcode == 0b101'0011;
fdiv_s : RType : func7 == 0b000'1100, opcode == 0b101'0011;
fsqrt_s : RType : func7 == 0b010'1100, rs2 == 0, opcode == 0b101'0011;
fsgnj_s : RType : func7 == 0b001'0000, func3 == 0b000, opcode == 0b101'0011;
fsgnjn_s : RType : func7 == 0b001'0000, func3 == 0b001, opcode == 0b101'0011;
fsgnjx_s : RType : func7 == 0b001'0000, func3 == 0b010, opcode == 0b101'0011;
fmin_s : RType : func7 == 0b001'0100, func3 == 0b000, opcode == 0b101'0011;
fmax_s : RType : func7 == 0b001'0100, func3 == 0b001, opcode == 0b101'0011;
fcvt_ws : RType : func7 == 0b110'0000, rs2 == 0, opcode == 0b101'0011;
fcvt_wus : RType : func7 == 0b110'0000, rs2 == 1, opcode == 0b101'0011;
fmv_xw : RType : func7 == 0b111'0000, rs2 == 0, func3 == 0b000, opcode == 0b101'0011;
fcmpeq_s : RType : func7 == 0b101'0000, func3 == 0b010, opcode == 0b101'0011;
fcmplt_s : RType : func7 == 0b101'0000, func3 == 0b001, opcode == 0b101'0011;
fcmple_s : RType : func7 == 0b101'0000, func3 == 0b000, opcode == 0b101'0011;
fclass_s : RType : func7 == 0b111'0000, rs2 == 0, func3 == 0b001, opcode == 0b101'0011;
fcvt_sw : RType : func7 == 0b110'1000, rs2 == 0b00000, opcode == 0b101'0011;
fcvt_swu : RType : func7 == 0b110'1000, rs2 == 0b00001, opcode == 0b101'0011;
fmv_wx : RType : func7 == 0b111'1000, rs2 == 0, func3 == 0b000, opcode == 0b101'0011;
// RiscV64 additional fp instructions.
fcvt_ls : RType : func7 == 0b110'0000, rs2 == 0b00010, opcode == 0b101'0011;
fcvt_lus : RType : func7 == 0b110'0000, rs2 == 0b00011, opcode == 0b101'0011;
fcvt_sl : RType : func7 == 0b110'1000, rs2 == 0b00010, opcode == 0b101'0011;
fcvt_slu : RType : func7 == 0b110'1000, rs2 == 0b00011, opcode == 0b101'0011;
// RiscV32 double precision floating point instructions.
fld : IType : func3 == 0b011, opcode == 0b000'0111;
fsd : SType : func3 == 0b011, opcode == 0b010'0111;
fmadd_d : R4Type : func2 == 0b01, opcode == 0b100'0011;
fmsub_d : R4Type : func2 == 0b01, opcode == 0b100'0111;
fnmsub_d : R4Type : func2 == 0b01, opcode == 0b100'1011;
fnmadd_d : R4Type : func2 == 0b01, opcode == 0b100'1111;
fadd_d : RType : func7 == 0b000'0001, opcode == 0b101'0011;
fsub_d : RType : func7 == 0b000'0101, opcode == 0b101'0011;
fmul_d : RType : func7 == 0b000'1001, opcode == 0b101'0011;
fdiv_d : RType : func7 == 0b000'1101, opcode == 0b101'0011;
fsqrt_d : RType : func7 == 0b010'1101, rs2 == 0, opcode == 0b101'0011;
fsgnj_d : RType : func7 == 0b001'0001, func3 == 0b000, opcode == 0b101'0011;
fsgnjn_d : RType : func7 == 0b001'0001, func3 == 0b001, opcode == 0b101'0011;
fsgnjx_d : RType : func7 == 0b001'0001, func3 == 0b010, opcode == 0b101'0011;
fmin_d : RType : func7 == 0b001'0101, func3 == 0b000, opcode == 0b101'0011;
fmax_d : RType : func7 == 0b001'0101, func3 == 0b001, opcode == 0b101'0011;
fcvt_sd : RType : func7 == 0b010'0000, rs2 == 1, opcode == 0b101'0011;
fcvt_ds : RType : func7 == 0b010'0001, rs2 == 0, opcode == 0b101'0011;
fcmpeq_d : RType : func7 == 0b101'0001, func3 == 0b010, opcode == 0b101'0011;
fcmplt_d : RType : func7 == 0b101'0001, func3 == 0b001, opcode == 0b101'0011;
fcmple_d : RType : func7 == 0b101'0001, func3 == 0b000, opcode == 0b101'0011;
fclass_d : RType : func7 == 0b111'0001, rs2 == 0, func3 == 0b001, opcode == 0b101'0011;
fcvt_wd : RType : func7 == 0b110'0001, rs2 == 0, opcode == 0b101'0011;
fcvt_wud : RType : func7 == 0b110'0001, rs2 == 1, opcode == 0b101'0011;
fcvt_dw : RType : func7 == 0b110'1001, rs2 == 0, opcode == 0b101'0011;
fcvt_dwu : RType : func7 == 0b110'1001, rs2 == 1, opcode == 0b101'0011;
// RV64D in addition to RV32D.
fcvt_ld : RType : func7 == 0b110'0001, rs2 == 0b00010, opcode == 0b101'0011;
fcvt_lud : RType : func7 == 0b110'0001, rs2 == 0b00011, opcode == 0b101'0011;
fcvt_dl : RType : func7 == 0b110'1001, rs2 == 0b00010, opcode == 0b101'0011;
fcvt_dlu : RType : func7 == 0b110'1001, rs2 == 0b00011, opcode == 0b101'0011;
fmv_xd : RType : func7 == 0b111'0001, rs2 == 0b00000, func3 == 0b000, opcode == 0b101'0011;
fmv_dx : RType : func7 == 0b111'1001, rs2 == 0b00000, func3 == 0b000, opcode == 0b101'0011;
// RiscV32 CSR manipulation instructions.
csrrw : IType : func3 == 0b001, u_imm12 != 0b1100'0000'0000, rd != 0, opcode == 0b111'0011;
csrrs : IType : func3 == 0b010, rs1 != 0, rd != 0, opcode == 0b111'0011;
csrrc : IType : func3 == 0b011, rs1 != 0, rd != 0, opcode == 0b111'0011;
csrrs_nr : IType : func3 == 0b010, rs1 != 0, rd == 0, opcode == 0b111'0011;
csrrc_nr : IType : func3 == 0b011, rs1 != 0, rd == 0, opcode == 0b111'0011;
csrrw_nr : IType : func3 == 0b001, u_imm12 != 0b1100'0000'0000, rd == 0, opcode == 0b111'0011;
csrrs_nw : IType : func3 == 0b010, rs1 == 0, opcode == 0b111'0011;
csrrc_nw : IType : func3 == 0b011, rs1 == 0, opcode == 0b111'0011;
csrrwi : IType : func3 == 0b101, rd != 0, opcode == 0b111'0011;
csrrsi : IType : func3 == 0b110, rs1 != 0, rd != 0, opcode == 0b111'0011;
csrrci : IType : func3 == 0b111, rs1 != 0, rd != 0, opcode == 0b111'0011;
csrrsi_nr: IType : func3 == 0b110, rs1 != 0, rd == 0, opcode == 0b111'0011;
csrrci_nr: IType : func3 == 0b111, rs1 != 0, rd == 0, opcode == 0b111'0011;
csrrwi_nr: IType : func3 == 0b101, rd == 0, opcode == 0b111'0011;
csrrsi_nw: IType : func3 == 0b110, rs1 == 0, opcode == 0b111'0011;
csrrci_nw: IType : func3 == 0b111, rs1 == 0, opcode == 0b111'0011;
unimp : IType : func3 == 0b001, u_imm12 == 0b1100'0000'0000, rd == 0, rs1 == 0, opcode == 0b111'0011;
// RiscV32 Privileged instructions.
uret : Inst32Format : bits == 0b000'0000'00010'00000'000'00000, opcode == 0b111'0011;
sret : Inst32Format : bits == 0b000'1000'00010'00000'000'00000, opcode == 0b111'0011;
mret : Inst32Format : bits == 0b001'1000'00010'00000'000'00000, opcode == 0b111'0011;
wfi : Inst32Format : bits == 0b000'1000'00101'00000'000'00000, opcode == 0b111'0011;
sfence_vma_zz : RType : func7 == 0b000'1001, rs2 == 0, rs1 == 0, func3 == 0, rd == 0, opcode == 0b111'0011;
sfence_vma_zn : RType : func7 == 0b000'1001, rs2 != 0, rs1 == 0, func3 == 0, rd == 0, opcode == 0b111'0011;
sfence_vma_nz : RType : func7 == 0b000'1001, rs2 == 0, rs1 != 0, func3 == 0, rd == 0, opcode == 0b111'0011;
sfence_vma_nn : RType : func7 == 0b000'1001, rs2 != 0, rs1 != 0, func3 == 0, rd == 0, opcode == 0b111'0011;
};
// Encoding for RiscV hint instructions.
instruction group RiscVGHints32[32] : Inst32Format {
lui_hint: UType : opcode == 0b011'0111, rd == 0;
auipc_hint: UType : opcode == 0b001'0111, rd == 0;
addi_hint1: IType : func3 == 0b000, opcode == 0b001'0011, rd == 0, rs1 != 0;
addi_hint2: IType : func3 == 0b000, opcode == 0b001'0011, rd == 0, imm12 != 0;
slti_hint : IType : func3 == 0b010, opcode == 0b001'0011, rd == 0;
sltiu_hint: IType : func3 == 0b011, opcode == 0b001'0011, rd == 0;
xori_hint: IType : func3 == 0b100, rd == 0, opcode == 0b001'0011;
ori_hint: IType : func3 == 0b110, rd == 0b00000, opcode == 0b001'0011;
andi_hint: IType : func3 == 0b111, opcode == 0b001'0011, rd == 0;
srli_hint: RType : func7 == 0b000'0000, func3==0b101, rd == 0, opcode == 0b001'0011;
slt_hint: RType : func7 == 0b000'0000, func3==0b010, rd == 0, opcode == 0b011'0011;
slli_semihost: RType : func7 == 0b000'0000, func3==0b001, rd == 0, rs1 == 0, r_uimm5 == 31, opcode == 0b001'0011;
slli_hint1: RType : func7 == 0b000'0000, func3==0b001, rd == 0, rs1 != 0, opcode == 0b001'0011;
slli_hint2: RType : func7 == 0b000'0000, func3==0b001, rd == 0, r_uimm5 != 31, opcode == 0b001'0011;
srai_semihost: RType : func7 == 0b010'0000, func3==0b101, rd == 0, rs1 == 0, r_uimm5 == 7, opcode == 0b001'0011;
srai_hint1: RType : func7 == 0b010'0000, func3==0b101, rd == 0, rs1 != 0, opcode == 0b001'0011;
srai_hint2: RType : func7 == 0b010'0000, func3==0b101, rd == 0, r_uimm5 != 7, opcode == 0b001'0011;
add_hint1: RType : func7 == 0b000'0000, func3==0b000, rd == 0, rs1 != 0, opcode == 0b011'0011;
add_hint2: RType : func7 == 0b000'0000, func3==0b000, rd == 0, rs1 == 0, rs2 > 5, opcode == 0b011'0011;
add_hint3: RType : func7 == 0b000'0000, func3==0b000, rd == 0, rs1 == 0, rs2 < 2, opcode == 0b011'0011;
sub_hint: RType : func7 == 0b010'0000, func3==0b000, rd == 0, opcode == 0b011'0011;
sll_hint: RType : func7 == 0b000'0000, func3==0b001, rd == 0, opcode == 0b011'0011;
sltu_hint: RType : func7 == 0b000'0000, func3==0b011, rd == 0, opcode == 0b011'0011;
xor_hint: RType : func7 == 0b000'0000, func3==0b100, rd == 0, opcode == 0b011'0011;
srl_hint: RType : func7 == 0b000'0000, func3==0b101, rd == 0, opcode == 0b011'0011;
sra_hint: RType : func7 == 0b010'0000, func3==0b101, rd == 0, opcode == 0b011'0011;
or_hint : RType : func7 == 0b000'0000, func3==0b110, rd == 0, opcode == 0b011'0011;
and_hint: RType : func7 == 0b000'0000, func3==0b111, rd == 0, opcode == 0b011'0011;
fence_hint1: Fence : func3==0b000, rd == 0, rs1 != 0, fm == 0, pred == 0, opcode == 0b000'1111;
fence_hint2: Fence : func3==0b000, rd == 0, rs1 != 0, fm == 0, succ == 0, opcode == 0b000'1111;
fence_hint3: Fence : func3==0b000, rd != 0, rs1 == 0, fm == 0, pred == 0, opcode == 0b000'1111;
fence_hint4: Fence : func3==0b000, rd != 0, rs1 == 0, fm == 0, succ == 0, opcode == 0b000'1111;
fence_hint5: Fence : func3==0b000, rd == 0, rs1 == 0, fm == 0, pred == 0, succ != 0, opcode == 0b000'1111;
fence_hint6: Fence : func3==0b000, rd == 0, rs1 == 0, fm == 0, succ == 0, opcode == 0b000'1111;
fence_hint7: Fence : func3==0b000, rd != 0, rs1 == 0, fm == 0, pred != 1, succ == 0, opcode == 0b000'1111;
};
instruction group RiscVCInst16 = {RiscVCInstBase16, RiscVCHints16};
// Compact instruction encodings.
instruction group RiscVCInstBase16[16] : Inst16Format {
caddi4spn : CIW : func3 == 0b000, op == 0b00, imm8 != 0;
cfld : CL : func3 == 0b001, op == 0b00;
clw : CL : func3 == 0b010, op == 0b00;
cld : CL : func3 == 0b011, op == 0b00;
cfsd : CS : func3 == 0b101, op == 0b00;
csw : CS : func3 == 0b110, op == 0b00;
csd : CS : func3 == 0b111, op == 0b00;
cnop : CI : func3 == 0b000, imm1 == 0, rs1 == 0, imm5 == 0, op == 0b01;
caddi : CI : func3 == 0b000, imm6 != 0, rd != 0, op == 0b01;
caddiw : CI : func3 == 0b001, rs1 != 0, op == 0b01;
cli : CI : func3 == 0b010, rd != 0, op == 0b01;
caddi16sp : CI : func3 == 0b011, rd == 2, ci_imm10 != 0, op == 0b01;
clui : CI : func3 == 0b011, rd != 0, rd != 2, imm18 != 0, op == 0b01;
csrli : CB : func3 == 0b100, func2 == 0b00, op == 0b01, shamt != 0;
csrai : CB : func3 == 0b100, func2 == 0b01, op == 0b01, shamt != 0;
candi : CB : func3 == 0b100, func2 == 0b10, op == 0b01;
csub : CA : func6 == 0b100'011, func2 == 0b00, op == 0b01;
cxor : CA : func6 == 0b100'011, func2 == 0b01, op == 0b01;
cor : CA : func6 == 0b100'011, func2 == 0b10, op == 0b01;
cand : CA : func6 == 0b100'011, func2 == 0b11, op == 0b01;
csubw : CA : func6 == 0b100'111, func2 == 0b00, op == 0b01;
caddw : CA : func6 == 0b100'111, func2 == 0b01, op == 0b01;
cj : CJ : func3 == 0b101, op == 0b01;
cbeqz : CB : func3 == 0b110, op == 0b01;
cbnez : CB : func3 == 0b111, op == 0b01;
cslli : CI : func3 == 0b000, rs1 != 0, uimm6 != 0, op == 0b10;
cfldsp : CI : func3 == 0b001, op == 0b10;
clwsp : CI : func3 == 0b010, rd != 0, op == 0b10;
cldsp : CI : func3 == 0b011, rd != 0, op == 0b10;
cjr : CR : func4 == 0b1000, rs1 != 0, rs2 == 0, op == 0b10;
cmv : CR : func4 == 0b1000, rs1 != 0, rs2 != 0, op == 0b10;
cebreak : CR : func4 == 0b1001, rs1 == 0, rs2 == 0, op == 0b10;
cjalr : CR : func4 == 0b1001, rs1 != 0, rs2 == 0, op == 0b10;
cadd : CR : func4 == 0b1001, rs1 != 0, rs2 != 0, op == 0b10;
cfsdsp : CSS: func3 == 0b101, op == 0b10;
cswsp : CSS: func3 == 0b110, op == 0b10;
csdsp : CSS: func3 == 0b111, op == 0b10;
cunimp : Inst16Format : func3 == 0b000, bits == 0b000'0000'0000, op == 0b00;
};
instruction group RiscVCHints16[16] : Inst16Format {
cnop_hint : CI : func3 == 0b000, imm6 != 0, rs1 == 0, op == 0b01;
caddi_hint: CI : func3 == 0b000, imm6 == 0, rd != 0, op == 0b01;
cli_hint : CI : func3 == 0b010, rd == 0, op == 0b01;
clui_hint : CI : func3 == 0b011, rd == 0, imm6 != 0, op == 0b01;
cmv_hint : CR : func4 == 0b1000, rs1 == 0, rs2 != 0, op == 0b10;
cslli_hint: CI : func3 == 0b000, imm6 != 0, rd == 0, op == 0b10;
cadd_hint : CR : func4 == 0b1001, rs1 == 0, rs2 != 0, rs2 != 2, rs2 != 3, rs2 != 4, rs2 != 5, op == 0b10;
};