rvemu

RISC-V RV32I execution engine
git clone git://mcdim.xyz/revemu.git
Log | Files | Refs

decode.h (4973B)


      1 #ifndef DECODE
      2 #define DECODE
      3 
      4 /*
      5 I-TYPE INSTRUCTION FORMAT
      6 31                  20 19    15 14    12 11      7 6      0
      7 +---------------------+--------+--------+---------+--------+
      8 |      imm[11:0]      |  rs1   | funct3 |   rd    | opcode |
      9 +---------------------+--------+--------+---------+--------+
     10 opcode	 0x13	 0010011  immediates
     11 opcode	 0x33	 0000011  loads
     12 */
     13 
     14 typedef struct {
     15 	uint8_t opcode;
     16 	uint8_t rd, rs1;
     17 	//uint16_t imm;
     18 	int32_t imm;
     19 	uint8_t funct3;
     20 	uint8_t funct7, inimm;
     21 } itype_t;
     22 
     23 /*static inline void
     24 decode_itype(itype_t *i, uint32_t inst)
     25 {
     26 	i->rd =     (uint8_t)((inst >> 7) & 31);
     27 	i->funct3 = (uint8_t)((inst >> 12) & 7);
     28 	i->rs1 =    (uint8_t)((inst >> 15) & 31);
     29 	//i->imm =    (uint16_t)((inst >> 20) & 2047);
     30 	i->imm =    (uint32_t)((inst >> 20) & 0xfff);
     31 
     32 	i->inimm =  (uint8_t)(i->imm & 31);
     33 	i->funct7 = (uint8_t)((i->imm >> 5) & 127);
     34 }*/
     35 static inline void
     36 decode_itype(itype_t *i, uint32_t inst)
     37 {
     38     uint32_t raw_imm = (inst >> 20) & UINT32_C(0xfff);
     39 
     40     i->rd     = (uint8_t)((inst >> 7) & UINT32_C(31));
     41     i->funct3 = (uint8_t)((inst >> 12) & UINT32_C(7));
     42     i->rs1    = (uint8_t)((inst >> 15) & UINT32_C(31));
     43 
     44     i->inimm  = (uint8_t)(raw_imm & UINT32_C(31));
     45     i->funct7 = (uint8_t)((inst >> 25) & UINT32_C(127));
     46 
     47     i->imm = (int32_t)raw_imm;
     48 
     49     if ((raw_imm & UINT32_C(0x800)) != 0u)
     50         i->imm -= INT32_C(0x1000);
     51 }
     52 
     53 
     54 /*
     55 R-TYPE INSTRUCTION FORMAT
     56 31         25 24    20 19    15 14    12 11      7 6      0
     57 +------------+--------+--------+--------+---------+--------+
     58 |   funct7   |  rs2   |  rs1   | funct3 |   rd    | opcode |
     59 +------------+--------+--------+--------+---------+--------+
     60 opcode	 0x33	 0110011 
     61 */
     62 
     63 typedef struct {
     64 	uint8_t opcode;
     65 	uint8_t rd, rs1, rs2;
     66 	uint8_t funct3, funct7;
     67 } rtype_t;
     68 
     69 static inline void
     70 decode_rtype(rtype_t *r, uint32_t inst)
     71 {
     72 	r->rd =     (uint8_t)((inst >> 7) & 31);
     73 	r->funct3 = (uint8_t)((inst >> 12) & 7);
     74 	r->rs1 =    (uint8_t)((inst >> 15) & 31);
     75 	r->rs2 =    (uint8_t)((inst >> 20) & 31);
     76 	r->funct7 = (uint8_t)((inst >> 25) & 127);
     77 }
     78 
     79 /*
     80 S-TYPE INSTRUCTION FORMAT
     81 31         25 24    20 19    15 14    12 11      7 6      0
     82 +------------+--------+--------+--------+---------+--------+
     83 | imm[11:0]  |  rs2   |  rs1   | funct3 |imm[4:0] | opcode |
     84 +------------+--------+--------+--------+---------+--------+
     85 opcode	 0x33	 0100011 
     86 */
     87 
     88 typedef struct {
     89 	uint8_t opcode;
     90 	uint8_t rs1, rs2;
     91 	uint16_t imm;
     92 	uint8_t funct3;
     93 } stype_t;
     94 
     95 static inline void
     96 decode_stype(stype_t *s, uint32_t inst)
     97 {
     98 	uint32_t imm_11_5 = (inst >> 25) & 127;
     99 	uint32_t imm_4_0 = (inst >> 7) & 31;
    100 	s->imm = (uint16_t)((imm_4_0) | (imm_11_5 << 5));
    101 
    102 	s->funct3 = (inst >> 12) & 7;
    103 	s->rs1 = (inst >> 15) & 31;
    104 	s->rs2 = (inst >> 20) & 31;
    105 }
    106 
    107 /*
    108 B-TYPE INSTRUCTION FORMAT
    109 31            25 24    20 19    15 14    12 11         7 6       0
    110 +---------------+--------+--------+--------+------------+--------+
    111 | imm[12|10:5]  |  rs2   |  rs1   | funct3 |imm[4:1|11] | opcode |
    112 +---------------+--------+--------+--------+------------+--------+
    113 opcode	 0x63	 1100011 
    114 */
    115 typedef struct {
    116 	uint8_t opcode;
    117 	uint8_t rs1, rs2;
    118 	int16_t imm;
    119 	uint8_t funct3;
    120 } btype_t;
    121 
    122 static inline void
    123 decode_btype(btype_t *b, uint32_t inst)
    124 {
    125 	uint32_t imm_10_5 = (inst >> 25) & 63;
    126 	uint32_t imm_11 = (inst >> 7) & 1;
    127 	uint32_t imm_4_1 = (inst >> 8) & 15;
    128 	uint32_t imm_12 = (inst >> 31) & 1;
    129 
    130 	uint32_t raw_imm = (imm_12   << 12) | (imm_11   << 11) |
    131 			   (imm_10_5 << 5)  | (imm_4_1  << 1);
    132 	if (raw_imm & (1U << 12))
    133          	raw_imm |= 0xffffe000U;
    134 	b->imm = (int16_t)raw_imm;
    135 
    136 	b->funct3 = (inst >> 12) & 7;
    137 	b->rs1 = (inst >> 15) & 31;
    138 	b->rs2 = (inst >> 20) & 31;
    139 }
    140 
    141 /*
    142 J-TYPE INSTRUCTION FORMAT
    143 31                                    12 11      7 6      0
    144 +---------------------------------------+---------+--------+
    145 |        imm[20|10:1|11|19:12]          |   rd    | opcode |
    146 +---------------------------------------+---------+--------+
    147 opcode	 0x6f   1101111  jal 
    148 */
    149 
    150 typedef struct {
    151 	uint8_t opcode;
    152 	uint8_t rd;
    153 	uint32_t imm;
    154 } jtype_t;
    155 
    156 static inline void
    157 decode_jtype(jtype_t *j, uint32_t inst)
    158 {
    159 	j->rd =     (uint8_t)((inst >> 7) & 0x1f);
    160 
    161 	uint8_t imm_19_12 = (uint8_t)((inst >> 12) & 0xff);
    162 	uint8_t imm_11 = (uint8_t)((inst >> 20) & 1);
    163 	uint16_t imm_10_1 = (uint16_t)((inst >> 21) & 0x3ff);
    164 	uint8_t imm_20 = (uint8_t)((inst >> 31) & 1);
    165 
    166 	j->imm =    (uint32_t)(imm_19_12 | imm_11 | imm_10_1 | imm_20);
    167 }
    168 
    169 /*
    170 U-TYPE INSTRUCTION FORMAT
    171 31                                       11      7 6      0
    172 +---------------------------------------+---------+--------+
    173 |             imm[31:12]                |   rd    | opcode |
    174 +---------------------------------------+---------+--------+
    175 opcode	 0x37	 0110111	lui
    176 opcode	 0x17	 0010111	auipc 
    177 */
    178 
    179 typedef struct {
    180 	uint8_t opcode;
    181 	uint8_t rd;
    182 	uint32_t imm;
    183 } utype_t;
    184 
    185 static inline void
    186 decode_utype(utype_t *u, uint32_t inst)
    187 {
    188 	u->rd =     (uint8_t)((inst >> 7) & 31);
    189 	u->imm =    (uint32_t)((inst >> 12) & 0xfffff);
    190 }
    191 
    192 #endif