[PATCH 01/10] RISC-V: Expand instruction definitions

Charlie Jenkins charlie at rivosinc.com
Thu Aug 3 19:10:26 PDT 2023


There are many systems across the kernel that rely on directly creating
and modifying instructions. In order to unify them, create shared
definitions for instructions and registers.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/include/asm/insn.h            | 2742 +++++++++++++++++++++++++++---
 arch/riscv/include/asm/reg.h             |   88 +
 arch/riscv/kernel/kgdb.c                 |    4 +-
 arch/riscv/kernel/probes/simulate-insn.c |   39 +-
 arch/riscv/kernel/vector.c               |    2 +-
 5 files changed, 2629 insertions(+), 246 deletions(-)

diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
index 4e1505cef8aa..04f7649e1add 100644
--- a/arch/riscv/include/asm/insn.h
+++ b/arch/riscv/include/asm/insn.h
@@ -7,15 +7,28 @@
 #define _ASM_RISCV_INSN_H
 
 #include <linux/bits.h>
+#include <asm/reg.h>
+
+#define RV_INSN_FUNCT5_IN_OPOFF	2
+#define RV_INSN_AQ_IN_OPOFF	1
+#define RV_INSN_RL_IN_OPOFF	0
 
-#define RV_INSN_FUNCT3_MASK	GENMASK(14, 12)
-#define RV_INSN_FUNCT3_OPOFF	12
-#define RV_INSN_OPCODE_MASK	GENMASK(6, 0)
 #define RV_INSN_OPCODE_OPOFF	0
+#define RV_INSN_FUNCT3_OPOFF	12
+#define RV_INSN_FUNCT5_OPOFF	27
+#define RV_INSN_FUNCT7_OPOFF	25
 #define RV_INSN_FUNCT12_OPOFF	20
-
-#define RV_ENCODE_FUNCT3(f_)	(RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF)
-#define RV_ENCODE_FUNCT12(f_)	(RVG_FUNCT12_##f_ << RV_INSN_FUNCT12_OPOFF)
+#define RV_INSN_RD_OPOFF	7
+#define RV_INSN_RS1_OPOFF	15
+#define RV_INSN_RS2_OPOFF	20
+#define RV_INSN_OPCODE_MASK	GENMASK(6, 0)
+#define RV_INSN_FUNCT3_MASK	GENMASK(2, 0)
+#define RV_INSN_FUNCT5_MASK	GENMASK(4, 0)
+#define RV_INSN_FUNCT7_MASK	GENMASK(6, 0)
+#define RV_INSN_FUNCT12_MASK	GENMASK(11, 0)
+#define RV_INSN_RD_MASK		GENMASK(4, 0)
+#define RV_INSN_RS1_MASK	GENMASK(4, 0)
+#define RV_INSN_RS2_MASK	GENMASK(4, 0)
 
 /* The bit field of immediate value in I-type instruction */
 #define RV_I_IMM_SIGN_OPOFF	31
@@ -24,6 +37,33 @@
 #define RV_I_IMM_11_0_OFF	0
 #define RV_I_IMM_11_0_MASK	GENMASK(11, 0)
 
+/* The bit field of immediate value in S-type instruction */
+#define RV_S_IMM_11_5_OPOFF	25
+#define RV_S_IMM_4_0_OPOFF	7
+#define RV_S_IMM_11_5_OFF	5
+#define RV_S_IMM_4_0_OFF	0
+#define RV_S_IMM_11_5_MASK	GENMASK(6, 0)
+#define RV_S_IMM_4_0_MASK	GENMASK(4, 0)
+
+/* The bit field of immediate value in B-type instruction */
+#define RV_B_IMM_SIGN_OPOFF	31
+#define RV_B_IMM_4_1_OPOFF	8
+#define RV_B_IMM_10_5_OPOFF	25
+#define RV_B_IMM_11_OPOFF	7
+#define RV_B_IMM_SIGN_OFF	12
+#define RV_B_IMM_4_1_OFF	1
+#define RV_B_IMM_10_5_OFF	5
+#define RV_B_IMM_11_OFF		11
+#define RV_B_IMM_SIGN_MASK	GENMASK(0, 0)
+#define RV_B_IMM_4_1_MASK	GENMASK(3, 0)
+#define RV_B_IMM_10_5_MASK	GENMASK(5, 0)
+#define RV_B_IMM_11_MASK	GENMASK(0, 0)
+
+/* The bit field of immediate value in S-type instruction */
+#define RV_S_IMM_31_12_OPOFF	12
+#define RV_S_IMM_31_12_OFF	12
+#define RV_S_IMM_31_12_MASK	GENMASK(19, 0)
+
 /* The bit field of immediate value in J-type instruction */
 #define RV_J_IMM_SIGN_OPOFF	31
 #define RV_J_IMM_10_1_OPOFF	21
@@ -38,82 +78,716 @@
 #define RV_J_IMM_19_12_MASK	GENMASK(7, 0)
 
 /*
- * U-type IMMs contain the upper 20bits [31:20] of an immediate with
+ * U-type IMMs contain the upper 20bits [31:12] of an immediate with
  * the rest filled in by zeros, so no shifting required. Similarly,
  * bit31 contains the signed state, so no sign extension necessary.
  */
 #define RV_U_IMM_SIGN_OPOFF	31
-#define RV_U_IMM_31_12_OPOFF	0
-#define RV_U_IMM_31_12_MASK	GENMASK(31, 12)
-
-/* The bit field of immediate value in B-type instruction */
-#define RV_B_IMM_SIGN_OPOFF	31
-#define RV_B_IMM_10_5_OPOFF	25
-#define RV_B_IMM_4_1_OPOFF	8
-#define RV_B_IMM_11_OPOFF	7
-#define RV_B_IMM_SIGN_OFF	12
-#define RV_B_IMM_10_5_OFF	5
-#define RV_B_IMM_4_1_OFF	1
-#define RV_B_IMM_11_OFF		11
-#define RV_B_IMM_10_5_MASK	GENMASK(5, 0)
-#define RV_B_IMM_4_1_MASK	GENMASK(3, 0)
-#define RV_B_IMM_11_MASK	GENMASK(0, 0)
+#define RV_U_IMM_31_12_OPOFF	12
+#define RV_U_IMM_31_12_OFF	12
+#define RV_U_IMM_SIGN_OFF	31
+#define RV_U_IMM_31_12_MASK	GENMASK(19, 0)
 
 /* The register offset in RVG instruction */
 #define RVG_RS1_OPOFF		15
 #define RVG_RS2_OPOFF		20
 #define RVG_RD_OPOFF		7
+#define RVG_RS1_MASK		GENMASK(4, 0)
+#define RVG_RS2_MASK		GENMASK(4, 0)
 #define RVG_RD_MASK		GENMASK(4, 0)
 
-/* The bit field of immediate value in RVC J instruction */
-#define RVC_J_IMM_SIGN_OPOFF	12
-#define RVC_J_IMM_4_OPOFF	11
-#define RVC_J_IMM_9_8_OPOFF	9
-#define RVC_J_IMM_10_OPOFF	8
-#define RVC_J_IMM_6_OPOFF	7
-#define RVC_J_IMM_7_OPOFF	6
-#define RVC_J_IMM_3_1_OPOFF	3
-#define RVC_J_IMM_5_OPOFF	2
-#define RVC_J_IMM_SIGN_OFF	11
-#define RVC_J_IMM_4_OFF		4
-#define RVC_J_IMM_9_8_OFF	8
-#define RVC_J_IMM_10_OFF	10
-#define RVC_J_IMM_6_OFF		6
-#define RVC_J_IMM_7_OFF		7
-#define RVC_J_IMM_3_1_OFF	1
-#define RVC_J_IMM_5_OFF		5
-#define RVC_J_IMM_4_MASK	GENMASK(0, 0)
-#define RVC_J_IMM_9_8_MASK	GENMASK(1, 0)
-#define RVC_J_IMM_10_MASK	GENMASK(0, 0)
-#define RVC_J_IMM_6_MASK	GENMASK(0, 0)
-#define RVC_J_IMM_7_MASK	GENMASK(0, 0)
-#define RVC_J_IMM_3_1_MASK	GENMASK(2, 0)
-#define RVC_J_IMM_5_MASK	GENMASK(0, 0)
+/* Register sizes in RV instructions */
+#define RV_STANDARD_REG_BITS	5
+#define RV_COMPRESSED_REG_BITS	3
+#define RV_STANDARD_REG_MASK	GENMASK(4, 0)
+#define RV_COMPRESSED_REG_MASK	GENMASK(2, 0)
+
+/* The bit field for F,D,Q extensions */
+#define RVG_FL_FS_WIDTH_OFF	12
+#define RVG_FL_FS_WIDTH_MASK	GENMASK(3, 0)
+#define RVG_FL_FS_WIDTH_W	2
+#define RVG_FL_FS_WIDTH_D	3
+#define RVG_LS_FS_WIDTH_Q	4
+
+/* The bit field for Zicsr extension */
+#define RVG_SYSTEM_CSR_OPOFF	20
+#define RVG_SYSTEM_CSR_MASK	GENMASK(12, 0)
+
+/* RVV widths */
+#define RVV_VL_VS_WIDTH_8	0
+#define RVV_VL_VS_WIDTH_16	5
+#define RVV_VL_VS_WIDTH_32	6
+#define RVV_VL_VS_WIDTH_64	7
+
+/* The bit field of immediate value in RVC I instruction */
+#define RVC_I_IMM_LO_OPOFF	2
+#define RVC_I_IMM_HI_OPOFF	12
+#define RVC_I_IMM_LO_OFF	0
+#define RVC_I_IMM_HI_OFF	0
+#define RVC_I_IMM_LO_MASK	GENMASK(4, 0)
+#define RVC_I_IMM_HI_MASK	GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC SS instruction */
+#define RVC_SS_IMM_OPOFF	6
+#define RVC_SS_IMM_OFF		0
+#define RVC_SS_IMM_MASK		GENMASK(5, 0)
+
+/* The bit field of immediate value in RVC IW instruction */
+#define RVC_IW_IMM_OPOFF	5
+#define RVC_IW_IMM_OFF		0
+#define RVC_IW_IMM_MASK		GENMASK(7, 0)
+
+/* The bit field of immediate value in RVC L instruction */
+#define RVC_L_IMM_LO_OPOFF	5
+#define RVC_L_IMM_HI_OPOFF	10
+#define RVC_L_IMM_LO_OFF	0
+#define RVC_L_IMM_HI_OFF	0
+#define RVC_L_IMM_LO_MASK	GENMASK(1, 0)
+#define RVC_L_IMM_HI_MASK	GENMASK(2, 0)
+
+/* The bit field of immediate value in RVC S instruction */
+#define RVC_S_IMM_LO_OPOFF	5
+#define RVC_S_IMM_HI_OPOFF	10
+#define RVC_S_IMM_LO_OFF	0
+#define RVC_S_IMM_HI_OFF	0
+#define RVC_S_IMM_LO_MASK	GENMASK(1, 0)
+#define RVC_S_IMM_HI_MASK	GENMASK(2, 0)
 
 /* The bit field of immediate value in RVC B instruction */
