提交 c9463c09 编写于 作者: Z Zihao Yu

Merge branch 'word-rtl' into 'master'

Word rtl

See merge request projectn/nemu!60
......@@ -27,6 +27,7 @@ paddr_t isa_mmu_translate(vaddr_t vaddr, int type, int len);
#ifndef isa_vaddr_check
int isa_vaddr_check(vaddr_t vaddr, int type, int len);
#endif
#define isa_has_mem_exception concat(__ISA__, _has_mem_exception)
// difftest
// for dut
......
......@@ -76,5 +76,6 @@ typedef struct {
} mips32_ISADecodeInfo;
#define isa_vaddr_check(vaddr, type, len) ((vaddr & 0x80000000u) == 0 ? MEM_RET_NEED_TRANSLATE : MEM_RET_OK)
#define mips32_has_mem_exception() (cpu.mem_exception != 0)
#endif
......@@ -108,5 +108,6 @@ typedef struct {
} riscv32_ISADecodeInfo;
#define isa_vaddr_check(vaddr, type, len) (cpu.satp.mode ? MEM_RET_NEED_TRANSLATE : MEM_RET_OK)
#define riscv32_has_mem_exception() (false)
#endif
......@@ -96,4 +96,6 @@ typedef struct {
} instr;
} riscv64_ISADecodeInfo;
#define riscv64_has_mem_exception() (cpu.mem_exception != 0)
#endif
......@@ -101,5 +101,6 @@ typedef struct {
#define suffix_char(width) ((width) == 4 ? 'l' : ((width) == 1 ? 'b' : ((width) == 2 ? 'w' : '?')))
#define isa_vaddr_check(vaddr, type, len) (cpu.cr0.paging ? MEM_RET_NEED_TRANSLATE : MEM_RET_OK)
#define x86_has_mem_exception() (false)
#endif
......@@ -14,15 +14,29 @@
#define c_and(a, b) ((a) & (b))
#define c_or(a, b) ((a) | (b))
#define c_xor(a, b) ((a) ^ (b))
#define c_shl(a, b) ((a) << (b & c_shift_mask))
#define c_shr(a, b) ((a) >> (b & c_shift_mask))
#define c_sar(a, b) ((sword_t)(a) >> (b & c_shift_mask))
#define c_shl(a, b) ((a) << ((b) & c_shift_mask))
#define c_shr(a, b) ((a) >> ((b) & c_shift_mask))
#define c_sar(a, b) ((sword_t)(a) >> ((b) & c_shift_mask))
#ifdef ISA64
#define c_sext32to64(a) ((int64_t)(int32_t)(a))
#define c_addw(a, b) c_sext32to64((a) + (b))
#define c_subw(a, b) c_sext32to64((a) - (b))
#define c_shlw(a, b) c_sext32to64((uint32_t)(a) << ((b) & 0x1f))
#define c_shrw(a, b) c_sext32to64((uint32_t)(a) >> ((b) & 0x1f))
#define c_sarw(a, b) c_sext32to64(( int32_t)(a) >> ((b) & 0x1f))
#endif
#define c_mul_lo(a, b) ((a) * (b))
#define c_imul_lo(a, b) ((sword_t)(a) * (sword_t)(b))
#ifdef ISA64
# define c_mul_hi(a, b) (((__uint128_t)(a) * (__uint128_t)(b)) >> 64)
# define c_imul_hi(a, b) (((__int128_t)(sword_t)(a) * (__int128_t)(sword_t)(b)) >> 64)
# define c_mulw(a, b) c_sext32to64((a) * (b))
# define c_divw(a, b) c_sext32to64(( int32_t)(a) / ( int32_t)(b))
# define c_divuw(a, b) c_sext32to64((uint32_t)(a) / (uint32_t)(b))
# define c_remw(a, b) c_sext32to64(( int32_t)(a) % ( int32_t)(b))
# define c_remuw(a, b) c_sext32to64((uint32_t)(a) % (uint32_t)(b))
#else
# define c_mul_hi(a, b) (((uint64_t)(a) * (uint64_t)(b)) >> 32)
# define c_imul_hi(a, b) (((int64_t)(sword_t)(a) * (int64_t)(sword_t)(b)) >> 32)
......
......@@ -31,6 +31,18 @@ make_rtl_compute_reg_imm(shl)
make_rtl_compute_reg_imm(shr)
make_rtl_compute_reg_imm(sar)
#ifdef ISA64
make_rtl_compute_reg_imm(addw)
make_rtl_compute_reg_imm(subw)
make_rtl_compute_reg_imm(shlw)
make_rtl_compute_reg_imm(shrw)
make_rtl_compute_reg_imm(sarw)
#define rtl_addiw rtl_addwi
#define rtl_shliw rtl_shlwi
#define rtl_shriw rtl_shrwi
#define rtl_sariw rtl_sarwi
#endif
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);
......@@ -52,6 +64,14 @@ make_rtl_compute_reg(div_r)
make_rtl_compute_reg(idiv_q)
make_rtl_compute_reg(idiv_r)
#ifdef ISA64
make_rtl_compute_reg(mulw)
make_rtl_compute_reg(divw)
make_rtl_compute_reg(divuw)
make_rtl_compute_reg(remw)
make_rtl_compute_reg(remuw)
#endif
static inline make_rtl(div64_q, rtlreg_t* dest,
const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) {
uint64_t dividend = ((uint64_t)(*src1_hi) << 32) | (*src1_lo);
......@@ -83,13 +103,26 @@ static inline make_rtl(idiv64_r, rtlreg_t* dest,
// memory
static inline make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, word_t offset, int len) {
*dest = vaddr_read(*addr + offset, len);
word_t val = vaddr_read(*addr + offset, len);
if (!isa_has_mem_exception()) *dest = val;
}
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(lms, rtlreg_t *dest, const rtlreg_t* addr, word_t offset, int len) {
word_t val = vaddr_read(*addr + offset, len);
if (!isa_has_mem_exception()) {
switch (len) {
case 4: *dest = (sword_t)(int32_t)val; return;
case 1: *dest = (sword_t)( int8_t)val; return;
case 2: *dest = (sword_t)(int16_t)val; return;
default: assert(0);
}
}
}
static inline make_rtl(host_lm, rtlreg_t* dest, const void *addr, int len) {
switch (len) {
case 4: *dest = *(uint32_t *)addr; return;
......
......@@ -24,6 +24,18 @@ 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);
#ifdef ISA64
make_rtl(addw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(subw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(shlw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(shrw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(sarw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(addiw, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm);
make_rtl(shliw, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm);
make_rtl(shriw, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm);
make_rtl(sariw, rtlreg_t* dest, const rtlreg_t *src1, const sword_t imm);
#endif
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);
......@@ -37,8 +49,17 @@ make_rtl(div64_r, rtlreg_t* dest, const rtlreg_t* src1_hi, const rtlreg_t* src1_
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);
#ifdef ISA64
make_rtl(mulw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(divw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(divuw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(remw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
make_rtl(remuw, rtlreg_t* dest, const rtlreg_t *src1, const rtlreg_t *src2);
#endif
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(lms, rtlreg_t *dest, const rtlreg_t* addr, const sword_t offset, 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);
......
......@@ -102,6 +102,16 @@ make_rtl_compute_reg(sar, sra)
make_rtl_compute_imm(shli, slli)
make_rtl_compute_imm(shri, srli)
make_rtl_compute_imm(sari, srai)
make_rtl_compute_reg(addw, addw)
make_rtl_compute_reg(subw, subw)
make_rtl_compute_reg(shlw, sllw)
make_rtl_compute_reg(shrw, srlw)
make_rtl_compute_reg(sarw, sraw)
make_rtl_compute_imm_opt(addiw, addw, addiw)
make_rtl_compute_imm(shliw, slliw)
make_rtl_compute_imm(shriw, srliw)
make_rtl_compute_imm(sariw, sraiw)
#else
make_rtl_compute_reg(add, addw)
make_rtl_compute_reg(sub, subw)
......@@ -151,6 +161,12 @@ make_rtl_compute_reg(div_q, divu)
make_rtl_compute_reg(div_r, remu)
make_rtl_compute_reg(idiv_q, div)
make_rtl_compute_reg(idiv_r, rem)
make_rtl_compute_reg(mulw, mulw)
make_rtl_compute_reg(divw, divw)
make_rtl_compute_reg(divuw, divuw)
make_rtl_compute_reg(remw, remw)
make_rtl_compute_reg(remuw, remuw)
#else
make_rtl_compute_reg(mul_lo, mulw)
make_rtl_compute_reg(imul_lo, mulw)
......@@ -209,30 +225,33 @@ make_x86_div64(div64_r, rv64_zextw, remu)
make_x86_div64(idiv64_q, rv64_sextw, div)
make_x86_div64(idiv64_r, rv64_sextw, rem)
make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, const sword_t imm, int len) {
uint32_t ret = rtlreg2rvidx_pair(s, dest, false, addr, true);
uint32_t dest_rvidx = ret >> 16;
uint32_t addr_rvidx = ret & 0xffff;
uint32_t addr_rvidx_final = dest_rvidx;
if (dest_rvidx == 0) return;
static inline int prepare_addr(int addr_rvidx_final, int addr_rvidx, 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)) & 0xfffffu;
if (addr == rz) rv64_lui(dest_rvidx, lui_imm);
if (addr_rvidx == 0) rv64_lui(addr_rvidx_final, lui_imm);
else if (lui_imm == 0) {
#ifdef ISA64
addr_rvidx_final = addr_rvidx;
#else
rv64_zextw(dest_rvidx, addr_rvidx);
rv64_zextw(addr_rvidx_final, addr_rvidx);
#endif
}
else {
rv64_lui(tmp0, lui_imm);
rv64_add(dest_rvidx, tmp0, addr_rvidx);
rv64_zextw(dest_rvidx, dest_rvidx);
rv64_add(addr_rvidx_final, tmp0, addr_rvidx);
rv64_zextw(addr_rvidx_final, addr_rvidx_final);
}
return addr_rvidx_final;
}
make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, const sword_t imm, int len) {
uint32_t ret = rtlreg2rvidx_pair(s, dest, false, addr, true);
uint32_t dest_rvidx = ret >> 16;
uint32_t addr_rvidx = ret & 0xffff;
if (dest_rvidx == 0) return;
uint32_t addr_rvidx_final = prepare_addr(dest_rvidx, addr_rvidx, imm);
switch (len) {
case 1: rv64_lbu(dest_rvidx, addr_rvidx_final, imm & 0xfff); break;
case 2: rv64_lhu(dest_rvidx, addr_rvidx_final, imm & 0xfff); break;
......@@ -247,27 +266,28 @@ make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, const sword_t imm, int len) {
spill_set_dirty_rvidx(dest_rvidx);
}
make_rtl(lms, rtlreg_t *dest, const rtlreg_t* addr, const sword_t imm, int len) {
uint32_t ret = rtlreg2rvidx_pair(s, dest, false, addr, true);
uint32_t dest_rvidx = ret >> 16;
uint32_t addr_rvidx = ret & 0xffff;
if (dest_rvidx == 0) return;
uint32_t addr_rvidx_final = prepare_addr(dest_rvidx, addr_rvidx, imm);
switch (len) {
case 1: rv64_lb(dest_rvidx, addr_rvidx_final, imm & 0xfff); break;
case 2: rv64_lh(dest_rvidx, addr_rvidx_final, imm & 0xfff); break;
case 4: rv64_lw(dest_rvidx, addr_rvidx_final, imm & 0xfff); break;
default: assert(0);
}
spill_set_dirty_rvidx(dest_rvidx);
}
make_rtl(sm, const rtlreg_t* addr, const sword_t imm, const rtlreg_t* src1, int len) {
uint32_t ret = rtlreg2rvidx_pair(s, addr, true, src1, true);
uint32_t addr_rvidx = ret >> 16;
uint32_t src1_rvidx = ret & 0xffff;
uint32_t addr_rvidx_final = tmp0;
RV_IMM rv_imm = { .val = imm };
uint32_t lui_imm = (rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11)) & 0xfffffu;
if (addr == rz) rv64_lui(tmp0, lui_imm);
else if (lui_imm == 0) {
#ifdef ISA64
addr_rvidx_final = addr_rvidx;
#else
rv64_zextw(tmp0, addr_rvidx);
#endif
}
else {
rv64_lui(tmp0, lui_imm);
rv64_add(tmp0, tmp0, addr_rvidx);
rv64_zextw(tmp0, tmp0);
}
uint32_t addr_rvidx_final = prepare_addr(tmp0, addr_rvidx, imm);
switch (len) {
case 1: rv64_sb(src1_rvidx, addr_rvidx_final, imm & 0xfff); break;
case 2: rv64_sh(src1_rvidx, addr_rvidx_final, imm & 0xfff); break;
......
......@@ -68,7 +68,7 @@ static inline make_EHelper(cop0) {
static inline void exec(DecodeExecState *s) {
s->isa.instr.val = instr_fetch(&s->seq_pc, 4);
check_mem_ex();
return_on_mem_ex();
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)
......
#include "../local-include/intr.h"
static inline make_EHelper(ld) {
rtl_lm(s, s0, dsrc1, id_src2->imm, s->width);
check_mem_ex();
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->imm, reg_name(id_src1->reg, 4));
switch (s->width) {
......@@ -16,9 +14,7 @@ static inline make_EHelper(ld) {
// load sign value
static inline make_EHelper(lds) {
rtl_lm(s, s0, dsrc1, id_src2->imm, s->width);
check_mem_ex();
rtl_sext(s, ddest, s0, s->width);
rtl_lms(s, ddest, dsrc1, id_src2->imm, s->width);
print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4));
switch (s->width) {
......@@ -30,7 +26,6 @@ static inline make_EHelper(lds) {
static inline make_EHelper(st) {
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) {
......@@ -51,7 +46,7 @@ static inline make_EHelper(swl) {
// load the aligned memory word
rtl_andi(s, s0, s0, ~0x3u);
rtl_lm(s, s0, s0, 0, 4);
check_mem_ex();
return_on_mem_ex();
// prepare memory data
rtl_shri(s, s0, s0, 8); // shift 8 bit
......@@ -73,7 +68,7 @@ static inline make_EHelper(swl) {
rtl_addi(s, s0, dsrc1, id_src2->imm);
rtl_andi(s, s0, s0, ~0x3u);
rtl_sm(s, s0, 0, s1, 4);
check_mem_ex();
return_on_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);
......@@ -91,7 +86,7 @@ static inline make_EHelper(swr) {
// load the aligned memory word
rtl_andi(s, s0, s0, ~0x3u);
rtl_lm(s, s0, s0, 0, 4);
check_mem_ex();
return_on_mem_ex();
// prepare memory data
rtl_shli(s, s0, s0, 8); // shift 8 bit
......@@ -113,7 +108,7 @@ static inline make_EHelper(swr) {
rtl_addi(s, s0, dsrc1, id_src2->imm);
rtl_andi(s, s0, s0, ~0x3u);
rtl_sm(s, s0, 0, s1, 4);
check_mem_ex();
return_on_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);
......@@ -131,7 +126,7 @@ static inline make_EHelper(lwl) {
// load the aligned memory word
rtl_andi(s, s0, s0, ~0x3u);
rtl_lm(s, s0, s0, 0, 4);
check_mem_ex();
return_on_mem_ex();
// prepare memory data
rtl_shl(s, s0, s0, s1);
......@@ -163,7 +158,7 @@ static inline make_EHelper(lwr) {
// load the aligned memory word
rtl_andi(s, s0, s0, ~0x3u);
rtl_lm(s, s0, s0, 0, 4);
check_mem_ex();
return_on_mem_ex();
// prepare memory data
rtl_shr(s, s0, s0, s1);
......
......@@ -11,6 +11,6 @@
#define MEM_OK 0
void raise_intr(DecodeExecState *s, uint32_t NO, vaddr_t epc);
#define check_mem_ex() do { if (cpu.mem_exception != MEM_OK) return; } while (0)
#define return_on_mem_ex() do { if (cpu.mem_exception != MEM_OK) return; } while (0)
#endif
......@@ -12,8 +12,7 @@ static inline make_EHelper(ld) {
// load sign value
static inline make_EHelper(lds) {
rtl_lm(s, s0, dsrc1, id_src2->imm, s->width);
rtl_sext(s, ddest, s0, s->width);
rtl_lms(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) {
......
......@@ -2,7 +2,7 @@
static inline make_EHelper(lr) {
rtl_lm(s, s0, dsrc1, 0, s->width);
check_mem_ex();
return_on_mem_ex();
cpu.lr_addr = *dsrc1;
rtl_sext(s, ddest, s0, s->width);
......@@ -13,7 +13,7 @@ static inline make_EHelper(sc) {
// should check overlapping instead of equality
if (cpu.lr_addr == *dsrc1) {
rtl_sm(s, dsrc1, 0, dsrc2, s->width);
check_mem_ex();
return_on_mem_ex();
rtl_li(s, s0, 0);
} else {
rtl_li(s, s0, 1);
......@@ -30,60 +30,60 @@ static void inline amo_load(DecodeExecState *s) {
static void inline amo_update(DecodeExecState *s) {
rtl_sm(s, dsrc1, 0, s1, s->width);
check_mem_ex();
return_on_mem_ex();
rtl_sr(s, id_dest->reg, s0, 0);
}
static inline make_EHelper(amoswap) {
amo_load(s);
check_mem_ex();
return_on_mem_ex();
rtl_mv(s, s1, dsrc2); // swap
amo_update(s);
check_mem_ex();
return_on_mem_ex();
print_asm_template3(amoswap);
}
static inline make_EHelper(amoadd) {
amo_load(s);
check_mem_ex();
return_on_mem_ex();
rtl_add(s, s1, s0, dsrc2);
amo_update(s);
check_mem_ex();
return_on_mem_ex();
print_asm_template3(amoor);
}
static inline make_EHelper(amoor) {
amo_load(s);
check_mem_ex();
return_on_mem_ex();
rtl_or(s, s1, s0, dsrc2);
amo_update(s);
check_mem_ex();
return_on_mem_ex();
print_asm_template3(amoor);
}
static inline make_EHelper(amoand) {
amo_load(s);
check_mem_ex();
return_on_mem_ex();
rtl_and(s, s1, s0, dsrc2);
amo_update(s);
check_mem_ex();
return_on_mem_ex();
print_asm_template3(amoand);
}
static inline make_EHelper(amomaxu) {
amo_load(s);
check_mem_ex();
return_on_mem_ex();
*s1 = (*s0 > *dsrc2 ? *s0 : *dsrc2);
amo_update(s);
check_mem_ex();
return_on_mem_ex();
print_asm_template3(amomaxu);
}
static inline make_EHelper(amoxor) {
amo_load(s);
check_mem_ex();
return_on_mem_ex();
rtl_xor(s, s1, s0, dsrc2);
amo_update(s);
check_mem_ex();
return_on_mem_ex();
print_asm_template3(amoxor);
}
......@@ -116,40 +116,30 @@ static inline make_EHelper(lui) {
}
static inline make_EHelper(addw) {
rtl_add(s, s0, dsrc1, dsrc2);
rtl_sext(s, ddest, s0, 4);
rtl_addw(s, ddest, dsrc1, dsrc2);
print_asm_template3(addw);
}
static inline make_EHelper(subw) {
rtl_sub(s, s0, dsrc1, dsrc2);
rtl_sext(s, ddest, s0, 4);
rtl_subw(s, ddest, dsrc1, dsrc2);
print_asm_template3(subw);
}
static inline make_EHelper(sllw) {
rtl_andi(s, s0, dsrc2, 0x1f);
rtl_shl(s, s0, dsrc1, s0);
rtl_sext(s, ddest, s0, 4);
rtl_shlw(s, ddest, dsrc1, dsrc2);
print_asm_template3(sllw);
}
static inline make_EHelper(srlw) {
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, s1, dsrc1, 4);
rtl_sar(s, s0, s1, s0);
rtl_sarw(s, ddest, dsrc1, dsrc2);
print_asm_template3(sraw);
}
else {
// srlw
rtl_zext(s, s1, dsrc1, 4);
rtl_shr(s, s0, s1, s0);
rtl_shrw(s, ddest, dsrc1, dsrc2);
print_asm_template3(srlw);
}
rtl_sext(s, ddest, s0, 4);
}
static inline make_EHelper(sraw) {
......@@ -157,31 +147,23 @@ static inline make_EHelper(sraw) {
}
static inline make_EHelper(addiw) {
rtl_addi(s, s0, dsrc1, id_src2->imm);
rtl_sext(s, ddest, s0, 4);
rtl_addiw(s, ddest, dsrc1, id_src2->imm);
print_asm_template3(addiw);
}
static inline make_EHelper(slliw) {
rtl_shli(s, s0, dsrc1, id_src2->imm & 0x1f);
rtl_sext(s, ddest, s0, 4);
rtl_shliw(s, ddest, dsrc1, id_src2->imm);
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);
rtl_sariw(s, ddest, dsrc1, id_src2->imm);
print_asm_template3(sraiw);
}
else {
// srlw
rtl_zext(s, s0, dsrc1, 4);
rtl_shri(s, s0, s0, id_src2->imm & 0x1f);
rtl_shriw(s, ddest, dsrc1, id_src2->imm);
print_asm_template3(srliw);
}
rtl_sext(s, ddest, s0, 4);
}
......@@ -160,7 +160,7 @@ static inline void exec(DecodeExecState *s) {
if ((s->seq_pc & 0xfff) == 0xffe) {
// instruction may accross page boundary
uint32_t lo = instr_fetch(&s->seq_pc, 2);
check_mem_ex();
return_on_mem_ex();
s->isa.instr.val = lo & 0xffff;
if (s->isa.instr.r.opcode1_0 != 0x3) {
// this is an RVC instruction
......@@ -178,7 +178,7 @@ static inline void exec(DecodeExecState *s) {
s->isa.instr.val = instr_fetch(&s->seq_pc, 4);
}
check_mem_ex();
return_on_mem_ex();
if (s->isa.instr.r.opcode1_0 == 0x3) {
switch (s->isa.instr.r.opcode6_2) {
......
#include "../local-include/intr.h"
static inline make_EHelper(ld) {
rtl_lm(s, s0, dsrc1, id_src2->imm, s->width);
check_mem_ex();
rtl_mv(s, ddest, s0);
rtl_lm(s, ddest, dsrc1, id_src2->imm, s->width);
print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4));
switch (s->width) {
......@@ -17,9 +15,7 @@ static inline make_EHelper(ld) {
// load sign value
static inline make_EHelper(lds) {
rtl_lm(s, s0, dsrc1, id_src2->imm, s->width);
check_mem_ex();
rtl_sext(s, ddest, s0, s->width);
rtl_lms(s, ddest, dsrc1, id_src2->imm, s->width);
print_Dop(id_src1->str, OP_STR_SIZE, "%d(%s)", id_src2->imm, reg_name(id_src1->reg, 4));
switch (s->width) {
......@@ -32,7 +28,6 @@ static inline make_EHelper(lds) {
static inline make_EHelper(st) {
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) {
......
......@@ -81,12 +81,12 @@ static inline make_EHelper(remu) {
}
static inline make_EHelper(mulw) {
rtl_mul_lo(s, s0, dsrc1, dsrc2);
rtl_sext(s, ddest, s0, 4);
rtl_mulw(s, ddest, dsrc1, dsrc2);
print_asm_template3(mulw);
}
static inline make_EHelper(divw) {
#if 0
rtl_sext(s, s0, dsrc1, 4);
rtl_sext(s, s1, dsrc2, 4);
//if (*s1 == 0) {
......@@ -97,11 +97,13 @@ static inline make_EHelper(divw) {
rtl_idiv_q(s, s0, s0, s1);
//}
rtl_sext(s, ddest, s0, 4);
#endif
rtl_divw(s, ddest, dsrc1, dsrc2);
print_asm_template3(divw);
}
static inline make_EHelper(remw) {
#if 0
rtl_sext(s, s0, dsrc1, 4);
rtl_sext(s, s1, dsrc2, 4);
//if (*s1 == 0) {
......@@ -112,11 +114,13 @@ static inline make_EHelper(remw) {
rtl_idiv_r(s, s0, s0, s1);
//}
rtl_sext(s, ddest, s0, 4);
#endif
rtl_remw(s, ddest, dsrc1, dsrc2);
print_asm_template3(remw);
}
static inline make_EHelper(divuw) {
#if 0
rtl_zext(s, s0, dsrc1, 4);
rtl_zext(s, s1, dsrc2, 4);
//if (*s1 == 0) {
......@@ -125,11 +129,13 @@ static inline make_EHelper(divuw) {
rtl_div_q(s, s0, s0, s1);
//}
rtl_sext(s, ddest, s0, 4);
#endif
rtl_divuw(s, ddest, dsrc1, dsrc2);
print_asm_template3(divuw);
}
static inline make_EHelper(remuw) {
#if 0
rtl_zext(s, s0, dsrc1, 4);
rtl_zext(s, s1, dsrc2, 4);
//if (*s1 == 0) {
......@@ -138,6 +144,7 @@ static inline make_EHelper(remuw) {
rtl_div_r(s, s0, s0, s1);
//}
rtl_sext(s, ddest, s0, 4);
#endif
rtl_remuw(s, ddest, dsrc1, dsrc2);
print_asm_template3(remuw);
}
......@@ -27,7 +27,7 @@ enum {
#define MEM_OK 0
void raise_intr(DecodeExecState *s, word_t NO, vaddr_t epc);
#define check_mem_ex() do { if (cpu.mem_exception != MEM_OK) return; } while (0)
#define return_on_mem_ex() do { if (cpu.mem_exception != MEM_OK) return; } while (0)
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册