diff --git a/include/cpu/decode.h b/include/cpu/decode.h index b7ca534802b0159b87d9e84292f925361c0c8e5e..865fbf245fe1152d47de5deabe831ffaf2e40065 100644 --- a/include/cpu/decode.h +++ b/include/cpu/decode.h @@ -11,10 +11,10 @@ typedef struct { int width; union { uint32_t reg; - rtlreg_t addr; word_t imm; sword_t simm; }; + rtlreg_t *preg; rtlreg_t val; char str[OP_STR_SIZE]; } Operand; @@ -26,7 +26,7 @@ typedef struct { vaddr_t jmp_pc; Operand src1, dest, src2; int width; - rtlreg_t tmp_reg[5]; + rtlreg_t tmp_reg[4]; struct ISADecodeInfo isa; } DecodeExecState; diff --git a/include/isa/x86.h b/include/isa/x86.h index 387dc0e3307522a9684d7eb9ac0df399c8591bd1..4abeafd8d9b3b3de7762abea1e559142f61efd3c 100644 --- a/include/isa/x86.h +++ b/include/isa/x86.h @@ -82,6 +82,9 @@ typedef struct { struct ISADecodeInfo { bool is_operand_size_16; uint8_t ext_opcode; + const rtlreg_t *mbase; + rtlreg_t mbr; + word_t moff; }; #define suffix_char(width) ((width) == 4 ? 'l' : ((width) == 1 ? 'b' : ((width) == 2 ? 'w' : '?'))) diff --git a/include/rtl/pseudo.h b/include/rtl/pseudo.h index 0a15d56daca7cc5c79154bb50f53c739fea796f1..1863d67013a108f2f8e4e26cd6772dfc44495761 100644 --- a/include/rtl/pseudo.h +++ b/include/rtl/pseudo.h @@ -7,28 +7,13 @@ /* RTL pseudo instructions */ -#define make_rtl_compute_imm(name) \ - static inline make_rtl(name ## i, rtlreg_t* dest, const rtlreg_t* src1, sword_t imm) { \ - rtl_li(s, ir, imm); \ - rtl_ ## name (s, dest, src1, ir); \ - } +static inline make_rtl(li, rtlreg_t* dest, const rtlreg_t imm) { + rtl_addi(s, dest, rz, imm); +} -make_rtl_compute_imm(add) -make_rtl_compute_imm(sub) -make_rtl_compute_imm(and) -make_rtl_compute_imm(or) -make_rtl_compute_imm(xor) -make_rtl_compute_imm(shl) -make_rtl_compute_imm(shr) -make_rtl_compute_imm(sar) -make_rtl_compute_imm(mul_lo) -make_rtl_compute_imm(mul_hi) -make_rtl_compute_imm(imul_lo) -make_rtl_compute_imm(imul_hi) -make_rtl_compute_imm(div_q) -make_rtl_compute_imm(div_r) -make_rtl_compute_imm(idiv_q) -make_rtl_compute_imm(idiv_r) +static inline make_rtl(mv, rtlreg_t* dest, const rtlreg_t *src1) { + if (dest != src1) rtl_add(s, dest, src1, rz); +} static inline make_rtl(not, rtlreg_t *dest, const rtlreg_t* src1) { // dest <- ~src1 @@ -50,12 +35,6 @@ static inline make_rtl(sext, rtlreg_t* dest, const rtlreg_t* src1, int width) { } } -static inline make_rtl(setrelopi, uint32_t relop, rtlreg_t *dest, - const rtlreg_t *src1, int imm) { - rtl_li(s, ir, imm); - rtl_setrelop(s, relop, dest, src1, ir); -} - static inline make_rtl(msb, rtlreg_t* dest, const rtlreg_t* src1, int width) { // dest <- src1[width * 8 - 1] // TODO(); diff --git a/include/rtl/rtl.h b/include/rtl/rtl.h index 84dabd788f417cdb7938481415afcb5d742ae508..443d5b0b0e2bc0be8e159a71921dd0c71bfe5443 100644 --- a/include/rtl/rtl.h +++ b/include/rtl/rtl.h @@ -7,14 +7,16 @@ #define id_src2 (&s->src2) #define id_dest (&s->dest) -#define dsrc1 (&id_src1->val) -#define dsrc2 (&id_src2->val) -#define ddest (&id_dest->val) -#define ir (&s->tmp_reg[0]) -#define s0 (&s->tmp_reg[1]) -#define s1 (&s->tmp_reg[2]) -#define t0 (&s->tmp_reg[3]) -#define t1 (&s->tmp_reg[4]) +#define dsrc1 (id_src1->preg) +#define dsrc2 (id_src2->preg) +#define ddest (id_dest->preg) +#define s0 (&s->tmp_reg[0]) +#define s1 (&s->tmp_reg[1]) +#define t0 (&s->tmp_reg[2]) +#define t1 (&s->tmp_reg[3]) + +extern const rtlreg_t rzero; +#define rz (&rzero) #define make_rtl(name, ...) void concat(rtl_, name)(DecodeExecState *s, __VA_ARGS__) diff --git a/src/engine/interpreter/rtl-basic.h b/src/engine/interpreter/rtl-basic.h index 241ef4962c39a1760618fbab8f0ed9e45d66b0e2..3dc5ec02b9169d017229897398817f8fec0e5e95 100644 --- a/src/engine/interpreter/rtl-basic.h +++ b/src/engine/interpreter/rtl-basic.h @@ -6,27 +6,43 @@ /* RTL basic instructions */ -static inline make_rtl(li, rtlreg_t* dest, rtlreg_t imm) { - *dest = imm; -} - -static inline make_rtl(mv, rtlreg_t* dest, const rtlreg_t *src1) { - *dest = *src1; -} - #define make_rtl_compute_reg(name) \ static inline make_rtl(name, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { \ *dest = concat(c_, name) (*src1, *src2); \ } -make_rtl_compute_reg(add) -make_rtl_compute_reg(sub) -make_rtl_compute_reg(and) -make_rtl_compute_reg(or) -make_rtl_compute_reg(xor) -make_rtl_compute_reg(shl) -make_rtl_compute_reg(shr) -make_rtl_compute_reg(sar) +#define make_rtl_compute_imm(name) \ + static inline make_rtl(name ## i, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { \ + *dest = concat(c_, name) (*src1, imm); \ + } + +#define make_rtl_compute_reg_imm(name) \ + make_rtl_compute_reg(name) \ + make_rtl_compute_imm(name) \ + +// compute + +make_rtl_compute_reg_imm(add) +make_rtl_compute_reg_imm(sub) +make_rtl_compute_reg_imm(and) +make_rtl_compute_reg_imm(or) +make_rtl_compute_reg_imm(xor) +make_rtl_compute_reg_imm(shl) +make_rtl_compute_reg_imm(shr) +make_rtl_compute_reg_imm(sar) + +static inline make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, + const rtlreg_t *src1, const rtlreg_t *src2) { + *dest = interpret_relop(relop, *src1, *src2); +} + +static inline make_rtl(setrelopi, uint32_t relop, rtlreg_t *dest, + const rtlreg_t *src1, sword_t imm) { + *dest = interpret_relop(relop, *src1, imm); +} + +// mul/div + make_rtl_compute_reg(mul_lo) make_rtl_compute_reg(mul_hi) make_rtl_compute_reg(imul_lo) @@ -64,12 +80,14 @@ static inline make_rtl(idiv64_r, rtlreg_t* dest, *dest = dividend % divisor; } -static inline make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, int len) { - *dest = vaddr_read(*addr, len); +// memory + +static inline make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, word_t offset, int len) { + *dest = vaddr_read(*addr + offset, len); } -static inline make_rtl(sm, const rtlreg_t* addr, const rtlreg_t* src1, int len) { - vaddr_write(*addr, *src1, len); +static inline make_rtl(sm, const rtlreg_t* addr, word_t offset, const rtlreg_t* src1, int len) { + vaddr_write(*addr + offset, *src1, len); } static inline make_rtl(host_lm, rtlreg_t* dest, const void *addr, int len) { @@ -90,10 +108,7 @@ static inline make_rtl(host_sm, void *addr, const rtlreg_t *src1, int len) { } } -static inline make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, - const rtlreg_t *src1, const rtlreg_t *src2) { - *dest = interpret_relop(relop, *src1, *src2); -} +// control static inline make_rtl(j, vaddr_t target) { s->jmp_pc = target; diff --git a/src/engine/rv64/isa/x86.c b/src/engine/rv64/isa/x86.c index 7815beb133af4f0f497808342211870087c0fa84..ca4dc009826d714003d1ab6b858d09d56ddd4c39 100644 --- a/src/engine/rv64/isa/x86.c +++ b/src/engine/rv64/isa/x86.c @@ -10,17 +10,15 @@ uint8_t reg_ptr2idx(DecodeExecState *s, const rtlreg_t* dest) { return (dest - gpr_start)|0x10;//from x16 to x23 #define CASE(ptr, idx) if (dest == ptr) return idx; + CASE(rz, 0) CASE(s0, 2) CASE(s1, 3) CASE(t0, 4) CASE(t1, 5) - CASE(ir, 6) - CASE(dsrc1, 7) - CASE(dsrc2, 8) - CASE(ddest, 9) - CASE(&id_src1->addr, 10) - CASE(&id_src2->addr, 11) - CASE(&id_dest->addr, 12) + CASE(&id_src1->val, 7) + CASE(&id_src2->val, 8) + CASE(&id_dest->val, 9) + CASE(&s->isa.mbr, 10) CASE(&cpu.CF, 13) CASE(&cpu.OF, 14) CASE(&cpu.ZF, 15) diff --git a/src/engine/rv64/rtl-basic.h b/src/engine/rv64/rtl-basic.h index f91c875d43c145388990528d766bab1f0a12e3ad..b0c391aef27d2acaa691722e83e07da387c2f051 100644 --- a/src/engine/rv64/rtl-basic.h +++ b/src/engine/rv64/rtl-basic.h @@ -5,8 +5,6 @@ /* RTL basic instructions */ -make_rtl(li, rtlreg_t* dest, rtlreg_t imm); -make_rtl(mv, rtlreg_t* dest, const rtlreg_t *src1); make_rtl(add, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); make_rtl(sub, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); make_rtl(and, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); @@ -15,6 +13,17 @@ make_rtl(xor, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); make_rtl(shl, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); make_rtl(shr, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); make_rtl(sar, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); +make_rtl(addi, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(subi, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(andi, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(ori, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(xori, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(shli, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(shri, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(sari, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm); +make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const rtlreg_t *src2); +make_rtl(setrelopi, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const sword_t imm); + make_rtl(mul_lo, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); make_rtl(mul_hi, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); make_rtl(imul_lo, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2); @@ -27,11 +36,12 @@ make_rtl(div64_q, rtlreg_t* dest, const rtlreg_t* src1_hi, const rtlreg_t* src1_ make_rtl(div64_r, rtlreg_t* dest, const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2); make_rtl(idiv64_q, rtlreg_t* dest, const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2); make_rtl(idiv64_r, rtlreg_t* dest, const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2); -make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, int len); -make_rtl(sm, const rtlreg_t* addr, const rtlreg_t* src1, int len); + +make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, const sword_t offset, int len); +make_rtl(sm, const rtlreg_t* addr, const sword_t offset, const rtlreg_t* src1, int len); make_rtl(host_lm, rtlreg_t* dest, const void *addr, int len); make_rtl(host_sm, void *addr, const rtlreg_t *src1, int len); -make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const rtlreg_t *src2); + make_rtl(j, vaddr_t target); make_rtl(jr, rtlreg_t *target); make_rtl(jrelop, uint32_t relop, const rtlreg_t *src1, const rtlreg_t *src2, vaddr_t target); diff --git a/src/engine/rv64/rv64-backend/relop.c b/src/engine/rv64/rv64-backend/relop.c index 36610c42c9156213757f3263dda07d1f492e7f44..66f1210758053403545079c968dd98cc6599f64f 100644 --- a/src/engine/rv64/rv64-backend/relop.c +++ b/src/engine/rv64/rv64-backend/relop.c @@ -1,14 +1,7 @@ -#include #include #include "rv_ins_def.h" -uint8_t reg_ptr2idx(DecodeExecState *s, const rtlreg_t* dest); - -void rv64_relop(DecodeExecState *s, uint32_t relop, - const rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { - uint8_t idx_dest = reg_ptr2idx(s, dest); - uint8_t idx_src1 = reg_ptr2idx(s, src1); - uint8_t idx_src2 = reg_ptr2idx(s, src2); +void rv64_relop(uint32_t relop, uint32_t idx_dest, uint32_t idx_src1, uint32_t idx_src2) { switch (relop) { case RELOP_FALSE: rv64_addi(idx_dest, x0, 0); return; case RELOP_TRUE: rv64_addi(idx_dest, x0, 1); return; diff --git a/src/engine/rv64/rv64-backend/rtl-basic.c b/src/engine/rv64/rv64-backend/rtl-basic.c index f54889a0246013a693c68bc0f0c165f77ee24c8f..e53e04437d50de34f3d764075027519e687bd818 100644 --- a/src/engine/rv64/rv64-backend/rtl-basic.c +++ b/src/engine/rv64/rv64-backend/rtl-basic.c @@ -1,8 +1,7 @@ #include #include "rv_ins_def.h" -void rv64_relop(DecodeExecState *s, uint32_t relop, - const rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2); +void rv64_relop(uint32_t relop, uint32_t idx_dest, uint32_t idx_src1, uint32_t idx_src2); uint8_t reg_ptr2idx(DecodeExecState *s, const rtlreg_t* dest); extern int tran_is_jmp; @@ -11,62 +10,107 @@ static inline void rv64_zextw(uint8_t rd, uint8_t rs) { rv64_and(rd, rs, x24); } -/* RTL basic instructions */ - -make_rtl(li, rtlreg_t* dest, rtlreg_t imm) { - uint8_t idx = reg_ptr2idx(s, dest); +// return true if `imm` can be represented within 12 bits +// else load it to x31, and reture false +static inline bool load_imm(const sword_t imm) { RV_IMM rv_imm = { .val = imm }; uint32_t lui_imm = rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11); - if (lui_imm == 0) { - rv64_addiw(idx, x0, rv_imm.imm_11_0); - } else { - rv64_lui(idx, lui_imm); - rv64_addiw(idx, idx, rv_imm.imm_11_0); + if (lui_imm == 0) return true; + else { + rv64_lui(x31, lui_imm); + if (rv_imm.imm_11_0 != 0) rv64_addiw(x31, x31, rv_imm.imm_11_0); + return false; } } -make_rtl(mv, rtlreg_t* dest, const rtlreg_t *src1) { - uint8_t idx_dest = reg_ptr2idx(s, dest); - uint8_t idx_src1 = reg_ptr2idx(s, src1); - if (dest != src1) rv64_addiw(idx_dest, idx_src1, 0); -} - -#define rv64_shlw rv64_sllw -#define rv64_shrw rv64_srlw -#define rv64_sarw rv64_sraw -#define rv64_mul_lo rv64_mulw -#define rv64_imul_lo rv64_mulw -#define rv64_div_q rv64_divuw -#define rv64_div_r rv64_remuw -#define rv64_idiv_q rv64_divw -#define rv64_idiv_r rv64_remw - -#define make_rtl_arith_logic_w(name) \ - make_rtl(name, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { \ - concat3(rv64_, name, w) (reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), reg_ptr2idx(s, src2)); \ +/* RTL basic instructions */ + +#define make_rtl_compute_reg(rtl_name, rv64_name) \ + make_rtl(rtl_name, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { \ + concat(rv64_, rv64_name) (reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), reg_ptr2idx(s, src2)); \ + } + +#define make_rtl_compute_imm(rtl_name, rv64_name) \ + make_rtl(rtl_name, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { \ + concat(rv64_, rv64_name) (reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); \ } -#define make_rtl_arith_logic(name) \ - make_rtl(name, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { \ - concat(rv64_, name) (reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), reg_ptr2idx(s, src2)); \ +make_rtl_compute_reg(and, and) +make_rtl_compute_reg(or, or) +make_rtl_compute_reg(xor, xor) + +make_rtl(addi, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { + if (load_imm(imm)) rv64_addiw(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); + else rv64_addw(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), x31); +} + +make_rtl(subi, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { + rtl_addi(s, dest, src1, -imm); +} + +make_rtl(andi, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { + if (load_imm(imm)) rv64_andi(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); + else rv64_and(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), x31); +} + +make_rtl(xori, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { + if (load_imm(imm)) rv64_xori(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); + else rv64_xor(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), x31); +} + +make_rtl(ori, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { + if (load_imm(imm)) rv64_ori(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); + else rv64_or(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), x31); +} + +#ifdef ISA64 +make_rtl_compute_reg(add, add) +make_rtl_compute_reg(sub, sub) +make_rtl_compute_reg(shl, sll) +make_rtl_compute_reg(shr, srl) +make_rtl_compute_reg(sar, sra) +make_rtl_compute_imm(shli, slli) +make_rtl_compute_imm(shri, srli) +make_rtl_compute_imm(sari, srai) +#else +make_rtl_compute_reg(add, addw) +make_rtl_compute_reg(sub, subw) +make_rtl_compute_reg(shl, sllw) +make_rtl_compute_reg(shr, srlw) +make_rtl_compute_reg(sar, sraw) +make_rtl_compute_imm(shli, slliw) +make_rtl_compute_imm(shri, srliw) +make_rtl_compute_imm(sari, sraiw) +#endif + +make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const rtlreg_t *src2) { + rv64_relop(relop, reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), reg_ptr2idx(s, src2)); +} + +make_rtl(setrelopi, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const sword_t imm) { + int small_imm = load_imm(imm); + uint32_t idx_dest = reg_ptr2idx(s, dest); + uint32_t idx_src1 = reg_ptr2idx(s, src1); + if (small_imm && (relop == RELOP_LT || relop == RELOP_LTU)) { + switch (relop) { + case RELOP_LT: rv64_slt(idx_dest, idx_src1, imm); return; + case RELOP_LTU: rv64_sltu(idx_dest, idx_src1, imm); return; + // fall through for default cases + } } + rv64_addiw(x31, x0, imm); + rv64_relop(relop, idx_dest, idx_src1, x31); +} + -make_rtl_arith_logic_w(add) -make_rtl_arith_logic_w(sub) -make_rtl_arith_logic(and) -make_rtl_arith_logic(or) -make_rtl_arith_logic(xor) -make_rtl_arith_logic_w(shl) -make_rtl_arith_logic_w(shr) -make_rtl_arith_logic_w(sar) -make_rtl_arith_logic(mul_lo) //make_rtl_arith_logic(mul_hi) -make_rtl_arith_logic(imul_lo) //make_rtl_arith_logic(imul_hi) -make_rtl_arith_logic(div_q) -make_rtl_arith_logic(div_r) -make_rtl_arith_logic(idiv_q) -make_rtl_arith_logic(idiv_r) +make_rtl_compute_reg(mul_lo, mulw) +make_rtl_compute_reg(imul_lo, mulw) +make_rtl_compute_reg(div_q, divuw) +make_rtl_compute_reg(div_r, remuw) +make_rtl_compute_reg(idiv_q, divw) +make_rtl_compute_reg(idiv_r, remw) #ifdef ISA64 # define rv64_mul_hi(c, a, b) TODO() @@ -145,28 +189,46 @@ make_rtl(idiv64_r, rtlreg_t* dest, rv64_rem(idx_dest, x30, idx_src2); } -make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, int len) { +make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, const sword_t imm, int len) { uint8_t idx_dest = reg_ptr2idx(s, dest); uint8_t idx_addr = reg_ptr2idx(s, addr); - rv64_zextw(x31, idx_addr); + + RV_IMM rv_imm = { .val = imm }; + uint32_t lui_imm = rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11); + if (lui_imm != 0) { + rv64_lui(x31, lui_imm); + rv64_add(x31, x31, idx_addr); + rv64_zextw(x31, x31); + } else { + rv64_zextw(x31, idx_addr); + } switch (len) { - case 1: rv64_lbu(idx_dest, x31, 0); break; - case 2: rv64_lhu(idx_dest, x31, 0); break; - case 4: rv64_lwu(idx_dest, x31, 0); break; - case 8: rv64_ld (idx_dest, x31, 0); break; + case 1: rv64_lbu(idx_dest, x31, imm & 0xfff); break; + case 2: rv64_lhu(idx_dest, x31, imm & 0xfff); break; + case 4: rv64_lwu(idx_dest, x31, imm & 0xfff); break; + case 8: rv64_ld (idx_dest, x31, imm & 0xfff); break; default: assert(0); } } -make_rtl(sm, const rtlreg_t* addr, const rtlreg_t* src1, int len) { +make_rtl(sm, const rtlreg_t* addr, const sword_t imm, const rtlreg_t* src1, int len) { uint8_t idx_addr = reg_ptr2idx(s, addr); uint8_t idx_src1 = reg_ptr2idx(s, src1); - rv64_zextw(x31, idx_addr); + + RV_IMM rv_imm = { .val = imm }; + uint32_t lui_imm = rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11); + if (lui_imm != 0) { + rv64_lui(x31, lui_imm); + rv64_add(x31, x31, idx_addr); + rv64_zextw(x31, x31); + } else { + rv64_zextw(x31, idx_addr); + } switch (len) { - case 1: rv64_sb(x31, idx_src1, 0); break; - case 2: rv64_sh(x31, idx_src1, 0); break; - case 4: rv64_sw(x31, idx_src1, 0); break; - case 8: rv64_sd(x31, idx_src1, 0); break; + case 1: rv64_sb(x31, idx_src1, imm & 0xfff); break; + case 2: rv64_sh(x31, idx_src1, imm & 0xfff); break; + case 4: rv64_sw(x31, idx_src1, imm & 0xfff); break; + case 8: rv64_sd(x31, idx_src1, imm & 0xfff); break; default: assert(0); } } @@ -229,14 +291,10 @@ make_rtl(host_sm, void *addr, const rtlreg_t *src1, int len) { } } -make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const rtlreg_t *src2) { - rv64_relop(s, relop, dest, src1, src2); -} - // we use x30 to store x86.pc of the next basic block make_rtl(j, vaddr_t target) { - rtl_li(s, ir, target); - rv64_addi(x30, reg_ptr2idx(s, ir), 0); + if (load_imm(target)) rv64_addiw(x31, x31, target & 0xfff); + rv64_addi(x30, x31, 0); tran_is_jmp = true; } @@ -246,10 +304,10 @@ make_rtl(jr, rtlreg_t *target) { } make_rtl(jrelop, uint32_t relop, const rtlreg_t *src1, const rtlreg_t *src2, vaddr_t target) { - rtl_setrelop(s, relop, ddest, src1, src2); - rtl_li(s, dsrc1, target); - rtl_li(s, dsrc2, s->seq_pc); - rtl_mux(s, ddest, ddest, dsrc1, dsrc2); - rv64_addi(x30, reg_ptr2idx(s, ddest), 0); + rtl_setrelop(s, relop, &id_dest->val, src1, src2); + rtl_li(s, &id_src1->val, target); + rtl_li(s, &id_src2->val, s->seq_pc); + rtl_mux(s, &id_dest->val, &id_dest->val, &id_src1->val, &id_src2->val); + rv64_addi(x30, reg_ptr2idx(s, &id_dest->val), 0); tran_is_jmp = true; } diff --git a/src/engine/rv64/rv64-backend/rv_ins_def.h b/src/engine/rv64/rv64-backend/rv_ins_def.h index c4a8d256b55153b1c766046c51724bebe468d3f2..440133a0b160c2ae0ac17960534772114f36a6fc 100644 --- a/src/engine/rv64/rv64-backend/rv_ins_def.h +++ b/src/engine/rv64/rv64-backend/rv_ins_def.h @@ -193,7 +193,7 @@ enum { x0 = 0, x24 = 24, x25, x26, x27, x28, x29, x30, x31 }; #define rv64_slti(rd, rs1, imm) gen_rv64_I_inst(0b0010011, rd, 0b010, rs1, imm) #define rv64_sltiu(rd, rs1, imm) gen_rv64_I_inst(0b0010011, rd, 0b011, rs1, imm) #define rv64_xori(rd, rs1, imm) gen_rv64_I_inst(0b0010011, rd, 0b100, rs1, imm) -#define rv64_xoi(rd, rs1, imm) gen_rv64_I_inst(0b0010011, rd, 0b110, rs1, imm) +#define rv64_ori(rd, rs1, imm) gen_rv64_I_inst(0b0010011, rd, 0b110, rs1, imm) #define rv64_andi(rd, rs1, imm) gen_rv64_I_inst(0b0010011, rd, 0b111, rs1, imm) #define rv64_slli(rd, rs1, shamt) gen_rv64_R64_inst(0b0010011, rd, 0b001, rs1, shamt, 0b000000) #define rv64_srli(rd, rs1, shamt) gen_rv64_R64_inst(0b0010011, rd, 0b101, rs1, shamt, 0b000000) diff --git a/src/engine/rv64/tran.c b/src/engine/rv64/tran.c index e22aa41ad489a3d394e0b31462900706b0c26499..068dfa6c7527f0f1faba2c553a6f5a13a9fde898 100644 --- a/src/engine/rv64/tran.c +++ b/src/engine/rv64/tran.c @@ -22,6 +22,7 @@ void write_ins(uint32_t ins) { void mainloop() { nemu_state.state = NEMU_RUNNING; + uint64_t total_instr = 0; while (1) { __attribute__((unused)) vaddr_t ori_pc = cpu.pc; __attribute__((unused)) vaddr_t seq_pc = isa_exec_once(); @@ -34,6 +35,7 @@ void mainloop() { if (tran_is_jmp) { #endif vaddr_t next_pc = rv64_exec_trans_buffer(trans_buffer, trans_buffer_index); + total_instr += trans_buffer_index; if (tran_is_jmp) cpu.pc = next_pc; // Log("new basic block pc = %x", cpu.pc); clear_trans_buffer(); @@ -61,4 +63,6 @@ void mainloop() { nemu_state.halt_pc); if (nemu_state.state == NEMU_ABORT) abort(); } + + Log("#(rv64 instr) = %ld\n", total_instr); } diff --git a/src/isa/mips32/exec/compute.h b/src/isa/mips32/exec/compute.h index e8700fb18b84a35951acc81b17baa4ca6aa1aabd..ff55a381d6b6d0a2ebd4d205cedfbbb97619c211 100644 --- a/src/isa/mips32/exec/compute.h +++ b/src/isa/mips32/exec/compute.h @@ -1,98 +1,115 @@ static inline make_EHelper(lui) { - rtl_shli(s, s0, dsrc2, 16); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_li(s, ddest, id_src2->imm << 16); print_asm_template3(lui); } static inline make_EHelper(add) { - rtl_add(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_add(s, ddest, dsrc1, dsrc2); print_asm_template3(add); } static inline make_EHelper(sub) { - rtl_sub(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_sub(s, ddest, dsrc1, dsrc2); print_asm_template3(sub); } static inline make_EHelper(slt) { - rtl_setrelop(s, RELOP_LT, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_setrelop(s, RELOP_LT, ddest, dsrc1, dsrc2); print_asm_template3(slt); } static inline make_EHelper(sltu) { - rtl_setrelop(s, RELOP_LTU, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_setrelop(s, RELOP_LTU, ddest, dsrc1, dsrc2); print_asm_template3(sltu); } static inline make_EHelper(and) { - rtl_and(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_and(s, ddest, dsrc1, dsrc2); print_asm_template3(and); } static inline make_EHelper(or) { - rtl_or(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_or(s, ddest, dsrc1, dsrc2); print_asm_template3(or); } static inline make_EHelper(xor) { - rtl_xor(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_xor(s, ddest, dsrc1, dsrc2); print_asm_template3(xor); } static inline make_EHelper(nor) { rtl_or(s, s0, dsrc1, dsrc2); - rtl_not(s, s0, s0); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_not(s, ddest, s0); print_asm_template3(nor); } static inline make_EHelper(sll) { - rtl_shl(s, s0, dsrc2, dsrc1); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_shl(s, ddest, dsrc2, dsrc1); print_asm_template3(sll); } static inline make_EHelper(srl) { - rtl_shr(s, s0, dsrc2, dsrc1); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_shr(s, ddest, dsrc2, dsrc1); print_asm_template3(srl); } static inline make_EHelper(sra) { - rtl_sar(s, s0, dsrc2, dsrc1); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_sar(s, ddest, dsrc2, dsrc1); print_asm_template3(sra); } -static inline make_EHelper(movz) { - rtl_mux(s, s0, dsrc2, ddest, dsrc1); - rtl_sr(s, id_dest->reg, s0, 4); +static inline make_EHelper(addi) { + rtl_addi(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(addi); +} + +static inline make_EHelper(slti) { + rtl_setrelopi(s, RELOP_LT, ddest, dsrc1, id_src2->imm); + print_asm_template3(slti); +} +static inline make_EHelper(sltui) { + rtl_setrelopi(s, RELOP_LTU, ddest, dsrc1, id_src2->imm); + print_asm_template3(sltui); +} + +static inline make_EHelper(andi) { + rtl_andi(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(andi); +} + +static inline make_EHelper(ori) { + rtl_ori(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(ori); +} + +static inline make_EHelper(xori) { + rtl_xori(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(xori); +} + +static inline make_EHelper(slli) { + rtl_shli(s, ddest, dsrc2, id_src1->imm); + print_asm_template3(slli); +} + +static inline make_EHelper(srli) { + rtl_shri(s, ddest, dsrc2, id_src1->imm); + print_asm_template3(srli); +} + +static inline make_EHelper(srai) { + rtl_sari(s, ddest, dsrc2, id_src1->imm); + print_asm_template3(srai); +} + +static inline make_EHelper(movz) { + rtl_mux(s, ddest, dsrc2, ddest, dsrc1); print_asm_template3(movz); } static inline make_EHelper(movn) { - rtl_mux(s, s0, dsrc2, dsrc1, ddest); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_mux(s, ddest, dsrc2, dsrc1, ddest); print_asm_template3(movn); } diff --git a/src/isa/mips32/exec/control.h b/src/isa/mips32/exec/control.h index 9c4c360d7dd92c56c70e1d54e4c5d4bf08c0cc00..200133de5d58521d313ec2ddf092700a28c06c13 100644 --- a/src/isa/mips32/exec/control.h +++ b/src/isa/mips32/exec/control.h @@ -6,86 +6,64 @@ static inline void difftest_skip_delay_slot(void) { static inline make_EHelper(j) { difftest_skip_delay_slot(); - rtl_j(s, s->jmp_pc); - print_asm_template1(j); } static inline make_EHelper(jal) { difftest_skip_delay_slot(); - - rtl_addi(s, s0, &cpu.pc, 8); - rtl_sr(s, 31, s0, 4); + word_t ra = cpu.pc + 8; rtl_j(s, s->jmp_pc); - + rtl_li(s, ®_l(31), ra); print_asm_template1(jal); } static inline make_EHelper(jr) { difftest_skip_delay_slot(); - rtl_jr(s, dsrc1); - print_asm_template2(jr); } static inline make_EHelper(jalr) { difftest_skip_delay_slot(); - - rtl_addi(s, s0, &cpu.pc, 8); - rtl_sr(s, id_dest->reg, s0, 4); + word_t ra = cpu.pc + 8; rtl_jr(s, dsrc1); - + rtl_li(s, ddest, ra); print_asm_template2(jalr); } static inline make_EHelper(bne) { difftest_skip_delay_slot(); - rtl_jrelop(s, RELOP_NE, dsrc1, dsrc2, s->jmp_pc); - print_asm_template3(bne); } static inline make_EHelper(beq) { difftest_skip_delay_slot(); - rtl_jrelop(s, RELOP_EQ, dsrc1, dsrc2, s->jmp_pc); - print_asm_template3(beq); } static inline make_EHelper(blez) { difftest_skip_delay_slot(); - rtl_jrelop(s, RELOP_LE, dsrc1, dsrc2, s->jmp_pc); - print_asm_template3(blez); } static inline make_EHelper(bltz) { difftest_skip_delay_slot(); - - rtl_li(s, s0, 0); - rtl_jrelop(s, RELOP_LT, dsrc1, s0, s->jmp_pc); - + rtl_jrelop(s, RELOP_LT, dsrc1, rz, s->jmp_pc); print_asm_template3(bltz); } static inline make_EHelper(bgtz) { difftest_skip_delay_slot(); - rtl_jrelop(s, RELOP_GT, dsrc1, dsrc2, s->jmp_pc); - print_asm_template3(blez); } static inline make_EHelper(bgez) { difftest_skip_delay_slot(); - - rtl_li(s, s0, 0); - rtl_jrelop(s, RELOP_GE, dsrc1, s0, s->jmp_pc); - + rtl_jrelop(s, RELOP_GE, dsrc1, rz, s->jmp_pc); print_asm_template3(bltz); } diff --git a/src/isa/mips32/exec/exec.c b/src/isa/mips32/exec/exec.c index 60a03e5384a27a7622a001571c65f4895baf40bd..1f3f3afd205aac448cbf9a99b8226d631a39fe3f 100644 --- a/src/isa/mips32/exec/exec.c +++ b/src/isa/mips32/exec/exec.c @@ -20,7 +20,7 @@ static inline void set_width(DecodeExecState *s, int width) { static inline make_EHelper(special) { switch (s->isa.instr.r.func) { - IDEX (000, shift, sll) IDEX (002, shift, srl) IDEX (003, shift, sra) + IDEX (000, shift, slli) IDEX (002, shift, srli)IDEX (003, shift, srai) IDEX (004, R, sll) IDEX (006, R, srl) IDEX (007, R, sra) IDEX (010, R, jr) IDEX (011, R, jalr) IDEX (012, cmov, movz) IDEX (013, cmov, movn) EX (014, syscall) @@ -72,8 +72,8 @@ static inline void exec(DecodeExecState *s) { switch (s->isa.instr.r.opcode) { EX (000, special) EX (001, regimm) IDEX (002, J, j) IDEX (003, J, jal) IDEX (004, B, beq) IDEX (005, B, bne) IDEX (006, B, blez) IDEX (007, B, bgtz) - IDEX (011, I, add) IDEX (012, I, slt) IDEX (013, I, sltu) - IDEX (014, IU, and) IDEX (015, IU, or) IDEX (016, IU, xor) IDEX (017, IU, lui) + IDEX (011, I, addi) IDEX (012, I, slti) IDEX (013, I, sltui) + IDEX (014, IU, andi) IDEX (015, IU, ori) IDEX (016, IU, xori) IDEX (017, IU, lui) EX (020, cop0) diff --git a/src/isa/mips32/exec/ldst.h b/src/isa/mips32/exec/ldst.h index a07ee10fe37b02ed1540fd595a0dd1e6b0d4551b..b2c9d1a01a73da1448ec185f54b584d4d75e7224 100644 --- a/src/isa/mips32/exec/ldst.h +++ b/src/isa/mips32/exec/ldst.h @@ -1,10 +1,11 @@ #include "../local-include/intr.h" static inline make_EHelper(ld) { - rtl_lm(s, s0, &id_src1->addr, s->width); + rtl_lm(s, s0, dsrc1, id_src2->imm, s->width); check_mem_ex(); rtl_sr(s, id_dest->reg, s0, 4); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); switch (s->width) { case 4: print_asm_template2(lw); break; case 2: print_asm_template2(lhu); break; @@ -15,11 +16,11 @@ static inline make_EHelper(ld) { // load sign value static inline make_EHelper(lds) { - rtl_lm(s, s0, &id_src1->addr, s->width); + rtl_lm(s, s0, dsrc1, id_src2->imm, s->width); check_mem_ex(); - rtl_sext(s, s0, s0, s->width); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_sext(s, ddest, s0, s->width); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); switch (s->width) { case 2: print_asm_template2(lh); break; case 1: print_asm_template2(lb); break; @@ -28,9 +29,10 @@ static inline make_EHelper(lds) { } static inline make_EHelper(st) { - rtl_sm(s, &id_src1->addr, ddest, s->width); + rtl_sm(s, dsrc1, id_src2->imm, ddest, s->width); check_mem_ex(); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); switch (s->width) { case 4: print_asm_template2(sw); break; case 2: print_asm_template2(sh); break; @@ -39,10 +41,12 @@ static inline make_EHelper(st) { } } +// we do not use pseudo-rtl here, so we can use t0/t1 safely static inline make_EHelper(swl) { // int reg_right_shift_amount [] = {24, 16, 8, 0}; // (3 - n) << 3 - rtl_not(s, s0, &id_src1->addr); + rtl_addi(s, t0, dsrc1, id_src2->imm); // t0 = addr + rtl_not(s, s0, t0); rtl_andi(s, s0, s0, 0x3); rtl_shli(s, s0, s0, 3); // prepare register data @@ -54,8 +58,8 @@ static inline make_EHelper(swl) { rtl_sar(s, s1, s1, s0); rtl_shli(s, s1, s1, 1); // load the aligned memory word - rtl_andi(s, &id_src1->addr, &id_src1->addr, ~0x3u); - rtl_lm(s, s0, &id_src1->addr, 4); + rtl_andi(s, t0, t0, ~0x3u); + rtl_lm(s, s0, t0, 0, 4); check_mem_ex(); // prepare memory data rtl_and(s, s0, s0, s1); @@ -64,16 +68,18 @@ static inline make_EHelper(swl) { rtl_or(s, s0, s0, ddest); // write back - rtl_sm(s, &id_src1->addr, s0, 4); + rtl_sm(s, t0, 0, s0, 4); check_mem_ex(); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); print_asm_template2(swl); } static inline make_EHelper(swr) { // int reg_left_shift_amount [] = {0, 8, 16, 24}; // n << 3 - rtl_andi(s, s0, &id_src1->addr, 0x3); + rtl_addi(s, t0, dsrc1, id_src2->imm); // t0 = addr + rtl_andi(s, s0, t0, 0x3); rtl_shli(s, s0, s0, 3); // prepare register data rtl_shl(s, ddest, ddest, s0); @@ -84,8 +90,8 @@ static inline make_EHelper(swr) { rtl_shl(s, s1, s1, s0); rtl_not(s, s1, s1); // load the aligned memory word - rtl_andi(s, &id_src1->addr, &id_src1->addr, ~0x3u); - rtl_lm(s, s0, &id_src1->addr, 4); + rtl_andi(s, t0, t0, ~0x3u); + rtl_lm(s, s0, t0, 0, 4); check_mem_ex(); // prepare memory data rtl_and(s, s0, s0, s1); @@ -94,16 +100,18 @@ static inline make_EHelper(swr) { rtl_or(s, s0, s0, ddest); // write back - rtl_sm(s, &id_src1->addr, s0, 4); + rtl_sm(s, t0, 0, s0, 4); check_mem_ex(); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); print_asm_template2(swr); } static inline make_EHelper(lwl) { // int mem_left_shift_amount [] = {24, 16, 8, 0}; // (3 - n) << 3 - rtl_not(s, s0, &id_src1->addr); + rtl_addi(s, t0, dsrc1, id_src2->imm); // t0 = addr + rtl_not(s, s0, t0); rtl_andi(s, s0, s0, 0x3); rtl_shli(s, s0, s0, 3); @@ -116,8 +124,8 @@ static inline make_EHelper(lwl) { rtl_and(s, ddest, ddest, s1); // load the aligned memory word - rtl_andi(s, &id_src1->addr, &id_src1->addr, ~0x3u); - rtl_lm(s, s1, &id_src1->addr, 4); + rtl_andi(s, t0, t0, ~0x3u); + rtl_lm(s, s1, t0, 0, 4); check_mem_ex(); // prepare memory data rtl_shl(s, s1, s1, s0); @@ -128,13 +136,15 @@ static inline make_EHelper(lwl) { // write back rtl_sr(s, id_dest->reg, ddest, 4); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); print_asm_template2(lwl); } static inline make_EHelper(lwr) { // int mem_right_shift_amount [] = {0, 8, 16, 24}; // n << 3 - rtl_andi(s, s0, &id_src1->addr, 0x3); + rtl_addi(s, t0, dsrc1, id_src2->imm); // t0 = addr + rtl_andi(s, s0, t0, 0x3); rtl_shli(s, s0, s0, 3); // int reg_mask [] = {0x0, 0xff000000, 0xffff0000, 0xffffff00}; @@ -146,8 +156,8 @@ static inline make_EHelper(lwr) { rtl_and(s, ddest, ddest, s1); // load the aligned memory word - rtl_andi(s, &id_src1->addr, &id_src1->addr, ~0x3u); - rtl_lm(s, s1, &id_src1->addr, 4); + rtl_andi(s, t0, t0, ~0x3u); + rtl_lm(s, s1, t0, 0, 4); check_mem_ex(); // prepare memory data rtl_shr(s, s1, s1, s0); @@ -158,5 +168,6 @@ static inline make_EHelper(lwr) { // write back rtl_sr(s, id_dest->reg, ddest, 4); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); print_asm_template2(lwr); } diff --git a/src/isa/mips32/exec/muldiv.h b/src/isa/mips32/exec/muldiv.h index f7d6146c0bcf99900e5ddcf16a323bbc0072e12f..d8bd436f2785059694a2818db708f2b8bfe3b355 100644 --- a/src/isa/mips32/exec/muldiv.h +++ b/src/isa/mips32/exec/muldiv.h @@ -1,58 +1,48 @@ static inline make_EHelper(mfhi) { - rtl_sr(s, id_dest->reg, &cpu.hi, 4); - + rtl_mv(s, ddest, &cpu.hi); print_asm_template3(mfhi); } static inline make_EHelper(mflo) { - rtl_sr(s, id_dest->reg, &cpu.lo, 4); - + rtl_mv(s, ddest, &cpu.lo); print_asm_template3(mflo); } static inline make_EHelper(mthi) { rtl_mv(s, &cpu.hi, dsrc1); - print_asm_template2(mthi); } static inline make_EHelper(mtlo) { rtl_mv(s, &cpu.lo, dsrc1); - print_asm_template2(mtlo); } static inline make_EHelper(mul) { - rtl_imul_lo(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_imul_lo(s, ddest, dsrc1, dsrc2); print_asm_template3(mul); } static inline make_EHelper(mult) { rtl_imul_lo(s, &cpu.lo, dsrc1, dsrc2); rtl_imul_hi(s, &cpu.hi, dsrc1, dsrc2); - print_asm_template3(mult); } static inline make_EHelper(multu) { rtl_mul_lo(s, &cpu.lo, dsrc1, dsrc2); rtl_mul_hi(s, &cpu.hi, dsrc1, dsrc2); - print_asm_template3(multu); } static inline make_EHelper(div) { rtl_idiv_q(s, &cpu.lo, dsrc1, dsrc2); rtl_idiv_r(s, &cpu.hi, dsrc1, dsrc2); - print_asm_template3(div); } static inline make_EHelper(divu) { rtl_div_q(s, &cpu.lo, dsrc1, dsrc2); rtl_div_r(s, &cpu.hi, dsrc1, dsrc2); - print_asm_template3(divu); } diff --git a/src/isa/mips32/exec/system.h b/src/isa/mips32/exec/system.h index c7530c5ddd55f366c83a988c848c678e03c5cb7f..1e9e8a0a20d287af94e8aa22381614334d51a9d9 100644 --- a/src/isa/mips32/exec/system.h +++ b/src/isa/mips32/exec/system.h @@ -2,15 +2,12 @@ static inline make_EHelper(syscall) { raise_intr(s, EX_SYSCALL, cpu.pc); - print_asm("syscall"); } static inline make_EHelper(eret) { - rtl_li(s, s0, cpu.epc); - rtl_jr(s, s0); + rtl_j(s, cpu.epc); cpu.status.exl = 0; - print_asm("eret"); } @@ -30,19 +27,18 @@ static inline make_EHelper(mfc0) { default: assert(0); } - rtl_li(s, s0, val); - rtl_sr(s, id_src2->reg, s0, 4); + rtl_li(s, dsrc2, val); } static inline make_EHelper(mtc0) { switch (id_dest->reg) { - case 0: cpu.index = id_src2->val; print_asm("mtc0 %s, index", id_src2->str); break; - case 2: cpu.entrylo0 = id_src2->val; print_asm("mtc0 %s, entrylo0", id_src2->str); break; - case 3: cpu.entrylo1 = id_src2->val; print_asm("mtc0 %s, entrylo1", id_src2->str); break; - case 10: cpu.entryhi.val = id_src2->val & ~0x1f00; print_asm("mtc0 %s, entryhi", id_src2->str); break; - case 12: cpu.status.val = id_src2->val; print_asm("mtc0 %s, status", id_src2->str); break; - case 13: cpu.cause = id_src2->val; print_asm("mtc0 %s, cause", id_src2->str); break; - case 14: cpu.epc = id_src2->val; print_asm("mtc0 %s, epc", id_src2->str); break; + case 0: cpu.index = *dsrc2; print_asm("mtc0 %s, index", id_src2->str); break; + case 2: cpu.entrylo0 = *dsrc2; print_asm("mtc0 %s, entrylo0", id_src2->str); break; + case 3: cpu.entrylo1 = *dsrc2; print_asm("mtc0 %s, entrylo1", id_src2->str); break; + case 10: cpu.entryhi.val = *dsrc2 & ~0x1f00; print_asm("mtc0 %s, entryhi", id_src2->str); break; + case 12: cpu.status.val = *dsrc2; print_asm("mtc0 %s, status", id_src2->str); break; + case 13: cpu.cause = *dsrc2; print_asm("mtc0 %s, cause", id_src2->str); break; + case 14: cpu.epc = *dsrc2; print_asm("mtc0 %s, epc", id_src2->str); break; default: assert(0); } } diff --git a/src/isa/mips32/local-include/decode.h b/src/isa/mips32/local-include/decode.h index 662ecd3d0bc9e4c605f45398f4c0ad9d5b4fc6d0..fdb94aae7412a5e4e184552be5cefc4b08a5f72e 100644 --- a/src/isa/mips32/local-include/decode.h +++ b/src/isa/mips32/local-include/decode.h @@ -8,7 +8,6 @@ static inline make_DopHelper(i) { op->type = OP_TYPE_IMM; op->imm = val; - rtl_li(s, &op->val, op->imm); print_Dop(op->str, OP_STR_SIZE, "%d", op->imm); } @@ -16,9 +15,8 @@ static inline make_DopHelper(i) { static inline make_DopHelper(r) { op->type = OP_TYPE_REG; op->reg = val; - if (load_val) { - rtl_lr(s, &op->val, op->reg, 4); - } + op->preg = ®_l(val); + reg_l(0) = 0; print_Dop(op->str, OP_STR_SIZE, "%s", reg_name(op->reg, 4)); } @@ -39,9 +37,7 @@ static inline make_DHelper(IU) { static inline make_DHelper(J) { vaddr_t target = (cpu.pc & 0xf0000000) | (s->isa.instr.j.target << 2); - decode_op_i(s, id_dest, target, true); s->jmp_pc = target; - print_Dop(id_dest->str, OP_STR_SIZE, "0x%x", s->jmp_pc); } @@ -51,22 +47,15 @@ static inline make_DHelper(R) { decode_op_r(s, id_dest, s->isa.instr.r.rd, false); } -static inline make_DHelper(addr) { +static inline make_DHelper(ld) { decode_op_r(s, id_src1, s->isa.instr.i.rs, true); decode_op_i(s, id_src2, s->isa.instr.i.simm, true); - - print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->val, reg_name(id_src1->reg, 4)); - - rtl_add(s, &id_src1->addr, dsrc1, dsrc2); -} - -static inline make_DHelper(ld) { - decode_addr(s); decode_op_r(s, id_dest, s->isa.instr.i.rt, false); } static inline make_DHelper(st) { - decode_addr(s); + decode_op_r(s, id_src1, s->isa.instr.i.rs, true); + decode_op_i(s, id_src2, s->isa.instr.i.simm, true); decode_op_r(s, id_dest, s->isa.instr.i.rt, true); } @@ -77,7 +66,6 @@ static inline make_DHelper(B) { decode_op_r(s, id_src1, s->isa.instr.i.rs, true); decode_op_r(s, id_src2, s->isa.instr.i.rt, true); - decode_op_i(s, id_dest, s->jmp_pc, true); print_Dop(id_dest->str, OP_STR_SIZE, "0x%x", s->jmp_pc); } diff --git a/src/isa/riscv32/difftest/dut.c b/src/isa/riscv32/difftest/dut.c index 060dd2f0890b2853271c4abfbb2254f6ab82a340..13f402546af0aae5211a5276d25fcb5f9f2360da 100644 --- a/src/isa/riscv32/difftest/dut.c +++ b/src/isa/riscv32/difftest/dut.c @@ -4,9 +4,10 @@ #include "difftest.h" bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) { - if (memcmp(&cpu, ref_r, DIFFTEST_REG_SIZE)) { + if (memcmp(&cpu.gpr[1], &ref_r->gpr[1], DIFFTEST_REG_SIZE - sizeof(cpu.gpr[0]))) { int i; - for (i = 0; i < sizeof(cpu.gpr) / sizeof(cpu.gpr[0]); i ++) { + // do not check $0 + for (i = 1; i < sizeof(cpu.gpr) / sizeof(cpu.gpr[0]); i ++) { difftest_check_reg(reg_name(i, 4), pc, ref_r->gpr[i]._32, cpu.gpr[i]._32); } difftest_check_reg("pc", pc, ref_r->pc, cpu.pc); diff --git a/src/isa/riscv32/exec/compute.h b/src/isa/riscv32/exec/compute.h index 54a1970ae393f9fa91b8f9f154d965cae020d15d..bc7f6c6b26811454b99db17d2ed4f68101a020ad 100644 --- a/src/isa/riscv32/exec/compute.h +++ b/src/isa/riscv32/exec/compute.h @@ -1,39 +1,28 @@ static inline make_EHelper(add) { - rtl_add(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_add(s, ddest, dsrc1, dsrc2); print_asm_template3(add); } static inline make_EHelper(sub) { - rtl_sub(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_sub(s, ddest, dsrc1, dsrc2); print_asm_template3(sub); } static inline make_EHelper(sll) { - rtl_andi(s, dsrc2, dsrc2, 0x1f); - rtl_shl(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_shl(s, ddest, dsrc1, dsrc2); print_asm_template3(sll); } static inline make_EHelper(srl) { - rtl_andi(s, dsrc2, dsrc2, 0x1f); - if (s->isa.instr.r.funct7 == 32) { // sra - rtl_sar(s, s0, dsrc1, dsrc2); + rtl_sar(s, ddest, dsrc1, dsrc2); print_asm_template3(sra); } else { - rtl_shr(s, s0, dsrc1, dsrc2); + rtl_shr(s, ddest, dsrc1, dsrc2); print_asm_template3(srl); } - - rtl_sr(s, id_dest->reg, s0, 4); } static inline make_EHelper(sra) { @@ -41,49 +30,87 @@ static inline make_EHelper(sra) { } static inline make_EHelper(slt) { - rtl_setrelop(s, RELOP_LT, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_setrelop(s, RELOP_LT, ddest, dsrc1, dsrc2); print_asm_template3(slt); } static inline make_EHelper(sltu) { - rtl_setrelop(s, RELOP_LTU, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_setrelop(s, RELOP_LTU, ddest, dsrc1, dsrc2); print_asm_template3(sltu); } static inline make_EHelper(xor) { - rtl_xor(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_xor(s, ddest, dsrc1, dsrc2); print_asm_template3(xor); } static inline make_EHelper(or) { - rtl_or(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_or(s, ddest, dsrc1, dsrc2); print_asm_template3(or); } static inline make_EHelper(and) { - rtl_and(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_and(s, ddest, dsrc1, dsrc2); print_asm_template3(and); } -static inline make_EHelper(auipc) { - rtl_add(s, s0, dsrc1, &cpu.pc); - rtl_sr(s, id_dest->reg, s0, 4); +static inline make_EHelper(addi) { + rtl_addi(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(addi); +} + +static inline make_EHelper(slli) { + rtl_shli(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(slli); +} +static inline make_EHelper(srli) { + if (s->isa.instr.r.funct7 == 32) { + // sra + rtl_sari(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(srai); + } + else { + rtl_shri(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(srli); + } +} + +static inline make_EHelper(srai) { + exec_srli(s); +} + +static inline make_EHelper(slti) { + rtl_setrelopi(s, RELOP_LT, ddest, dsrc1, id_src2->imm); + print_asm_template3(slti); +} + +static inline make_EHelper(sltui) { + rtl_setrelopi(s, RELOP_LTU, ddest, dsrc1, id_src2->imm); + print_asm_template3(sltui); +} + +static inline make_EHelper(xori) { + rtl_xori(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(xori); +} + +static inline make_EHelper(ori) { + rtl_ori(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(ori); +} + +static inline make_EHelper(andi) { + rtl_andi(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(andi); +} + +static inline make_EHelper(auipc) { + rtl_li(s, ddest, id_src1->imm + cpu.pc); print_asm_template2(auipc); } static inline make_EHelper(lui) { - rtl_sr(s, id_dest->reg, dsrc1, 4); - + rtl_li(s, ddest, id_src1->imm); print_asm_template2(lui); } diff --git a/src/isa/riscv32/exec/control.h b/src/isa/riscv32/exec/control.h index af5751f6e545752ed9b7ca3215ab712a99a7f344..56e681745b2bb010734994fb0d0d561fe96f26b2 100644 --- a/src/isa/riscv32/exec/control.h +++ b/src/isa/riscv32/exec/control.h @@ -1,21 +1,19 @@ #include static inline make_EHelper(jal) { - rtl_addi(s, s0, &cpu.pc, 4); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_li(s, ddest, s->seq_pc); rtl_j(s, s->jmp_pc); print_asm_template2(jal); } static inline make_EHelper(jalr) { - rtl_addi(s, s0, &cpu.pc, 4); - rtl_sr(s, id_dest->reg, s0, 4); - - rtl_add(s, s0, dsrc1, dsrc2); + rtl_addi(s, s0, dsrc1, id_src2->imm); rtl_andi(s, s0, s0, ~0x1u); rtl_jr(s, s0); + rtl_li(s, ddest, s->seq_pc); + difftest_skip_dut(1, 2); print_asm_template3(jalr); @@ -38,5 +36,5 @@ static inline make_EHelper(branch) { assert(type != 2 && type != 3); rtl_jrelop(s, branch_map[type].relop, dsrc1, dsrc2, s->jmp_pc); - print_asm("b%s %s,%s,%s", branch_map[type].name, id_src1->str, id_src2->str, id_dest->str); + print_asm("b%s %s,%s,0x%x", branch_map[type].name, id_src1->str, id_src2->str, s->jmp_pc); } diff --git a/src/isa/riscv32/exec/exec.c b/src/isa/riscv32/exec/exec.c index db412defc29bbfc6bd7da640077d0b30f7525b82..4db372a886cf891184edf1fdc5a1faba7f4b3447 100644 --- a/src/isa/riscv32/exec/exec.c +++ b/src/isa/riscv32/exec/exec.c @@ -32,8 +32,8 @@ static inline make_EHelper(store) { static inline make_EHelper(op_imm) { switch (s->isa.instr.i.funct3) { - EX(0, add) EX(1, sll) EX(2, slt) EX(3, sltu) - EX(4, xor) EX(5, srl) EX(6, or) EX(7, and) + EX(0, addi) EX(1, slli) EX(2, slti) EX(3, sltui) + EX(4, xori) EX(5, srli) EX(6, ori) EX(7, andi) default: exec_inv(s); } } @@ -68,10 +68,10 @@ static inline void exec(DecodeExecState *s) { s->isa.instr.val = instr_fetch(&s->seq_pc, 4); assert(s->isa.instr.r.opcode1_0 == 0x3); switch (s->isa.instr.r.opcode6_2) { - IDEX (0b00000, ld, load) + IDEX (0b00000, I, load) IDEX (0b00100, I, op_imm) IDEX (0b00101, U, auipc) - IDEX (0b01000, st, store) IDEX (0b01100, R, op) + IDEX (0b01000, S, store) IDEX (0b01100, R, op) IDEX (0b01101, U, lui) IDEX (0b11000, B, branch) IDEX (0b11001, I, jalr) EX (0b11010, nemu_trap) IDEX (0b11011, J, jal) EX (0b11100, system) default: exec_inv(s); diff --git a/src/isa/riscv32/exec/ldst.h b/src/isa/riscv32/exec/ldst.h index 068d1dd210e70f06f37582d0f31be32874490278..d2618ca685a934f3cf260adca38b043c7834580d 100644 --- a/src/isa/riscv32/exec/ldst.h +++ b/src/isa/riscv32/exec/ldst.h @@ -1,7 +1,7 @@ static inline make_EHelper(ld) { - rtl_lm(s, s0, &id_src1->addr, s->width); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_lm(s, ddest, dsrc1, id_src2->imm, s->width); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->val, reg_name(id_src1->reg, 4)); switch (s->width) { case 4: print_asm_template2(lw); break; case 2: print_asm_template2(lhu); break; @@ -12,10 +12,10 @@ static inline make_EHelper(ld) { // load sign value static inline make_EHelper(lds) { - rtl_lm(s, s0, &id_src1->addr, s->width); - rtl_sext(s, s0, s0, s->width); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_lm(s, s0, dsrc1, id_src2->imm, s->width); + rtl_sext(s, ddest, s0, s->width); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->val, reg_name(id_src1->reg, 4)); switch (s->width) { case 2: print_asm_template2(lh); break; case 1: print_asm_template2(lb); break; @@ -24,8 +24,9 @@ static inline make_EHelper(lds) { } static inline make_EHelper(st) { - rtl_sm(s, &id_src1->addr, ddest, s->width); + rtl_sm(s, dsrc1, id_src2->imm, ddest, s->width); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->val, reg_name(id_src1->reg, 4)); switch (s->width) { case 4: print_asm_template2(sw); break; case 2: print_asm_template2(sh); break; diff --git a/src/isa/riscv32/exec/muldiv.h b/src/isa/riscv32/exec/muldiv.h index 340666d1b28caa3595b212cfd0f0cd6ae7326406..3217381726aa983a2abf87cff76d7c80f6bf3436 100644 --- a/src/isa/riscv32/exec/muldiv.h +++ b/src/isa/riscv32/exec/muldiv.h @@ -1,48 +1,34 @@ static inline make_EHelper(mul) { - rtl_imul_lo(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_imul_lo(s, ddest, dsrc1, dsrc2); print_asm_template3(mul); } static inline make_EHelper(mulh) { - rtl_imul_hi(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_imul_hi(s, ddest, dsrc1, dsrc2); print_asm_template3(mulh); } static inline make_EHelper(mulhu) { - rtl_mul_hi(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_mul_hi(s, ddest, dsrc1, dsrc2); print_asm_template3(mulh); } static inline make_EHelper(div) { - rtl_idiv_q(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_idiv_q(s, ddest, dsrc1, dsrc2); print_asm_template3(div); } static inline make_EHelper(divu) { - rtl_div_q(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_div_q(s, ddest, dsrc1, dsrc2); print_asm_template3(divu); } static inline make_EHelper(rem) { - rtl_idiv_r(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_idiv_r(s, ddest, dsrc1, dsrc2); print_asm_template3(rem); } static inline make_EHelper(remu) { - rtl_div_r(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_div_r(s, ddest, dsrc1, dsrc2); print_asm_template3(remu); } diff --git a/src/isa/riscv32/exec/system.h b/src/isa/riscv32/exec/system.h index ef0e148ec7aaf7b9a0e3e79ac545a36f9c12a36e..fb3f961e6d487effef0f06159ca9e7f197126e3d 100644 --- a/src/isa/riscv32/exec/system.h +++ b/src/isa/riscv32/exec/system.h @@ -14,19 +14,31 @@ static inline rtlreg_t* csr_decode(uint32_t csr) { } static inline make_EHelper(csrrw) { - rtlreg_t *csr = csr_decode(id_src2->val); + rtlreg_t *csr = csr_decode(id_src2->imm); - rtl_sr(s, id_dest->reg, csr, 4); - rtl_mv(s, csr, dsrc1); + if (ddest == dsrc1) { + rtl_mv(s, s0, csr); + rtl_mv(s, csr, dsrc1); + rtl_mv(s, dsrc1, s0); + } else { + rtl_mv(s, ddest, csr); + rtl_mv(s, csr, dsrc1); + } print_asm_template3("csrrw"); } static inline make_EHelper(csrrs) { - rtlreg_t *csr = csr_decode(id_src2->val); + rtlreg_t *csr = csr_decode(id_src2->imm); - rtl_sr(s, id_dest->reg, csr, 4); - rtl_or(s, csr, csr, dsrc1); + if (ddest == dsrc1) { + rtl_mv(s, s0, csr); + rtl_or(s, csr, csr, dsrc1); + rtl_mv(s, dsrc1, s0); + } else { + rtl_mv(s, ddest, csr); + rtl_or(s, csr, csr, dsrc1); + } print_asm_template3("csrrs"); } @@ -42,8 +54,7 @@ static inline make_EHelper(priv) { case 0x102: cpu.sstatus.sie = cpu.sstatus.spie; cpu.sstatus.spie = 1; - rtl_li(s, s0, cpu.sepc); - rtl_jr(s, s0); + rtl_j(s, cpu.sepc); print_asm("sret"); break; default: panic("unimplemented priv instruction type = 0x%x", type); diff --git a/src/isa/riscv32/local-include/decode.h b/src/isa/riscv32/local-include/decode.h index f702d71e24cb65176c28a63cd2d3df6d10bc6d25..978d97576083d08c2859146c3558c5aa8b817509 100644 --- a/src/isa/riscv32/local-include/decode.h +++ b/src/isa/riscv32/local-include/decode.h @@ -8,7 +8,6 @@ static inline make_DopHelper(i) { op->type = OP_TYPE_IMM; op->imm = val; - rtl_li(s, &op->val, op->imm); print_Dop(op->str, OP_STR_SIZE, "%d", op->imm); } @@ -16,9 +15,8 @@ static inline make_DopHelper(i) { static inline make_DopHelper(r) { op->type = OP_TYPE_REG; op->reg = val; - if (load_val) { - rtl_lr(s, &op->val, op->reg, 4); - } + op->preg = ®_l(val); + reg_l(0) = 0; print_Dop(op->str, OP_STR_SIZE, "%s", reg_name(op->reg, 4)); } @@ -46,7 +44,6 @@ static inline make_DHelper(J) { sword_t offset = (s->isa.instr.j.simm20 << 20) | (s->isa.instr.j.imm19_12 << 12) | (s->isa.instr.j.imm11 << 11) | (s->isa.instr.j.imm10_1 << 1); s->jmp_pc = cpu.pc + offset; - decode_op_i(s, id_src1, s->jmp_pc, true); print_Dop(id_src1->str, OP_STR_SIZE, "0x%x", s->jmp_pc); decode_op_r(s, id_dest, s->isa.instr.j.rd, false); @@ -56,27 +53,16 @@ static inline make_DHelper(B) { sword_t offset = (s->isa.instr.b.simm12 << 12) | (s->isa.instr.b.imm11 << 11) | (s->isa.instr.b.imm10_5 << 5) | (s->isa.instr.b.imm4_1 << 1); s->jmp_pc = cpu.pc + offset; - decode_op_i(s, id_dest, s->jmp_pc, true); - print_Dop(id_dest->str, OP_STR_SIZE, "0x%x", s->jmp_pc); decode_op_r(s, id_src1, s->isa.instr.b.rs1, true); decode_op_r(s, id_src2, s->isa.instr.b.rs2, true); } -static inline make_DHelper(ld) { - decode_I(s); - print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->val, reg_name(id_src1->reg, 4)); - rtl_add(s, &id_src1->addr, dsrc1, dsrc2); -} - -static inline make_DHelper(st) { +static inline make_DHelper(S) { decode_op_r(s, id_src1, s->isa.instr.s.rs1, true); sword_t simm = (s->isa.instr.s.simm11_5 << 5) | s->isa.instr.s.imm4_0; decode_op_i(s, id_src2, simm, true); decode_op_r(s, id_dest, s->isa.instr.s.rs2, true); - - print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->val, reg_name(id_src1->reg, 4)); - rtl_add(s, &id_src1->addr, dsrc1, dsrc2); } static inline make_DHelper(csr) { diff --git a/src/isa/riscv64/difftest/dut.c b/src/isa/riscv64/difftest/dut.c index fdac2ddba67396134e692d1f79d983a0eaad02b4..507f40b0632cfd1ec77a871b554cac665eb45f25 100644 --- a/src/isa/riscv64/difftest/dut.c +++ b/src/isa/riscv64/difftest/dut.c @@ -5,9 +5,10 @@ #include "difftest.h" bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) { - if (memcmp(&cpu, ref_r, DIFFTEST_REG_SIZE)) { + if (memcmp(&cpu.gpr[1], &ref_r->gpr[1], DIFFTEST_REG_SIZE - sizeof(cpu.gpr[0]))) { int i; - for (i = 0; i < sizeof(cpu.gpr) / sizeof(cpu.gpr[0]); i ++) { + // do not check $0 + for (i = 1; i < sizeof(cpu.gpr) / sizeof(cpu.gpr[0]); i ++) { difftest_check_reg(reg_name(i, 4), pc, ref_r->gpr[i]._64, cpu.gpr[i]._64); } difftest_check_reg("pc", pc, ref_r->pc, cpu.pc); diff --git a/src/isa/riscv64/exec/amo.h b/src/isa/riscv64/exec/amo.h index f9079b4392462783f206a95f2edecb956414110c..80cf064debcfd8c0a9c469c34767352f20629dd4 100644 --- a/src/isa/riscv64/exec/amo.h +++ b/src/isa/riscv64/exec/amo.h @@ -1,12 +1,10 @@ #include "../local-include/intr.h" static inline make_EHelper(lr) { - rtl_lm(s, s0, dsrc1, s->width); + rtl_lm(s, s0, dsrc1, 0, s->width); check_mem_ex(); - rtl_sext(s, s0, s0, s->width); - rtl_sr(s, id_dest->reg, s0, 0); - cpu.lr_addr = *dsrc1; + rtl_sext(s, ddest, s0, s->width); print_asm_template3(lr); } @@ -14,7 +12,7 @@ static inline make_EHelper(lr) { static inline make_EHelper(sc) { // should check overlapping instead of equality if (cpu.lr_addr == *dsrc1) { - rtl_sm(s, dsrc1, dsrc2, s->width); + rtl_sm(s, dsrc1, 0, dsrc2, s->width); check_mem_ex(); rtl_li(s, s0, 0); } else { @@ -26,12 +24,12 @@ static inline make_EHelper(sc) { } static void inline amo_load(DecodeExecState *s) { - rtl_lm(s, s0, dsrc1, s->width); + rtl_lm(s, s0, dsrc1, 0, s->width); rtl_sext(s, s0, s0, s->width); } static void inline amo_update(DecodeExecState *s) { - rtl_sm(s, dsrc1, s1, s->width); + rtl_sm(s, dsrc1, 0, s1, s->width); check_mem_ex(); rtl_sr(s, id_dest->reg, s0, 0); } diff --git a/src/isa/riscv64/exec/compute.h b/src/isa/riscv64/exec/compute.h index ea3ce6d1b2f3ca08791cbcdd4c66bcef78881370..b95c95a62320136cecf48ecfb00d90101da51c45 100644 --- a/src/isa/riscv64/exec/compute.h +++ b/src/isa/riscv64/exec/compute.h @@ -1,30 +1,21 @@ static inline make_EHelper(add) { - rtl_add(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_add(s, ddest, dsrc1, dsrc2); print_asm_template3(add); } static inline make_EHelper(sub) { - rtl_sub(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_sub(s, ddest, dsrc1, dsrc2); print_asm_template3(sub); } static inline make_EHelper(sll) { - rtl_andi(s, dsrc2, dsrc2, 0x3f); - rtl_shl(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_shl(s, ddest, dsrc1, dsrc2); print_asm_template3(sll); } static inline make_EHelper(sra) { - rtl_andi(s, dsrc2, dsrc2, 0x3f); - rtl_sar(s, s0, dsrc1, dsrc2); + rtl_sar(s, ddest, dsrc1, dsrc2); print_asm_template3(sra); - rtl_sr(s, id_dest->reg, s0, 4); } static inline make_EHelper(srl) { @@ -34,108 +25,163 @@ static inline make_EHelper(srl) { exec_sra(s); return; } - rtl_andi(s, dsrc2, dsrc2, 0x3f); - rtl_shr(s, s0, dsrc1, dsrc2); + rtl_shr(s, ddest, dsrc1, dsrc2); print_asm_template3(srl); - rtl_sr(s, id_dest->reg, s0, 4); } static inline make_EHelper(slt) { - rtl_setrelop(s, RELOP_LT, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_setrelop(s, RELOP_LT, ddest, dsrc1, dsrc2); print_asm_template3(slt); } static inline make_EHelper(sltu) { - rtl_setrelop(s, RELOP_LTU, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_setrelop(s, RELOP_LTU, ddest, dsrc1, dsrc2); print_asm_template3(sltu); } static inline make_EHelper(xor) { - rtl_xor(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_xor(s, ddest, dsrc1, dsrc2); print_asm_template3(xor); } static inline make_EHelper(or) { - rtl_or(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_or(s, ddest, dsrc1, dsrc2); print_asm_template3(or); } static inline make_EHelper(and) { - rtl_and(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_and(s, ddest, dsrc1, dsrc2); print_asm_template3(and); } -static inline make_EHelper(auipc) { - rtl_shli(s, s0, dsrc2, 12); - rtl_add(s, s0, s0, &cpu.pc); - rtl_sr(s, id_dest->reg, s0, 4); +static inline make_EHelper(addi) { + rtl_addi(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(addi); +} + +static inline make_EHelper(slli) { + rtl_shli(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(slli); +} + +static inline make_EHelper(srai) { + rtl_sari(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(srai); +} + +static inline make_EHelper(srli) { + // the LSB of funct7 may be "1" due to the shift amount can be >= 32 + // this rule is disabled when a compressed inst comes in + if ((s->isa.instr.r.funct7 & ~0x1) == 32 && s->isa.instr.r.opcode1_0 == 0x3) { + exec_srai(s); + } else { + rtl_shri(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(srli); + } +} + +static inline make_EHelper(slti) { + rtl_setrelopi(s, RELOP_LT, ddest, dsrc1, id_src2->imm); + print_asm_template3(slti); +} + +static inline make_EHelper(sltui) { + rtl_setrelopi(s, RELOP_LTU, ddest, dsrc1, id_src2->imm); + print_asm_template3(sltui); +} +static inline make_EHelper(xori) { + rtl_xori(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(xori); +} + +static inline make_EHelper(ori) { + rtl_ori(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(ori); +} + +static inline make_EHelper(andi) { + rtl_andi(s, ddest, dsrc1, id_src2->imm); + print_asm_template3(andi); +} + +static inline make_EHelper(auipc) { + rtl_li(s, ddest, id_src2->imm + cpu.pc); print_asm("auipc " FMT_WORD ",%s", *s0, id_dest->str); } static inline make_EHelper(lui) { - rtl_shli(s, s0, dsrc2, 12); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_li(s, ddest, id_src2->imm); print_asm("lui " FMT_WORD ",%s", *s0, id_dest->str); } static inline make_EHelper(addw) { rtl_add(s, s0, dsrc1, dsrc2); - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_sext(s, ddest, s0, 4); print_asm_template3(addw); } static inline make_EHelper(subw) { rtl_sub(s, s0, dsrc1, dsrc2); - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_sext(s, ddest, s0, 4); print_asm_template3(subw); } static inline make_EHelper(sllw) { - rtl_andi(s, dsrc2, dsrc2, 0x1f); - rtl_shl(s, s0, dsrc1, dsrc2); - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_andi(s, s0, dsrc2, 0x1f); + rtl_shl(s, s0, dsrc1, s0); + rtl_sext(s, ddest, s0, 4); print_asm_template3(sllw); } static inline make_EHelper(srlw) { - rtl_andi(s, dsrc2, dsrc2, 0x1f); + rtl_andi(s, s0, dsrc2, 0x1f); assert((s->isa.instr.r.funct7 & 0x1) == 0); if (s->isa.instr.r.funct7 == 32) { // sraw - rtl_sext(s, dsrc1, dsrc1, 4); - rtl_sar(s, s0, dsrc1, dsrc2); - rtl_sext(s, s0, s0, 4); + rtl_sext(s, s1, dsrc1, 4); + rtl_sar(s, s0, s1, s0); print_asm_template3(sraw); } else { // srlw - rtl_andi(s, dsrc1, dsrc1, 0xffffffffu); - rtl_shr(s, s0, dsrc1, dsrc2); - rtl_sext(s, s0, s0, 4); + rtl_andi(s, s1, dsrc1, 0xffffffffu); + rtl_shr(s, s0, s1, s0); print_asm_template3(srlw); } - - rtl_sr(s, id_dest->reg, s0, 4); + rtl_sext(s, ddest, s0, 4); } static inline make_EHelper(sraw) { exec_srlw(s); } + +static inline make_EHelper(addiw) { + rtl_addi(s, s0, dsrc1, id_src2->imm); + rtl_sext(s, ddest, s0, 4); + print_asm_template3(addiw); +} + +static inline make_EHelper(slliw) { + rtl_shli(s, s0, dsrc1, id_src2->imm & 0x1f); + rtl_sext(s, ddest, s0, 4); + print_asm_template3(slliw); +} + +static inline make_EHelper(srliw) { + assert((s->isa.instr.r.funct7 & 0x1) == 0); + if (s->isa.instr.r.funct7 == 32) { + // sraw + rtl_sext(s, s0, dsrc1, 4); + rtl_sari(s, s0, s0, id_src2->imm & 0x1f); + print_asm_template3(sraiw); + } + else { + // srlw + rtl_andi(s, s0, dsrc1, 0xffffffffu); + rtl_shri(s, s0, s0, id_src2->imm & 0x1f); + print_asm_template3(srliw); + } + + rtl_sext(s, ddest, s0, 4); +} diff --git a/src/isa/riscv64/exec/control.h b/src/isa/riscv64/exec/control.h index a6f00dfbd69118c2b8eba797aba0c6e51470df1c..cd70a4bdae1028d21c4b4f761504d32d8c49a6a9 100644 --- a/src/isa/riscv64/exec/control.h +++ b/src/isa/riscv64/exec/control.h @@ -1,21 +1,19 @@ #include static inline make_EHelper(jal) { - rtl_li(s, s0, s->seq_pc); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_li(s, ddest, s->seq_pc); rtl_j(s, s->jmp_pc); print_asm_template2(jal); } static inline make_EHelper(jalr) { - rtl_li(s, s0, s->seq_pc); - rtl_sr(s, id_dest->reg, s0, 4); - - rtl_add(s, s0, dsrc1, dsrc2); + rtl_addi(s, s0, dsrc1, id_src2->imm); rtl_andi(s, s0, s0, ~0x1lu); rtl_jr(s, s0); + rtl_li(s, ddest, s->seq_pc); + difftest_skip_dut(1, 2); print_asm_template3(jalr); diff --git a/src/isa/riscv64/exec/exec.c b/src/isa/riscv64/exec/exec.c index c8da4fd306ce30a13f424444cd194ee28cc58bb1..98c0adda7097ad572a21a00469fbf6749573e358 100644 --- a/src/isa/riscv64/exec/exec.c +++ b/src/isa/riscv64/exec/exec.c @@ -33,14 +33,14 @@ static inline make_EHelper(store) { static inline make_EHelper(op_imm) { switch (s->isa.instr.i.funct3) { - EX(0, add) EX(1, sll) EX(2, slt) EX(3, sltu) - EX(4, xor) EX(5, srl) EX(6, or) EX(7, and) + EX(0, addi) EX(1, slli) EX(2, slti) EX(3, sltui) + EX(4, xori) EX(5, srli) EX(6, ori) EX(7, andi) } } static inline make_EHelper(op_imm32) { switch (s->isa.instr.i.funct3) { - EX(0, addw) EX(1, sllw) EX(5, srlw) + EX(0, addiw) EX(1, slliw) EX(5, srliw) default: exec_inv(s); } } @@ -88,7 +88,7 @@ static inline make_EHelper(branch) { static inline make_EHelper(system) { switch (s->isa.instr.i.funct3) { EX(0, priv) IDEX(1, csr, csrrw) IDEX(2, csr, csrrs) IDEX(3, csr, csrrc) - EMPTY(4) IDEX(5, csri, csrrw) IDEX(6, csri, csrrs) IDEX(7, csri, csrrc) + EMPTY(4) IDEX(5, csri, csrrwi)IDEX(6, csri, csrrsi)IDEX(7, csri, csrrci) } } @@ -132,9 +132,9 @@ static inline make_EHelper(lui_addi16sp) { uint32_t rd = BITS(s->isa.instr.val, 11, 7); assert(rd != 0); switch (rd) { - IDEX (2, C_ADDI16SP, add) + IDEX (2, C_ADDI16SP, addi) default: // and other cases - IDEX (1, CI_simm, lui) + IDEX (1, CI_simm_lui, lui) } } @@ -149,9 +149,9 @@ static inline make_EHelper(misc_alu) { } } else { switch (op) { - IDEX (0, CB_shift, srl) - IDEX (1, CB_shift, sra) - IDEX (2, CB_andi, and) + IDEX (0, CB_shift, srli) + IDEX (1, CB_shift, srai) + IDEX (2, CB_andi, andi) } } } @@ -182,9 +182,9 @@ static inline void exec(DecodeExecState *s) { if (s->isa.instr.r.opcode1_0 == 0x3) { switch (s->isa.instr.r.opcode6_2) { - IDEX (000, ld, load) EX (001, fp) EX (003, fence) + IDEX (000, I, load) EX (001, fp) EX (003, fence) IDEX (004, I, op_imm) IDEX (005, U, auipc) IDEX (006, I, op_imm32) - IDEX (010, st, store) EX (011, fp) IDEX (013, R, atomic) + IDEX (010, S, store) EX (011, fp) IDEX (013, R, atomic) IDEX (014, R, op) IDEX (015, U, lui) IDEX (016, R, op32) EX (020, fp) EX (024, fp) @@ -199,11 +199,11 @@ rvc: ; //idex(pc, &rvc_table[decinfo.isa.instr.opcode1_0][decinfo.isa.instr.c_funct3]); uint32_t rvc_opcode = (s->isa.instr.r.opcode1_0 << 3) | BITS(s->isa.instr.val, 15, 13); switch (rvc_opcode) { - IDEX (000, C_ADDI4SPN, add) EX (001, fp) IDEXW(002, C_LW, lds, 4) IDEXW(003, C_LD, ld, 8) + IDEX (000, C_ADDI4SPN, addi)EX (001, fp) IDEXW(002, C_LW, lds, 4) IDEXW(003, C_LD, ld, 8) EX (005, fp) IDEXW(006, C_SW, st, 4) IDEXW(007, C_SD, st, 8) - IDEX (010, CI_simm, add) IDEX (011, CI_simm, addw) IDEX (012, C_LI, add) EX (013, lui_addi16sp) + IDEX (010, CI_simm, addi)IDEX (011, CI_simm, addiw)IDEX (012, C_LI, addi)EX (013, lui_addi16sp) EX (014, misc_alu) IDEX (015, C_J, jal) IDEX (016, CB, beq) IDEX (017, CB, bne) - IDEX (020, CI_uimm, sll) EX (021, fp) IDEXW(022, C_LWSP, lds, 4)IDEXW(023, C_LDSP, ld, 8) + IDEX (020, CI_uimm, slli)EX (021, fp) IDEXW(022, C_LWSP, lds, 4)IDEXW(023, C_LDSP, ld, 8) EX (024, misc) EX (025, fp) IDEXW(026, C_SWSP, st, 4) IDEXW(027, C_SDSP, st, 8) default: exec_inv(s); } diff --git a/src/isa/riscv64/exec/ldst.h b/src/isa/riscv64/exec/ldst.h index e2fb950722e8f0ad4a4ae461e65ae3096e0692cc..a6ec0c6ee1774d7a4c6e84af766bd03658ce6f89 100644 --- a/src/isa/riscv64/exec/ldst.h +++ b/src/isa/riscv64/exec/ldst.h @@ -1,10 +1,11 @@ #include "../local-include/intr.h" static inline make_EHelper(ld) { - rtl_lm(s, s0, &id_src1->addr, s->width); + rtl_lm(s, s0, dsrc1, id_src2->imm, s->width); check_mem_ex(); - rtl_sr(s, id_dest->reg, s0, 0); + rtl_mv(s, ddest, s0); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); switch (s->width) { case 8: print_asm_template2(ld); break; case 4: print_asm_template2(lwu); break; @@ -16,11 +17,11 @@ static inline make_EHelper(ld) { // load sign value static inline make_EHelper(lds) { - rtl_lm(s, s0, &id_src1->addr, s->width); + rtl_lm(s, s0, dsrc1, id_src2->imm, s->width); check_mem_ex(); - rtl_sext(s, s0, s0, s->width); - rtl_sr(s, id_dest->reg, s0, 0); + rtl_sext(s, ddest, s0, s->width); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); switch (s->width) { case 4: print_asm_template2(lw); break; case 2: print_asm_template2(lh); break; @@ -30,9 +31,10 @@ static inline make_EHelper(lds) { } static inline make_EHelper(st) { - rtl_sm(s, &id_src1->addr, ddest, s->width); + rtl_sm(s, dsrc1, id_src2->imm, ddest, s->width); check_mem_ex(); + print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4)); switch (s->width) { case 8: print_asm_template2(sd); break; case 4: print_asm_template2(sw); break; diff --git a/src/isa/riscv64/exec/muldiv.h b/src/isa/riscv64/exec/muldiv.h index 429af63a89773c15ba6109dc47750a7dc2495c29..0111606a4e9908177661033f56308ddf2dfcc0f9 100644 --- a/src/isa/riscv64/exec/muldiv.h +++ b/src/isa/riscv64/exec/muldiv.h @@ -1,21 +1,15 @@ static inline make_EHelper(mul) { - rtl_mul_lo(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_mul_lo(s, ddest, dsrc1, dsrc2); print_asm_template3(mul); } static inline make_EHelper(mulh) { - rtl_imul_hi(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_imul_hi(s, ddest, dsrc1, dsrc2); print_asm_template3(mulh); } static inline make_EHelper(mulhu) { - rtl_mul_hi(s, s0, dsrc1, dsrc2); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_mul_hi(s, ddest, dsrc1, dsrc2); print_asm_template3(mulhu); } @@ -37,66 +31,58 @@ static inline make_EHelper(mulhsu) { rtl_sari(s, s0, dsrc1, 63); rtl_and(s, s0, dsrc2, s0); // s0 = (id_src1->val < 0 ? id_src2->val : 0) rtl_mul_hi(s, s1, dsrc1, dsrc2); - rtl_sub(s, s0, s1, s0); - - rtl_sr(s, id_dest->reg, s0, 4); + rtl_sub(s, ddest, s1, s0); print_asm_template3(mulhsu); } static inline make_EHelper(div) { if (*dsrc2 == 0) { - rtl_li(s, s0, ~0lu); + rtl_li(s, ddest, ~0lu); } else if (*dsrc1 == 0x8000000000000000LL && *dsrc2 == -1) { - rtl_mv(s, s0, dsrc1); + rtl_mv(s, ddest, dsrc1); } else { - rtl_idiv_q(s, s0, dsrc1, dsrc2); + rtl_idiv_q(s, ddest, dsrc1, dsrc2); } - rtl_sr(s, id_dest->reg, s0, 4); print_asm_template3(div); } static inline make_EHelper(divu) { if (*dsrc2 == 0) { - rtl_li(s, s0, ~0lu); + rtl_li(s, ddest, ~0lu); } else { - rtl_div_q(s, s0, dsrc1, dsrc2); + rtl_div_q(s, ddest, dsrc1, dsrc2); } - rtl_sr(s, id_dest->reg, s0, 4); print_asm_template3(divu); } static inline make_EHelper(rem) { if (*dsrc2 == 0) { - rtl_mv(s, s0, dsrc1); + rtl_mv(s, ddest, dsrc1); } else if (*dsrc1 == 0x8000000000000000LL && *dsrc2 == -1) { - rtl_li(s, s0, 0); + rtl_li(s, ddest, 0); } else { - rtl_idiv_r(s, s0, dsrc1, dsrc2); + rtl_idiv_r(s, ddest, dsrc1, dsrc2); } - rtl_sr(s, id_dest->reg, s0, 4); print_asm_template3(rem); } static inline make_EHelper(remu) { if (*dsrc2 == 0) { - rtl_mv(s, s0, dsrc1); + rtl_mv(s, ddest, dsrc1); } else { - rtl_div_r(s, s0, dsrc1, dsrc2); + rtl_div_r(s, ddest, dsrc1, dsrc2); } - rtl_sr(s, id_dest->reg, s0, 4); print_asm_template3(remu); } static inline make_EHelper(mulw) { rtl_mul_lo(s, s0, dsrc1, dsrc2); - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); - + rtl_sext(s, ddest, s0, 4); print_asm_template3(mulw); } @@ -110,8 +96,7 @@ static inline make_EHelper(divw) { } else { rtl_idiv_q(s, s0, s0, s1); } - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_sext(s, ddest, s0, 4); print_asm_template3(divw); } @@ -126,8 +111,7 @@ static inline make_EHelper(remw) { } else { rtl_idiv_r(s, s0, s0, s1); } - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_sext(s, ddest, s0, 4); print_asm_template3(remw); } @@ -140,8 +124,7 @@ static inline make_EHelper(divuw) { } else { rtl_div_q(s, s0, s0, s1); } - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_sext(s, ddest, s0, 4); print_asm_template3(divuw); } @@ -154,8 +137,7 @@ static inline make_EHelper(remuw) { } else { rtl_div_r(s, s0, s0, s1); } - rtl_sext(s, s0, s0, 4); - rtl_sr(s, id_dest->reg, s0, 4); + rtl_sext(s, ddest, s0, 4); print_asm_template3(remuw); } diff --git a/src/isa/riscv64/exec/system.h b/src/isa/riscv64/exec/system.h index 6191a22bd26f00d167d7af3fa87b4cd39d6a490a..ac62996d860c1bc165d65a0991a769596566d3fb 100644 --- a/src/isa/riscv64/exec/system.h +++ b/src/isa/riscv64/exec/system.h @@ -14,42 +14,79 @@ static inline bool csr_check(DecodeExecState *s, uint32_t addr) { } static inline make_EHelper(csrrw) { - uint32_t addr = *dsrc2; + uint32_t addr = id_src2->imm; if (!csr_check(s, addr)) return; csr_read(s0, addr); - rtl_sr(s, id_dest->reg, s0, 8); csr_write(addr, dsrc1); + rtl_mv(s, ddest, s0); print_asm_template3("csrrw"); } static inline make_EHelper(csrrs) { - uint32_t addr = *dsrc2; + uint32_t addr = id_src2->imm; if (!csr_check(s, addr)) return; csr_read(s0, addr); - rtl_sr(s, id_dest->reg, s0, 8); if (id_src1->reg != 0) { - rtl_or(s, s0, s0, dsrc1); - csr_write(addr, s0); + rtl_or(s, s1, s0, dsrc1); + csr_write(addr, s1); } + rtl_mv(s, ddest, s0); print_asm_template3("csrrs"); } static inline make_EHelper(csrrc) { - uint32_t addr = id_src2->val; + uint32_t addr = id_src2->imm; if (!csr_check(s, addr)) return; csr_read(s0, addr); - rtl_sr(s, id_dest->reg, s0, 8); if (id_src1->reg != 0) { rtl_not(s, s1, dsrc1); - rtl_and(s, s0, s0, s1); - csr_write(addr, s0); + rtl_and(s, s1, s0, s1); + csr_write(addr, s1); } + rtl_mv(s, ddest, s0); print_asm_template3("csrrc"); } +static inline make_EHelper(csrrwi) { + uint32_t addr = id_src2->imm; + if (!csr_check(s, addr)) return; + csr_read(s0, addr); + rtl_li(s, s1, id_src1->imm); + csr_write(addr, s1); + rtl_mv(s, ddest, s0); + + print_asm_template3("csrrwi"); +} + +static inline make_EHelper(csrrsi) { + uint32_t addr = id_src2->imm; + if (!csr_check(s, addr)) return; + csr_read(s0, addr); + if (id_src1->reg != 0) { + rtl_ori(s, s1, s0, id_src1->imm); + csr_write(addr, s1); + } + rtl_mv(s, ddest, s0); + + print_asm_template3("csrrsi"); +} + +static inline make_EHelper(csrrci) { + uint32_t addr = id_src2->imm; + if (!csr_check(s, addr)) return; + csr_read(s0, addr); + if (id_src1->reg != 0) { + rtl_andi(s, s1, s0, ~id_src1->imm); + csr_write(addr, s1); + } + rtl_mv(s, ddest, s0); + + print_asm_template3("csrrci"); +} + static inline make_EHelper(priv) { uint32_t type = s->isa.instr.csr.csr; switch (type) { diff --git a/src/isa/riscv64/local-include/decode.h b/src/isa/riscv64/local-include/decode.h index 560bdb1b228655a59105d9e3e3612fba7103346e..db56c0db6784e5ff99ca02edbc8bcdfe1a948fa6 100644 --- a/src/isa/riscv64/local-include/decode.h +++ b/src/isa/riscv64/local-include/decode.h @@ -8,7 +8,6 @@ static inline make_DopHelper(i) { op->type = OP_TYPE_IMM; op->imm = val; - rtl_li(s, &op->val, op->imm); print_Dop(op->str, OP_STR_SIZE, "%ld", op->imm); } @@ -16,9 +15,8 @@ static inline make_DopHelper(i) { static inline make_DopHelper(r) { op->type = OP_TYPE_REG; op->reg = val; - if (load_val) { - rtl_lr(s, &op->val, op->reg, 4); - } + op->preg = ®_l(val); + reg_l(0) = 0; print_Dop(op->str, OP_STR_SIZE, "%s", reg_name(op->reg, 4)); } @@ -36,8 +34,7 @@ static inline make_DHelper(R) { } static inline make_DHelper(U) { - // shift at execute stage - decode_op_i(s, id_src2, (sword_t)s->isa.instr.u.simm31_12, true); + decode_op_i(s, id_src2, (sword_t)s->isa.instr.u.simm31_12 << 12, true); decode_op_r(s, id_dest, s->isa.instr.u.rd, false); print_Dop(id_src2->str, OP_STR_SIZE, "0x%x", s->isa.instr.u.simm31_12); @@ -47,7 +44,6 @@ static inline make_DHelper(J) { sword_t offset = (s->isa.instr.j.simm20 << 20) | (s->isa.instr.j.imm19_12 << 12) | (s->isa.instr.j.imm11 << 11) | (s->isa.instr.j.imm10_1 << 1); s->jmp_pc = cpu.pc + offset; - decode_op_i(s, id_src1, s->jmp_pc, true); print_Dop(id_src1->str, OP_STR_SIZE, "0x%lx", s->jmp_pc); decode_op_r(s, id_dest, s->isa.instr.j.rd, false); @@ -57,33 +53,16 @@ static inline make_DHelper(B) { sword_t offset = (s->isa.instr.b.simm12 << 12) | (s->isa.instr.b.imm11 << 11) | (s->isa.instr.b.imm10_5 << 5) | (s->isa.instr.b.imm4_1 << 1); s->jmp_pc = cpu.pc + offset; - decode_op_i(s, id_dest, s->jmp_pc, true); - print_Dop(id_dest->str, OP_STR_SIZE, "0x%lx", s->jmp_pc); + print_Dop(id_dest->str, OP_STR_SIZE, "0x%x", s->jmp_pc); decode_op_r(s, id_src1, s->isa.instr.b.rs1, true); decode_op_r(s, id_src2, s->isa.instr.b.rs2, true); } -static inline make_DHelper(ld) { - decode_op_r(s, id_src1, s->isa.instr.i.rs1, true); - decode_op_i(s, id_src2, s->isa.instr.i.simm11_0, true); - - print_Dop(id_src1->str, OP_STR_SIZE, "%ld(%s)", id_src2->val, reg_name(id_src1->reg, 4)); - - rtl_add(s, &id_src1->addr, dsrc1, dsrc2); - - decode_op_r(s, id_dest, s->isa.instr.i.rd, false); -} - -static inline make_DHelper(st) { +static inline make_DHelper(S) { decode_op_r(s, id_src1, s->isa.instr.s.rs1, true); sword_t simm = (s->isa.instr.s.simm11_5 << 5) | s->isa.instr.s.imm4_0; decode_op_i(s, id_src2, simm, true); - - print_Dop(id_src1->str, OP_STR_SIZE, "%ld(%s)", id_src2->val, reg_name(id_src1->reg, 4)); - - rtl_add(s, &id_src1->addr, dsrc1, dsrc2); - decode_op_r(s, id_dest, s->isa.instr.s.rs2, true); } @@ -146,6 +125,11 @@ static inline make_DHelper(CI_simm) { decode_op_rd_rs1_imm6(s, true, 0, 0, false); } +static inline make_DHelper(CI_simm_lui) { + decode_CI_simm(s); + id_src2->imm <<= 12; +} + // for shift static inline make_DHelper(CI_uimm) { decode_op_rd_rs1_imm6(s, false, 0, 0, false); @@ -170,7 +154,6 @@ static inline make_DHelper(C_ADDI16SP) { static inline void decode_C_xxSP(DecodeExecState *s, uint32_t imm6, int rotate) { decode_op_r(s, id_src1, 2, true); decode_op_C_imm6(s, imm6, false, 0, rotate); - rtl_add(s, &id_src1->addr, dsrc1, dsrc2); } static inline void decode_C_LxSP(DecodeExecState *s, int rotate) { @@ -226,7 +209,6 @@ static inline void decode_C_ldst_common(DecodeExecState *s, int rotate, bool is_ uint32_t imm5 = (BITS(instr, 12, 10) << 2) | BITS(instr, 6, 5); uint32_t imm = ror_imm(imm5, 5, rotate) << 1; decode_op_i(s, id_src2, imm, true); - rtl_add(s, &id_src1->addr, dsrc1, dsrc2); decode_op_r(s, id_dest, creg2reg(BITS(instr, 4, 2)), is_store); } @@ -311,7 +293,9 @@ static inline void decode_C_rs1_rs2_rd(DecodeExecState *s, bool is_rs1_zero, boo } static inline make_DHelper(C_JR) { - decode_C_rs1_rs2_rd(s, false, false, true); + decode_op_r(s, id_src1, BITS(s->isa.instr.val, 11, 7), true); + decode_op_i(s, id_src2, 0, true); + decode_op_r(s, id_dest, 0, false); } static inline make_DHelper(C_MOV) { @@ -324,6 +308,6 @@ static inline make_DHelper(C_ADD) { static inline make_DHelper(C_JALR) { decode_op_r(s, id_src1, BITS(s->isa.instr.val, 11, 7), true); - decode_op_r(s, id_src2, 0, true); + decode_op_i(s, id_src2, 0, true); decode_op_r(s, id_dest, 1, false); } diff --git a/src/isa/x86/decode.c b/src/isa/x86/decode.c index c2b1419517f09ea4a6d76a674d218fb78e2c6fcb..ba726cf4f62326bb07016755eacdee5181316d01 100644 --- a/src/isa/x86/decode.c +++ b/src/isa/x86/decode.c @@ -1,6 +1,7 @@ #include #include "local-include/rtl.h" #include "local-include/reg.h" +#include "local-include/decode.h" typedef union { struct { @@ -30,7 +31,6 @@ static inline void load_addr(DecodeExecState *s, ModR_M *m, Operand *rm) { sword_t disp = 0; int disp_size = 4; int base_reg = -1, index_reg = -1, scale = 0; - rtl_li(s, s0, 0); if (m->R_M == R_ESP) { SIB sib; @@ -55,19 +55,15 @@ static inline void load_addr(DecodeExecState *s, ModR_M *m, Operand *rm) { /* has disp */ disp = instr_fetch(&s->seq_pc, disp_size); if (disp_size == 1) { disp = (int8_t)disp; } - - rtl_addi(s, s0, s0, disp); - } - - if (base_reg != -1) { - rtl_add(s, s0, s0, ®_l(base_reg)); } + s->isa.mbase = (base_reg != -1 ? ®_l(base_reg) : rz); if (index_reg != -1) { rtl_shli(s, s1, ®_l(index_reg), scale); - rtl_add(s, s0, s0, s1); + rtl_add(s, &s->isa.mbr, s->isa.mbase, s1); + s->isa.mbase = &s->isa.mbr; } - rtl_mv(s, &rm->addr, s0); + s->isa.moff = disp; #ifdef DEBUG char disp_buf[16]; @@ -105,33 +101,13 @@ void read_ModR_M(DecodeExecState *s, Operand *rm, bool load_rm_val, Operand *reg ModR_M m; m.val = instr_fetch(&s->seq_pc, 1); s->isa.ext_opcode = m.opcode; - if (reg != NULL) { - reg->type = OP_TYPE_REG; - reg->reg = m.reg; - if (load_reg_val) { - rtl_lr(s, ®->val, reg->reg, reg->width); - } - -#ifdef DEBUG - snprintf(reg->str, OP_STR_SIZE, "%%%s", reg_name(reg->reg, reg->width)); -#endif - } - - if (m.mod == 3) { - rm->type = OP_TYPE_REG; - rm->reg = m.R_M; - if (load_rm_val) { - rtl_lr(s, &rm->val, m.R_M, rm->width); - } - -#ifdef DEBUG - sprintf(rm->str, "%%%s", reg_name(m.R_M, rm->width)); -#endif - } + if (reg != NULL) operand_reg(s, reg, load_reg_val, m.reg, reg->width); + if (m.mod == 3) operand_reg(s, rm, load_rm_val, m.R_M, rm->width); else { load_addr(s, &m, rm); if (load_rm_val) { - rtl_lm(s, &rm->val, &rm->addr, rm->width); + rtl_lm(s, &rm->val, s->isa.mbase, s->isa.moff, rm->width); + rm->preg = &rm->val; } } } diff --git a/src/isa/x86/exec/data-mov.h b/src/isa/x86/exec/data-mov.h index b133dad8c3b550d4c6bc454b49413b58b37c1c69..14297f6e946ab486a433cfa5b841b4d8ac804e5e 100644 --- a/src/isa/x86/exec/data-mov.h +++ b/src/isa/x86/exec/data-mov.h @@ -96,7 +96,8 @@ static inline make_EHelper(movzx) { } static inline make_EHelper(lea) { - operand_write(s, id_dest, &id_src1->addr); + rtl_addi(s, s0, s->isa.mbase, s->isa.moff); + operand_write(s, id_dest, s0); print_asm_template2(lea); } diff --git a/src/isa/x86/exec/string.h b/src/isa/x86/exec/string.h index 20a89f94f3c185e742871b440855b37157cfb23d..fb1f0de7177e869c700238b1acb17b08b3bffabb 100644 --- a/src/isa/x86/exec/string.h +++ b/src/isa/x86/exec/string.h @@ -1,6 +1,6 @@ static make_EHelper(movs) { - rtl_lm(s, s0, &cpu.esi, id_dest->width); - rtl_sm(s, &cpu.edi, s0, id_dest->width); + rtl_lm(s, s0, &cpu.esi, 0, id_dest->width); + rtl_sm(s, &cpu.edi, 0, s0, id_dest->width); rtl_addi(s, &cpu.esi, &cpu.esi, id_dest->width); rtl_addi(s, &cpu.edi, &cpu.edi, id_dest->width); diff --git a/src/isa/x86/exec/system.h b/src/isa/x86/exec/system.h index 52ec4ac25ced3a7ced70cff26b85f130b973662a..f6c1cd936d7541a596f7624a5217486866355147 100644 --- a/src/isa/x86/exec/system.h +++ b/src/isa/x86/exec/system.h @@ -1,8 +1,9 @@ #include static make_EHelper(lidt) { - cpu.idtr.limit = vaddr_read(id_dest->addr, 2); - cpu.idtr.base = vaddr_read(id_dest->addr + 2, 4); + word_t addr = *s->isa.mbase + s->isa.moff; + cpu.idtr.limit = vaddr_read(addr, 2); + cpu.idtr.base = vaddr_read(addr + 2, 4); print_asm_template1(lidt); } diff --git a/src/isa/x86/intr.c b/src/isa/x86/intr.c index c9fde7c9913c87cef5eb2f0ed893ca12c39fa50f..2fdaa2c9f8be9f229cff79d68a08190a19976b72 100644 --- a/src/isa/x86/intr.c +++ b/src/isa/x86/intr.c @@ -8,11 +8,9 @@ void raise_intr(DecodeExecState *s, uint32_t NO, vaddr_t ret_addr) { //TODO(); assert(NO < 256); - vaddr_t base = cpu.idtr.base + (NO << 3); - rtl_li(s, s0, base); - rtl_lm(s, s1, s0, 4); - rtl_addi(s, s0, s0, 4); - rtl_lm(s, s0, s0, 4); + rtl_li(s, s0, cpu.idtr.base); + rtl_lm(s, s1, s0, NO << 3, 4); + rtl_lm(s, s0, s0, (NO << 3) + 4, 4); // check the present bit assert((*s0 >> 15) & 0x1); diff --git a/src/isa/x86/local-include/decode.h b/src/isa/x86/local-include/decode.h index 3c34fe56e7de621f2b082b0763bfb9dc5ae0696d..0e147f204b46f3a67c9196da546c9d07ec28195d 100644 --- a/src/isa/x86/local-include/decode.h +++ b/src/isa/x86/local-include/decode.h @@ -3,6 +3,31 @@ void read_ModR_M(DecodeExecState *s, Operand *rm, bool load_rm_val, Operand *reg, bool load_reg_val); +static inline void operand_reg(DecodeExecState *s, Operand *op, bool load_val, int r, int width) { + op->type = OP_TYPE_REG; + op->reg = r; + + if (width == 4) { + op->preg = ®_l(r); + } else { + assert(width == 1 || width == 2); + op->preg = &op->val; + if (load_val) rtl_lr(s, &op->val, r, width); + } + + print_Dop(op->str, OP_STR_SIZE, "%%%s", reg_name(r, width)); +} + +static inline void operand_imm(DecodeExecState *s, Operand *op, bool load_val, word_t imm, int width) { + op->type = OP_TYPE_IMM; + op->imm = imm; + if (load_val) { + rtl_li(s, &op->val, imm); + op->preg = &op->val; + } + print_Dop(op->str, OP_STR_SIZE, "$0x%x", imm); +} + // decode operand helper #define make_DopHelper(name) void concat(decode_op_, name) (DecodeExecState *s, Operand *op, bool load_val) @@ -11,11 +36,8 @@ void read_ModR_M(DecodeExecState *s, Operand *rm, bool load_rm_val, Operand *reg /* Ib, Iv */ static inline make_DopHelper(I) { /* pc here is pointing to the immediate */ - op->type = OP_TYPE_IMM; - op->imm = instr_fetch(&s->seq_pc, op->width); - rtl_li(s, &op->val, op->imm); - - print_Dop(op->str, OP_STR_SIZE, "$0x%x", op->imm); + word_t imm = instr_fetch(&s->seq_pc, op->width); + operand_imm(s, op, load_val, imm, op->width); } /* I386 manual does not contain this abbreviation, but it is different from @@ -26,20 +48,15 @@ static inline make_DopHelper(I) { static inline make_DopHelper(SI) { assert(op->width == 1 || op->width == 4); - op->type = OP_TYPE_IMM; - /* TODO: Use instr_fetch() to read `op->width' bytes of memory * pointed by 'pc'. Interpret the result as a signed immediate, * and assign it to op->simm. * op->simm = ??? */ - op->simm = instr_fetch(&s->seq_pc, op->width); - if (op->width == 1) op->simm = (int8_t)op->simm; - - rtl_li(s, &op->val, op->simm); - - print_Dop(op->str, OP_STR_SIZE, "$0x%x", op->simm); + word_t imm = instr_fetch(&s->seq_pc, op->width); + if (op->width == 1) imm = (int8_t)imm; + operand_imm(s, op, load_val, imm, op->width); } /* I386 manual does not contain this abbreviation. @@ -47,13 +64,7 @@ static inline make_DopHelper(SI) { */ /* AL/eAX */ static inline make_DopHelper(a) { - op->type = OP_TYPE_REG; - op->reg = R_EAX; - if (load_val) { - rtl_lr(s, &op->val, R_EAX, op->width); - } - - print_Dop(op->str, OP_STR_SIZE, "%%%s", reg_name(R_EAX, op->width)); + operand_reg(s, op, load_val, R_EAX, op->width); } /* This helper function is use to decode register encoded in the opcode. */ @@ -61,17 +72,11 @@ static inline make_DopHelper(a) { * eXX: eAX, eCX, eDX, eBX, eSP, eBP, eSI, eDI */ static inline make_DopHelper(r) { - op->type = OP_TYPE_REG; - op->reg = s->opcode & 0x7; - if (load_val) { - rtl_lr(s, &op->val, op->reg, op->width); - } - - print_Dop(op->str, OP_STR_SIZE, "%%%s", reg_name(op->reg, op->width)); + operand_reg(s, op, load_val, s->opcode & 0x7, op->width); } /* I386 manual does not contain this abbreviation. - * We decode everything of modR/M byte by one time. + * We decode everything of modR/M byte in one time. */ /* Eb, Ew, Ev * Gb, Gv @@ -80,45 +85,47 @@ static inline make_DopHelper(r) { * Rd * Sw */ -static inline void decode_op_rm(DecodeExecState *s, Operand *rm, bool load_rm_val, Operand *reg, bool load_reg_val) { +static inline void operand_rm(DecodeExecState *s, Operand *rm, bool load_rm_val, Operand *reg, bool load_reg_val) { read_ModR_M(s, rm, load_rm_val, reg, load_reg_val); } /* Ob, Ov */ static inline make_DopHelper(O) { op->type = OP_TYPE_MEM; - rtl_li(s, &op->addr, instr_fetch(&s->seq_pc, 4)); + s->isa.moff = instr_fetch(&s->seq_pc, 4); + s->isa.mbase = rz; if (load_val) { - rtl_lm(s, &op->val, &op->addr, op->width); + rtl_lm(s, &op->val, s->isa.mbase, s->isa.moff, op->width); + op->preg = &op->val; } - print_Dop(op->str, OP_STR_SIZE, "0x%x", op->addr); + print_Dop(op->str, OP_STR_SIZE, "0x%x", s->isa.moff); } /* Eb <- Gb * Ev <- Gv */ static inline make_DHelper(G2E) { - decode_op_rm(s, id_dest, true, id_src1, true); + operand_rm(s, id_dest, true, id_src1, true); } static inline make_DHelper(mov_G2E) { - decode_op_rm(s, id_dest, false, id_src1, true); + operand_rm(s, id_dest, false, id_src1, true); } /* Gb <- Eb * Gv <- Ev */ static inline make_DHelper(E2G) { - decode_op_rm(s, id_src1, true, id_dest, true); + operand_rm(s, id_src1, true, id_dest, true); } static inline make_DHelper(mov_E2G) { - decode_op_rm(s, id_src1, true, id_dest, false); + operand_rm(s, id_src1, true, id_dest, false); } static inline make_DHelper(lea_M2G) { - decode_op_rm(s, id_src1, false, id_dest, false); + operand_rm(s, id_src1, false, id_dest, false); } /* AL <- Ib @@ -133,7 +140,7 @@ static inline make_DHelper(I2a) { * Gv <- EvIv * use for imul */ static inline make_DHelper(I_E2G) { - decode_op_rm(s, id_src2, true, id_dest, false); + operand_rm(s, id_src2, true, id_dest, false); decode_op_I(s, id_src1, true); } @@ -141,12 +148,12 @@ static inline make_DHelper(I_E2G) { * Ev <- Iv */ static inline make_DHelper(I2E) { - decode_op_rm(s, id_dest, true, NULL, false); + operand_rm(s, id_dest, true, NULL, false); decode_op_I(s, id_src1, true); } static inline make_DHelper(mov_I2E) { - decode_op_rm(s, id_dest, false, NULL, false); + operand_rm(s, id_dest, false, NULL, false); decode_op_I(s, id_src1, true); } @@ -173,15 +180,15 @@ static inline make_DHelper(r) { } static inline make_DHelper(E) { - decode_op_rm(s, id_dest, true, NULL, false); + operand_rm(s, id_dest, true, NULL, false); } static inline make_DHelper(setcc_E) { - decode_op_rm(s, id_dest, false, NULL, false); + operand_rm(s, id_dest, false, NULL, false); } static inline make_DHelper(gp7_E) { - decode_op_rm(s, id_dest, false, NULL, false); + operand_rm(s, id_dest, false, NULL, false); } /* used by test in group3 */ @@ -191,7 +198,7 @@ static inline make_DHelper(test_I) { static inline make_DHelper(SI2E) { assert(id_dest->width == 2 || id_dest->width == 4); - decode_op_rm(s, id_dest, true, NULL, false); + operand_rm(s, id_dest, true, NULL, false); id_src1->width = 1; decode_op_SI(s, id_src1, true); if (id_dest->width == 2) { @@ -201,7 +208,7 @@ static inline make_DHelper(SI2E) { static inline make_DHelper(SI_E2G) { assert(id_dest->width == 2 || id_dest->width == 4); - decode_op_rm(s, id_src2, true, id_dest, false); + operand_rm(s, id_src2, true, id_dest, false); id_src1->width = 1; decode_op_SI(s, id_src1, true); if (id_dest->width == 2) { @@ -210,25 +217,17 @@ static inline make_DHelper(SI_E2G) { } static inline make_DHelper(gp2_1_E) { - decode_op_rm(s, id_dest, true, NULL, false); - id_src1->type = OP_TYPE_IMM; - id_src1->imm = 1; - rtl_li(s, dsrc1, 1); - - print_Dop(id_src1->str, OP_STR_SIZE, "$1"); + operand_rm(s, id_dest, true, NULL, false); + operand_imm(s, id_src1, true, 1, 1); } static inline make_DHelper(gp2_cl2E) { - decode_op_rm(s, id_dest, true, NULL, false); - id_src1->type = OP_TYPE_REG; - id_src1->reg = R_CL; - rtl_lr(s, dsrc1, R_CL, 1); - - print_Dop(id_src1->str, OP_STR_SIZE, "%%cl"); + operand_rm(s, id_dest, true, NULL, false); + operand_reg(s, id_src1, true, R_CL, 1); } static inline make_DHelper(gp2_Ib2E) { - decode_op_rm(s, id_dest, true, NULL, false); + operand_rm(s, id_dest, true, NULL, false); id_src1->width = 1; decode_op_I(s, id_src1, true); } @@ -236,7 +235,7 @@ static inline make_DHelper(gp2_Ib2E) { /* Ev <- GvIb * use for shld/shrd */ static inline make_DHelper(Ib_G2E) { - decode_op_rm(s, id_dest, true, id_src2, true); + operand_rm(s, id_dest, true, id_src2, true); id_src1->width = 1; decode_op_I(s, id_src1, true); } @@ -244,12 +243,8 @@ static inline make_DHelper(Ib_G2E) { /* Ev <- GvCL * use for shld/shrd */ static inline make_DHelper(cl_G2E) { - decode_op_rm(s, id_dest, true, id_src2, true); - id_src1->type = OP_TYPE_REG; - id_src1->reg = R_CL; - rtl_lr(s, dsrc1, R_CL, 1); - - print_Dop(id_src1->str, OP_STR_SIZE, "%%cl"); + operand_rm(s, id_dest, true, id_src2, true); + operand_reg(s, id_src1, true, R_CL, 1); } static inline make_DHelper(O2a) { @@ -279,12 +274,7 @@ static inline make_DHelper(in_I2a) { } static inline make_DHelper(in_dx2a) { - id_src1->type = OP_TYPE_REG; - id_src1->reg = R_DX; - rtl_lr(s, dsrc1, R_DX, 2); - - print_Dop(id_src1->str, OP_STR_SIZE, "(%%dx)"); - + operand_reg(s, id_src1, true, R_DX, 2); decode_op_a(s, id_dest, false); } @@ -296,16 +286,11 @@ static inline make_DHelper(out_a2I) { static inline make_DHelper(out_a2dx) { decode_op_a(s, id_src1, true); - - id_dest->type = OP_TYPE_REG; - id_dest->reg = R_DX; - rtl_lr(s, ddest, R_DX, 2); - - print_Dop(id_dest->str, OP_STR_SIZE, "(%%dx)"); + operand_reg(s, id_dest, true, R_DX, 2); } static inline void operand_write(DecodeExecState *s, Operand *op, rtlreg_t* src) { if (op->type == OP_TYPE_REG) { rtl_sr(s, op->reg, src, op->width); } - else if (op->type == OP_TYPE_MEM) { rtl_sm(s, &op->addr, src, op->width); } + else if (op->type == OP_TYPE_MEM) { rtl_sm(s, s->isa.mbase, s->isa.moff, src, op->width); } else { assert(0); } } diff --git a/src/isa/x86/local-include/rtl.h b/src/isa/x86/local-include/rtl.h index 305f0386b63b0cffeea18de38d50ffb669324cd0..4dfef981fee86ea99170560817265f3cd2006661 100644 --- a/src/isa/x86/local-include/rtl.h +++ b/src/isa/x86/local-include/rtl.h @@ -29,14 +29,14 @@ static inline make_rtl(push, const rtlreg_t* src1) { // M[esp] <- src1 // TODO(); rtl_subi(s, &cpu.esp, &cpu.esp, 4); - rtl_sm(s, &cpu.esp, src1, 4); + rtl_sm(s, &cpu.esp, 0, src1, 4); } static inline make_rtl(pop, rtlreg_t* dest) { // dest <- M[esp] // esp <- esp + 4 // TODO(); - rtl_lm(s, dest, &cpu.esp, 4); + rtl_lm(s, dest, &cpu.esp, 0, 4); rtl_addi(s, &cpu.esp, &cpu.esp, 4); } diff --git a/src/monitor/cpu-exec.c b/src/monitor/cpu-exec.c index bedebc73c84d845b4c4bb39da48cdf3a87acd348..b744295bf74a24845ba4fad45a8b37b07372ef88 100644 --- a/src/monitor/cpu-exec.c +++ b/src/monitor/cpu-exec.c @@ -19,6 +19,7 @@ CPU_state cpu; NEMUState nemu_state = {.state = NEMU_STOP}; static uint64_t g_nr_guest_instr = 0; +const rtlreg_t rzero = 0; void asm_print(vaddr_t ori_pc, int instr_len, bool print_flag);