-#define RVC_B_IMM_SIGN_OPOFF	12
-#define RVC_B_IMM_4_3_OPOFF	10
-#define RVC_B_IMM_7_6_OPOFF	5
-#define RVC_B_IMM_2_1_OPOFF	3
-#define RVC_B_IMM_5_OPOFF	2
-#define RVC_B_IMM_SIGN_OFF	8
-#define RVC_B_IMM_4_3_OFF	3
-#define RVC_B_IMM_7_6_OFF	6
-#define RVC_B_IMM_2_1_OFF	1
-#define RVC_B_IMM_5_OFF		5
-#define RVC_B_IMM_4_3_MASK	GENMASK(1, 0)
-#define RVC_B_IMM_7_6_MASK	GENMASK(1, 0)
-#define RVC_B_IMM_2_1_MASK	GENMASK(1, 0)
-#define RVC_B_IMM_5_MASK	GENMASK(0, 0)
-
-#define RVC_INSN_FUNCT4_MASK	GENMASK(15, 12)
-#define RVC_INSN_FUNCT4_OPOFF	12
-#define RVC_INSN_FUNCT3_MASK	GENMASK(15, 13)
-#define RVC_INSN_FUNCT3_OPOFF	13
-#define RVC_INSN_J_RS2_MASK	GENMASK(6, 2)
-#define RVC_INSN_OPCODE_MASK	GENMASK(1, 0)
-#define RVC_ENCODE_FUNCT3(f_)	(RVC_FUNCT3_##f_ << RVC_INSN_FUNCT3_OPOFF)
-#define RVC_ENCODE_FUNCT4(f_)	(RVC_FUNCT4_##f_ << RVC_INSN_FUNCT4_OPOFF)
+#define RVC_B_IMM_LO_OFF	2
+#define RVC_B_IMM_HI_OFF	10
+#define RVC_B_IMM_LO_OPOFF	0
+#define RVC_B_IMM_HI_OPOFF	0
+#define RVC_B_IMM_LO_MASK	GENMASK(4, 0)
+#define RVC_B_IMM_HI_MASK	GENMASK(2, 0)
+
+/* The bit field of immediate value in RVC J instruction */
+#define RVC_J_IMM_OFF		2
+#define RVC_J_IMM_OPOFF		0
+#define RVC_J_IMM_MASK		GENMASK(10, 0)
+
+/*
+ * Bit field of various RVC instruction immediates.
+ * These base OPOFF on the start of the immediate
+ * rather than the start of the instruction.
+ */
+
+/* The bit field of immediate value in RVC ADDI4SPN instruction */
+#define RVC_ADDI4SPN_IMM_5_4_OPOFF	11
+#define RVC_ADDI4SPN_IMM_9_6_OPOFF	7
+#define RVC_ADDI4SPN_IMM_2_OPOFF	6
+#define RVC_ADDI4SPN_IMM_3_OPOFF	5
+#define RVC_ADDI4SPN_IMM_5_4_OFF	4
+#define RVC_ADDI4SPN_IMM_9_6_OFF	6
+#define RVC_ADDI4SPN_IMM_2_OFF		2
+#define RVC_ADDI4SPN_IMM_3_OFF		3
+#define RVC_ADDI4SPN_IMM_5_4_MASK	GENMASK(1, 0)
+#define RVC_ADDI4SPN_IMM_9_6_MASK	GENMASK(3, 0)
+#define RVC_ADDI4SPN_IMM_2_MASK		GENMASK(0, 0)
+#define RVC_ADDI4SPN_IMM_3_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC FLD instruction */
+#define RVC_FLD_IMM_5_3_OPOFF		0
+#define RVC_FLD_IMM_7_6_OPOFF		0
+#define RVC_FLD_IMM_5_3_OFF		3
+#define RVC_FLD_IMM_7_6_OFF		6
+#define RVC_FLD_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_FLD_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC LW instruction */
+#define RVC_LW_IMM_5_3_OPOFF		0
+#define RVC_LW_IMM_2_OPOFF		1
+#define RVC_LW_IMM_6_OPOFF		0
+#define RVC_LW_IMM_5_3_OFF		3
+#define RVC_LW_IMM_2_OFF		2
+#define RVC_LW_IMM_6_OFF		6
+#define RVC_LW_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_LW_IMM_2_MASK		GENMASK(0, 0)
+#define RVC_LW_IMM_6_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC FLW instruction */
+#define RVC_FLW_IMM_5_3_OPOFF		0
+#define RVC_FLW_IMM_2_OPOFF		1
+#define RVC_FLW_IMM_6_OPOFF		0
+#define RVC_FLW_IMM_5_3_OFF		3
+#define RVC_FLW_IMM_2_OFF		2
+#define RVC_FLW_IMM_6_OFF		6
+#define RVC_FLW_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_FLW_IMM_2_MASK		GENMASK(0, 0)
+#define RVC_FLW_IMM_6_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC LD instruction */
+#define RVC_LD_IMM_5_3_OPOFF		0
+#define RVC_LD_IMM_7_6_OPOFF		0
+#define RVC_LD_IMM_5_3_OFF		3
+#define RVC_LD_IMM_7_6_OFF		6
+#define RVC_LD_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_LD_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC FSD instruction */
+#define RVC_FSD_IMM_5_3_OPOFF		0
+#define RVC_FSD_IMM_7_6_OPOFF		0
+#define RVC_FSD_IMM_5_3_OFF		3
+#define RVC_FSD_IMM_7_6_OFF		6
+#define RVC_FSD_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_FSD_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC SW instruction */
+#define RVC_SW_IMM_5_3_OPOFF		0
+#define RVC_SW_IMM_2_OPOFF		1
+#define RVC_SW_IMM_6_OPOFF		0
+#define RVC_SW_IMM_5_3_OFF		3
+#define RVC_SW_IMM_2_OFF		2
+#define RVC_SW_IMM_6_OFF		6
+#define RVC_SW_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_SW_IMM_2_MASK		GENMASK(0, 0)
+#define RVC_SW_IMM_6_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC FSW instruction */
+#define RVC_FSW_IMM_5_3_OPOFF		0
+#define RVC_FSW_IMM_2_OPOFF		1
+#define RVC_FSW_IMM_6_OPOFF		0
+#define RVC_FSW_IMM_5_3_OFF		3
+#define RVC_FSW_IMM_2_OFF		2
+#define RVC_FSW_IMM_6_OFF		6
+#define RVC_FSW_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_FSW_IMM_2_MASK		GENMASK(0, 0)
+#define RVC_FSW_IMM_6_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC SD instruction */
+#define RVC_SD_IMM_5_3_OPOFF		0
+#define RVC_SD_IMM_7_6_OPOFF		0
+#define RVC_SD_IMM_5_3_OFF		3
+#define RVC_SD_IMM_7_6_OFF		6
+#define RVC_SD_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_SD_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC ADDI instruction */
+#define RVC_ADDI_IMM_5_OPOFF		0
+#define RVC_ADDI_IMM_4_0_OPOFF		0
+#define RVC_ADDI_IMM_5_OFF		5
+#define RVC_ADDI_IMM_4_0_OFF		0
+#define RVC_ADDI_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_ADDI_IMM_4_0_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC JAL instruction */
+#define RVC_JAL_IMM_SIGN_OPOFF		12
+#define RVC_JAL_IMM_4_OPOFF		11
+#define RVC_JAL_IMM_9_8_OPOFF		9
+#define RVC_JAL_IMM_10_OPOFF		8
+#define RVC_JAL_IMM_6_OPOFF		7
+#define RVC_JAL_IMM_7_OPOFF		6
+#define RVC_JAL_IMM_3_1_OPOFF		3
+#define RVC_JAL_IMM_5_OPOFF		2
+#define RVC_JAL_IMM_SIGN_OFF		11
+#define RVC_JAL_IMM_4_OFF		4
+#define RVC_JAL_IMM_9_8_OFF		8
+#define RVC_JAL_IMM_10_OFF		10
+#define RVC_JAL_IMM_6_OFF		6
+#define RVC_JAL_IMM_7_OFF		7
+#define RVC_JAL_IMM_3_1_OFF		1
+#define RVC_JAL_IMM_5_OFF		5
+#define RVC_JAL_IMM_SIGN_MASK		GENMASK(0, 0)
+#define RVC_JAL_IMM_4_MASK		GENMASK(0, 0)
+#define RVC_JAL_IMM_9_8_MASK		GENMASK(1, 0)
+#define RVC_JAL_IMM_10_MASK		GENMASK(0, 0)
+#define RVC_JAL_IMM_6_MASK		GENMASK(0, 0)
+#define RVC_JAL_IMM_7_MASK		GENMASK(0, 0)
+#define RVC_JAL_IMM_3_1_MASK		GENMASK(2, 0)
+#define RVC_JAL_IMM_5_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC ADDIW instruction */
+#define RVC_ADDIW_IMM_5_OPOFF		0
+#define RVC_ADDIW_IMM_4_0_OPOFF		0
+#define RVC_ADDIW_IMM_5_OFF		5
+#define RVC_ADDIW_IMM_4_0_OFF		0
+#define RVC_ADDIW_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_ADDIW_IMM_4_0_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC LI instruction */
+#define RVC_LI_IMM_5_OPOFF		0
+#define RVC_LI_IMM_4_0_OPOFF		0
+#define RVC_LI_IMM_5_OFF		5
+#define RVC_LI_IMM_4_0_OFF		0
+#define RVC_LI_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_LI_IMM_4_0_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC ADDI16SP instruction */
+#define RVC_ADDI16SP_IMM_9_OPOFF	0
+#define RVC_ADDI16SP_IMM_4_OPOFF	4
+#define RVC_ADDI16SP_IMM_6_OPOFF	3
+#define RVC_ADDI16SP_IMM_8_7_OPOFF	1
+#define RVC_ADDI16SP_IMM_5_OPOFF	0
+#define RVC_ADDI16SP_IMM_9_OFF		9
+#define RVC_ADDI16SP_IMM_4_OFF		4
+#define RVC_ADDI16SP_IMM_6_OFF		6
+#define RVC_ADDI16SP_IMM_8_7_OFF	7
+#define RVC_ADDI16SP_IMM_5_OFF		5
+#define RVC_ADDI16SP_IMM_9_MASK		GENMASK(0, 0)
+#define RVC_ADDI16SP_IMM_4_MASK		GENMASK(0, 0)
+#define RVC_ADDI16SP_IMM_6_MASK		GENMASK(0, 0)
+#define RVC_ADDI16SP_IMM_8_7_MASK	GENMASK(1, 0)
+#define RVC_ADDI16SP_IMM_5_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC LUI instruction */
+#define RVC_LUI_IMM_17_OPOFF		0
+#define RVC_LUI_IMM_16_12_OPOFF		0
+#define RVC_LUI_IMM_17_OFF		17
+#define RVC_LUI_IMM_16_12_OFF		12
+#define RVC_LUI_IMM_17_MASK		GENMASK(0, 0)
+#define RVC_LUI_IMM_16_12_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC SRLI instruction */
+#define RVC_SRLI_IMM_5_OPOFF		3
+#define RVC_SRLI_IMM_FUNC2_OPOFF	0
+#define RVC_SRLI_IMM_4_0_OPOFF		0
+#define RVC_SRLI_IMM_5_OFF		5
+#define RVC_SRLI_IMM_4_0_OFF		0
+#define RVC_SRLI_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_SRLI_IMM_4_0_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC SRAI instruction */
+#define RVC_SRAI_IMM_5_OPOFF		3
+#define RVC_SRAI_IMM_FUNC2_OPOFF	0
+#define RVC_SRAI_IMM_4_0_OPOFF		0
+#define RVC_SRAI_IMM_5_OFF		5
+#define RVC_SRAI_IMM_4_0_OFF		0
+#define RVC_SRAI_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_SRAI_IMM_4_0_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC ANDI instruction */
+#define RVC_ANDI_IMM_5_OPOFF		3
+#define RVC_ANDI_IMM_FUNC2_OPOFF	0
+#define RVC_ANDI_IMM_4_0_OPOFF		0
+#define RVC_ANDI_IMM_5_OFF		5
+#define RVC_ANDI_IMM_4_0_OFF		0
+#define RVC_ANDI_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_ANDI_IMM_4_0_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC J instruction */
+#define RVC_J_IMM_SIGN_OPOFF		12
+#define RVC_J_IMM_4_OPOFF		11
+#define RVC_J_IMM_9_8_OPOFF		9
+#define RVC_J_IMM_10_OPOFF		8
+#define RVC_J_IMM_6_OPOFF		7
+#define RVC_J_IMM_7_OPOFF		6
+#define RVC_J_IMM_3_1_OPOFF		3
+#define RVC_J_IMM_5_OPOFF		2
+#define RVC_J_IMM_SIGN_OFF		11
+#define RVC_J_IMM_4_OFF			4
+#define RVC_J_IMM_9_8_OFF		8
+#define RVC_J_IMM_10_OFF		10
+#define RVC_J_IMM_6_OFF			6
+#define RVC_J_IMM_7_OFF			7
+#define RVC_J_IMM_3_1_OFF		1
+#define RVC_J_IMM_5_OFF			5
+#define RVC_J_IMM_SIGN_MASK		GENMASK(0, 0)
+#define RVC_J_IMM_4_MASK		GENMASK(0, 0)
+#define RVC_J_IMM_9_8_MASK		GENMASK(1, 0)
+#define RVC_J_IMM_10_MASK		GENMASK(0, 0)
+#define RVC_J_IMM_6_MASK		GENMASK(0, 0)
+#define RVC_J_IMM_7_MASK		GENMASK(0, 0)
+#define RVC_J_IMM_3_1_MASK		GENMASK(2, 0)
+#define RVC_J_IMM_5_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC BEQZ/BNEZ instruction */
+#define RVC_BZ_IMM_SIGN_OPOFF		12
+#define RVC_BZ_IMM_4_3_OPOFF		10
+#define RVC_BZ_IMM_7_6_OPOFF		5
+#define RVC_BZ_IMM_2_1_OPOFF		3
+#define RVC_BZ_IMM_5_OPOFF		2
+#define RVC_BZ_IMM_SIGN_OFF		8
+#define RVC_BZ_IMM_4_3_OFF		3
+#define RVC_BZ_IMM_7_6_OFF		6
+#define RVC_BZ_IMM_2_1_OFF		1
+#define RVC_BZ_IMM_5_OFF		5
+#define RVC_BZ_IMM_SIGN_MASK		GENMASK(0, 0)
+#define RVC_BZ_IMM_4_3_MASK		GENMASK(1, 0)
+#define RVC_BZ_IMM_7_6_MASK		GENMASK(1, 0)
+#define RVC_BZ_IMM_2_1_MASK		GENMASK(1, 0)
+#define RVC_BZ_IMM_5_MASK		GENMASK(0, 0)
+
+/* The bit field of immediate value in RVC SLLI instruction */
+#define RVC_SLLI_IMM_5_OPOFF		0
+#define RVC_SLLI_IMM_4_0_OPOFF		0
+#define RVC_SLLI_IMM_5_OFF		5
+#define RVC_SLLI_IMM_4_0_OFF		0
+#define RVC_SLLI_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_SLLI_IMM_4_0_MASK		GENMASK(4, 0)
+
+/* The bit field of immediate value in RVC FLDSP instruction */
+#define RVC_FLDSP_IMM_5_OPOFF		0
+#define RVC_FLDSP_IMM_4_3_OPOFF		3
+#define RVC_FLDSP_IMM_8_6_OPOFF		0
+#define RVC_FLDSP_IMM_5_OFF		5
+#define RVC_FLDSP_IMM_4_3_OFF		3
+#define RVC_FLDSP_IMM_8_6_OFF		6
+#define RVC_FLDSP_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_FLDSP_IMM_4_3_MASK		GENMASK(1, 0)
+#define RVC_FLDSP_IMM_8_6_MASK		GENMASK(2, 0)
+
+/* The bit field of immediate value in RVC LWSP instruction */
+#define RVC_LWSP_IMM_5_OPOFF		0
+#define RVC_LWSP_IMM_4_2_OPOFF		2
+#define RVC_LWSP_IMM_7_6_OPOFF		0
+#define RVC_LWSP_IMM_5_OFF		5
+#define RVC_LWSP_IMM_4_2_OFF		2
+#define RVC_LWSP_IMM_7_6_OFF		6
+#define RVC_LWSP_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_LWSP_IMM_4_2_MASK		GENMASK(2, 0)
+#define RVC_LWSP_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC FLWSP instruction */
+#define RVC_FLWSP_IMM_5_OPOFF		0
+#define RVC_FLWSP_IMM_4_2_OPOFF		2
+#define RVC_FLWSP_IMM_7_6_OPOFF		0
+#define RVC_FLWSP_IMM_5_OFF		5
+#define RVC_FLWSP_IMM_4_2_OFF		2
+#define RVC_FLWSP_IMM_7_6_OFF		6
+#define RVC_FLWSP_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_FLWSP_IMM_4_2_MASK		GENMASK(2, 0)
+#define RVC_FLWSP_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC LDSP instruction */
+#define RVC_LDSP_IMM_5_OPOFF		0
+#define RVC_LDSP_IMM_4_3_OPOFF		3
+#define RVC_LDSP_IMM_8_6_OPOFF		0
+#define RVC_LDSP_IMM_5_OFF		5
+#define RVC_LDSP_IMM_4_3_OFF		3
+#define RVC_LDSP_IMM_8_6_OFF		6
+#define RVC_LDSP_IMM_5_MASK		GENMASK(0, 0)
+#define RVC_LDSP_IMM_4_3_MASK		GENMASK(1, 0)
+#define RVC_LDSP_IMM_8_6_MASK		GENMASK(2, 0)
+
+/* The bit field of immediate value in RVC FSDSP instruction */
+#define RVC_FSDSP_IMM_5_3_OPOFF		3
+#define RVC_FSDSP_IMM_8_6_OPOFF		0
+#define RVC_FSDSP_IMM_5_3_OFF		3
+#define RVC_FSDSP_IMM_8_6_OFF		6
+#define RVC_FSDSP_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_FSDSP_IMM_8_6_MASK		GENMASK(2, 0)
+
+/* The bit field of immediate value in RVC SWSP instruction */
+#define RVC_SWSP_IMM_5_2_OPOFF		3
+#define RVC_SWSP_IMM_7_6_OPOFF		0
+#define RVC_SWSP_IMM_5_2_OFF		2
+#define RVC_SWSP_IMM_7_6_OFF		6
+#define RVC_SWSP_IMM_5_2_MASK		GENMASK(3, 0)
+#define RVC_SWSP_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC FSWSP instruction */
+#define RVC_FSWSP_IMM_5_2_OPOFF		3
+#define RVC_FSWSP_IMM_7_6_OPOFF		0
+#define RVC_FSWSP_IMM_5_2_OFF		2
+#define RVC_FSWSP_IMM_7_6_OFF		6
+#define RVC_FSWSP_IMM_5_2_MASK		GENMASK(3, 0)
+#define RVC_FSWSP_IMM_7_6_MASK		GENMASK(1, 0)
+
+/* The bit field of immediate value in RVC SDSP instruction */
+#define RVC_SDSP_IMM_5_3_OPOFF		3
+#define RVC_SDSP_IMM_8_6_OPOFF		0
+#define RVC_SDSP_IMM_5_3_OFF		3
+#define RVC_SDSP_IMM_8_6_OFF		6
+#define RVC_SDSP_IMM_5_3_MASK		GENMASK(2, 0)
+#define RVC_SDSP_IMM_8_6_MASK		GENMASK(2, 0)
+
+/* Bit fields for RVC parts */
+#define RVC_INSN_FUNCT6_MASK		GENMASK(5, 0)
+#define RVC_INSN_FUNCT6_OPOFF		10
+#define RVC_INSN_FUNCT4_MASK		GENMASK(3, 0)
+#define RVC_INSN_FUNCT4_OPOFF		12
+#define RVC_INSN_FUNCT3_MASK		GENMASK(2, 0)
+#define RVC_INSN_FUNCT3_OPOFF		13
+#define RVC_INSN_FUNCT2_MASK		GENMASK(1, 0)
+#define RVC_INSN_FUNCT2_CB_OPOFF	10
+#define RVC_INSN_FUNCT2_CA_OPOFF	5
+#define RVC_INSN_OPCODE_MASK		GENMASK(1, 0)
+
+/* Compositions of RVC Immediates */
+#define RVC_ADDI4SPN_IMM(imm) \
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_ADDI4SPN_IMM_5_4_OFF, RVC_ADDI4SPN_IMM_5_4_MASK) \
+		<< RVC_ADDI4SPN_IMM_5_4_OPOFF) | \
+	(RV_X(_imm, RVC_ADDI4SPN_IMM_9_6_OFF, RVC_ADDI4SPN_IMM_9_6_MASK) \
+		<< RVC_ADDI4SPN_IMM_9_6_OPOFF) | \
+	(RV_X(_imm, RVC_ADDI4SPN_IMM_2_OFF, RVC_ADDI4SPN_IMM_2_MASK) \
+		<< RVC_ADDI4SPN_IMM_2_OPOFF) | \
+	(RV_X(_imm, RVC_ADDI4SPN_IMM_3_OFF, RVC_ADDI4SPN_IMM_3_MASK) \
+		<< RVC_ADDI4SPN_IMM_3_OPOFF)); })
+
+#define RVC_FLD_IMM_HI(imm)	\
+	(RV_X(imm, RVC_FLD_IMM_5_3_OPOFF, RVC_FLD_IMM_5_3_OFF) \
+		<< RVC_FLD_IMM_5_3_MASK)
+#define RVC_FLD_IMM_LO(imm)	\
+	(RV_X(imm, RVC_FLD_IMM_7_6_OPOFF, RVC_FLD_IMM_7_6_OFF) \
+		<< RVC_FLD_IMM_7_6_MASK)
+
+#define RVC_LW_IMM_HI(imm)	\
+	((RV_X(imm, RVC_LW_IMM_5_3_OFF, RVC_LW_IMM_5_3_MASK) \
+		<< RVC_LW_IMM_5_3_OPOFF))
+#define RVC_LW_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_LW_IMM_2_OFF, RVC_LW_IMM_2_MASK) \
+		<< RVC_LW_IMM_2_OPOFF) | \
+	(RV_X(_imm, RVC_LW_IMM_6_OFF, RVC_LW_IMM_6_MASK) \
+		<< RVC_LW_IMM_6_OPOFF)); })
+
+#define RVC_FLW_IMM_HI(imm)	\
+	((RV_X(imm, RVC_FLW_IMM_5_3_OFF, RVC_FLW_IMM_5_3_MASK) \
+		<< RVC_FLW_IMM_5_3_OPOFF))
+#define RVC_FLW_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_FLW_IMM_2_OFF, RVC_FLW_IMM_2_MASK) \
+		<< RVC_FLW_IMM_2_OPOFF) |	\
+	(RV_X(_imm, RVC_FLW_IMM_6_OFF, RVC_FLW_IMM_6_MASK) \
+		<< RVC_FLW_IMM_6_OPOFF)); })
+
+#define RVC_LD_IMM_HI(imm)	\
+	(RV_X(imm, RVC_LD_IMM_5_3_OPOFF, RVC_LD_IMM_5_3_OFF) \
+		<< RVC_LD_IMM_5_3_MASK)
+#define RVC_LD_IMM_LO(imm)	\
+	(RV_X(imm, RVC_LD_IMM_7_6_OPOFF, RVC_LD_IMM_7_6_OFF) \
+		<< RVC_LD_IMM_7_6_MASK)
+
+#define RVC_FSD_IMM_HI(imm)	\
+	(RV_X(imm, RVC_FSD_IMM_5_3_OPOFF, RVC_FSD_IMM_5_3_OFF) \
+		<< RVC_FSD_IMM_5_3_MASK)
+#define RVC_FSD_IMM_LO(imm)	\
+	(RV_X(imm, RVC_FSD_IMM_7_6_OPOFF, RVC_FSD_IMM_7_6_OFF) \
+		<< RVC_FSD_IMM_7_6_MASK)
+
+#define RVC_SW_IMM_HI(imm)	\
+	(RV_X(imm, RVC_SW_IMM_5_3_OFF, RVC_SW_IMM_5_3_MASK) \
+		<< RVC_SW_IMM_5_3_OPOFF)
+#define RVC_SW_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_SW_IMM_2_OFF, RVC_SW_IMM_2_MASK) \
+		<< RVC_SW_IMM_2_OPOFF) | \
+	(RV_X(_imm, RVC_SW_IMM_6_OFF, RVC_SW_IMM_6_MASK) \
+		<< RVC_SW_IMM_6_OPOFF)); })
+
+#define RVC_FSW_IMM_HI(imm)	\
+	(RV_X(imm, RVC_FSW_IMM_5_3_OFF, RVC_FSW_IMM_5_3_MASK) \
+		<< RVC_FSW_IMM_5_3_OPOFF)
+#define RVC_FSW_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_FSW_IMM_2_OFF, RVC_FSW_IMM_2_MASK) \
+		<< RVC_FSW_IMM_2_OPOFF) |	\
+	(RV_X(_imm, RVC_FSW_IMM_6_OFF, RVC_FSW_IMM_6_MASK) \
+		<< RVC_FSW_IMM_6_OPOFF)); })
+
+#define RVC_SD_IMM_HI(imm)	\
+	(RV_X(imm, RVC_SD_IMM_5_3_OPOFF, RVC_SD_IMM_5_3_OFF) \
+		<< RVC_SD_IMM_5_3_MASK)
+#define RVC_SD_IMM_LO(imm)	\
+	(RV_X(imm, RVC_SD_IMM_7_6_OPOFF, RVC_SD_IMM_7_6_OFF) \
+		<< RVC_SD_IMM_7_6_MASK)
+
+#define RVC_ADDI_IMM_HI(imm)		\
+	(RV_X(imm, RVC_ADDI_IMM_5_OPOFF, RVC_ADDI_IMM_5_OFF) \
+		<< RVC_ADDI_IMM_5_MASK)
+#define RVC_ADDI_IMM_LO(imm)		\
+	(RV_X(imm, RVC_ADDI_IMM_4_0_OPOFF, RVC_ADDI_IMM_4_0_OFF) \
+		<< RVC_ADDI_IMM_4_0_MASK)
+
+#define RVC_JAL_IMM(imm)		\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_JAL_IMM_SIGN_OPOFF, RVC_JAL_IMM_SIGN_OFF) \
+		<< RVC_JAL_IMM_SIGN_MASK) |	\
+	(RV_X(_imm, RVC_JAL_IMM_4_OPOFF, RVC_JAL_IMM_4_OFF) \
+		<< RVC_JAL_IMM_4_MASK) |	\
+	(RV_X(_imm, RVC_JAL_IMM_9_8_OPOFF, RVC_JAL_IMM_9_8_OFF) \
+		<< RVC_JAL_IMM_9_8_MASK) |	\
+	(RV_X(_imm, RVC_JAL_IMM_10_OPOFF, RVC_JAL_IMM_10_OFF) \
+		<< RVC_JAL_IMM_10_MASK) |	\
+	(RV_X(_imm, RVC_JAL_IMM_6_OPOFF, RVC_JAL_IMM_6_OFF) \
+		<< RVC_JAL_IMM_6_MASK) |	\
+	(RV_X(_imm, RVC_JAL_IMM_7_OPOFF, RVC_JAL_IMM_7_OFF) \
+		<< RVC_JAL_IMM_7_MASK) |	\
+	(RV_X(_imm, RVC_JAL_IMM_3_1_OPOFF, RVC_JAL_IMM_3_1_OFF) \
+		<< RVC_JAL_IMM_3_1_MASK) |	\
+	(RV_X(_imm, RVC_JAL_IMM_5_OPOFF, RVC_JAL_IMM_5_OFF) \
+		<< RVC_JAL_IMM_5_MASK)); })
+
+#define RVC_ADDIW_IMM_HI(imm)		\
+	(RV_X(imm, RVC_ADDIW_IMM_5_OPOFF, RVC_ADDIW_IMM_5_OFF) \
+		<< RVC_ADDIW_IMM_5_MASK)
+#define RVC_ADDIW_IMM_LO(imm)		\
+	(RV_X(imm, RVC_ADDIW_IMM_4_0_OPOFF, RVC_ADDIW_IMM_4_0_OFF) \
+		<< RVC_ADDIW_IMM_4_0_MASK)
+
+#define RVC_LI_IMM_HI(imm)		\
+	(RV_X(imm, RVC_LI_IMM_5_OPOFF, RVC_LI_IMM_5_OFF) \
+		<< RVC_LI_IMM_5_MASK)
+#define RVC_LI_IMM_LO(imm)		\
+	(RV_X(imm, RVC_LI_IMM_4_0_OPOFF, RVC_LI_IMM_4_0_OFF) \
+		<< RVC_LI_IMM_4_0_MASK)
+
+#define RVC_ADDI16SP_IMM_HI(imm)	\
+	(RV_X(imm, RVC_ADDI16SP_IMM_9_OFF, RVC_ADDI16SP_IMM_9_MASK) \
+		<< RVC_ADDI16SP_IMM_9_OPOFF)
+#define RVC_ADDI16SP_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_ADDI16SP_IMM_4_OFF, RVC_ADDI16SP_IMM_4_MASK) \
+		<< RVC_ADDI16SP_IMM_4_OPOFF) |	\
+	(RV_X(_imm, RVC_ADDI16SP_IMM_6_OFF, RVC_ADDI16SP_IMM_6_MASK) \
+		<< RVC_ADDI16SP_IMM_4_OPOFF) |	\
+	(RV_X(_imm, RVC_ADDI16SP_IMM_5_OFF, RVC_ADDI16SP_IMM_5_MASK) \
+		<< RVC_ADDI16SP_IMM_4_OPOFF) |	\
+	(RV_X(_imm, RVC_ADDI16SP_IMM_8_7_OFF, RVC_ADDI16SP_IMM_8_7_MASK) \
+		<< RVC_ADDI16SP_IMM_4_OPOFF)); })
+
+#define RVC_LUI_IMM_HI(imm)		\
+	(RV_X(imm, RVC_LUI_IMM_17_OPOFF, RVC_LUI_IMM_17_OFF) \
+		<< RVC_LUI_IMM_17_MASK)
+#define RVC_LUI_IMM_LO(imm)		\
+	(RV_X(imm, RVC_LUI_IMM_16_12_OPOFF, RVC_LUI_IMM_16_12_OFF) \
+		<< RVC_LUI_IMM_16_12_MASK)
+
+#define RVC_SRLI_IMM_HI(imm)		\
+	(RV_X(imm, RVC_SRLI_IMM_5_OPOFF, RVC_SRLI_IMM_5_OFF) \
+		<< RVC_SRLI_IMM_5_MASK)
+#define RVC_SRLI_IMM_LO(imm)		\
+	(RV_X(imm, RVC_SRLI_IMM_4_0_OPOFF, RVC_SRLI_IMM_4_0_OFF) \
+		<< RVC_SRLI_IMM_4_0_MASK)
+
+#define RVC_SRAI_IMM_HI(imm)		\
+	(RV_X(imm, RVC_SRAI_IMM_5_OPOFF, RVC_SRAI_IMM_5_OFF) \
+		<< RVC_SRAI_IMM_5_MASK)
+#define RVC_SRAI_IMM_LO(imm)		\
+	(RV_X(imm, RVC_SRAI_IMM_4_0_OPOFF, RVC_SRAI_IMM_4_0_OFF) \
+		<< RVC_SRAI_IMM_4_0_MASK)
+
+#define RVC_ANDI_IMM_HI(imm)		\
+	(RV_X(imm, RVC_ANDI_IMM_5_OPOFF, RVC_ANDI_IMM_5_OFF) \
+		<< RVC_ANDI_IMM_5_MASK)
+#define RVC_ANDI_IMM_LO(imm)		\
+	(RV_X(imm, RVC_ANDI_IMM_4_0_OPOFF, RVC_ANDI_IMM_4_0_OFF) \
+		<< RVC_ANDI_IMM_4_0_MASK)
+
+#define RVC_J_IMM(imm)		\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_J_IMM_SIGN_OPOFF, RVC_J_IMM_SIGN_OFF) \
+		<< RVC_J_IMM_SIGN_MASK) |	\
+	(RV_X(_imm, RVC_J_IMM_4_OPOFF, RVC_J_IMM_4_OFF) \
+		<< RVC_J_IMM_4_MASK) |	\
+	(RV_X(_imm, RVC_J_IMM_9_8_OPOFF, RVC_J_IMM_9_8_OFF) \
+		<< RVC_J_IMM_9_8_MASK) |	\
+	(RV_X(_imm, RVC_J_IMM_10_OPOFF, RVC_J_IMM_10_OFF) \
+		<< RVC_J_IMM_10_MASK) |	\
+	(RV_X(_imm, RVC_J_IMM_6_OPOFF, RVC_J_IMM_6_OFF) \
+		<< RVC_J_IMM_6_MASK) |	\
+	(RV_X(_imm, RVC_J_IMM_7_OPOFF, RVC_J_IMM_7_OFF) \
+		<< RVC_J_IMM_7_MASK) |	\
+	(RV_X(_imm, RVC_J_IMM_3_1_OPOFF, RVC_J_IMM_3_1_OFF) \
+		<< RVC_J_IMM_3_1_MASK) |	\
+	(RV_X(_imm, RVC_J_IMM_5_OPOFF, RVC_J_IMM_5_OFF) \
+		<< RVC_J_IMM_5_MASK)); })
+
+#define RVC_BEQZ_IMM_HI(imm)		\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_BZ_IMM_SIGN_OPOFF, RVC_BZ_IMM_SIGN_OFF) \
+		<< RVC_BZ_IMM_SIGN_MASK) |	\
+	(RV_X(_imm, RVC_BZ_IMM_4_3_OPOFF, RVC_BZ_IMM_4_3_OFF) \
+		<< RVC_BZ_IMM_4_3_MASK)); })
+#define RVC_BEQZ_IMM_LO(imm)		\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_BZ_IMM_7_6_OPOFF, RVC_BZ_IMM_7_6_OFF) \
+		<< RVC_BZ_IMM_7_6_MASK) |	\
+	(RV_X(_imm, RVC_BZ_IMM_2_1_OPOFF, RVC_BZ_IMM_2_1_OFF) \
+		<< RVC_BZ_IMM_2_1_MASK) |	\
+	(RV_X(_imm, RVC_BZ_IMM_5_OPOFF, RVC_BZ_IMM_5_OFF) \
+		<< RVC_BZ_IMM_5_MASK)); })
+
+#define RVC_BNEZ_IMM_HI(imm)		\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_BZ_IMM_SIGN_OPOFF, RVC_BZ_IMM_SIGN_OFF) \
+		<< RVC_BZ_IMM_SIGN_MASK) |	\
+	(RV_X(_imm, RVC_BZ_IMM_4_3_OPOFF, RVC_BZ_IMM_4_3_OFF) \
+		<< RVC_BZ_IMM_4_3_MASK)); })
+#define RVC_BNEZ_IMM_LO(imm)		\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_BZ_IMM_7_6_OPOFF, RVC_BZ_IMM_7_6_OFF) \
+		<< RVC_BZ_IMM_7_6_MASK) |	\
+	(RV_X(_imm, RVC_BZ_IMM_2_1_OPOFF, RVC_BZ_IMM_2_1_OFF) \
+		<< RVC_BZ_IMM_2_1_MASK) |	\
+	(RV_X(_imm, RVC_BZ_IMM_5_OPOFF, RVC_BZ_IMM_5_OFF) \
+		<< RVC_BZ_IMM_5_MASK)); })
+
+#define RVC_SLLI_IMM_HI(imm)	\
+	(RV_X(imm, RVC_SLLI_IMM_5_OFF, RVC_SLLI_IMM_5_MASK) \
+		<< RVC_SLLI_IMM_5_OPOFF)
+#define RVC_SLLI_IMM_LO(imm)	\
+	(RV_X(imm, RVC_SLLI_IMM_4_0_OFF, RVC_SLLI_IMM_4_0_MASK) \
+		<< RVC_SLLI_IMM_4_0_OPOFF)
+
+#define RVC_FLDSP_IMM_HI(imm)	\
+	(RV_X(imm, RVC_FLDSP_IMM_5_OFF, RVC_FLDSP_IMM_5_MASK) \
+		<< RVC_FLDSP_IMM_5_OPOFF)
+#define RVC_FLDSP_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_FLDSP_IMM_4_3_OFF, RVC_FLDSP_IMM_4_3_MASK) \
+		<< RVC_FLDSP_IMM_4_3_OPOFF) |	\
+	(RV_X(_imm, RVC_FLDSP_IMM_8_6_OFF, RVC_FLDSP_IMM_8_6_MASK) \
+		<< RVC_FLDSP_IMM_8_6_OPOFF)); })
+
+#define RVC_LWSP_IMM_HI(imm)	\
+	(RV_X(imm, RVC_LWSP_IMM_5_OFF, RVC_LWSP_IMM_5_MASK) \
+		<< RVC_LWSP_IMM_5_OPOFF)
+#define RVC_LWSP_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_LWSP_IMM_4_2_OFF, RVC_LWSP_IMM_4_2_MASK) \
+		<< RVC_LWSP_IMM_4_2_OPOFF) |	\
+	(RV_X(_imm, RVC_LWSP_IMM_7_6_OFF, RVC_LWSP_IMM_7_6_MASK) \
+		<< RVC_LWSP_IMM_7_6_OPOFF)); })
+
+#define RVC_FLWSP_IMM_HI(imm)	\
+	(RV_X(imm, RVC_FLWSP_IMM_5_OFF, RVC_FLWSP_IMM_5_MASK) \
+		<< RVC_FLWSP_IMM_5_OPOFF)
+#define RVC_FLWSP_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_FLWSP_IMM_4_2_OFF, RVC_FLWSP_IMM_4_2_MASK) \
+		<< RVC_FLWSP_IMM_4_2_OPOFF) |	\
+	(RV_X(_imm, RVC_FLWSP_IMM_7_6_OFF, RVC_FLWSP_IMM_7_6_MASK) \
+		<< RVC_FLWSP_IMM_7_6_OPOFF)); })
+
+#define RVC_LDSP_IMM_HI(imm)	\
+	(RV_X(imm, RVC_LDSP_IMM_5_OPOFF, RVC_LDSP_IMM_5_OFF) \
+		<< RVC_LDSP_IMM_5_MASK)
+#define RVC_LDSP_IMM_LO(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_LDSP_IMM_4_3_OPOFF, RVC_LDSP_IMM_4_3_OFF) \
+		<< RVC_LDSP_IMM_4_3_MASK) |	\
+	(RV_X(_imm, RVC_LDSP_IMM_8_6_OPOFF, RVC_LDSP_IMM_8_6_OFF) \
+		<< RVC_LDSP_IMM_8_6_MASK)); })
+
+#define RVC_FSDSP_IMM(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_FSDSP_IMM_5_3_OPOFF, RVC_FSDSP_IMM_5_3_OFF) \
+		<< RVC_FSDSP_IMM_5_3_MASK) |	\
+	(RV_X(_imm, RVC_FSDSP_IMM_8_6_OPOFF, RVC_FSDSP_IMM_8_6_OFF) \
+		<< RVC_FSDSP_IMM_8_6_MASK)); })
+
+#define RVC_SWSP_IMM(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_SWSP_IMM_5_2_OPOFF, RVC_SWSP_IMM_5_2_MASK) \
+		<< RVC_SWSP_IMM_5_2_OPOFF) |	\
+	(RV_X(_imm, RVC_SWSP_IMM_7_6_OPOFF, RVC_SWSP_IMM_7_6_MASK) \
+		<< RVC_SWSP_IMM_7_6_OPOFF)); })
+
+#define RVC_FSWSP_IMM(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_FSWSP_IMM_5_2_OPOFF, RVC_FSWSP_IMM_5_2_MASK) \
+		<< RVC_FSWSP_IMM_5_2_OPOFF) |	\
+	(RV_X(_imm, RVC_FSWSP_IMM_7_6_OPOFF, RVC_FSWSP_IMM_7_6_MASK) \
+		<< RVC_FSWSP_IMM_7_6_OPOFF)); })
+
+#define RVC_SDSP_IMM(imm)	\
+	({ typeof(imm) _imm = imm; \
+	((RV_X(_imm, RVC_SDSP_IMM_5_3_OPOFF, RVC_SDSP_IMM_5_3_OFF) \
+		<< RVC_SDSP_IMM_5_3_MASK) |	\
+	(RV_X(_imm, RVC_SDSP_IMM_8_6_OPOFF, RVC_SDSP_IMM_8_6_OFF) \
+		<< RVC_SDSP_IMM_8_6_MASK)); })
 
 /* The register offset in RVC op=C0 instruction */
 #define RVC_C0_RS1_OPOFF	7
