diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h index e1256e31..f4df1ae4 100644 --- a/include/sbi/riscv_encoding.h +++ b/include/sbi/riscv_encoding.h @@ -1291,6 +1291,8 @@ #define SHIFT_FUNCT3 12 #define MASK_RS1 0xf8000 +#define MASK_RS2 0x1f00000 +#define MASK_RD 0xf80 #define MASK_CSR 0xfff00000 #define SHIFT_CSR 20 @@ -1356,28 +1358,17 @@ #define SHIFT_RIGHT(x, y) \ ((y) < 0 ? ((x) << -(y)) : ((x) >> (y))) -#define REG_MASK \ - ((1 << (5 + LOG_REGBYTES)) - (1 << LOG_REGBYTES)) - -#define REG_OFFSET(insn, pos) \ - (SHIFT_RIGHT((insn), (pos) - LOG_REGBYTES) & REG_MASK) - -#define REG_PTR(insn, pos, regs) \ - (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos)) - #define GET_FUNC3(insn) ((insn & MASK_FUNCT3) >> SHIFT_FUNCT3) #define GET_RM(insn) GET_FUNC3(insn) -#define GET_RS1_NUM(insn) ((insn & MASK_RS1) >> 15) +#define GET_RS1_NUM(insn) ((insn & MASK_RS1) >> SH_RS1) +#define GET_RS2_NUM(insn) ((insn & MASK_RS2) >> SH_RS2) +#define GET_RS1S_NUM(insn) RVC_RS1S(insn) +#define GET_RS2S_NUM(insn) RVC_RS2S(insn) +#define GET_RS2C_NUM(insn) RVC_RS2(insn) +#define GET_RD_NUM(insn) ((insn & MASK_RD) >> SH_RD) #define GET_CSR_NUM(insn) ((insn & MASK_CSR) >> SHIFT_CSR) #define GET_AQRL(insn) ((insn & MASK_AQRL) >> SHIFT_AQRL) -#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs)) -#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs)) -#define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs)) -#define GET_RS2S(insn, regs) (*REG_PTR(RVC_RS2S(insn), 0, regs)) -#define GET_RS2C(insn, regs) (*REG_PTR(insn, SH_RS2C, regs)) -#define GET_SP(regs) (*REG_PTR(2, 0, regs)) -#define SET_RD(insn, regs, val) (*REG_PTR(insn, SH_RD, regs) = (val)) #define IMM_I(insn) ((s32)(insn) >> 20) #define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \ (s32)(((insn) >> 7) & 0x1f)) diff --git a/include/sbi/sbi_trap.h b/include/sbi/sbi_trap.h index 5eec4dab..731a0c98 100644 --- a/include/sbi/sbi_trap.h +++ b/include/sbi/sbi_trap.h @@ -127,70 +127,75 @@ /** Representation of register state at time of trap/interrupt */ struct sbi_trap_regs { - /** zero register state */ - unsigned long zero; - /** ra register state */ - unsigned long ra; - /** sp register state */ - unsigned long sp; - /** gp register state */ - unsigned long gp; - /** tp register state */ - unsigned long tp; - /** t0 register state */ - unsigned long t0; - /** t1 register state */ - unsigned long t1; - /** t2 register state */ - unsigned long t2; - /** s0 register state */ - unsigned long s0; - /** s1 register state */ - unsigned long s1; - /** a0 register state */ - unsigned long a0; - /** a1 register state */ - unsigned long a1; - /** a2 register state */ - unsigned long a2; - /** a3 register state */ - unsigned long a3; - /** a4 register state */ - unsigned long a4; - /** a5 register state */ - unsigned long a5; - /** a6 register state */ - unsigned long a6; - /** a7 register state */ - unsigned long a7; - /** s2 register state */ - unsigned long s2; - /** s3 register state */ - unsigned long s3; - /** s4 register state */ - unsigned long s4; - /** s5 register state */ - unsigned long s5; - /** s6 register state */ - unsigned long s6; - /** s7 register state */ - unsigned long s7; - /** s8 register state */ - unsigned long s8; - /** s9 register state */ - unsigned long s9; - /** s10 register state */ - unsigned long s10; - /** s11 register state */ - unsigned long s11; - /** t3 register state */ - unsigned long t3; - /** t4 register state */ - unsigned long t4; - /** t5 register state */ - unsigned long t5; - /** t6 register state */ - unsigned long t6; + union { + unsigned long gprs[32]; + struct { + /** zero register state */ + unsigned long zero; + /** ra register state */ + unsigned long ra; + /** sp register state */ + unsigned long sp; + /** gp register state */ + unsigned long gp; + /** tp register state */ + unsigned long tp; + /** t0 register state */ + unsigned long t0; + /** t1 register state */ + unsigned long t1; + /** t2 register state */ + unsigned long t2; + /** s0 register state */ + unsigned long s0; + /** s1 register state */ + unsigned long s1; + /** a0 register state */ + unsigned long a0; + /** a1 register state */ + unsigned long a1; + /** a2 register state */ + unsigned long a2; + /** a3 register state */ + unsigned long a3; + /** a4 register state */ + unsigned long a4; + /** a5 register state */ + unsigned long a5; + /** a6 register state */ + unsigned long a6; + /** a7 register state */ + unsigned long a7; + /** s2 register state */ + unsigned long s2; + /** s3 register state */ + unsigned long s3; + /** s4 register state */ + unsigned long s4; + /** s5 register state */ + unsigned long s5; + /** s6 register state */ + unsigned long s6; + /** s7 register state */ + unsigned long s7; + /** s8 register state */ + unsigned long s8; + /** s9 register state */ + unsigned long s9; + /** s10 register state */ + unsigned long s10; + /** s11 register state */ + unsigned long s11; + /** t3 register state */ + unsigned long t3; + /** t4 register state */ + unsigned long t4; + /** t5 register state */ + unsigned long t5; + /** t6 register state */ + unsigned long t6; + }; + }; /** mepc register state */ unsigned long mepc; /** mstatus register state */ @@ -199,6 +204,21 @@ struct sbi_trap_regs { unsigned long mstatusH; }; +_Static_assert( + sizeof(((struct sbi_trap_regs *)0)->gprs) == + offsetof(struct sbi_trap_regs, t6) + + sizeof(((struct sbi_trap_regs *)0)->t6), + "struct sbi_trap_regs's layout differs between gprs and named members"); + +#define REG_VAL(idx, regs) ((regs)->gprs[(idx)]) + +#define GET_RS1(insn, regs) REG_VAL(GET_RS1_NUM(insn), regs) +#define GET_RS2(insn, regs) REG_VAL(GET_RS2_NUM(insn), regs) +#define GET_RS1S(insn, regs) REG_VAL(GET_RS1S_NUM(insn), regs) +#define GET_RS2S(insn, regs) REG_VAL(GET_RS2S_NUM(insn), regs) +#define GET_RS2C(insn, regs) REG_VAL(GET_RS2C_NUM(insn), regs) +#define SET_RD(insn, regs, val) (REG_VAL(GET_RD_NUM(insn), regs) = (val)) + /** Representation of trap details */ struct sbi_trap_info { /** cause Trap exception cause */