Skip to content

Commit

Permalink
Merge branch 'refactor-decode' into 'master'
Browse files Browse the repository at this point in the history
Refactor decode

See merge request projectn/nemu!114
  • Loading branch information
sashimi-yzh committed Mar 30, 2021
2 parents e24051f + c812062 commit dc35364
Show file tree
Hide file tree
Showing 10 changed files with 390 additions and 461 deletions.
40 changes: 40 additions & 0 deletions include/cpu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,46 @@ static inline def_DHelper(empty) {}
#define TAB(idx, tab) IDTAB(idx, empty, tab)
#define EMPTY(idx) TAB(idx, inv)

__attribute__((always_inline))
static inline void pattern_decode(const char *str, int len,
uint32_t *key, uint32_t *mask, uint32_t *shift) {
uint32_t __key = 0, __mask = 0, __shift = 0;
#define macro(i) \
if ((i) >= len) goto finish; \
else { \
char c = str[i]; \
if (c != ' ') { \
Assert(c == '0' || c == '1' || c == '?', \
"invalid character '%c' in pattern string", c); \
__key = (__key << 1) | (c == '1' ? 1 : 0); \
__mask = (__mask << 1) | (c == '?' ? 0 : 1); \
__shift = (c == '?' ? __shift + 1 : 0); \
} \
}

#define macro2(i) macro(i); macro((i) + 1)
#define macro4(i) macro2(i); macro2((i) + 2)
#define macro8(i) macro4(i); macro4((i) + 4)
#define macro16(i) macro8(i); macro8((i) + 8)
#define macro32(i) macro16(i); macro16((i) + 16)
#define macro64(i) macro32(i); macro32((i) + 32)
macro64(0);
#undef macro
finish:
*key = __key >> __shift;
*mask = __mask >> __shift;
*shift = __shift;
}

#define def_INSTR_IDTAB(pattern, id, tab) do { \
uint32_t key, mask, shift; \
pattern_decode(pattern, STRLEN(pattern), &key, &mask, &shift); \
if (((get_instr(s) >> shift) & mask) == key) \
{ concat(decode_, id)(s); return concat(table_, tab)(s); } \
} while (0)

#define def_INSTR_TAB(pattern, tab) def_INSTR_IDTAB(pattern, empty, tab)


#define print_Dop(...) IFDEF(CONFIG_DEBUG, snprintf(__VA_ARGS__))
#define print_asm(...) IFDEF(CONFIG_DEBUG, snprintf(log_asmbuf, sizeof(log_asmbuf), __VA_ARGS__))
Expand Down
3 changes: 3 additions & 0 deletions include/macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#define str_temp(x) #x
#define str(x) str_temp(x)

// strlen() for string constant
#define STRLEN(CONST_STR) (sizeof(CONST_STR) - 1)

// macro concatenation
#define concat_temp(x, y) x ## y
#define concat(x, y) concat_temp(x, y)
Expand Down
43 changes: 30 additions & 13 deletions src/isa/riscv64/instr/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

def_all_THelper();

__attribute__((always_inline))
static inline uint32_t get_instr(Decode *s) {
return s->isa.instr.val;
}

// decode operand helper
#define def_DopHelper(name) \
void concat(decode_op_, name) (Decode *s, Operand *op, uint64_t val, bool flag)
Expand All @@ -18,19 +23,31 @@ def_all_THelper();
#include "priv/decode.h"