@@ -130,136 +804,1099 @@
 #define RVC_C2_RS2_OPOFF	2
 #define RVC_C2_RD_OPOFF		7
 
-/* parts of opcode for RVG*/
-#define RVG_OPCODE_FENCE	0x0f
-#define RVG_OPCODE_AUIPC	0x17
-#define RVG_OPCODE_BRANCH	0x63
-#define RVG_OPCODE_JALR		0x67
-#define RVG_OPCODE_JAL		0x6f
-#define RVG_OPCODE_SYSTEM	0x73
-#define RVG_SYSTEM_CSR_OFF	20
-#define RVG_SYSTEM_CSR_MASK	GENMASK(12, 0)
+/* RVC RD definitions */
+#define RVC_RD_CR(insn)	(((insn) >> RVC_C2_RD_OPOFF) & RV_STANDARD_REG_MASK)
+#define RVC_RD_CI(insn)	(((insn) >> RVC_C2_RD_OPOFF) & RV_STANDARD_REG_MASK)
+#define RVC_RD_CIW(insn)(((insn) >> RVC_C0_RD_OPOFF) & RV_COMPRESSED_REG_MASK)
+#define RVC_RD_CL(insn)	(((insn) >> RVC_C0_RD_OPOFF) & RV_COMPRESSED_REG_MASK)
+#define RVC_RD_CA(insn)	(((insn) >> RVC_C2_RD_OPOFF) & RV_COMPRESSED_REG_MASK)
+#define RVC_RD_CB(insn)	(((insn) >> RVC_C2_RD_OPOFF) & RV_COMPRESSED_REG_MASK)
 
-/* parts of opcode for RVF, RVD and RVQ */
-#define RVFDQ_FL_FS_WIDTH_OFF	12
-#define RVFDQ_FL_FS_WIDTH_MASK	GENMASK(3, 0)
-#define RVFDQ_FL_FS_WIDTH_W	2
-#define RVFDQ_FL_FS_WIDTH_D	3
-#define RVFDQ_LS_FS_WIDTH_Q	4
-#define RVFDQ_OPCODE_FL		0x07
-#define RVFDQ_OPCODE_FS		0x27
-
-/* parts of opcode for RVV */
-#define RVV_OPCODE_VECTOR	0x57
-#define RVV_VL_VS_WIDTH_8	0
-#define RVV_VL_VS_WIDTH_16	5
-#define RVV_VL_VS_WIDTH_32	6
-#define RVV_VL_VS_WIDTH_64	7
-#define RVV_OPCODE_VL		RVFDQ_OPCODE_FL
-#define RVV_OPCODE_VS		RVFDQ_OPCODE_FS
+/* Special opcodes */
+#define RVG_OPCODE_SYSTEM	0b1110011
+#define RVG_OPCODE_NOP		0b0010011
+#define RVG_OPCODE_BRANCH	0b1100011
+/* RVG opcodes */
+#define RVG_OPCODE_LUI		0b0110111
+#define RVG_OPCODE_AUIPC	0b0010111
+#define RVG_OPCODE_JAL		0b1101111
+#define RVG_OPCODE_JALR		0b1100111
+#define RVG_OPCODE_BEQ		0b1100011
+#define RVG_OPCODE_BNE		0b1100011
+#define RVG_OPCODE_BLT		0b1100011
+#define RVG_OPCODE_BGE		0b1100011
+#define RVG_OPCODE_BLTU		0b1100011
+#define RVG_OPCODE_BGEU		0b1100011
+#define RVG_OPCODE_LB		0b0000011
+#define RVG_OPCODE_LH		0b0000011
+#define RVG_OPCODE_LW		0b0000011
+#define RVG_OPCODE_LBU		0b0000011
+#define RVG_OPCODE_LHU		0b0000011
+#define RVG_OPCODE_SB		0b0100011
+#define RVG_OPCODE_SH		0b0100011
+#define RVG_OPCODE_SW		0b0100011
+#define RVG_OPCODE_ADDI		0b0010011
+#define RVG_OPCODE_SLTI		0b0010011
+#define RVG_OPCODE_SLTIU	0b0010011
+#define RVG_OPCODE_XORI		0b0010011
+#define RVG_OPCODE_ORI		0b0010011
+#define RVG_OPCODE_ANDI		0b0010011
+#define RVG_OPCODE_SLLI		0b0010011
+#define RVG_OPCODE_SRLI		0b0010011
+#define RVG_OPCODE_SRAI		0b0010011
+#define RVG_OPCODE_ADD		0b0110011
+#define RVG_OPCODE_SUB		0b0110011
+#define RVG_OPCODE_SLL		0b0110011
+#define RVG_OPCODE_SLT		0b0110011
+#define RVG_OPCODE_SLTU		0b0110011
+#define RVG_OPCODE_XOR		0b0110011
+#define RVG_OPCODE_SRL		0b0110011
+#define RVG_OPCODE_SRA		0b0110011
+#define RVG_OPCODE_OR		0b0110011
+#define RVG_OPCODE_AND		0b0110011
+#define RVG_OPCODE_FENCE	0b0001111
+#define RVG_OPCODE_FENCETSO	0b0001111
+#define RVG_OPCODE_PAUSE	0b0001111
+#define RVG_OPCODE_ECALL	0b1110011
+#define RVG_OPCODE_EBREAK	0b1110011
+/* F Standard Extension */
+#define RVG_OPCODE_FLW		0b0000111
+#define RVG_OPCODE_FSW		0b0100111
+/* D Standard Extension */
+#define RVG_OPCODE_FLD		0b0000111
+#define RVG_OPCODE_FSD		0b0100111
+/* Q Standard Extension */
+#define RVG_OPCODE_FLQ		0b0000111
+#define RVG_OPCODE_FSQ		0b0100111
+/* Zicsr Standard Extension */
+#define RVG_OPCODE_CSRRW	0b1110011
+#define RVG_OPCODE_CSRRS	0b1110011
+#define RVG_OPCODE_CSRRC	0b1110011
+#define RVG_OPCODE_CSRRWI	0b1110011
+#define RVG_OPCODE_CSRRSI	0b1110011
+#define RVG_OPCODE_CSRRCI	0b1110011
+/* M Standard Extension */
+#define RVG_OPCODE_MUL		0b0110011
+#define RVG_OPCODE_MULH		0b0110011
+#define RVG_OPCODE_MULHSU	0b0110011
+#define RVG_OPCODE_MULHU	0b0110011
+#define RVG_OPCODE_DIV		0b0110011
+#define RVG_OPCODE_DIVU		0b0110011
+#define RVG_OPCODE_REM		0b0110011
+#define RVG_OPCODE_REMU		0b0110011
+/* A Standard Extension */
+#define RVG_OPCODE_LR_W		0b0101111
+#define RVG_OPCODE_SC_W		0b0101111
+#define RVG_OPCODE_AMOSWAP_W	0b0101111
+#define RVG_OPCODE_AMOADD_W	0b0101111
+#define RVG_OPCODE_AMOXOR_W	0b0101111
+#define RVG_OPCODE_AMOAND_W	0b0101111
+#define RVG_OPCODE_AMOOR_W	0b0101111
+#define RVG_OPCODE_AMOMIN_W	0b0101111
+#define RVG_OPCODE_AMOMAX_W	0b0101111
+#define RVG_OPCODE_AMOMINU_W	0b0101111
+#define RVG_OPCODE_AMOMAXU_W	0b0101111
+/* Vector Extension */
+#define RVV_OPCODE_VECTOR	0b1010111
+#define RVV_OPCODE_VL		RVG_OPCODE_FLW
+#define RVV_OPCODE_VS		RVG_OPCODE_FSW
+
+/* RVG 64-bit only opcodes */
+#define RVG_OPCODE_LWU		0b0000011
+#define RVG_OPCODE_LD		0b0000011
+#define RVG_OPCODE_SD		0b0100011
+#define RVG_OPCODE_ADDIW	0b0011011
+#define RVG_OPCODE_SLLIW	0b0011011
+#define RVG_OPCODE_SRLIW	0b0011011
+#define RVG_OPCODE_SRAIW	0b0011011
+#define RVG_OPCODE_ADDW		0b0111011
+#define RVG_OPCODE_SUBW		0b0111011
+#define RVG_OPCODE_SLLW		0b0111011
+#define RVG_OPCODE_SRLW		0b0111011
+#define RVG_OPCODE_SRAW		0b0111011
+/* M Standard Extension */
+#define RVG_OPCODE_MULW		0b0111011
+#define RVG_OPCODE_DIVW		0b0111011
+#define RVG_OPCODE_DIVUW	0b0111011
+#define RVG_OPCODE_REMW		0b0111011
+#define RVG_OPCODE_REMUW	0b0111011
+/* A Standard Extension */
+#define RVG_OPCODE_LR_D		0b0101111
+#define RVG_OPCODE_SC_D		0b0101111
+#define RVG_OPCODE_AMOSWAP_D	0b0101111
+#define RVG_OPCODE_AMOADD_D	0b0101111
+#define RVG_OPCODE_AMOXOR_D	0b0101111
+#define RVG_OPCODE_AMOAND_D	0b0101111
+#define RVG_OPCODE_AMOOR_D	0b0101111
+#define RVG_OPCODE_AMOMIN_D	0b0101111
+#define RVG_OPCODE_AMOMAX_D	0b0101111
+#define RVG_OPCODE_AMOMINU_D	0b0101111
+#define RVG_OPCODE_AMOMAXU_D	0b0101111
+
+/* RVG func3 codes */
+#define RVG_FUNCT3_JALR		0b000
+#define RVG_FUNCT3_BEQ		0b000
+#define RVG_FUNCT3_BNE		0b001
+#define RVG_FUNCT3_BLT		0b100
+#define RVG_FUNCT3_BGE		0b101
+#define RVG_FUNCT3_BLTU		0b110
+#define RVG_FUNCT3_BGEU		0b111
+#define RVG_FUNCT3_LB		0b000
+#define RVG_FUNCT3_LH		0b001
+#define RVG_FUNCT3_LW		0b010
+#define RVG_FUNCT3_LBU		0b100
+#define RVG_FUNCT3_LHU		0b101
+#define RVG_FUNCT3_SB		0b000
+#define RVG_FUNCT3_SH		0b001
+#define RVG_FUNCT3_SW		0b010
+#define RVG_FUNCT3_ADDI		0b000
+#define RVG_FUNCT3_SLTI		0b010
+#define RVG_FUNCT3_SLTIU	0b011
+#define RVG_FUNCT3_XORI		0b100
+#define RVG_FUNCT3_ORI		0b110
+#define RVG_FUNCT3_ANDI		0b111
+#define RVG_FUNCT3_SLLI		0b001
+#define RVG_FUNCT3_SRLI		0b101
+#define RVG_FUNCT3_SRAI		0b101
+#define RVG_FUNCT3_ADD		0b000
+#define RVG_FUNCT3_SUB		0b000
+#define RVG_FUNCT3_SLL		0b001
+#define RVG_FUNCT3_SLT		0b010
+#define RVG_FUNCT3_SLTU		0b011
+#define RVG_FUNCT3_XOR		0b100
+#define RVG_FUNCT3_SRL		0b101
+#define RVG_FUNCT3_SRA		0b101
+#define RVG_FUNCT3_OR		0b110
+#define RVG_FUNCT3_AND		0b111
+#define RVG_FUNCT3_NOP		RVG_FUNCT3_ADDI
+#define RVG_FUNCT3_FENCE	0b000
+#define RVG_FUNCT3_FENCETSO	0b000
+#define RVG_FUNCT3_PAUSE	0b000
+#define RVG_FUNCT3_ECALL	0b000
+#define RVG_FUNCT3_EBREAK	0b000
+/* F Standard Extension */
+#define RVG_FUNCT3_FLW		0b010
+#define RVG_FUNCT3_FSW		0b010
+/* D Standard Extension */
+#define RVG_FUNCT3_FLD		0b011
+#define RVG_FUNCT3_FSD		0b011
+/* Q Standard Extension */
+#define RVG_FUNCT3_FLQ		0b100
+#define RVG_FUNCT3_FSQ		0b100
+/* Zicsr Standard Extension */
+#define RVG_FUNCT3_CSRRW	0b001
+#define RVG_FUNCT3_CSRRS	0b010
+#define RVG_FUNCT3_CSRRC	0b011
+#define RVG_FUNCT3_CSRRWI	0b101
+#define RVG_FUNCT3_CSRRSI	0b110
+#define RVG_FUNCT3_CSRRCI	0b111
+/* M Standard Extension */
+#define RVG_FUNCT3_MUL		0b000
+#define RVG_FUNCT3_MULH		0b001
+#define RVG_FUNCT3_MULHSU	0b010
+#define RVG_FUNCT3_MULHU	0b011
+#define RVG_FUNCT3_DIV		0b100
+#define RVG_FUNCT3_DIVU		0b101
+#define RVG_FUNCT3_REM		0b110
+#define RVG_FUNCT3_REMU		0b111
+/* A Standard Extension */
+#define RVG_FUNCT3_LR_W		0b010
+#define RVG_FUNCT3_SC_W		0b010
+#define RVG_FUNCT3_AMOSWAP_W	0b010
+#define RVG_FUNCT3_AMOADD_W	0b010
+#define RVG_FUNCT3_AMOXOR_W	0b010
+#define RVG_FUNCT3_AMOAND_W	0b010
+#define RVG_FUNCT3_AMOOR_W	0b010
+#define RVG_FUNCT3_AMOMIN_W	0b010
+#define RVG_FUNCT3_AMOMAX_W	0b010
+#define RVG_FUNCT3_AMOMINU_W	0b010
+#define RVG_FUNCT3_AMOMAXU_W	0b010
+
+/* RVG 64-bit only func3 codes */
+#define RVG_FUNCT3_LWU		0b110
+#define RVG_FUNCT3_LD		0b011
+#define RVG_FUNCT3_SD		0b011
+#define RVG_FUNCT3_ADDIW	0b000
+#define RVG_FUNCT3_SLLIW	0b001
+#define RVG_FUNCT3_SRLIW	0b101
+#define RVG_FUNCT3_SRAIW	0b101
+#define RVG_FUNCT3_ADDW		0b000
+#define RVG_FUNCT3_SUBW		0b000
+#define RVG_FUNCT3_SLLW		0b001
+#define RVG_FUNCT3_SRLW		0b101
+#define RVG_FUNCT3_SRAW		0b101
+/* M Standard Extension */
+#define RVG_FUNCT3_MULW		0b000
+#define RVG_FUNCT3_DIVW		0b100
+#define RVG_FUNCT3_DIVUW	0b101
+#define RVG_FUNCT3_REMW		0b110
+#define RVG_FUNCT3_REMUW	0b111
+/* A Standard Extension */
+#define RVG_FUNCT3_LR_D		0b011
+#define RVG_FUNCT3_SC_D		0b011
+#define RVG_FUNCT3_AMOSWAP_D	0b011
+#define RVG_FUNCT3_AMOADD_D	0b011
+#define RVG_FUNCT3_AMOXOR_D	0b011
+#define RVG_FUNCT3_AMOAND_D	0b011
+#define RVG_FUNCT3_AMOOR_D	0b011
+#define RVG_FUNCT3_AMOMIN_D	0b011
+#define RVG_FUNCT3_AMOMAX_D	0b011
+#define RVG_FUNCT3_AMOMINU_D	0b011
+#define RVG_FUNCT3_AMOMAXU_D	0b011
+
+#if __riscv_xlen == 32
+/* RV-32 Shift Instruction Upper Bits */
+#define RVG_SLLI_UPPER		0b0000000
+#define RVG_SRLI_UPPER		0b0000000
+#define RVG_SRAI_UPPER		0b0100000
+#elif __riscv_xlen == 64
+/* RV-64 Shift Instruction Upper Bits */
+#define RVG_SLLI_UPPER		0b000000
+#define RVG_SRLI_UPPER		0b000000
+#define RVG_SRAI_UPPER		0b010000
+#endif /* __riscv_xlen */
+
+/* RVG funct5 codes */
+/* A Standard Extension */
+#define RVG_FUNCT5_LR_W		0b00010
+#define RVG_FUNCT5_SC_W		0b00011
+#define RVG_FUNCT5_AMOSWAP_W	0b00001
+#define RVG_FUNCT5_AMOADD_W	0b00000
+#define RVG_FUNCT5_AMOXOR_W	0b00100
+#define RVG_FUNCT5_AMOAND_W	0b01100
+#define RVG_FUNCT5_AMOOR_W	0b01000
+#define RVG_FUNCT5_AMOMIN_W	0b10000
+#define RVG_FUNCT5_AMOMAX_W	0b10100
+#define RVG_FUNCT5_AMOMINU_W	0b11000
+#define RVG_FUNCT5_AMOMAXU_W	0b11100
 
