diff --git a/src/compile.c b/src/compile.c index e8dcfeb6..254d90a4 100644 --- a/src/compile.c +++ b/src/compile.c @@ -125,7 +125,6 @@ static char funcbuf[128] = {0}; code; \ if (!insn_is_branch(ir->opcode)) { \ GEN(" rv->PC += %d;\n", ir->insn_len); \ - GEN(" ir = ir + 1;\n"); \ NEXT_INSN(pc + ir->insn_len); \ } \ } @@ -143,7 +142,6 @@ RVOP(jal, { if (ir->rd) { GEN(" rv->X[%u] = pc + %u;\n", ir->rd, ir->insn_len); } - GEN(" ir = ir->branch_taken;\n"); NEXT_INSN(pc + ir->imm); }) @@ -152,7 +150,6 @@ RVOP(jal, { #type, ir->rs2); \ UPDATE_PC(ir->imm); \ if (ir->branch_taken) { \ - GEN(" ir = ir->branch_taken;\n"); \ NEXT_INSN(pc + ir->imm); \ } else { \ GEN(" return true;\n"); \ @@ -160,7 +157,6 @@ RVOP(jal, { GEN(" }\n"); \ UPDATE_PC(ir->insn_len); \ if (ir->branch_untaken) { \ - GEN(" ir = ir->branch_untaken;\n"); \ NEXT_INSN(pc + ir->insn_len); \ } else { \ GEN(" return true;\n"); \ @@ -180,24 +176,24 @@ RVOP(bgeu, { BRNACH_FUNC(uint32_t, >=); }) RVOP(lb, { GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); - GEN(" rv->X[%u] = sign_extend_b(* (const uint8_t *) (m->mem_base + " - "addr));\n", + GEN(" rv->X[%u] = sign_extend_b(*((const uint8_t *) (m->mem_base + " + "addr)));\n", ir->rd); }) RVOP(lh, { GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); - GEN(" rv->X[%u] = sign_extend_h(* (const uint16_t *) (m->mem_base + " - "addr));\n", + GEN(" rv->X[%u] = sign_extend_h(*((const uint16_t *) (m->mem_base + " + "addr)));\n", ir->rd); }) -#define MEMORY_FUNC(type, IO) \ - GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); \ - IIF(IO) \ - (GEN(" rv->X[%u] = * (const %s *) (m->mem_base + addr);\n", ir->rd, \ - #type), \ - GEN(" *(%s *) (m->mem_base + addr) = (%s) rv->X[%u];\n", #type, #type, \ +#define MEMORY_FUNC(type, IO) \ + GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); \ + IIF(IO) \ + (GEN(" rv->X[%u] = *((const %s *) (m->mem_base + addr));\n", ir->rd, \ + #type), \ + GEN(" *((%s *) (m->mem_base + addr)) = (%s) rv->X[%u];\n", #type, #type, \ ir->rs2)); RVOP(lw, {MEMORY_FUNC(uint32_t, 1)}) @@ -212,27 +208,39 @@ RVOP(sh, {MEMORY_FUNC(uint16_t, 0)}) RVOP(sw, {MEMORY_FUNC(uint32_t, 0)}) +#if RV32_HAS(EXT_F) +RVOP(flw, { + GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); + GEN(" rv->F_int[%u] = *((const uint32_t *) (m->mem_base + addr));\n", + ir->rd); +}) + +/* FSW */ +RVOP(fsw, { + GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); + GEN(" *((uint32_t *) (m->mem_base + addr)) = rv->F_int[%u];\n", ir->rs2); +}) +#endif + #if RV32_HAS(EXT_C) RVOP(clw, { GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); - GEN(" rv->X[%u] = * (const uint32_t *) (m->mem_base + addr);\n", ir->rd); + GEN(" rv->X[%u] = *((const uint32_t *) (m->mem_base + addr));\n", ir->rd); }) RVOP(csw, { GEN(" addr = rv->X[%u] + %u;\n", ir->rs1, ir->imm); - GEN(" *(uint32_t *) (m->mem_base + addr) = rv->X[%u];\n", ir->rs2); + GEN(" *((uint32_t *) (m->mem_base + addr)) = rv->X[%u];\n", ir->rs2); }) RVOP(cjal, { GEN(" rv->X[1] = rv->PC + %u;\n", ir->insn_len); UPDATE_PC(ir->imm); - GEN(" ir = ir->branch_taken;\n"); NEXT_INSN(pc + ir->imm); }) RVOP(cj, { UPDATE_PC(ir->imm); - GEN(" ir = ir->branch_taken;\n"); NEXT_INSN(pc + ir->imm); }) @@ -240,7 +248,6 @@ RVOP(cbeqz, { GEN(" if (!rv->X[%u]){\n", ir->rs1); UPDATE_PC(ir->imm); if (ir->branch_taken) { - GEN(" ir = ir->branch_taken;\n"); NEXT_INSN(pc + ir->imm); } else { GEN(" return true;\n"); @@ -248,7 +255,6 @@ RVOP(cbeqz, { GEN(" }\n"); UPDATE_PC(ir->insn_len); if (ir->branch_untaken) { - GEN(" ir = ir->branch_untaken;\n"); NEXT_INSN(pc + ir->insn_len); } else { GEN(" return true;\n"); @@ -259,7 +265,6 @@ RVOP(cbnez, { GEN(" if (rv->X[%u]){\n", ir->rs1); UPDATE_PC(ir->imm); if (ir->branch_taken) { - GEN(" ir = ir->branch_taken;\n"); NEXT_INSN(pc + ir->imm); } else { GEN(" return true;\n"); @@ -267,7 +272,6 @@ RVOP(cbnez, { GEN(" }\n"); UPDATE_PC(ir->insn_len); if (ir->branch_untaken) { - GEN(" ir = ir->branch_untaken;\n"); NEXT_INSN(pc + ir->insn_len); } else { GEN(" return true;\n"); @@ -276,12 +280,12 @@ RVOP(cbnez, { RVOP(clwsp, { GEN("addr = rv->X[rv_reg_sp] + %u;\n", ir->imm); - GEN(" rv->X[%u] = * (const uint32_t *) (m->mem_base + addr);\n", ir->rd); + GEN(" rv->X[%u] = *((const uint32_t *) (m->mem_base + addr));\n", ir->rd); }) RVOP(cswsp, { GEN("addr = rv->X[rv_reg_sp] + %u;\n", ir->imm); - GEN(" *(uint32_t *) (m->mem_base + addr) = rv->X[%u];\n", ir->rs2); + GEN(" *((uint32_t *) (m->mem_base + addr)) = rv->X[%u];\n", ir->rs2); }) #endif @@ -330,7 +334,8 @@ static void gen_fuse3(riscv_t *rv UNUSED, opcode_fuse_t *fuse = ir->fuse; for (int i = 0; i < ir->imm2; i++) { GEN(" addr = rv->X[%u] + %u;\n", fuse[i].rs1, fuse[i].imm); - GEN(" *(uint32_t *) (m->mem_base + addr) = rv->X[%u];\n", fuse[i].rs2) + GEN(" *((uint32_t *) (m->mem_base + addr)) = rv->X[%u];\n", + fuse[i].rs2) } GEN(" rv->PC += ir->imm2 * ir->insn_len;\n"); GEN(" ir = ir + ir->imm2;\n"); @@ -349,7 +354,7 @@ static void gen_fuse4(riscv_t *rv UNUSED, opcode_fuse_t *fuse = ir->fuse; for (int i = 0; i < ir->imm2; i++) { GEN(" addr = rv->X[%u] + %u;\n", fuse[i].rs1, fuse[i].imm); - GEN(" rv->X[%u] = * (const uint32_t *) (m->mem_base + addr);\n", + GEN(" rv->X[%u] = *((const uint32_t *) (m->mem_base + addr));\n", fuse[i].rd); } GEN(" rv->PC += ir->imm2 * ir->insn_len;\n"); diff --git a/src/emulate.c b/src/emulate.c index b1dca6f8..c92c775f 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -576,7 +576,7 @@ static block_t *block_find_or_translate(riscv_t *rv) } #if RV32_HAS(JIT) -typedef bool (*exec_block_func_t)(riscv_t *rv, rv_insn_t *ir); +typedef bool (*exec_block_func_t)(riscv_t *rv); #endif void rv_step(riscv_t *rv, int32_t cycles) @@ -648,7 +648,7 @@ void rv_step(riscv_t *rv, int32_t cycles) } if (code) { /* execute machine code */ - code(rv, block->ir); + code(rv); /* block should not be extended if execution mode is jit */ prev = NULL; continue; diff --git a/src/io.c b/src/io.c index ad78c50f..8d53575f 100644 --- a/src/io.c +++ b/src/io.c @@ -72,23 +72,31 @@ uint32_t memory_read_str(memory_t *mem, uint32_t memory_ifetch(uint32_t addr) { - return *(const uint32_t *) (data_memory_base + addr); + return *((const uint32_t *) (data_memory_base + addr)); } -#define MEM_READ_IMPL(size, type) \ - type memory_read_##size(uint32_t addr) \ - { \ - return *(type *) (data_memory_base + addr); \ +#define MEM_READ_IMPL(size, type) \ + type memory_read_##size(uint32_t addr) \ + { \ + return *((type *) (data_memory_base + addr)); \ } MEM_READ_IMPL(w, uint32_t); MEM_READ_IMPL(s, uint16_t); MEM_READ_IMPL(b, uint8_t); -#define MEM_WRITE_IMPL(size, type) \ - void memory_write_##size(uint32_t addr, const uint8_t *src) \ - { \ - *(type *) (data_memory_base + addr) = *(const type *) src; \ +void memory_write(memory_t *mem, + uint32_t addr, + const uint8_t *src, + uint32_t size) +{ + memcpy(mem->mem_base + addr, src, size); +} + +#define MEM_WRITE_IMPL(size, type) \ + void memory_write_##size(uint32_t addr, const uint8_t *src) \ + { \ + *((type *) (data_memory_base + addr)) = *((const type *) src); \ } MEM_WRITE_IMPL(w, uint32_t); diff --git a/src/riscv.c b/src/riscv.c index 9694c723..632cf4bc 100644 --- a/src/riscv.c +++ b/src/riscv.c @@ -394,4 +394,4 @@ uint32_t csr_csrrc(riscv_t *rv, uint32_t csr, uint32_t val) *c &= ~val; return out; } -#endif \ No newline at end of file +#endif diff --git a/src/riscv_private.h b/src/riscv_private.h index 50318a21..1ce1cc90 100644 --- a/src/riscv_private.h +++ b/src/riscv_private.h @@ -93,20 +93,6 @@ struct riscv_internal { /* user provided data */ riscv_user_t userdata; -#if RV32_HAS(GDBSTUB) - /* gdbstub instance */ - gdbstub_t gdbstub; - - bool debug_mode; - - /* GDB instruction breakpoint */ - breakpoint_map_t breakpoint_map; - - /* The flag to notify interrupt from GDB client: it should - * be accessed by atomic operation when starting the GDBSTUB. */ - bool is_interrupted; -#endif - #if RV32_HAS(EXT_F) /* float registers */ union { @@ -130,6 +116,21 @@ struct riscv_internal { uint32_t csr_mbadaddr; bool compressed; /**< current instruction is compressed or not */ + +#if RV32_HAS(GDBSTUB) + /* gdbstub instance */ + gdbstub_t gdbstub; + + bool debug_mode; + + /* GDB instruction breakpoint */ + breakpoint_map_t breakpoint_map; + + /* The flag to notify interrupt from GDB client: it should + * be accessed by atomic operation when starting the GDBSTUB. */ + bool is_interrupted; +#endif + #if !RV32_HAS(JIT) block_map_t block_map; /**< basic block map */ #else diff --git a/tools/gen-jit-template.py b/tools/gen-jit-template.py index 1829eb7d..2341b30c 100755 --- a/tools/gen-jit-template.py +++ b/tools/gen-jit-template.py @@ -113,6 +113,8 @@ "sb", "sh", "sw", + "flw", + "fsw", "clw", "csw", "cjal", @@ -137,6 +139,7 @@ def parse_argv(EXT_LIST, SKIPLIST): def remove_comment(str): + str = re.sub(r'//[\s|\S]+?\n', "", str) return re.sub(r'/\*[\s|\S]+?\*/\n', "", str) @@ -152,6 +155,13 @@ def remove_comment(str): output = output + "\"" + \ re.sub("\n", "\"\\\n\"", re.findall( r'enum[\S|\s]+?riscv_io_t;', lines)[0]) + "\"\\\n" +if sys.argv.count("RV32_FEATURE_EXT_F=1"): + f = open('src/softfloat.h', 'r') + lines = f.read() + lines = remove_comment(lines) + output = output + "\"" + \ + re.sub("\n", "\"\\\n\"", re.findall( + r'enum[\S|\s]+?};', lines)[0]) + "\"\\\n" f = open('src/riscv_private.h', 'r') lines = f.read() lines = remove_comment(lines) @@ -183,7 +193,7 @@ def remove_comment(str): output = output + "\"" + \ re.sub("\n", "\"\\\n\"", re.findall( r'typedef[\S|\s]+?rv_insn_t;', lines)[0]) + "\"\\\n" -output += "\"bool start(volatile riscv_t *rv, rv_insn_t *ir) {\"\\\n" +output += "\"bool start(riscv_t *rv) {\"\\\n" output += "\" uint32_t pc, addr, udividend, udivisor, tmp, data, mask, ures, \"\\\n" output += "\"a, b, jump_to;\"\\\n" output += "\" int32_t dividend, divisor, res;\"\\\n"