def_THelper(main) {
switch (s->isa.instr.i.opcode6_2) {
IDTAB(000, I, load) IDTAB(001, fload, fload) IDTAB(003, I, mem_fence)
IDTAB(004, I, op_imm) IDTAB(005, auipc, auipc) IDTAB(006, I, op_imm32)
IDTAB(010, S, store) IDTAB(011, fstore, fstore) IDTAB(013, R, atomic)
IDTAB(014, R, op) IDTAB(015, U, lui) IDTAB(016, R, op32)
IDTAB(020, R4, fmadd_dispatch) IDTAB(021, R4, fmadd_dispatch)
IDTAB(022, R4, fmadd_dispatch) IDTAB(023, R4, fmadd_dispatch)
TAB (024, op_fp)
IDTAB(030, B, branch) IDTAB(031, I, jalr_dispatch) TAB (032, nemu_trap) IDTAB(033, J, jal_dispatch)
IDTAB(034, csr, system)
//IDTAB(036, R, rocc3)
IDTAB(036, R, rt_inv)
}
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 00000 ??", I , load);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 00001 ??", fload , fload);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 00011 ??", I , mem_fence);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 00100 ??", I , op_imm);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 00101 ??", auipc , auipc);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 00110 ??", I , op_imm32);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 01000 ??", S , store);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 01001 ??", fstore, fstore);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 01011 ??", R , atomic);
def_INSTR_IDTAB("0000001 ????? ????? ??? ????? 01100 ??", R , rvm);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 01100 ??", R , op);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 01101 ??", U , lui);
def_INSTR_IDTAB("0000001 ????? ????? ??? ????? 01110 ??", R , rvm32);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 01110 ??", R , op32);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 10000 ??", R4 , fmadd_dispatch);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 10001 ??", R4 , fmadd_dispatch);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 10010 ??", R4 , fmadd_dispatch);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 10011 ??", R4 , fmadd_dispatch);
def_INSTR_TAB ("??????? ????? ????? ??? ????? 10100 ??", op_fp);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 11000 ??", B , branch);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 11001 ??", I , jalr_dispatch);
def_INSTR_TAB ("??????? ????? ????? ??? ????? 11010 ??", nemu_trap);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 11011 ??", J , jal_dispatch);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 11100 ??", csr , system);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 11110 ??", R , rt_inv); // rocc3
return table_inv(s);
};

Expand Down
23 changes: 11 additions & 12 deletions src/isa/riscv64/instr/priv/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@ static inline def_DHelper(csr) {
}

#ifdef CONFIG_DEBUG
def_THelper(priv) {
switch (s->isa.instr.csr.csr) {
TAB(0, ecall) TAB (0x102, sret) TAB (0x105, wfi) TAB (0x120, sfence_vma)
TAB(0x302, mret)
}
return EXEC_ID_inv;
};