-/* parts of opcode for RVC*/
+/* RVG 64-bit only funct5 codes */
+/* A Standard Extension */
+#define RVG_FUNCT5_LR_D		0b00010
+#define RVG_FUNCT5_SC_D		0b00011
+#define RVG_FUNCT5_AMOSWAP_D	0b00001
+#define RVG_FUNCT5_AMOADD_D	0b00000
+#define RVG_FUNCT5_AMOXOR_D	0b00100
+#define RVG_FUNCT5_AMOAND_D	0b01100
+#define RVG_FUNCT5_AMOOR_D	0b01000
+#define RVG_FUNCT5_AMOMIN_D	0b10000
+#define RVG_FUNCT5_AMOMAX_D	0b10100
+#define RVG_FUNCT5_AMOMINU_D	0b11000
+#define RVG_FUNCT5_AMOMAXU_D	0b11100
+
+/* RVG funct7 codes */
+#define RVG_FUNCT7_SLLI		0b0000000
+#define RVG_FUNCT7_SRLI		0b0000000
+#define RVG_FUNCT7_SRAI		0b0100000
+#define RVG_FUNCT7_ADD		0b0000000
+#define RVG_FUNCT7_SUB		0b0100000
+#define RVG_FUNCT7_SLL		0b0000000
+#define RVG_FUNCT7_SLT		0b0000000
+#define RVG_FUNCT7_SLTU		0b0000000
+#define RVG_FUNCT7_XOR		0b0000000
+#define RVG_FUNCT7_SRL		0b0000000
+#define RVG_FUNCT7_SRA		0b0100000
+#define RVG_FUNCT7_OR		0b0000000
+#define RVG_FUNCT7_AND		0b0000000
+/* M Standard Extension */
+#define RVG_FUNCT7_MUL		0b0000001
+#define RVG_FUNCT7_MULH		0b0000001
+#define RVG_FUNCT7_MULHSU	0b0000001
+#define RVG_FUNCT7_MULHU	0b0000001
+#define RVG_FUNCT7_DIV		0b0000001
+#define RVG_FUNCT7_DIVU		0b0000001
+#define RVG_FUNCT7_REM		0b0000001
+#define RVG_FUNCT7_REMU		0b0000001
+
+/* RVG 64-bit only funct7 codes */
+#define RVG_FUNCT7_SLLIW	0b0000000
+#define RVG_FUNCT7_SRLIW	0b0000000
+#define RVG_FUNCT7_SRAIW	0b0100000
+#define RVG_FUNCT7_ADDW		0b0000000
+#define RVG_FUNCT7_SUBW		0b0100000
+#define RVG_FUNCT7_SLLW		0b0000000
+#define RVG_FUNCT7_SRLW		0b0000000
+#define RVG_FUNCT7_SRAW		0b0100000
+/* M Standard Extension */
+#define RVG_FUNCT7_MULW		0b0000001
+#define RVG_FUNCT7_DIVW		0b0000001
+#define RVG_FUNCT7_DIVUW	0b0000001
+#define RVG_FUNCT7_REMW		0b0000001
+#define RVG_FUNCT7_REMUW	0b0000001
+
+/* RVG funct12 codes */
+#define RVG_FUNCT12_ECALL	0b000000000000
+#define RVG_FUNCT12_EBREAK	0b000000000001
+
+/* RVG instruction match types */
+#define RVG_MATCH_R(f_) \
+	(RVG_FUNCT7_##f_ << RV_INSN_FUNCT7_OPOFF | \
+	 RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF | RVG_OPCODE_##f_)
+#define RVG_MATCH_I(f_) \
+	(RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF | RVG_OPCODE_##f_)
+#define RVG_MATCH_S(f_) \
+	(RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF | RVG_OPCODE_##f_)
+#define RVG_MATCH_B(f_) \
+	(RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF | RVG_OPCODE_##f_)
+#define RVG_MATCH_U(f_) (RVG_OPCODE_##f_)
+#define RVG_MATCH_J(f_) (RVG_OPCODE_##f_)
+#define RVG_MATCH_AMO(f_) \
+	(RVG_FUNCT5_##f_ << RV_INSN_FUNCT7_OPOFF | \
+	 RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF | RVG_OPCODE_##f_)
+
+/* RVG instruction matches */
+#define RVG_MATCH_LUI		(RVG_MATCH_U(LUI))
+#define RVG_MATCH_AUIPC		(RVG_MATCH_U(AUIPC))
+#define RVG_MATCH_JAL		(RVG_MATCH_J(JAL))
+#define RVG_MATCH_JALR		(RVG_MATCH_I(JALR))
+#define RVG_MATCH_BEQ		(RVG_MATCH_B(BEQ))
+#define RVG_MATCH_BNE		(RVG_MATCH_B(BNE))
+#define RVG_MATCH_BLT		(RVG_MATCH_B(BLT))
+#define RVG_MATCH_BGE		(RVG_MATCH_B(BGE))
+#define RVG_MATCH_BLTU		(RVG_MATCH_B(BLTU))
+#define RVG_MATCH_BGEU		(RVG_MATCH_B(BGEU))
+#define RVG_MATCH_LB		(RVG_MATCH_I(LB))
+#define RVG_MATCH_LH		(RVG_MATCH_I(LH))
+#define RVG_MATCH_LW		(RVG_MATCH_I(LW))
+#define RVG_MATCH_LBU		(RVG_MATCH_I(LBU))
+#define RVG_MATCH_LHU		(RVG_MATCH_I(LHU))
+#define RVG_MATCH_SB		(RVG_MATCH_S(SB))
+#define RVG_MATCH_SH		(RVG_MATCH_S(SH))
+#define RVG_MATCH_SW		(RVG_MATCH_S(SW))
+#define RVG_MATCH_ADDI		(RVG_MATCH_I(ADDI))
+#define RVG_MATCH_SLTI		(RVG_MATCH_I(SLTI))
+#define RVG_MATCH_SLTIU		(RVG_MATCH_I(SLTIU))
+#define RVG_MATCH_XORI		(RVG_MATCH_I(XORI))
+#define RVG_MATCH_ORI		(RVG_MATCH_I(ORI))
+#define RVG_MATCH_ANDI		(RVG_MATCH_I(ANDI))
+#define RVG_MATCH_SLLI		(RVG_SLLI_UPPER | RVG_MATCH_I(SLLI))
+#define RVG_MATCH_SRLI		(RVG_SRLI_UPPER | RVG_MATCH_I(SRLI))
+#define RVG_MATCH_SRAI		(RVG_SRAI_UPPER | RVG_MATCH_I(SRAI))
+#define RVG_MATCH_ADD		(RVG_MATCH_R(ADD))
+#define RVG_MATCH_SUB		(RVG_MATCH_R(SUB))
+#define RVG_MATCH_SLL		(RVG_MATCH_R(SLL))
+#define RVG_MATCH_SLT		(RVG_MATCH_R(SLT))
+#define RVG_MATCH_SLTU		(RVG_MATCH_R(SLTU))
+#define RVG_MATCH_XOR		(RVG_MATCH_R(XOR))
+#define RVG_MATCH_SRL		(RVG_MATCH_R(SRL))
+#define RVG_MATCH_SRA		(RVG_MATCH_R(SRA))
+#define RVG_MATCH_OR		(RVG_MATCH_R(OR))
+#define RVG_MATCH_AND		(RVG_MATCH_R(AND))
+#define RVG_MATCH_NOP		(RVG_MATCH_I(NOP))
+#define RVG_MATCH_FENCE		(RVG_FUNCT3_FENCE | RVG_OPCODE_FENCE)
+#define RVG_MATCH_FENCETSO	0b1000001100110000000000000
+#define RVG_MATCH_PAUSE		0b0000000100000000000000000
+#define RVG_MATCH_ECALL		0b0000000000000000000000000
+#define RVG_MATCH_EBREAK	0b0000000000010000000000000
+/* F Standard Extension */
+#define RVG_MATCH_FLW		(RVG_MATCH_I(FLW))
+#define RVG_MATCH_FSW		(RVG_MATCH_S(FSW))
+/* D Standard Extension */
+#define RVG_MATCH_FLD		(RVG_MATCH_I(FLD))
+#define RVG_MATCH_FSD		(RVG_MATCH_S(FSD))
+/* Q Standard Extension */
+#define RVG_MATCH_FLQ		(RVG_MATCH_I(FLQ))
+#define RVG_MATCH_FSQ		(RVG_MATCH_S(FSQ))
+/* Zicsr Standard Extension */
+#define RVG_MATCH_CSRRW		(RVG_MATCH_I(CSRRW))
+#define RVG_MATCH_CSRRS		(RVG_MATCH_I(CSRRS))
+#define RVG_MATCH_CSRRC		(RVG_MATCH_I(CSRRC))
+#define RVG_MATCH_CSRRWI	(RVG_MATCH_I(CSRRWI))
+#define RVG_MATCH_CSRRSI	(RVG_MATCH_I(CSRRSI))
+#define RVG_MATCH_CSRRCI	(RVG_MATCH_I(CSRRCI))
+/* M Standard Extension */
+#define RVG_MATCH_MUL		(RVG_MATCH_R(MUL))
+#define RVG_MATCH_MULH		(RVG_MATCH_R(MULH))
+#define RVG_MATCH_MULHSU	(RVG_MATCH_R(MULHSU))
+#define RVG_MATCH_MULHU		(RVG_MATCH_R(MULHU))
+#define RVG_MATCH_DIV		(RVG_MATCH_R(DIV))
+#define RVG_MATCH_DIVU		(RVG_MATCH_R(DIVU))
+#define RVG_MATCH_REM		(RVG_MATCH_R(REM))
+#define RVG_MATCH_REMU		(RVG_MATCH_R(REMU))
+/* A Standard Extension */
+#define RVG_MATCH_LR_W		(RVG_MATCH_AMO(LR_W))
+#define RVG_MATCH_SC_W		(RVG_MATCH_AMO(SC_W))
+#define RVG_MATCH_AMOSWAP_W	(RVG_MATCH_AMO(AMOSWAP_W))
+#define RVG_MATCH_AMOADD_W	(RVG_MATCH_AMO(AMOADD_W))
+#define RVG_MATCH_AMOXOR_W	(RVG_MATCH_AMO(AMOXOR_W))
+#define RVG_MATCH_AMOAND_W	(RVG_MATCH_AMO(AMOAND_W))
+#define RVG_MATCH_AMOOR_W	(RVG_MATCH_AMO(AMOOR_W))
+#define RVG_MATCH_AMOMIN_W	(RVG_MATCH_AMO(AMOMIN_W))
+#define RVG_MATCH_AMOMAX_W	(RVG_MATCH_AMO(AMOMAX_W))
+#define RVG_MATCH_AMOMINU_W	(RVG_MATCH_AMO(AMOMINU_W))
+#define RVG_MATCH_AMOMAXU_W	(RVG_MATCH_AMO(AMOMAXU_W))
+
+/* RVG 64-bit only matches */
+#define RVG_MATCH_LWU		(RVG_MATCH_I(LWU))
+#define RVG_MATCH_LD		(RVG_MATCH_I(LD))
+#define RVG_MATCH_SD		(RVG_MATCH_S(SD))
+#define RVG_MATCH_ADDIW		(RVG_MATCH_I(ADDIW))
+#define RVG_MATCH_SLLIW		(RVG_MATCH_R(SLLIW))
+#define RVG_MATCH_SRLIW		(RVG_MATCH_R(SRLIW))
+#define RVG_MATCH_SRAIW		(RVG_MATCH_R(SRAIW))
+#define RVG_MATCH_ADDW		(RVG_MATCH_R(ADDW))
+#define RVG_MATCH_SUBW		(RVG_MATCH_R(SUBW))
+#define RVG_MATCH_SLLW		(RVG_MATCH_R(SLLW))
+#define RVG_MATCH_SRLW		(RVG_MATCH_R(SRLW))
+#define RVG_MATCH_SRAW		(RVG_MATCH_R(SRAW))
+/* M Standard Extension */
+#define RVG_MATCH_MULW		(RVG_MATCH_R(MULW))
+#define RVG_MATCH_DIVW		(RVG_MATCH_R(DIVW))
+#define RVG_MATCH_DIVUW		(RVG_MATCH_R(DIVUW))
+#define RVG_MATCH_REMW		(RVG_MATCH_R(REMW))
+#define RVG_MATCH_REMUW		(RVG_MATCH_R(REMUW))
+/* A Standard Extension */
+#define RVG_MATCH_LR_D		(RVG_MATCH_AMO(LR_W))
+#define RVG_MATCH_SC_D		(RVG_MATCH_AMO(SC_W))
+#define RVG_MATCH_AMOSWAP_D	(RVG_MATCH_AMO(AMOSWAP_W))
+#define RVG_MATCH_AMOADD_D	(RVG_MATCH_AMO(AMOADD_W))
+#define RVG_MATCH_AMOXOR_D	(RVG_MATCH_AMO(AMOXOR_W))
+#define RVG_MATCH_AMOAND_D	(RVG_MATCH_AMO(AMOAND_W))
+#define RVG_MATCH_AMOOR_D	(RVG_MATCH_AMO(AMOOR_W))
+#define RVG_MATCH_AMOMIN_D	(RVG_MATCH_AMO(AMOMIN_W))
+#define RVG_MATCH_AMOMAX_D	(RVG_MATCH_AMO(AMOMAX_W))
+#define RVG_MATCH_AMOMINU_D	(RVG_MATCH_AMO(AMOMINU_W))
+#define RVG_MATCH_AMOMAXU_D	(RVG_MATCH_AMO(AMOMAXU_W))
+
+/* Privileged instruction match */
+#define RV_MATCH_SRET		0b00010000001000000000000001110011
+#define RV_MATCH_WFI		0b00010000010100000000000001110011
+
+/* Bit masks for each type of RVG instruction */
+#define RVG_MASK_R \
+	((RV_INSN_FUNCT7_MASK << RV_INSN_FUNCT7_OPOFF) | \
+	 (RV_INSN_FUNCT3_MASK << RV_INSN_FUNCT3_OPOFF) | RV_INSN_OPCODE_MASK)
+#define RVG_MASK_I \
+	((RV_INSN_FUNCT3_MASK << RV_INSN_FUNCT3_OPOFF) | RV_INSN_OPCODE_MASK)
+#define RVG_MASK_S \
+	((RV_INSN_FUNCT3_MASK << RV_INSN_FUNCT3_OPOFF) | RV_INSN_OPCODE_MASK)
+#define RVG_MASK_B \
+	((RV_INSN_FUNCT3_MASK << RV_INSN_FUNCT3_OPOFF) | RV_INSN_OPCODE_MASK)
+#define RVG_MASK_U	(RV_INSN_OPCODE_MASK)
+#define RVG_MASK_J	(RV_INSN_OPCODE_MASK)
+#define RVG_MASK_AMO \
+	((RV_INSN_FUNCT5_MASK << RV_INSN_FUNCT5_OPOFF) | \
+	 (RV_INSN_FUNCT3_MASK << RV_INSN_FUNCT3_OPOFF) | RV_INSN_OPCODE_MASK)
+
+#if __riscv_xlen == 32
+#define RVG_MASK_SHIFT (GENMASK(6, 0) << 25)
+#elif __riscv_xlen == 64
+#define RVG_MASK_SHIFT (GENMASK(5, 0) << 26)
+#endif /* __riscv_xlen */
+
+/* RVG instruction masks */
+#define RVG_MASK_LUI		(RVG_MASK_U)
+#define RVG_MASK_AUIPC		(RVG_MASK_U)
+#define RVG_MASK_JAL		(RVG_MASK_J)
+#define RVG_MASK_JALR		(RVG_MASK_I)
+#define RVG_MASK_BEQ		(RVG_MASK_B)
+#define RVG_MASK_BNE		(RVG_MASK_B)
+#define RVG_MASK_BLT		(RVG_MASK_B)
+#define RVG_MASK_BGE		(RVG_MASK_B)
+#define RVG_MASK_BLTU		(RVG_MASK_B)
+#define RVG_MASK_BGEU		(RVG_MASK_B)
+#define RVG_MASK_LB		(RVG_MASK_I)
+#define RVG_MASK_LH		(RVG_MASK_I)
+#define RVG_MASK_LW		(RVG_MASK_I)
+#define RVG_MASK_LBU		(RVG_MASK_I)
+#define RVG_MASK_LHU		(RVG_MASK_I)
+#define RVG_MASK_SB		(RVG_MASK_S)
+#define RVG_MASK_SH		(RVG_MASK_S)
+#define RVG_MASK_SW		(RVG_MASK_S)
+#define RVG_MASK_ADDI		(RVG_MASK_I)
+#define RVG_MASK_SLTI		(RVG_MASK_I)
+#define RVG_MASK_SLTIU		(RVG_MASK_I)
+#define RVG_MASK_XORI		(RVG_MASK_I)
+#define RVG_MASK_ORI		(RVG_MASK_I)
+#define RVG_MASK_ANDI		(RVG_MASK_I)
+#define RVG_MASK_SLLI		(RVG_MASK_SHIFT | RVG_MASK_I)
+#define RVG_MASK_SRLI		(RVG_MASK_SHIFT | RVG_MASK_I)
+#define RVG_MASK_SRAI		(RVG_MASK_SHIFT | RVG_MASK_I)
+#define RVG_MASK_ADD		(RVG_MASK_R)
+#define RVG_MASK_SUB		(RVG_MASK_R)
+#define RVG_MASK_SLL		(RVG_MASK_R)
+#define RVG_MASK_SLT		(RVG_MASK_R)
+#define RVG_MASK_SLTU		(RVG_MASK_R)
+#define RVG_MASK_XOR		(RVG_MASK_R)
+#define RVG_MASK_SRL		(RVG_MASK_R)
+#define RVG_MASK_SRA		(RVG_MASK_R)
+#define RVG_MASK_OR		(RVG_MASK_R)
+#define RVG_MASK_AND		(RVG_MASK_R)
+#define RVG_MASK_NOP		(RVG_MASK_I)
+#define RVG_MASK_FENCE		(RVG_MASK_I)
+#define RVG_MASK_FENCETSO	0xffffffff
+#define RVG_MASK_PAUSE		0xffffffff
+#define RVG_MASK_ECALL		0xffffffff
+#define RVG_MASK_EBREAK		0xffffffff
+/* F Standard Extension */
+#define RVG_MASK_FLW		(RVG_MASK_I)
+#define RVG_MASK_FSW		(RVG_MASK_S)
+/* D Standard Extension */
+#define RVG_MASK_FLD		(RVG_MASK_I)
+#define RVG_MASK_FSD		(RVG_MASK_S)
+/* Q Standard Extension */
+#define RVG_MASK_FLQ		(RVG_MASK_I)
+#define RVG_MASK_FSQ		(RVG_MASK_S)
+/* Zicsr Standard Extension */
+#define RVG_MASK_CSRRW		(RVG_MASK_I)
+#define RVG_MASK_CSRRS		(RVG_MASK_I)
+#define RVG_MASK_CSRRC		(RVG_MASK_I)
+#define RVG_MASK_CSRRWI		(RVG_MASK_I)
+#define RVG_MASK_CSRRSI		(RVG_MASK_I)
+#define RVG_MASK_CSRRCI		(RVG_MASK_I)
+/* M Standard Extension */
+#define RVG_MASK_MUL		(RVG_MASK_R)
+#define RVG_MASK_MULH		(RVG_MASK_R)
+#define RVG_MASK_MULHSU		(RVG_MASK_R)
+#define RVG_MASK_MULHU		(RVG_MASK_R)
+#define RVG_MASK_DIV		(RVG_MASK_R)
+#define RVG_MASK_DIVU		(RVG_MASK_R)
+#define RVG_MASK_REM		(RVG_MASK_R)
+#define RVG_MASK_REMU		(RVG_MASK_R)
+/* A Standard Extension */
+#define RVG_MASK_LR_W		(RVG_MASK_AMO)
+#define RVG_MASK_SC_W		(RVG_MASK_AMO)
+#define RVG_MASK_AMOSWAP_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOADD_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOXOR_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOAND_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOOR_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMIN_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMAX_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMINU_W	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMAXU_W	(RVG_MASK_AMO)
+
+/* RVG 64-bit only masks */
+#define RVG_MASK_LWU		(RVG_MASK_I)
+#define RVG_MASK_LD		(RVG_MASK_I)
+#define RVG_MASK_SD		(RVG_MASK_S)
+#define RVG_MASK_ADDIW		(RVG_MASK_I)
+#define RVG_MASK_SLLIW		(RVG_MASK_R)
+#define RVG_MASK_SRLIW		(RVG_MASK_R)
+#define RVG_MASK_SRAIW		(RVG_MASK_R)
+#define RVG_MASK_ADDW		(RVG_MASK_R)
+#define RVG_MASK_SUBW		(RVG_MASK_R)
+#define RVG_MASK_SLLW		(RVG_MASK_R)
+#define RVG_MASK_SRLW		(RVG_MASK_R)
+#define RVG_MASK_SRAW		(RVG_MASK_R)
+/* M Standard Extension */
+#define RVG_MASK_MULW		(RVG_MASK_R)
+#define RVG_MASK_DIVW		(RVG_MASK_R)
+#define RVG_MASK_DIVUW		(RVG_MASK_R)
+#define RVG_MASK_REMW		(RVG_MASK_R)
+#define RVG_MASK_REMUW		(RVG_MASK_R)
+/* A Standard Extension */
+#define RVG_MASK_LR_D		(RVG_MASK_AMO)
+#define RVG_MASK_SC_D		(RVG_MASK_AMO)
+#define RVG_MASK_AMOSWAP_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOADD_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOXOR_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOAND_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOOR_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMIN_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMAX_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMINU_D	(RVG_MASK_AMO)
+#define RVG_MASK_AMOMAXU_D	(RVG_MASK_AMO)
+
+/* Privileged instruction masks */
+#define RV_MASK_SRET		0xffffffff
+#define RV_MASK_WFI		0xffffffff
+
+/* RVC opcodes */
 #define RVC_OPCODE_C0		0x0
 #define RVC_OPCODE_C1		0x1
 #define RVC_OPCODE_C2		0x2
 
-/* parts of funct3 code for I, M, A extension*/
-#define RVG_FUNCT3_JALR		0x0
-#define RVG_FUNCT3_BEQ		0x0
-#define RVG_FUNCT3_BNE		0x1
-#define RVG_FUNCT3_BLT		0x4
-#define RVG_FUNCT3_BGE		0x5
-#define RVG_FUNCT3_BLTU		0x6
-#define RVG_FUNCT3_BGEU		0x7
-
-/* parts of funct3 code for C extension*/
-#define RVC_FUNCT3_C_BEQZ	0x6
-#define RVC_FUNCT3_C_BNEZ	0x7
-#define RVC_FUNCT3_C_J		0x5
-#define RVC_FUNCT3_C_JAL	0x1
-#define RVC_FUNCT4_C_JR		0x8
-#define RVC_FUNCT4_C_JALR	0x9
-#define RVC_FUNCT4_C_EBREAK	0x9
-
-#define RVG_FUNCT12_EBREAK	0x1
-#define RVG_FUNCT12_SRET	0x102
-
-#define RVG_MATCH_AUIPC		(RVG_OPCODE_AUIPC)
-#define RVG_MATCH_JALR		(RV_ENCODE_FUNCT3(JALR) | RVG_OPCODE_JALR)
-#define RVG_MATCH_JAL		(RVG_OPCODE_JAL)
-#define RVG_MATCH_FENCE		(RVG_OPCODE_FENCE)
-#define RVG_MATCH_BEQ		(RV_ENCODE_FUNCT3(BEQ) | RVG_OPCODE_BRANCH)
-#define RVG_MATCH_BNE		(RV_ENCODE_FUNCT3(BNE) | RVG_OPCODE_BRANCH)
-#define RVG_MATCH_BLT		(RV_ENCODE_FUNCT3(BLT) | RVG_OPCODE_BRANCH)
-#define RVG_MATCH_BGE		(RV_ENCODE_FUNCT3(BGE) | RVG_OPCODE_BRANCH)
-#define RVG_MATCH_BLTU		(RV_ENCODE_FUNCT3(BLTU) | RVG_OPCODE_BRANCH)
-#define RVG_MATCH_BGEU		(RV_ENCODE_FUNCT3(BGEU) | RVG_OPCODE_BRANCH)
-#define RVG_MATCH_EBREAK	(RV_ENCODE_FUNCT12(EBREAK) | RVG_OPCODE_SYSTEM)
-#define RVG_MATCH_SRET		(RV_ENCODE_FUNCT12(SRET) | RVG_OPCODE_SYSTEM)
-#define RVC_MATCH_C_BEQZ	(RVC_ENCODE_FUNCT3(C_BEQZ) | RVC_OPCODE_C1)
-#define RVC_MATCH_C_BNEZ	(RVC_ENCODE_FUNCT3(C_BNEZ) | RVC_OPCODE_C1)
-#define RVC_MATCH_C_J		(RVC_ENCODE_FUNCT3(C_J) | RVC_OPCODE_C1)
-#define RVC_MATCH_C_JAL		(RVC_ENCODE_FUNCT3(C_JAL) | RVC_OPCODE_C1)
-#define RVC_MATCH_C_JR		(RVC_ENCODE_FUNCT4(C_JR) | RVC_OPCODE_C2)
-#define RVC_MATCH_C_JALR	(RVC_ENCODE_FUNCT4(C_JALR) | RVC_OPCODE_C2)
-#define RVC_MATCH_C_EBREAK	(RVC_ENCODE_FUNCT4(C_EBREAK) | RVC_OPCODE_C2)
-
-#define RVG_MASK_AUIPC		(RV_INSN_OPCODE_MASK)
-#define RVG_MASK_JALR		(RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK)
-#define RVG_MASK_JAL		(RV_INSN_OPCODE_MASK)
-#define RVG_MASK_FENCE		(RV_INSN_OPCODE_MASK)
-#define RVC_MASK_C_JALR		(RVC_INSN_FUNCT4_MASK | RVC_INSN_J_RS2_MASK | RVC_INSN_OPCODE_MASK)
-#define RVC_MASK_C_JR		(RVC_INSN_FUNCT4_MASK | RVC_INSN_J_RS2_MASK | RVC_INSN_OPCODE_MASK)
-#define RVC_MASK_C_JAL		(RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK)
-#define RVC_MASK_C_J		(RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK)
-#define RVG_MASK_BEQ		(RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK)
-#define RVG_MASK_BNE		(RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK)
-#define RVG_MASK_BLT		(RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK)
-#define RVG_MASK_BGE		(RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK)
-#define RVG_MASK_BLTU		(RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK)
-#define RVG_MASK_BGEU		(RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK)
-#define RVC_MASK_C_BEQZ		(RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK)
-#define RVC_MASK_C_BNEZ		(RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK)
-#define RVC_MASK_C_EBREAK	0xffff
-#define RVG_MASK_EBREAK		0xffffffff
-#define RVG_MASK_SRET		0xffffffff
+/* RVC Segments */
+#define RVC_6_2			(GENMASK(4, 0) << 2)
+#define RVC_11_7		(GENMASK(4, 0) << 7)
+#define RVC_TWO_11_7		(BIT(8))
 
-#define __INSN_LENGTH_MASK	_UL(0x3)
-#define __INSN_LENGTH_GE_32	_UL(0x3)
-#define __INSN_OPCODE_MASK	_UL(0x7F)
-#define __INSN_BRANCH_OPCODE	_UL(RVG_OPCODE_BRANCH)
+/* RVC Quadrant 1 FUNCT2 */
+#define RVC_FUNCT2_C_SRLI	0b00
+#define RVC_FUNCT2_C_SRAI	0b01
+#define RVC_FUNCT2_C_ANDI	0b10
+#define RVC_FUNCT2_C_SUB	0b00
+#define RVC_FUNCT2_C_XOR	0b01
+#define RVC_FUNCT2_C_OR		0b10
+#define RVC_FUNCT2_C_AND	0b11
+#define RVC_FUNCT2_C_SUBW	0b00
+#define RVC_FUNCT2_C_ADDW	0b01
+
+/* RVC Quadrant 0 FUNCT3 */
+#define RVC_FUNCT3_C_ADDI4SPN	0b000
+#define RVC_FUNCT3_C_FLD	0b001
+#define RVC_FUNCT3_C_LW		0b010
+#define RVC_FUNCT3_C_FLW	0b011
+#define RVC_FUNCT3_C_LD		0b011
+#define RVC_FUNCT3_C_FSD	0b101
+#define RVC_FUNCT3_C_SW		0b110
+#define RVC_FUNCT3_C_FSW	0b111
+#define RVC_FUNCT3_C_SD		0b111
+/* RVC Quadrant 1 FUNCT3 */
+#define RVC_FUNCT3_C_NOP	0b000
+#define RVC_FUNCT3_C_ADDI	0b000
+#define RVC_FUNCT3_C_JAL	0b001
+#define RVC_FUNCT3_C_ADDIW	0b001
+#define RVC_FUNCT3_C_LI		0b010
+#define RVC_FUNCT3_C_ADDI16SP	0b011
+#define RVC_FUNCT3_C_LUI	0b011
+#define RVC_FUNCT3_C_SRLI	0b100
+#define RVC_FUNCT3_C_SRAI	0b100
+#define RVC_FUNCT3_C_ANDI	0b100
+#define RVC_FUNCT3_C_J		0b101
+#define RVC_FUNCT3_C_BEQZ	0b110
+#define RVC_FUNCT3_C_BNEZ	0b111
+/* RVC Quadrant 2 FUNCT3 */
+#define RVC_FUNCT3_C_SLLI	0b000
+#define RVC_FUNCT3_C_FLDSP	0b001
+#define RVC_FUNCT3_C_LWSP	0b010
+#define RVC_FUNCT3_C_FLWSP	0b011
+#define RVC_FUNCT3_C_LDSP	0b011
+#define RVC_FUNCT3_C_FSDSP	0b101
+#define RVC_FUNCT3_C_SWSP	0b110
+#define RVC_FUNCT3_C_FSWSP	0b111
+#define RVC_FUNCT3_C_SDSP	0b111
+
+/* RVC Quadrant 2 FUNCT4 */
+#define RVC_FUNCT4_C_JR		0b1000
+#define RVC_FUNCT4_C_MV		0b1000
+#define RVC_FUNCT4_C_EBREAK	0b1001
+#define RVC_FUNCT4_C_JALR	0b1001
+#define RVC_FUNCT4_C_ADD	0b1001
+
+/* RVC Quadrant 1 FUNCT6 */
+#define RVC_FUNCT6_C_SUB	0b100011
+#define RVC_FUNCT6_C_XOR	0b100011
+#define RVC_FUNCT6_C_OR		0b100011
+#define RVC_FUNCT6_C_AND	0b100011
+#define RVC_FUNCT6_C_SUBW	0b100111
+#define RVC_FUNCT6_C_ADDW	0b100111
+
+/* RVC instruction match types */
+#define RVC_MATCH_CR(f_)	(RVC_FUNCT4_C_##f_ << RVC_INSN_FUNCT4_OPOFF)
+#define RVC_MATCH_CI(f_)	(RVC_FUNCT3_C_##f_ << RVC_INSN_FUNCT3_OPOFF)
+#define RVC_MATCH_CSS(f_)	(RVC_FUNCT3_C_##f_ << RVC_INSN_FUNCT3_OPOFF)
+#define RVC_MATCH_CIW(f_)	(RVC_FUNCT3_C_##f_ << RVC_INSN_FUNCT3_OPOFF)
+#define RVC_MATCH_CL(f_)	(RVC_FUNCT3_C_##f_ << RVC_INSN_FUNCT3_OPOFF)
+#define RVC_MATCH_CS(f_)	(RVC_FUNCT3_C_##f_ << RVC_INSN_FUNCT3_OPOFF)
+#define RVC_MATCH_CA(f_)	(RVC_FUNCT6_C_##f_ << RVC_INSN_FUNCT6_OPOFF | \
+			RVC_FUNCT2_C_##f_ << RVC_INSN_FUNCT2_CA_OPOFF)
+#define RVC_MATCH_CB(f_)	(RVC_FUNCT3_C_##f_ << RVC_INSN_FUNCT3_OPOFF)
+#define RVC_MATCH_CJ(f_)	(RVC_FUNCT3_C_##f_ << RVC_INSN_FUNCT3_OPOFF)
+
+/* RVC Quadrant 0 matches */
+#define RVC_MATCH_C_ADDI4SPN	(RVC_MATCH_CIW(ADDI4SPN) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_FLD		(RVC_MATCH_CL(FLD) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_LW		(RVC_MATCH_CL(LW) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_FLW		(RVC_MATCH_CL(FLW) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_LD		(RVC_MATCH_CL(LD) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_FSD		(RVC_MATCH_CS(FSD) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_SW		(RVC_MATCH_CS(SW) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_FSW		(RVC_MATCH_CS(FSW) | RVC_OPCODE_C0)
+#define RVC_MATCH_C_SD		(RVC_MATCH_CS(SD) | RVC_OPCODE_C0)
+/* RVC Quadrant 1 matches */
+#define RVC_MATCH_C_NOP		(RVC_MATCH_CI(NOP) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_ADDI	(RVC_MATCH_CI(ADDI) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_JAL		(RVC_MATCH_CJ(JAL) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_ADDIW	(RVC_MATCH_CI(ADDIW) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_LI		(RVC_MATCH_CI(LI) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_ADDI16SP \
+	(RVC_MATCH_CI(ADDI16SP) | RVC_TWO_11_7 | RVC_OPCODE_C1)
+#define RVC_MATCH_C_LUI (RVC_MATCH_CI(LUI) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_SRLI \
+	(RVC_MATCH_CB(SRLI) | RVC_FUNCT2_C_SRLI << RVC_INSN_FUNCT2_CB_OPOFF | \
+	 RVC_OPCODE_C1)
+#define RVC_MATCH_C_SRAI \
+	(RVC_MATCH_CB(SRAI) | RVC_FUNCT2_C_SRAI << RVC_INSN_FUNCT2_CB_OPOFF | \
+	 RVC_OPCODE_C1)
+#define RVC_MATCH_C_ANDI \
+	(RVC_MATCH_CB(ANDI) | RVC_FUNCT2_C_ANDI << RVC_INSN_FUNCT2_CB_OPOFF | \
+	 RVC_OPCODE_C1)
+#define RVC_MATCH_C_SUB (RVC_MATCH_CA(SUB) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_XOR		(RVC_MATCH_CA(XOR) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_OR		(RVC_MATCH_CA(OR) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_AND		(RVC_MATCH_CA(AND) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_SUBW	(RVC_MATCH_CA(SUBW) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_ADDW	(RVC_MATCH_CA(ADDW) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_J		(RVC_MATCH_CJ(J) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_BEQZ	(RVC_MATCH_CB(BEQZ) | RVC_OPCODE_C1)
+#define RVC_MATCH_C_BNEZ	(RVC_MATCH_CB(BNEZ) | RVC_OPCODE_C1)
+/* RVC Quadrant 2 matches */
+#define RVC_MATCH_C_SLLI	(RVC_MATCH_CI(SLLI) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_FLDSP	(RVC_MATCH_CI(FLDSP) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_LWSP	(RVC_MATCH_CI(LWSP) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_FLWSP	(RVC_MATCH_CI(FLWSP) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_LDSP	(RVC_MATCH_CI(LDSP) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_JR		(RVC_MATCH_CR(JR) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_MV		(RVC_MATCH_CR(MV) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_EBREAK	(RVC_MATCH_CR(EBREAK) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_JALR	(RVC_MATCH_CR(JALR) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_ADD		(RVC_MATCH_CR(ADD) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_FSDSP	(RVC_MATCH_CSS(FSDSP) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_SWSP	(RVC_MATCH_CSS(SWSP) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_FSWSP	(RVC_MATCH_CSS(FSWSP) | RVC_OPCODE_C2)
+#define RVC_MATCH_C_SDSP	(RVC_MATCH_CSS(SDSP) | RVC_OPCODE_C2)
+
+/* Bit masks for each type of RVC instruction */
+#define RVC_MASK_CR \
+	(RVC_INSN_FUNCT4_MASK << RVC_INSN_FUNCT4_OPOFF | RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CI \
+	(RVC_INSN_FUNCT3_MASK << RVC_INSN_FUNCT3_OPOFF | RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CSS \
+	(RVC_INSN_FUNCT3_MASK << RVC_INSN_FUNCT3_OPOFF | RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CIW \
+	(RVC_INSN_FUNCT3_MASK << RVC_INSN_FUNCT3_OPOFF | RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CL \
+	(RVC_INSN_FUNCT3_MASK << RVC_INSN_FUNCT3_OPOFF | RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CS \
+	(RVC_INSN_FUNCT3_MASK << RVC_INSN_FUNCT3_OPOFF | RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CA \
+	(RVC_INSN_FUNCT6_MASK << RVC_INSN_FUNCT6_OPOFF | \
+	 RVC_INSN_FUNCT2_MASK << RVC_INSN_FUNCT2_CA_OPOFF | \
+	 RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CB \
+	(RVC_INSN_FUNCT3_MASK << RVC_INSN_FUNCT3_OPOFF | RVC_INSN_OPCODE_MASK)
+#define RVC_MASK_CJ \
+	(RVC_INSN_FUNCT3_MASK << RVC_INSN_FUNCT3_OPOFF | RVC_INSN_OPCODE_MASK)
+
+/* RVC Quadrant 0 masks */
+#define RVC_MASK_C_ADDI4SPN	(RVC_MASK_CIW)
+#define RVC_MASK_C_FLD		(RVC_MASK_CL)
+#define RVC_MASK_C_LW		(RVC_MASK_CL)
+#define RVC_MASK_C_FLW		(RVC_MASK_CL)
+#define RVC_MASK_C_LD		(RVC_MASK_CL)
+#define RVC_MASK_C_FSD		(RVC_MASK_CS)
+#define RVC_MASK_C_SW		(RVC_MASK_CS)
+#define RVC_MASK_C_FSW		(RVC_MASK_CS)
+#define RVC_MASK_C_SD		(RVC_MASK_CS)
+/* RVC Quadrant 1 masks */
+#define RVC_MASK_C_NOP		(RVC_MASK_CI)
+#define RVC_MASK_C_ADDI		(RVC_MASK_CI)
+#define RVC_MASK_C_JAL		(RVC_MASK_CJ)
+#define RVC_MASK_C_ADDIW	(RVC_MASK_CI)
+#define RVC_MASK_C_LI		(RVC_MASK_CI)
+#define RVC_MASK_C_ADDI16SP	(RVC_MASK_CI | RVC_TWO_11_7)
+#define RVC_MASK_C_LUI		(RVC_MASK_CI)
+#define RVC_MASK_C_SRLI \
+	(RVC_MASK_CB | RVC_INSN_FUNCT2_MASK << RVC_INSN_FUNCT2_CB_OPOFF)
+#define RVC_MASK_C_SRAI \
+	(RVC_MASK_CB | RVC_INSN_FUNCT2_MASK << RVC_INSN_FUNCT2_CB_OPOFF)
+#define RVC_MASK_C_ANDI \
+	(RVC_MASK_CB | RVC_INSN_FUNCT2_MASK << RVC_INSN_FUNCT2_CB_OPOFF)
+#define RVC_MASK_C_SUB		(RVC_MASK_CA)
+#define RVC_MASK_C_XOR		(RVC_MASK_CA)
+#define RVC_MASK_C_OR		(RVC_MASK_CA)
+#define RVC_MASK_C_AND		(RVC_MASK_CA)
+#define RVC_MASK_C_SUBW		(RVC_MASK_CA)
+#define RVC_MASK_C_ADDW		(RVC_MASK_CA)
+#define RVC_MASK_C_J		(RVC_MASK_CJ)
+#define RVC_MASK_C_BEQZ		(RVC_MASK_CB)
+#define RVC_MASK_C_BNEZ		(RVC_MASK_CB)
+/* RVC Quadrant 2 masks */
+#define RVC_MASK_C_SLLI		(RVC_MASK_CI)
+#define RVC_MASK_C_FLDSP	(RVC_MASK_CI)
+#define RVC_MASK_C_LWSP		(RVC_MASK_CI)
+#define RVC_MASK_C_FLWSP	(RVC_MASK_CI)
+#define RVC_MASK_C_LDSP		(RVC_MASK_CI)
+#define RVC_MASK_C_JR		(RVC_MASK_CR | RVC_6_2)
+#define RVC_MASK_C_MV		(RVC_MASK_CR)
+#define RVC_MASK_C_EBREAK	(RVC_MASK_CR | RVC_11_7 | RVC_6_2)
+#define RVC_MASK_C_JALR		(RVC_MASK_CR | RVC_6_2)
+#define RVC_MASK_C_ADD		(RVC_MASK_CR)
+#define RVC_MASK_C_FSDSP	(RVC_MASK_CSS)
+#define RVC_MASK_C_SWSP		(RVC_MASK_CSS)
+#define RVC_MASK_C_FSWSP	(RVC_MASK_CSS)
+#define RVC_MASK_C_SDSP		(RVC_MASK_CSS)
+
+#define INSN_C_MASK		0x3
+#define INSN_IS_C(insn)	(((insn) & INSN_C_MASK) != INSN_C_MASK)
+#define INSN_LEN(insn)	(INSN_IS_C(insn) ? 2 : 4)
 
 #define __RISCV_INSN_FUNCS(name, mask, val)				\
 static __always_inline bool riscv_insn_is_##name(u32 code)		\
 {									\
 	BUILD_BUG_ON(~(mask) & (val));					\
 	return (code & (mask)) == (val);				\
+}
+
+/* R-Type Instructions */
+#define __RISCV_RTYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_##name(u8 rd, u8 rs1, u8 rs2)	\
+{									\
+	return rv_r_insn(RVG_FUNCT7_##upper_name, rs2, rs1,		\
+				RVG_FUNCT3_##upper_name, rd,		\
+				RVG_OPCODE_##upper_name);		\
+}
+
+/* I-Type Instructions */
+#define __RISCV_ITYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_##name(u8 rd, u8 rs1, u16 imm11_0) \
+{									\
+	return rv_i_insn(imm11_0, rs1, RVG_FUNCT3_##upper_name,		\
+				rd, RVG_OPCODE_##upper_name);		\
+}
+
+/* S-Type Instructions */
+#define __RISCV_STYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_##name(u8 rs1, u16 imm11_0, u8 rs2) \
+{									\
+	return rv_s_insn(imm11_0, rs2, rs1, RVG_FUNCT3_##upper_name,	\
+				RVG_OPCODE_##upper_name);		\
+}
+
+/* B-Type Instructions */
+#define __RISCV_BTYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_##name(u8 rs1, u8 rs2, u16 imm12_1) \
+{									\
+	return rv_b_insn(imm12_1, rs2, rs1, RVG_FUNCT3_##upper_name,	\
+				RVG_OPCODE_##upper_name);		\
+}
+
+/* Reversed B-Type Instructions */
+#define __RISCV_REV_BTYPE_FUNCS(name, upper_name)			\
+static __always_inline bool rv_##name(u8 rs1, u8 rs2, u16 imm12_1) \
+{									\
+	return rv_b_insn(imm12_1, rs1, rs2, RVG_FUNCT3_##upper_name,	\
+				RVG_OPCODE_##upper_name);		\
+}
+
+/* U-Type Instructions */
+#define __RISCV_UTYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_##name(u8 rd, u32 imm31_12)	\
+{									\
+	return rv_u_insn(imm31_12, rd, RVG_OPCODE_##upper_name);	\
+}
+
+/* J-Type Instructions */
+#define __RISCV_JTYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_##name(u8 rd, u32 imm20_1)	\
+{									\
+	return rv_j_insn(imm20_1, rd, RVG_OPCODE_##upper_name);		\
+}
+
+/* AMO-Type Instructions */
+#define __RISCV_AMOTYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_##name(u8 rd, u8 rs2, u8 rs1, u8 aq, \
+						u8 rl)			\
+{									\
+	return rv_amo_insn(RVG_FUNCT5_##upper_name, aq, rl, rs2, rs1,	\
+			RVG_FUNCT3_##upper_name, rd, RVG_OPCODE_##upper_name); \
+}
+
+/* FENCE Instruction */
+#define __RISCV_NOPTYPE_FUNCS(name, upper_name)				\
+static __always_inline bool rv_nop(void)				\
+{									\
+	return RVG_MATCH_NOP;						\
+}
+
+/* FENCE Instruction */
+#define __RISCV_FENCETYPE_FUNCS(name, upper_name)			\
+static __always_inline bool rv_fence(u8 pred, u8 succ)			\
+{									\
+	u16 imm11_0 = pred << 4 | succ;					\
+	return rv_i_insn(imm11_0, 0, 0, 0, RVG_OPCODE_FENCE);		\
+}
+
+/* FENCETSO Instruction */
+#define __RISCV_FENCETSOTYPE_FUNCS(name, upper_name)			\
+static __always_inline bool rv_fencetso(void)				\
+{									\
+	return RVG_MATCH_FENCETSO; \
+}
+
+/* PAUSE Instruction */
+#define __RISCV_PAUSETYPE_FUNCS(name, upper_name)			\
+static __always_inline bool rv_pause(void)				\
+{									\
+	return RVG_MATCH_PAUSE; \
+}
+
+/* ECALL Instruction */
+#define __RISCV_ECALLTYPE_FUNCS(name, upper_name)			\
+static __always_inline bool rv_ecall(void)				\
+{									\
+	return RVG_MATCH_ECALL; \
+}
+
+/* EBREAK Instruction */
+#define __RISCV_EBREAKTYPE_FUNCS(name, upper_name)			\
+static __always_inline bool rv_ebreak(void)				\
+{									\
+	return RVG_MATCH_EBREAK; \
+}
+
+#define __RVG_INSN_FUNCS(name, upper_name, type)			\
+static __always_inline bool riscv_insn_is_##name(u32 code)		\
+{									\
+	BUILD_BUG_ON(~(RVG_MASK_##upper_name) & (RVG_MATCH_##upper_name)); \
+	return (code & (RVG_MASK_##upper_name)) == (RVG_MATCH_##upper_name); \
 }									\
+__RISCV_##type##TYPE_FUNCS(name, upper_name)
 
-#if __riscv_xlen == 32
-/* C.JAL is an RV32C-only instruction */
-__RISCV_INSN_FUNCS(c_jal, RVC_MASK_C_JAL, RVC_MATCH_C_JAL)
-#else
-#define riscv_insn_is_c_jal(opcode) 0
-#endif
-__RISCV_INSN_FUNCS(auipc, RVG_MASK_AUIPC, RVG_MATCH_AUIPC)
-__RISCV_INSN_FUNCS(jalr, RVG_MASK_JALR, RVG_MATCH_JALR)
-__RISCV_INSN_FUNCS(jal, RVG_MASK_JAL, RVG_MATCH_JAL)
-__RISCV_INSN_FUNCS(c_jr, RVC_MASK_C_JR, RVC_MATCH_C_JR)
-__RISCV_INSN_FUNCS(c_jalr, RVC_MASK_C_JALR, RVC_MATCH_C_JALR)
-__RISCV_INSN_FUNCS(c_j, RVC_MASK_C_J, RVC_MATCH_C_J)
-__RISCV_INSN_FUNCS(beq, RVG_MASK_BEQ, RVG_MATCH_BEQ)
-__RISCV_INSN_FUNCS(bne, RVG_MASK_BNE, RVG_MATCH_BNE)
-__RISCV_INSN_FUNCS(blt, RVG_MASK_BLT, RVG_MATCH_BLT)
-__RISCV_INSN_FUNCS(bge, RVG_MASK_BGE, RVG_MATCH_BGE)
-__RISCV_INSN_FUNCS(bltu, RVG_MASK_BLTU, RVG_MATCH_BLTU)
-__RISCV_INSN_FUNCS(bgeu, RVG_MASK_BGEU, RVG_MATCH_BGEU)
-__RISCV_INSN_FUNCS(c_beqz, RVC_MASK_C_BEQZ, RVC_MATCH_C_BEQZ)
-__RISCV_INSN_FUNCS(c_bnez, RVC_MASK_C_BNEZ, RVC_MATCH_C_BNEZ)
-__RISCV_INSN_FUNCS(c_ebreak, RVC_MASK_C_EBREAK, RVC_MATCH_C_EBREAK)
-__RISCV_INSN_FUNCS(ebreak, RVG_MASK_EBREAK, RVG_MATCH_EBREAK)
-__RISCV_INSN_FUNCS(sret, RVG_MASK_SRET, RVG_MATCH_SRET)
-__RISCV_INSN_FUNCS(fence, RVG_MASK_FENCE, RVG_MATCH_FENCE);
+/* Compressed instruction types */
+
+/* CR-Type Instructions */
+#define __RISCV_CRTYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u8 rd, u8 rs)			\
+{									\
+	return rv_cr_insn(RVC_FUNCT4_##upper_name, rd, rs,		\
+			RVC_OPCODE_##opcode);				\
+}
+
+#define __RISCV_CR_ZERO_RSTYPE_FUNCS(name, upper_name, opcode)		\
+static __always_inline bool rv##name(u8 rs1)				\
+{									\
+	return rv_cr_insn(RVC_FUNCT4_##upper_name, rs1, RV_REG_ZERO,	\
+			RVC_OPCODE_##opcode);				\
+}
+
+/* CI-Type Instructions */
+#define __RISCV_CITYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u8 rd, u32 imm)			\
+{									\
+	u32 imm_hi = RV##upper_name##_IMM_HI(imm);			\
+	u32 imm_lo = RV##upper_name##_IMM_LO(imm);			\
+	return rv_ci_insn(RVC_FUNCT3_##upper_name, imm_hi, rd,		\
+			imm_lo, RVC_OPCODE_##opcode);			\
+}
+
+#define __RISCV_CI_SPTYPE_FUNCS(name, upper_name, opcode)		\
+static __always_inline bool rv##name(u32 imm)			\
+{									\
+	u32 imm_hi = RV##upper_name##_IMM_HI(imm);			\
+	u32 imm_lo = RV##upper_name##_IMM_LO(imm);			\
+	return rv_ci_insn(RVC_FUNCT3_##upper_name, imm_hi, 2,		\
+			imm_lo, RVC_OPCODE_##opcode);			\
+}
+
+/* CSS-Type Instructions */
+#define __RISCV_CSSTYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u32 imm, u8 rs2)			\
+{									\
+	imm = RV##upper_name##_IMM(imm);				\
+	return rv_css_insn(RVC_FUNCT3_##upper_name, imm, rs2,		\
+			RVC_OPCODE_##opcode);				\
+}
+
+/* CIW-Type Instructions */
+#define __RISCV_CIWTYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u8 rd, u32 imm)			\
+{									\
+	imm = RV##upper_name##_IMM(imm);				\
+	return rv_ciw_insn(RVC_FUNCT3_##upper_name, imm, rd,		\
+			RVC_OPCODE_##opcode);				\
+}
+
+/* CL-Type Instructions */
+#define __RISCV_CLTYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u8 rd, u32 imm, u8 rs1)		\
+{									\
+	u32 imm_hi = RV##upper_name##_IMM_HI(imm);			\
+	u32 imm_lo = RV##upper_name##_IMM_LO(imm);			\
+	return rv_cl_insn(RVC_FUNCT3_##upper_name, imm_hi, rs1, rd,	\
+			imm_lo, RVC_OPCODE_##opcode);			\
+}
+
+/* CS-Type Instructions */
+#define __RISCV_CSTYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u8 rs1, u32 imm, u8 rs2)		\
+{									\
+	u32 imm_hi = RV##upper_name##_IMM_HI(imm);			\
+	u32 imm_lo = RV##upper_name##_IMM_LO(imm);			\
+	return rv_cs_insn(RVC_FUNCT3_##upper_name, imm_hi, rs1, imm_lo,	\
+			rs2, RVC_OPCODE_##opcode);			\
+}
+
+/* CA-Type Instructions */
+#define __RISCV_CATYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u8 rd, u8 rs2)			\
+{									\
+	return rv_ca_insn(RVC_FUNCT6_##upper_name, rd,			\
+			RVC_FUNCT2_##upper_name, rs2,			\
+			RVC_OPCODE_##opcode);				\
+}
+
+/* CB-Type Instructions */
+#define __RISCV_CBTYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u8 rd, u32 imm)			\
+{									\
+	u32 imm_hi = RV##upper_name##_IMM_HI(imm);			\
+	u32 imm_lo = RV##upper_name##_IMM_LO(imm);			\
+	return rv_cb_insn(RVC_FUNCT3_##upper_name, imm_hi, rd, imm_lo,	\
+			RVC_OPCODE_##opcode);				\
+}
+
+#define __RISCV_CB_FUNCT2TYPE_FUNCS(name, upper_name, opcode)		\
+static __always_inline bool rv##name(u8 rd, u32 imm)			\
+{									\
+	u32 imm_hi = RV##upper_name##_IMM_HI(imm);			\
+	u32 imm_lo = RV##upper_name##_IMM_LO(imm);			\
+	imm_hi = (imm_hi << 2) | RVC_FUNCT2_##upper_name;		\
+	return rv_cb_insn(RVC_FUNCT3_##upper_name, imm_hi, rd, imm_lo,	\
+			RVC_OPCODE_##opcode);				\
+}
+
+/* CJ-Type Instructions */
+#define __RISCV_CJTYPE_FUNCS(name, upper_name, opcode)			\
+static __always_inline bool rv##name(u32 imm)				\
+{									\
+	imm = RV##upper_name##_IMM(imm);				\
+	return rv_cj_insn(RVC_FUNCT3_##upper_name, imm,			\
+			RVC_OPCODE_##opcode);				\
+}
+
+/* CEBREAK instruction */
+#define __RISCV_CEBREAKTYPE_FUNCS(name, upper_name, opcode)		\
+static __always_inline bool rv##name(u32 imm)				\
+{									\
+	return RVC_MATCH_C_EBREAK;					\
+}
+
+/* CNOP instruction */
+#define __RISCV_CNOPTYPE_FUNCS(name, upper_name, opcode)		\
+static __always_inline bool rv##name(u32 imm)				\
+{									\
+	return RVC_MATCH_C_NOP;						\
+}
+
+#define __RVC_INSN_IS_DEFAULTTYPE(name, upper_name)			\
+static __always_inline bool riscv_insn_is_##name(u32 code)		\
+{									\
+	BUILD_BUG_ON(~(RVC_MASK_##upper_name) & (RVC_MATCH_##upper_name)); \
+	return (code & (RVC_MASK_##upper_name)) == (RVC_MATCH_##upper_name); \
+}
+
+#define __RVC_INSN_IS_NON_ZERO_RS1_RDTYPE(name, upper_name)		\
+static __always_inline bool riscv_insn_is_##name(u32 code)		\
+{									\
+	BUILD_BUG_ON(~(RVC_MASK_##upper_name) & (RVC_MATCH_##upper_name)); \
+	return ((code & (RVC_MASK_##upper_name)) == (RVC_MATCH_##upper_name)) \
+		&& (RVC_X(code, RVC_C0_RS1_OPOFF, RV_STANDARD_REG_MASK) != 0); \
+}
+
+#define __RVC_INSN_IS_NON_ZERO_TWO_RDTYPE(name, upper_name)		\
+static __always_inline bool riscv_insn_is_##name(u32 code)		\
+{									\
+	BUILD_BUG_ON(~(RVC_MASK_##upper_name) & (RVC_MATCH_##upper_name)); \
+	return ((code & (RVC_MASK_##upper_name)) == (RVC_MATCH_##upper_name)) \
+		&& (RVC_X(code, RVC_C0_RS1_OPOFF, RV_STANDARD_REG_MASK) != 0) \
+		&& (RVC_X(code, RVC_C0_RS1_OPOFF, RV_STANDARD_REG_MASK) != 2); \
+}
+
+#define __RVC_INSN_IS_NON_ZERO_RD_RS2TYPE(name, upper_name)		\
+static __always_inline bool riscv_insn_is_##name(u32 code)		\
+{									\
+	BUILD_BUG_ON(~(RVC_MASK_##upper_name) & (RVC_MATCH_##upper_name)); \
+	return ((code & (RVC_MASK_##upper_name)) == (RVC_MATCH_##upper_name)) \
+		&& (RVC_X(code, RVC_C0_RS1_OPOFF, RV_STANDARD_REG_MASK) != 0) \
+		&& (RVC_X(code, RVC_C0_RD_OPOFF, RV_STANDARD_REG_MASK) != 0); \
+}
+
+#define __RVC_INSN_FUNCS(name, upper_name, type, opcode, equality_type)	\
+__RVC_INSN_IS_##equality_type##TYPE(name, upper_name)			\
+__RISCV_##type##TYPE_FUNCS(name, upper_name, opcode)
 
 /* special case to catch _any_ system instruction */
 static __always_inline bool riscv_insn_is_system(u32 code)
@@ -278,61 +1915,196 @@ static __always_inline bool riscv_insn_is_branch(u32 code)
 #define RV_X(X, s, mask)  (((X) >> (s)) & (mask))
 #define RVC_X(X, s, mask) RV_X(X, s, mask)
 
+#define RV_EXTRACT_RS1_REG(x) \
+	({typeof(x) x_ = (x); \
+	(RV_X(x_, RVG_RS1_OPOFF, RVG_RS1_MASK)); })
+
+#define RV_EXTRACT_RS2_REG(x) \
+	({typeof(x) x_ = (x); \
+	(RV_X(x_, RVG_RS2_OPOFF, RVG_RS2_MASK)); })
+
 #define RV_EXTRACT_RD_REG(x) \
 	({typeof(x) x_ = (x); \
 	(RV_X(x_, RVG_RD_OPOFF, RVG_RD_MASK)); })
 
+#define RVC_EXTRACT_R_RS2_REG(x) \
+	({typeof(x) x_ = (x); \
+	(RV_X(x_, RVC_C0_RS2_OPOFF, RV_COMPRESSED_REG_MASK)); })
+
+#define RVC_EXTRACT_SA_RS2_REG(x) \
+	({typeof(x) x_ = (x); \
+	(RV_X(x_, RVC_C2_RS2_OPOFF, RV_STANDARD_REG_MASK)); })
+
+#define RV_EXTRACT_FUNCT3(x) \
+	({typeof(x) x_ = (x); \
+	(RV_X(x_, RV_INSN_FUNCT3_OPOFF, RV_INSN_FUNCT3_MASK)); })
+
 #define RV_EXTRACT_UTYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
-	(RV_X(x_, RV_U_IMM_31_12_OPOFF, RV_U_IMM_31_12_MASK)); })
+	(RV_X(x_, RV_U_IMM_31_12_OPOFF, RV_U_IMM_31_12_MASK) \
+		<< RV_U_IMM_31_12_OFF) | \
+	(RV_IMM_SIGN(x_) << RV_U_IMM_SIGN_OFF); })
 
 #define RV_EXTRACT_JTYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
-	(RV_X(x_, RV_J_IMM_10_1_OPOFF, RV_J_IMM_10_1_MASK) << RV_J_IMM_10_1_OFF) | \
-	(RV_X(x_, RV_J_IMM_11_OPOFF, RV_J_IMM_11_MASK) << RV_J_IMM_11_OFF) | \
-	(RV_X(x_, RV_J_IMM_19_12_OPOFF, RV_J_IMM_19_12_MASK) << RV_J_IMM_19_12_OFF) | \
+	(RV_X(x_, RV_J_IMM_10_1_OPOFF, RV_J_IMM_10_1_MASK) \
+		<< RV_J_IMM_10_1_OFF) | \
+	(RV_X(x_, RV_J_IMM_11_OPOFF, RV_J_IMM_11_MASK) \
+		<< RV_J_IMM_11_OFF) | \
+	(RV_X(x_, RV_J_IMM_19_12_OPOFF, RV_J_IMM_19_12_MASK) \
+		<< RV_J_IMM_19_12_OFF) | \
 	(RV_IMM_SIGN(x_) << RV_J_IMM_SIGN_OFF); })
 
 #define RV_EXTRACT_ITYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
-	(RV_X(x_, RV_I_IMM_11_0_OPOFF, RV_I_IMM_11_0_MASK)) | \
+	(RV_X(x_, RV_I_IMM_11_0_OPOFF, RV_I_IMM_11_0_MASK) \
+		<< RV_I_IMM_11_0_OFF) | \
 	(RV_IMM_SIGN(x_) << RV_I_IMM_SIGN_OFF); })
 
 #define RV_EXTRACT_BTYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
-	(RV_X(x_, RV_B_IMM_4_1_OPOFF, RV_B_IMM_4_1_MASK) << RV_B_IMM_4_1_OFF) | \
-	(RV_X(x_, RV_B_IMM_10_5_OPOFF, RV_B_IMM_10_5_MASK) << RV_B_IMM_10_5_OFF) | \
+	(RV_X(x_, RV_B_IMM_4_1_OPOFF, RV_B_IMM_4_1_MASK) \
+		<< RV_B_IMM_4_1_OFF) | \
+	(RV_X(x_, RV_B_IMM_10_5_OPOFF, RV_B_IMM_10_5_MASK) \
+		<< RV_B_IMM_10_5_OFF) | \
 	(RV_X(x_, RV_B_IMM_11_OPOFF, RV_B_IMM_11_MASK) << RV_B_IMM_11_OFF) | \
 	(RV_IMM_SIGN(x_) << RV_B_IMM_SIGN_OFF); })
 
 #define RVC_EXTRACT_JTYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
-	(RVC_X(x_, RVC_J_IMM_3_1_OPOFF, RVC_J_IMM_3_1_MASK) << RVC_J_IMM_3_1_OFF) | \
+	(RVC_X(x_, RVC_J_IMM_3_1_OPOFF, RVC_J_IMM_3_1_MASK) \
+		<< RVC_J_IMM_3_1_OFF) | \
 	(RVC_X(x_, RVC_J_IMM_4_OPOFF, RVC_J_IMM_4_MASK) << RVC_J_IMM_4_OFF) | \
 	(RVC_X(x_, RVC_J_IMM_5_OPOFF, RVC_J_IMM_5_MASK) << RVC_J_IMM_5_OFF) | \
 	(RVC_X(x_, RVC_J_IMM_6_OPOFF, RVC_J_IMM_6_MASK) << RVC_J_IMM_6_OFF) | \
 	(RVC_X(x_, RVC_J_IMM_7_OPOFF, RVC_J_IMM_7_MASK) << RVC_J_IMM_7_OFF) | \
-	(RVC_X(x_, RVC_J_IMM_9_8_OPOFF, RVC_J_IMM_9_8_MASK) << RVC_J_IMM_9_8_OFF) | \
-	(RVC_X(x_, RVC_J_IMM_10_OPOFF, RVC_J_IMM_10_MASK) << RVC_J_IMM_10_OFF) | \
+	(RVC_X(x_, RVC_J_IMM_9_8_OPOFF, RVC_J_IMM_9_8_MASK) \
+		<< RVC_J_IMM_9_8_OFF) | \
+	(RVC_X(x_, RVC_J_IMM_10_OPOFF, RVC_J_IMM_10_MASK) \
+		<< RVC_J_IMM_10_OFF) | \
 	(RVC_IMM_SIGN(x_) << RVC_J_IMM_SIGN_OFF); })
 
 #define RVC_EXTRACT_BTYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
-	(RVC_X(x_, RVC_B_IMM_2_1_OPOFF, RVC_B_IMM_2_1_MASK) << RVC_B_IMM_2_1_OFF) | \
-	(RVC_X(x_, RVC_B_IMM_4_3_OPOFF, RVC_B_IMM_4_3_MASK) << RVC_B_IMM_4_3_OFF) | \
-	(RVC_X(x_, RVC_B_IMM_5_OPOFF, RVC_B_IMM_5_MASK) << RVC_B_IMM_5_OFF) | \
-	(RVC_X(x_, RVC_B_IMM_7_6_OPOFF, RVC_B_IMM_7_6_MASK) << RVC_B_IMM_7_6_OFF) | \
-	(RVC_IMM_SIGN(x_) << RVC_B_IMM_SIGN_OFF); })
+	(RVC_X(x_, RVC_BZ_IMM_2_1_OPOFF, RVC_BZ_IMM_2_1_MASK) \
+		<< RVC_BZ_IMM_2_1_OFF) | \
+	(RVC_X(x_, RVC_BZ_IMM_4_3_OPOFF, RVC_BZ_IMM_4_3_MASK) \
+		<< RVC_BZ_IMM_4_3_OFF) | \
+	(RVC_X(x_, RVC_BZ_IMM_5_OPOFF, RVC_BZ_IMM_5_MASK) \
+		<< RVC_BZ_IMM_5_OFF) | \
+	(RVC_X(x_, RVC_BZ_IMM_7_6_OPOFF, RVC_BZ_IMM_7_6_MASK) \
+		<< RVC_BZ_IMM_7_6_OFF) | \
+	(RVC_IMM_SIGN(x_) << RVC_BZ_IMM_SIGN_OFF); })
 
 #define RVG_EXTRACT_SYSTEM_CSR(x) \
-	({typeof(x) x_ = (x); RV_X(x_, RVG_SYSTEM_CSR_OFF, RVG_SYSTEM_CSR_MASK); })
+	({typeof(x) x_ = (x); \
+	RV_X(x_, RVG_SYSTEM_CSR_OPOFF, RVG_SYSTEM_CSR_MASK); })
 
 #define RVFDQ_EXTRACT_FL_FS_WIDTH(x) \
-	({typeof(x) x_ = (x); RV_X(x_, RVFDQ_FL_FS_WIDTH_OFF, \
-				   RVFDQ_FL_FS_WIDTH_MASK); })
+	({typeof(x) x_ = (x); RV_X(x_, RVG_FL_FS_WIDTH_OFF, \
+				RVG_FL_FS_WIDTH_MASK); })
 
 #define RVV_EXRACT_VL_VS_WIDTH(x) RVFDQ_EXTRACT_FL_FS_WIDTH(x)
 
+/*
+ * Get the rd from an RVG instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline u32 riscv_insn_extract_rd(u32 insn)
+{
+	return RV_EXTRACT_RD_REG(insn);
+}
+
+/*
+ * Get the rs1 from an RVG instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline u32 riscv_insn_extract_rs1(u32 insn)
+{
+	return RV_EXTRACT_RS1_REG(insn);
+}
+
+/*
+ * Get the rs2 from an RVG instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline u32 riscv_insn_extract_rs2(u32 insn)
+{
+	return RV_EXTRACT_RS2_REG(insn);
+}
+
+/*
+ * Get the rs2 from a CR instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline u32 riscv_insn_extract_cr_rs2(u32 insn)
+{
+	return RVC_EXTRACT_R_RS2_REG(insn);
+}
+
+/*
+ * Get the rs2 from a CS or a CA instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline u32 riscv_insn_extract_csca_rs2(u32 insn)
+{
+	return RVC_EXTRACT_SA_RS2_REG(insn);
+}
+
+/*
+ * Get the funct3 from an RVG instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline u32 riscv_insn_extract_funct3(u32 insn)
+{
+	return RV_EXTRACT_FUNCT3(insn);
+}
+
+/*
+ * Get the immediate from a I-type instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline s32 riscv_insn_extract_itype_imm(u32 insn)
+{
+	return RV_EXTRACT_ITYPE_IMM(insn);
+}
+
+/*
+ * Get the immediate from a U-type instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline s32 riscv_insn_extract_utype_imm(u32 insn)
+{
+	return RV_EXTRACT_UTYPE_IMM(insn);
+}
+
+/*
+ * Get the immediate from a B-type instruction.
+ *
+ * @insn: instruction to process
+ * Return: immediate
+ */
+static inline s32 riscv_insn_extract_btype_imm(u32 insn)
+{
+	return RV_EXTRACT_BTYPE_IMM(insn);
+}
+
 /*
  * Get the immediate from a J-type instruction.
  *
@@ -344,6 +2116,70 @@ static inline s32 riscv_insn_extract_jtype_imm(u32 insn)
 	return RV_EXTRACT_JTYPE_IMM(insn);
 }
 
+/*
+ * Update a I-type instruction with an immediate value.
+ *
+ * @insn: pointer to the itype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_itype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all I-type IMM bits sit at 31:20 */
+	*insn &= ~GENMASK(31, 20);
+	*insn |= (RV_X(imm, RV_I_IMM_11_0_OFF, RV_I_IMM_11_0_MASK)
+		  << RV_I_IMM_11_0_OPOFF);
+}
+
+/*
+ * Update a S-type instruction with an immediate value.
+ *
+ * @insn: pointer to the stype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_stype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all S-type IMM bits sit at 31:25 and 11:7 */
+	*insn &= ~(GENMASK(31, 25) | GENMASK(11, 7));
+	*insn |= (RV_X(imm, RV_S_IMM_4_0_OFF, RV_S_IMM_4_0_MASK)
+		  << RV_S_IMM_4_0_OPOFF) |
+		 (RV_X(imm, RV_S_IMM_11_5_OFF, RV_S_IMM_11_5_MASK)
+		  << RV_S_IMM_11_5_OPOFF);
+}
+
+/*
+ * Update a B-type instruction with an immediate value.
+ *
+ * @insn: pointer to the btype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_btype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all B-type IMM bits sit at 31:25 and 11:7 */
+	*insn &= ~(GENMASK(31, 25) | GENMASK(11, 7));
+	*insn |= (RV_X(imm, RV_B_IMM_4_1_OFF, RV_B_IMM_4_1_MASK)
+		  << RV_B_IMM_4_1_OPOFF) |
+		 (RV_X(imm, RV_B_IMM_10_5_OFF, RV_B_IMM_10_5_MASK)
+		  << RV_B_IMM_10_5_OPOFF) |
+		 (RV_X(imm, RV_B_IMM_11_OFF, RV_B_IMM_11_MASK)
+		  << RV_B_IMM_11_OPOFF) |
+		 (RV_X(imm, RV_B_IMM_SIGN_OFF, RV_B_IMM_SIGN_MASK)
+		  << RV_B_IMM_SIGN_OPOFF);
+}
+
+/*
+ * Update a U-type instruction with an immediate value.
+ *
+ * @insn: pointer to the jtype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_utype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all U-type IMM bits sit at 31:12 */
+	*insn &= ~GENMASK(31, 12);
+	*insn |= (RV_X(imm, RV_S_IMM_31_12_OFF, RV_S_IMM_31_12_MASK)
+		  << RV_S_IMM_31_12_OPOFF);
+}
+
 /*
  * Update a J-type instruction with an immediate value.
  *
@@ -352,14 +2188,147 @@ static inline s32 riscv_insn_extract_jtype_imm(u32 insn)
  */
 static inline void riscv_insn_insert_jtype_imm(u32 *insn, s32 imm)
 {
-	/* drop the old IMMs, all jal IMM bits sit at 31:12 */
+	/* drop the old IMMs, all J-type IMM bits sit at 31:12 */
 	*insn &= ~GENMASK(31, 12);
-	*insn |= (RV_X(imm, RV_J_IMM_10_1_OFF, RV_J_IMM_10_1_MASK) << RV_J_IMM_10_1_OPOFF) |
-		 (RV_X(imm, RV_J_IMM_11_OFF, RV_J_IMM_11_MASK) << RV_J_IMM_11_OPOFF) |
-		 (RV_X(imm, RV_J_IMM_19_12_OFF, RV_J_IMM_19_12_MASK) << RV_J_IMM_19_12_OPOFF) |
+	*insn |= (RV_X(imm, RV_J_IMM_10_1_OFF, RV_J_IMM_10_1_MASK)
+		  << RV_J_IMM_10_1_OPOFF) |
+		 (RV_X(imm, RV_J_IMM_11_OFF, RV_J_IMM_11_MASK)
+		  << RV_J_IMM_11_OPOFF) |
+		 (RV_X(imm, RV_J_IMM_19_12_OFF, RV_J_IMM_19_12_MASK)
+		  << RV_J_IMM_19_12_OPOFF) |
 		 (RV_X(imm, RV_J_IMM_SIGN_OFF, 1) << RV_J_IMM_SIGN_OPOFF);
 }
 
+/*
+ * Update a CI-type instruction with an immediate value.
+ * slot.
+ *
+ * @insn: pointer to the citype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_citype_imm(u32 *insn, u32 imm_hi,
+						u32 imm_lo)
+{
+	/* drop the old IMMs, all CI-type IMM bits sit at 12 and 6:2 */
+	*insn &= ~(12 | GENMASK(6, 2));
+	*insn |= (RV_X(imm_lo, RVC_I_IMM_LO_OFF, RVC_I_IMM_LO_MASK)
+		  << RVC_I_IMM_LO_OPOFF) |
+		 (RV_X(imm_hi, RVC_I_IMM_HI_OFF, RVC_I_IMM_HI_MASK)
+		  << RVC_I_IMM_HI_OPOFF);
+}
+
+/*
+ * Update a CSS-type instruction with an immediate value.
+ *
+ * @insn: pointer to the csstype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_csstype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all CSS-type IMM bits sit at 11:6 */
+	*insn &= ~GENMASK(11, 6);
+	*insn |= (RV_X(imm, RVC_SS_IMM_OFF, RVC_SS_IMM_MASK)
+		  << RVC_SS_IMM_OPOFF);
+}
+
+/*
+ * Update a CIW-type instruction with an immediate value.
+ *
+ * @insn: pointer to the ciwtype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_ciwtype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all CIW-type IMM bits sit at 11:6 */
+	*insn &= ~GENMASK(11, 6);
+	*insn |= (RV_X(imm, RVC_IW_IMM_OFF, RVC_IW_IMM_MASK)
+		  << RVC_IW_IMM_OPOFF);
+}
+
+/*
+ * Update a CL-type instruction with an immediate value.
+ *
+ * @insn: pointer to the cltype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_cltype_imm(u32 *insn, u32 imm_hi,
+						u32 imm_lo)
+{
+	/* drop the old IMMs, all CL-type IMM bits sit at 11:6 */
+	*insn &= ~GENMASK(11, 6);
+	*insn |= (RV_X(imm_lo, RVC_L_IMM_LO_OFF, RVC_L_IMM_LO_MASK)
+		  << RVC_L_IMM_LO_OPOFF) |
+		 (RV_X(imm_hi, RVC_L_IMM_HI_OFF, RVC_L_IMM_HI_MASK)
+		  << RVC_L_IMM_HI_OPOFF);
+}
+
+/*
+ * Update a CS-type instruction with an immediate value.
+ *
+ * @insn: pointer to the cstype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_cstype_imm(u32 *insn, u32 imm_hi,
+						u32 imm_lo)
+{
+	/* drop the old IMMs, all CS-type IMM bits sit at 11:6 */
+	*insn &= ~GENMASK(11, 6);
+	*insn |= (RV_X(imm_lo, RVC_S_IMM_LO_OFF, RVC_S_IMM_LO_MASK)
+		  << RVC_S_IMM_LO_OPOFF) |
+		 (RV_X(imm_hi, RVC_S_IMM_HI_OFF, RVC_S_IMM_HI_MASK)
+		  << RVC_S_IMM_HI_OPOFF);
+}
+
+/*
+ * Update a RVC BEQZ/BNEZ instruction with an immediate value.
+ *
+ * @insn: pointer to the cbtype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_cbztype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all CB-type IMM bits sit at 12:10 and 6:2 */
+	*insn &= ~(GENMASK(12, 10) | GENMASK(6, 2));
+	*insn |= (RV_X(imm, RVC_BZ_IMM_SIGN_OFF, RVC_BZ_IMM_SIGN_MASK)
+		  << RVC_BZ_IMM_SIGN_OPOFF) |
+		 (RV_X(imm, RVC_BZ_IMM_4_3_OFF, RVC_BZ_IMM_4_3_MASK)
+		  << RVC_BZ_IMM_4_3_OPOFF) |
+		 (RV_X(imm, RVC_BZ_IMM_7_6_OFF, RVC_BZ_IMM_7_6_MASK)
+		  << RVC_BZ_IMM_7_6_OPOFF) |
+		 (RV_X(imm, RVC_BZ_IMM_2_1_OFF, RVC_BZ_IMM_2_1_MASK)
+		  << RVC_BZ_IMM_2_1_OPOFF) |
+		 (RV_X(imm, RVC_BZ_IMM_5_OFF, RVC_BZ_IMM_5_MASK)
+		  << RVC_BZ_IMM_5_OPOFF);
+}
+
+/*
+ * Update a CJ-type instruction with an immediate value.
+ *
+ * @insn: pointer to the cjtype instruction
+ * @imm: the immediate to insert into the instruction
+ */
+static inline void riscv_insn_insert_cjtype_imm(u32 *insn, s32 imm)
+{
+	/* drop the old IMMs, all CJ-type IMM bits sit at 12:2 */
+	*insn &= ~GENMASK(12, 2);
+	*insn |= (RV_X(imm, RVC_J_IMM_SIGN_OFF, RVC_J_IMM_SIGN_MASK)
+		  << RVC_J_IMM_SIGN_OPOFF) |
+		 (RV_X(imm, RVC_J_IMM_4_OFF, RVC_J_IMM_4_MASK)
+		  << RVC_J_IMM_4_OPOFF) |
+		 (RV_X(imm, RVC_J_IMM_9_8_OFF, RVC_J_IMM_9_8_MASK)
+		  << RVC_J_IMM_9_8_OPOFF) |
+		 (RV_X(imm, RVC_J_IMM_10_OFF, RVC_J_IMM_10_MASK)
+		  << RVC_J_IMM_10_OPOFF) |
+		 (RV_X(imm, RVC_J_IMM_6_OFF, RVC_J_IMM_6_MASK)
+		  << RVC_J_IMM_6_OPOFF) |
+		 (RV_X(imm, RVC_J_IMM_7_OFF, RVC_J_IMM_7_MASK)
+		  << RVC_J_IMM_7_OPOFF) |
+		 (RV_X(imm, RVC_J_IMM_3_1_OFF, RVC_J_IMM_3_1_MASK)
+		  << RVC_J_IMM_3_1_OPOFF) |
+		 (RV_X(imm, RVC_J_IMM_5_OFF, RVC_J_IMM_5_MASK)
+		  << RVC_J_IMM_5_OPOFF);
+}
+
 /*
  * Put together one immediate from a U-type and I-type instruction pair.
  *
@@ -372,7 +2341,8 @@ static inline void riscv_insn_insert_jtype_imm(u32 *insn, s32 imm)
  * @itype_insn: instruction
  * Return: combined immediate
  */
-static inline s32 riscv_insn_extract_utype_itype_imm(u32 utype_insn, u32 itype_insn)
+static inline s32 riscv_insn_extract_utype_itype_imm(u32 utype_insn,
+						     u32 itype_insn)
 {
 	s32 imm;
 
@@ -391,20 +2361,370 @@ static inline s32 riscv_insn_extract_utype_itype_imm(u32 utype_insn, u32 itype_i
  *
  * This also takes into account that both separate immediates are
  * considered as signed values, so if the I-type immediate becomes
- * negative (BIT(11) set) the U-type part gets adjusted.
+ * negative (BIT(11) aka 0x800 set) the U-type part gets adjusted.
  *
  * @utype_insn: pointer to the utype instruction of the pair
  * @itype_insn: pointer to the itype instruction of the pair
  * @imm: the immediate to insert into the two instructions
  */
-static inline void riscv_insn_insert_utype_itype_imm(u32 *utype_insn, u32 *itype_insn, s32 imm)
+static inline void riscv_insn_insert_utype_itype_imm(u32 *utype_insn,
+						     u32 *itype_insn, s32 imm)
 {
 	/* drop possible old IMM values */
-	*utype_insn &= ~(RV_U_IMM_31_12_MASK);
+	*utype_insn &= ~(RV_U_IMM_31_12_MASK << RV_U_IMM_31_12_OPOFF);
 	*itype_insn &= ~(RV_I_IMM_11_0_MASK << RV_I_IMM_11_0_OPOFF);
 
 	/* add the adapted IMMs */
-	*utype_insn |= (imm & RV_U_IMM_31_12_MASK) + ((imm & BIT(11)) << 1);
+	*utype_insn |=
+		((imm + 0x800) & (RV_U_IMM_31_12_MASK << RV_U_IMM_31_12_OPOFF));
 	*itype_insn |= ((imm & RV_I_IMM_11_0_MASK) << RV_I_IMM_11_0_OPOFF);
 }
+
+static inline bool rvc_enabled(void)
+{
+	return IS_ENABLED(CONFIG_RISCV_ISA_C);
+}
+
+/* RISC-V instruction formats. */
+
+static inline u32 rv_r_insn(u8 funct7, u8 rs2, u8 rs1, u8 funct3, u8 rd,
+			    u8 opcode)
+{
+	return (funct7 << RV_INSN_FUNCT7_OPOFF) | (rs2 << RV_INSN_RS2_OPOFF) |
+		(rs1 << RV_INSN_RS1_OPOFF) | (funct3 << RV_INSN_FUNCT3_OPOFF) |
+		(rd << RV_INSN_RD_OPOFF) | opcode;
+}
+
+static inline u32 rv_i_insn(u16 imm11_0, u8 rs1, u8 funct3, u8 rd, u8 opcode)
+{
+	u32 imm = 0;
+
+	riscv_insn_insert_stype_imm(&imm, imm11_0);
+	return imm | (rs1 << RV_INSN_RS1_OPOFF) |
+		(funct3 << RV_INSN_FUNCT3_OPOFF) | (rd << RV_INSN_RD_OPOFF) |
+		opcode;
+}
+
+static inline u32 rv_s_insn(u16 imm11_0, u8 rs2, u8 rs1, u8 funct3, u8 opcode)
+{
+	u32 imm = 0;
+
+	riscv_insn_insert_stype_imm(&imm, imm11_0);
+	return imm | (rs2 << RV_INSN_RS2_OPOFF) | (rs1 << RV_INSN_RS1_OPOFF) |
+		(funct3 << RV_INSN_FUNCT3_OPOFF) | opcode;
+}
+
+static inline u32 rv_b_insn(u16 imm12_1, u8 rs2, u8 rs1, u8 funct3, u8 opcode)
+{
+	u32 imm = 0;
+
+	riscv_insn_insert_btype_imm(&imm, imm12_1);
+	return imm | (rs2 << RV_INSN_RS2_OPOFF) | (rs1 << RV_INSN_RS1_OPOFF) |
+		(funct3 << RV_INSN_FUNCT3_OPOFF) | opcode;
+}
+
+static inline u32 rv_u_insn(u32 imm31_12, u8 rd, u8 opcode)
+{
+	u32 imm = 0;
+
+	riscv_insn_insert_btype_imm(&imm, imm31_12);
+	return imm | (rd << RV_INSN_RD_OPOFF) | opcode;
+}
+
+static inline u32 rv_j_insn(u32 imm20_1, u8 rd, u8 opcode)
+{
+	u32 imm = 0;
+
+	riscv_insn_insert_jtype_imm(&imm, imm20_1);
+	return imm | (rd << RV_INSN_RD_OPOFF) | opcode;
+}
+
+static inline u32 rv_amo_insn(u8 funct5, u8 aq, u8 rl, u8 rs2, u8 rs1,
+			      u8 funct3, u8 rd, u8 opcode)
+{
+	u8 funct7 = (funct5 << RV_INSN_FUNCT5_IN_OPOFF) |
+		(aq << RV_INSN_AQ_IN_OPOFF) | (rl << RV_INSN_RL_IN_OPOFF);
+
+	return rv_r_insn(funct7, rs2, rs1, funct3, rd, opcode);
+}
+
+/* RISC-V compressed instruction formats. */
+
+static inline u16 rv_cr_insn(u8 funct4, u8 rd, u8 rs2, u8 op)
+{
+	return (funct4 << RVC_INSN_FUNCT4_OPOFF) | (rd << RVC_C2_RD_OPOFF) |
+		(rs2 << RVC_C2_RS2_OPOFF) | op;
+}
+
+static inline u16 rv_ci_insn(u8 funct3, u32 imm_hi, u8 rd, u32 imm_lo, u8 op)
+{
+	u32 imm;
+
+	imm = (RV_X(imm_lo, RVC_I_IMM_LO_OFF, RVC_I_IMM_LO_MASK)
+			<< RVC_I_IMM_LO_OPOFF) |
+		(RV_X(imm_hi, RVC_I_IMM_HI_OFF, RVC_I_IMM_HI_MASK)
+			<< RVC_I_IMM_HI_OPOFF);
+
+	return imm | (funct3 << RVC_INSN_FUNCT3_OPOFF) |
+		(rd << RVC_C1_RD_OPOFF) | op;
+}
+
+static inline u16 rv_css_insn(u8 funct3, u32 uimm, u8 rs2, u8 op)
+{
+	u32 imm;
+
+	imm = (RV_X(uimm, RVC_SS_IMM_OFF, RVC_SS_IMM_MASK) << RVC_SS_IMM_OPOFF);
+	return imm | (funct3 << RVC_INSN_FUNCT3_OPOFF) |
+		(rs2 << RVC_C2_RS2_OPOFF) | op;
+}
+
+static inline u16 rv_ciw_insn(u8 funct3, u32 uimm, u8 rd, u8 op)
+{
+	u32 imm;
+
+	imm = (RV_X(uimm, RVC_IW_IMM_OFF, RVC_IW_IMM_MASK) << RVC_IW_IMM_OPOFF);
+	return imm | (funct3 << RVC_INSN_FUNCT3_OPOFF) |
+		(rd << RVC_C0_RD_OPOFF) | op;
+}
+
+static inline u16 rv_cl_insn(u8 funct3, u32 imm_hi, u8 rs1, u8 rd, u32 imm_lo,
+			     u8 op)
+{
+	u32 imm;
+
+	imm = (RV_X(imm_lo, RVC_L_IMM_LO_OFF, RVC_L_IMM_LO_MASK)
+			<< RVC_L_IMM_LO_OPOFF) |
+		(RV_X(imm_hi, RVC_L_IMM_HI_OFF, RVC_L_IMM_HI_MASK)
+			<< RVC_L_IMM_HI_OPOFF);
+	return imm | (funct3 << RVC_INSN_FUNCT3_OPOFF) |
+		(rs1 << RVC_C0_RS1_OPOFF) | (rd << RVC_C0_RD_OPOFF) | op;
+}
+
+static inline u16 rv_cs_insn(u8 funct3, u32 imm_hi, u8 rs1, u32 imm_lo, u8 rs2,
+			     u8 op)
+{
+	u32 imm;
+
+	imm = (RV_X(imm_lo, RVC_S_IMM_LO_OFF, RVC_S_IMM_LO_MASK)
+			<< RVC_S_IMM_LO_OPOFF) |
+		(RV_X(imm_hi, RVC_S_IMM_HI_OFF, RVC_S_IMM_HI_MASK)
+			<< RVC_S_IMM_HI_OPOFF);
+	return imm | (funct3 << RVC_INSN_FUNCT3_OPOFF) |
+		(rs1 << RVC_C0_RS1_OPOFF) | (rs2 << RVC_C0_RS2_OPOFF) | op;
+}
+
+static inline u16 rv_ca_insn(u8 funct6, u8 rd, u8 funct2, u8 rs2, u8 op)
+{
+	return (funct6 << RVC_INSN_FUNCT6_OPOFF) | (rd << RVC_C1_RD_OPOFF) |
+		(funct2 << RVC_INSN_FUNCT2_CA_OPOFF) |
+		(rs2 << RVC_C0_RS2_OPOFF) | op;
+}
+
+static inline u16 rv_cb_insn(u8 funct3, u32 off_hi, u8 rd, u32 off_lo, u8 op)
+{
+	u32 imm;
+
+	imm = (RV_X(off_lo, RVC_B_IMM_LO_OFF, RVC_B_IMM_LO_MASK)
+			<< RVC_B_IMM_LO_OPOFF) |
+		(RV_X(off_hi, RVC_B_IMM_HI_OFF, RVC_B_IMM_HI_MASK)
+			<< RVC_B_IMM_HI_OPOFF);
+	return imm | (funct3 << RVC_INSN_FUNCT3_OPOFF) |
+		(rd << RVC_C1_RD_OPOFF) | op;
+}
+
+static inline u16 rv_cj_insn(u8 funct3, u32 uimm, u8 op)
+{
+	u32 imm;
+
+	imm = (RV_X(uimm, RVC_J_IMM_OFF, RVC_J_IMM_MASK) << RVC_J_IMM_OPOFF);
+	return imm | (funct3 << RVC_INSN_FUNCT3_OPOFF) | op;
+}
+
+/* RVG instructions */
+__RVG_INSN_FUNCS(lui, LUI, U)
+__RVG_INSN_FUNCS(auipc, AUIPC, U)
+__RVG_INSN_FUNCS(jal, JAL, J)
+__RVG_INSN_FUNCS(jalr, JALR, I)
+__RVG_INSN_FUNCS(beq, BEQ, B)
+__RVG_INSN_FUNCS(bne, BNE, B)
+__RVG_INSN_FUNCS(blt, BLT, B)
+__RVG_INSN_FUNCS(bge, BGE, B)
+__RVG_INSN_FUNCS(bltu, BLTU, B)
+__RVG_INSN_FUNCS(bgeu, BGEU, B)
+__RVG_INSN_FUNCS(lb, LB, I)
+__RVG_INSN_FUNCS(lh, LH, I)
+__RVG_INSN_FUNCS(lw, LW, I)
+__RVG_INSN_FUNCS(lbu, LBU, I)
+__RVG_INSN_FUNCS(lhu, LHU, I)
+__RVG_INSN_FUNCS(sb, SB, S)
+__RVG_INSN_FUNCS(sh, SH, S)
+__RVG_INSN_FUNCS(sw, SW, S)
+__RVG_INSN_FUNCS(addi, ADDI, I)
+__RVG_INSN_FUNCS(slti, SLTI, I)
+__RVG_INSN_FUNCS(sltiu, SLTIU, I)
+__RVG_INSN_FUNCS(xori, XORI, I)
+__RVG_INSN_FUNCS(ori, ORI, I)
+__RVG_INSN_FUNCS(andi, ANDI, I)
+__RVG_INSN_FUNCS(slli, SLLI, I)
+__RVG_INSN_FUNCS(srli, SRLI, I)
+__RVG_INSN_FUNCS(srai, SRAI, I)
+__RVG_INSN_FUNCS(add, ADD, R)
+__RVG_INSN_FUNCS(sub, SUB, R)
+__RVG_INSN_FUNCS(sll, SLL, R)
+__RVG_INSN_FUNCS(slt, SLT, R)
+__RVG_INSN_FUNCS(sltu, SLTU, R)
+__RVG_INSN_FUNCS(xor, XOR, R)
+__RVG_INSN_FUNCS(srl, SRL, R)
+__RVG_INSN_FUNCS(sra, SRA, R)
+__RVG_INSN_FUNCS(or, OR, R)
+__RVG_INSN_FUNCS(and, AND, R)
+__RVG_INSN_FUNCS(nop, NOP, NOP)
+__RVG_INSN_FUNCS(fence, FENCE, FENCE)
+__RVG_INSN_FUNCS(fencetso, FENCETSO, FENCETSO)
+__RVG_INSN_FUNCS(pause, PAUSE, PAUSE)
+__RVG_INSN_FUNCS(ecall, ECALL, ECALL)
+__RVG_INSN_FUNCS(ebreak, EBREAK, EBREAK)
+/* Extra Instructions */
+__RVG_INSN_FUNCS(bgtu, BLTU, REV_B)
+__RVG_INSN_FUNCS(bleu, BGEU, REV_B)
+__RVG_INSN_FUNCS(bgt, BLT, REV_B)
+__RVG_INSN_FUNCS(ble, BGE, REV_B)
+/* F Standard Extension */
+__RVG_INSN_FUNCS(flw, FLW, I)
+__RVG_INSN_FUNCS(fsw, FSW, S)
+/* D Standard Extension */
+__RVG_INSN_FUNCS(fld, FLD, I)
+__RVG_INSN_FUNCS(fsd, FSD, S)
+/* Q Standard Extension */
+__RVG_INSN_FUNCS(flq, FLQ, I)
+__RVG_INSN_FUNCS(fsq, FSQ, S)
+/* Zicsr Standard Extension */
+__RVG_INSN_FUNCS(csrrw, CSRRW, I)
+__RVG_INSN_FUNCS(csrrs, CSRRS, I)
+__RVG_INSN_FUNCS(csrrc, CSRRC, I)
+__RVG_INSN_FUNCS(csrrwi, CSRRWI, I)
+__RVG_INSN_FUNCS(csrrsi, CSRRSI, I)
+__RVG_INSN_FUNCS(csrrci, CSRRCI, I)
+/* M Standard Extension */
+__RVG_INSN_FUNCS(mul, MUL, R)
+__RVG_INSN_FUNCS(mulh, MULH, R)
+__RVG_INSN_FUNCS(mulhsu, MULHSU, R)
+__RVG_INSN_FUNCS(mulhu, MULHU, R)
+__RVG_INSN_FUNCS(div, DIV, R)
+__RVG_INSN_FUNCS(divu, DIVU, R)
+__RVG_INSN_FUNCS(rem, REM, R)
+__RVG_INSN_FUNCS(remu, REMU, R)
+/* A Standard Extension */
+__RVG_INSN_FUNCS(lr_w, LR_W, AMO)
+__RVG_INSN_FUNCS(sc_w, SC_W, AMO)
+__RVG_INSN_FUNCS(amoswap_w, AMOSWAP_W, AMO)
+__RVG_INSN_FUNCS(amoadd_w, AMOADD_W, AMO)
+__RVG_INSN_FUNCS(amoxor_w, AMOXOR_W, AMO)
+__RVG_INSN_FUNCS(amoand_w, AMOAND_W, AMO)
+__RVG_INSN_FUNCS(amoor_w, AMOOR_W, AMO)
+__RVG_INSN_FUNCS(amomin_w, AMOMIN_W, AMO)
+__RVG_INSN_FUNCS(amomax_w, AMOMAX_W, AMO)
+__RVG_INSN_FUNCS(amominu_w, AMOMINU_W, AMO)
+__RVG_INSN_FUNCS(amomaxu_w, AMOMAXU_W, AMO)
+
+/* RVG 64-bit only instructions*/
+__RVG_INSN_FUNCS(lwu, LWU, I)
+__RVG_INSN_FUNCS(ld, LD, I)
+__RVG_INSN_FUNCS(sd, SD, S)
+__RVG_INSN_FUNCS(addiw, ADDIW, I)
+__RVG_INSN_FUNCS(slliw, SLLIW, I)
+__RVG_INSN_FUNCS(srliw, SRLIW, I)
+__RVG_INSN_FUNCS(sraiw, SRAIW, I)
+__RVG_INSN_FUNCS(addw, ADDW, R)
+__RVG_INSN_FUNCS(subw, SUBW, R)
+__RVG_INSN_FUNCS(sllw, SLLW, R)
+__RVG_INSN_FUNCS(srlw, SRLW, R)
+__RVG_INSN_FUNCS(sraw, SRAW, R)
+/* M Standard Extension */
+__RVG_INSN_FUNCS(divw, DIVW, R)
+__RVG_INSN_FUNCS(mulw, MULW, R)
+__RVG_INSN_FUNCS(divuw, DIVUW, R)
+__RVG_INSN_FUNCS(remw, REMW, R)
+__RVG_INSN_FUNCS(remuw, REMUW, R)
+/* A Standard Extension */
+__RVG_INSN_FUNCS(lr_d, LR_D, AMO)
+__RVG_INSN_FUNCS(sc_d, SC_D, AMO)
+__RVG_INSN_FUNCS(amoswap_d, AMOSWAP_D, AMO)
+__RVG_INSN_FUNCS(amoadd_d, AMOADD_D, AMO)
+__RVG_INSN_FUNCS(amoxor_d, AMOXOR_D, AMO)
+__RVG_INSN_FUNCS(amoand_d, AMOAND_D, AMO)
+__RVG_INSN_FUNCS(amoor_d, AMOOR_D, AMO)
+__RVG_INSN_FUNCS(amomin_d, AMOMIN_D, AMO)
+__RVG_INSN_FUNCS(amomax_d, AMOMAX_D, AMO)
+__RVG_INSN_FUNCS(amominu_d, AMOMINU_D, AMO)
+__RVG_INSN_FUNCS(amomaxu_d, AMOMAXU_D, AMO)
+/* Privileged instructions */
+__RISCV_INSN_FUNCS(sret, RV_MASK_SRET, RV_MATCH_SRET)
+
+/* RVC Quadrant 0 instructions */
+__RVC_INSN_FUNCS(c_addi4spn, C_ADDI4SPN, CIW, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_fld, C_FLD, CL, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_lw, C_LW, CL, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_fsd, C_FSD, CS, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_sw, C_SW, CS, C0, DEFAULT)
+/* RVC Quadrant 1 instructions */
+__RVC_INSN_FUNCS(c_nop, C_NOP, CNOP, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_addi, C_ADDI, CI, C1, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_li, C_LI, CI, C1, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_addi16sp, C_ADDI16SP, CI_SP, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_lui, C_LUI, CI, C1, NON_ZERO_TWO_RD)
+__RVC_INSN_FUNCS(c_srli, C_SRLI, CB, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_srai, C_SRAI, CB, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_andi, C_ANDI, CB, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_sub, C_SUB, CA, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_or, C_OR, CA, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_and, C_AND, CA, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_xor, C_XOR, CA, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_j, C_J, CJ, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_beqz, C_BEQZ, CB, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_bnez, C_BNEZ, CB, C1, DEFAULT)
+/* RVC Quadrant 2 instructions */
+__RVC_INSN_FUNCS(c_slli, C_SLLI, CI, C2, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_fldsp, C_FLDSP, CI, C2, DEFAULT)
+__RVC_INSN_FUNCS(c_lwsp, C_LWSP, CI, C2, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_jr, C_JR, CR_ZERO_RS, C2, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_mv, C_MV, CR, C2, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_ebreak, C_EBREAK, CEBREAK, C2, DEFAULT)
+__RVC_INSN_FUNCS(c_jalr, C_JALR, CR_ZERO_RS, C2, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_add, C_ADD, CR, C2, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_fsdsp, C_FSDSP, CSS, C2, DEFAULT)
+__RVC_INSN_FUNCS(c_swsp, C_SWSP, CSS, C2, DEFAULT)
+
+#if __riscv_xlen == 32
+/* RV32C-only instructions */
+__RVC_INSN_FUNCS(c_flw, C_FLW, CL, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_fsw, C_FSW, CS, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_jal, C_JAL, CJ, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_flwsp, C_FLWSP, CI, C2, DEFAULT)
+__RVC_INSN_FUNCS(c_fswsp, C_FSWSP, CSS, C2, DEFAULT)
+#else
+#define riscv_insn_is_c_flw(opcode) 0
+#define riscv_insn_is_c_fsw(opcode) 0
+#define riscv_insn_is_c_jal(opcode) 0
+#define riscv_insn_is_c_flwsp(opcode) 0
+#define riscv_insn_is_c_fswsp(opcode) 0
+#endif
+
+#if __riscv_xlen == 64
+/* RV64C-only instructions */
+__RVC_INSN_FUNCS(c_ld, C_LD, CL, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_sd, C_SD, CS, C0, DEFAULT)
+__RVC_INSN_FUNCS(c_addiw, C_ADDIW, CI, C1, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_subw, C_SUBW, CA, C1, DEFAULT)
+__RVC_INSN_FUNCS(c_ldsp, C_LDSP, CI, C2, NON_ZERO_RS1_RD)
+__RVC_INSN_FUNCS(c_sdsp, C_SDSP, CSS, C2, DEFAULT)
+#else
+#define riscv_insn_is_c_ld(opcode) 0
+#define riscv_insn_is_c_sd(opcode) 0
+#define riscv_insn_is_c_addi(opcode) 0
+#define riscv_insn_is_c_subw(opcode) 0
+#define riscv_insn_is_c_ldsp(opcode) 0
+#define riscv_insn_is_c_sdsp(opcode) 0
+#endif
+
 #endif /* _ASM_RISCV_INSN_H */
diff --git a/arch/riscv/include/asm/reg.h b/arch/riscv/include/asm/reg.h
new file mode 100644
index 000000000000..b653d5e4906d
--- /dev/null
+++ b/arch/riscv/include/asm/reg.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Definitions of RISC-V registers
+ *
+ * Copyright (c) 2023 Rivos Inc
+ *
+ */
+
+#ifndef _ASM_RISCV_REG_H
+#define _ASM_RISCV_REG_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+enum {
+	RV_REG_ZERO =	0,	/* The constant value 0 */
+	RV_REG_RA =	1,	/* Return address */
+	RV_REG_SP =	2,	/* Stack pointer */
+	RV_REG_GP =	3,	/* Global pointer */
+	RV_REG_TP =	4,	/* Thread pointer */
+	RV_REG_T0 =	5,	/* Temporaries */
+	RV_REG_T1 =	6,
+	RV_REG_T2 =	7,
+	RV_REG_FP =	8,	/* Saved register/frame pointer */
+	RV_REG_S1 =	9,	/* Saved register */
+	RV_REG_A0 =	10,	/* Function argument/return values */
+	RV_REG_A1 =	11,	/* Function arguments */
+	RV_REG_A2 =	12,
+	RV_REG_A3 =	13,
+	RV_REG_A4 =	14,
+	RV_REG_A5 =	15,
+	RV_REG_A6 =	16,
+	RV_REG_A7 =	17,
+	RV_REG_S2 =	18,	/* Saved registers */
+	RV_REG_S3 =	19,
+	RV_REG_S4 =	20,
+	RV_REG_S5 =	21,
+	RV_REG_S6 =	22,
+	RV_REG_S7 =	23,
+	RV_REG_S8 =	24,
+	RV_REG_S9 =	25,
+	RV_REG_S10 =	26,
+	RV_REG_S11 =	27,
+	RV_REG_T3 =	28,	/* Temporaries */
+	RV_REG_T4 =	29,
+	RV_REG_T5 =	30,
+	RV_REG_T6 =	31,
+};
+
+static inline bool is_creg(u8 reg)
+{
+	return (1 << reg) & (BIT(RV_REG_FP) |
+			     BIT(RV_REG_S1) |
+			     BIT(RV_REG_A0) |
+			     BIT(RV_REG_A1) |
+			     BIT(RV_REG_A2) |
+			     BIT(RV_REG_A3) |
+			     BIT(RV_REG_A4) |
+			     BIT(RV_REG_A5));
+}
+
+static inline bool rv_insn_reg_get_val(unsigned long *regs, u32 index,
+				       unsigned long *ptr)
+{
+	if (index == 0)
+		*ptr = 0;
+	else if (index <= 31)
+		*ptr = *((unsigned long *)regs + index);
+	else
+		return false;
+
+	return true;
+}
+
+static inline bool rv_insn_reg_set_val(unsigned long *regs, u32 index,
+				       unsigned long val)
+{
+	if (index == 0)
+		return false;
+	else if (index <= 31)
+		*((unsigned long *)regs + index) = val;
+	else
+		return false;
+
+	return true;
+}
+
+#endif /* _ASM_RISCV_REG_H */
diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c
index 2e0266ae6bd7..2393342ab362 100644
--- a/arch/riscv/kernel/kgdb.c
+++ b/arch/riscv/kernel/kgdb.c
@@ -43,7 +43,7 @@ static int get_step_address(struct pt_regs *regs, unsigned long *next_addr)
 
 	if (get_kernel_nofault(op_code, (void *)pc))
 		return -EINVAL;
-	if ((op_code & __INSN_LENGTH_MASK) != __INSN_LENGTH_GE_32) {
+	if ((op_code & __INSN_LENGTH_MASK) != INSN_C_MASK) {
 		if (riscv_insn_is_c_jalr(op_code) ||
 		    riscv_insn_is_c_jr(op_code)) {
 			rs1_num = decode_register_index(op_code, RVC_C2_RS1_OPOFF);
@@ -69,7 +69,7 @@ static int get_step_address(struct pt_regs *regs, unsigned long *next_addr)
 			*next_addr = pc + 2;
 		}
 	} else {
-		if ((op_code & __INSN_OPCODE_MASK) == __INSN_BRANCH_OPCODE) {
+		if (riscv_insn_is_branch(op_code)) {
 			bool result = false;
 			long imm = RV_EXTRACT_BTYPE_IMM(op_code);
 			unsigned long rs1_val = 0, rs2_val = 0;
diff --git a/arch/riscv/kernel/probes/simulate-insn.c b/arch/riscv/kernel/probes/simulate-insn.c
index 7441ac8a6843..994edb4bd16a 100644
--- a/arch/riscv/kernel/probes/simulate-insn.c
+++ b/arch/riscv/kernel/probes/simulate-insn.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 
+#include <asm/reg.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
@@ -7,32 +8,6 @@
 #include "decode-insn.h"
 #include "simulate-insn.h"
 
-static inline bool rv_insn_reg_get_val(struct pt_regs *regs, u32 index,
-				       unsigned long *ptr)
-{
-	if (index == 0)
-		*ptr = 0;
-	else if (index <= 31)
-		*ptr = *((unsigned long *)regs + index);
-	else
-		return false;
-
-	return true;
-}
-
-static inline bool rv_insn_reg_set_val(struct pt_regs *regs, u32 index,
-				       unsigned long val)
-{
-	if (index == 0)
-		return false;
-	else if (index <= 31)
-		*((unsigned long *)regs + index) = val;
-	else
-		return false;
-
-	return true;
-}
-
 bool __kprobes simulate_jal(u32 opcode, unsigned long addr, struct pt_regs *regs)
 {
 	/*
@@ -44,7 +19,7 @@ bool __kprobes simulate_jal(u32 opcode, unsigned long addr, struct pt_regs *regs
 	u32 imm;
 	u32 index = (opcode >> 7) & 0x1f;
 
-	ret = rv_insn_reg_set_val(regs, index, addr + 4);
+	ret = rv_insn_reg_set_val((unsigned long *)regs, index, addr + 4);
 	if (!ret)
 		return ret;
 
@@ -71,11 +46,11 @@ bool __kprobes simulate_jalr(u32 opcode, unsigned long addr, struct pt_regs *reg
 	u32 rd_index = (opcode >> 7) & 0x1f;
 	u32 rs1_index = (opcode >> 15) & 0x1f;
 
-	ret = rv_insn_reg_get_val(regs, rs1_index, &base_addr);
+	ret = rv_insn_reg_get_val((unsigned long *)regs, rs1_index, &base_addr);
 	if (!ret)
 		return ret;
 
-	ret = rv_insn_reg_set_val(regs, rd_index, addr + 4);
+	ret = rv_insn_reg_set_val((unsigned long *)regs, rd_index, addr + 4);
 	if (!ret)
 		return ret;
 
@@ -110,7 +85,7 @@ bool __kprobes simulate_auipc(u32 opcode, unsigned long addr, struct pt_regs *re
 	u32 rd_idx = auipc_rd_idx(opcode);
 	unsigned long rd_val = addr + auipc_offset(opcode);
 
-	if (!rv_insn_reg_set_val(regs, rd_idx, rd_val))
+	if (!rv_insn_reg_set_val((unsigned long *)regs, rd_idx, rd_val))
 		return false;
 
 	instruction_pointer_set(regs, addr + 4);
@@ -156,8 +131,8 @@ bool __kprobes simulate_branch(u32 opcode, unsigned long addr, struct pt_regs *r
 	unsigned long rs1_val;
 	unsigned long rs2_val;
 
-	if (!rv_insn_reg_get_val(regs, branch_rs1_idx(opcode), &rs1_val) ||
-	    !rv_insn_reg_get_val(regs, branch_rs2_idx(opcode), &rs2_val))
+	if (!rv_insn_reg_get_val((unsigned long *)regs, riscv_insn_extract_rs1(opcode), &rs1_val) ||
+	    !rv_insn_reg_get_val((unsigned long *)regs, riscv_insn_extract_rs2(opcode), &rs2_val))
 		return false;
 
 	offset_tmp = branch_offset(opcode);
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 8d92fb6c522c..d67a60369e02 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -49,7 +49,7 @@ int riscv_v_setup_vsize(void)
 
 static bool insn_is_vector(u32 insn_buf)
 {
-	u32 opcode = insn_buf & __INSN_OPCODE_MASK;
+	u32 opcode = insn_buf & RV_INSN_OPCODE_MASK;
 	u32 width, csr;
 
 	/*

-- 
2.34.1




More information about the linux-riscv mailing list