def_THelper(system) {
switch (s->isa.instr.i.funct3) {
TAB(0, priv) TAB(1, csrrw) TAB(2, csrrs) TAB(3, csrrc)
TAB(5, csrrwi) TAB(6, csrrsi) TAB(7, csrrci)
}
def_INSTR_TAB("000000000000 ????? 000 ????? ????? ??", ecall);
def_INSTR_TAB("000100000010 ????? 000 ????? ????? ??", sret);
def_INSTR_TAB("000100000101 ????? 000 ????? ????? ??", wfi);
def_INSTR_TAB("000100100000 ????? 000 ????? ????? ??", sfence_vma);
def_INSTR_TAB("001100000010 ????? 000 ????? ????? ??", mret);
def_INSTR_TAB("???????????? ????? 001 ????? ????? ??", csrrw);
def_INSTR_TAB("???????????? ????? 010 ????? ????? ??", csrrs);
def_INSTR_TAB("???????????? ????? 011 ????? ????? ??", csrrc);
def_INSTR_TAB("???????????? ????? 101 ????? ????? ??", csrrwi);
def_INSTR_TAB("???????????? ????? 110 ????? ????? ??", csrrsi);
def_INSTR_TAB("???????????? ????? 111 ????? ????? ??", csrrci);
return EXEC_ID_inv;
};
#endif
43 changes: 23 additions & 20 deletions src/isa/riscv64/instr/rva/decode.h
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
#ifdef CONFIG_DEBUG
def_THelper(atomic) {
uint32_t funct5 = s->isa.instr.r.funct7 >> 2;
int funct3 = s->isa.instr.r.funct3;
assert((funct3 == 2) || (funct3 == 3));
int width = funct3 & 1;
#define pair(x, y) (((x) << 1) | (y))
switch (pair(funct5, width)) {
TAB(pair(0b00000, 0), amoadd_w) TAB(pair(0b00001, 0), amoswap_w)
TAB(pair(0b00010, 0), lr_w) TAB(pair(0b00011, 0), sc_w)
TAB(pair(0b00100, 0), amoxor_w) TAB(pair(0b01000, 0), amoor_w)
TAB(pair(0b01100, 0), amoand_w)
TAB(pair(0b10000, 0), amomin_w) TAB(pair(0b10100, 0), amomax_w)
TAB(pair(0b11000, 0), amominu_w) TAB(pair(0b11100, 0), amomaxu_w)
def_INSTR_TAB("00010 ?? 00000 ????? 011 ????? ????? ??", lr_d);
def_INSTR_TAB("00011 ?? ????? ????? 011 ????? ????? ??", sc_d);
def_INSTR_TAB("00001 ?? ????? ????? 011 ????? ????? ??", amoswap_d);
def_INSTR_TAB("00000 ?? ????? ????? 011 ????? ????? ??", amoadd_d);
def_INSTR_TAB("00100 ?? ????? ????? 011 ????? ????? ??", amoxor_d);
def_INSTR_TAB("01100 ?? ????? ????? 011 ????? ????? ??", amoand_d);
def_INSTR_TAB("01000 ?? ????? ????? 011 ????? ????? ??", amoor_d);
def_INSTR_TAB("10000 ?? ????? ????? 011 ????? ????? ??", amomin_d);
def_INSTR_TAB("10100 ?? ????? ????? 011 ????? ????? ??", amomax_d);
def_INSTR_TAB("11000 ?? ????? ????? 011 ????? ????? ??", amominu_d);
def_INSTR_TAB("11100 ?? ????? ????? 011 ????? ????? ??", amomaxu_d);

def_INSTR_TAB("00010 ?? 00000 ????? 010 ????? ????? ??", lr_w);
def_INSTR_TAB("00011 ?? ????? ????? 010 ????? ????? ??", sc_w);
def_INSTR_TAB("00001 ?? ????? ????? 010 ????? ????? ??", amoswap_w);
def_INSTR_TAB("00000 ?? ????? ????? 010 ????? ????? ??", amoadd_w);
def_INSTR_TAB("00100 ?? ????? ????? 010 ????? ????? ??", amoxor_w);
def_INSTR_TAB("01100 ?? ????? ????? 010 ????? ????? ??", amoand_w);
def_INSTR_TAB("01000 ?? ????? ????? 010 ????? ????? ??", amoor_w);
def_INSTR_TAB("10000 ?? ????? ????? 010 ????? ????? ??", amomin_w);
def_INSTR_TAB("10100 ?? ????? ????? 010 ????? ????? ??", amomax_w);
def_INSTR_TAB("11000 ?? ????? ????? 010 ????? ????? ??", amominu_w);
def_INSTR_TAB("11100 ?? ????? ????? 010 ????? ????? ??", amomaxu_w);

TAB(pair(0b00000, 1), amoadd_d) TAB(pair(0b00001, 1), amoswap_d)
TAB(pair(0b00010, 1), lr_d) TAB(pair(0b00011, 1), sc_d)
TAB(pair(0b00100, 1), amoxor_d) TAB(pair(0b01000, 1), amoor_d)
TAB(pair(0b01100, 1), amoand_d)
TAB(pair(0b10000, 1), amomin_d) TAB(pair(0b10100, 1), amomax_d)
TAB(pair(0b11000, 1), amominu_d) TAB(pair(0b11100, 1), amomaxu_d)
}
#undef pair
return EXEC_ID_inv;
}
#endif
Loading

0 comments on commit dc35364

Please sign in to comment.