Skip to content

Commit

Permalink
jit: Fix float-point instruction (sysprog21#172)
Browse files Browse the repository at this point in the history
This commit modifies the file src/softfloat.h, which is then traced in
the gen-jit script to include an enumeration for floating-point
instructions. Moreover, the data structure of riscv_internal is updated
to streamline the definition of JIT code generation.

To improve efficiency and codebase clarity, the fields necessary for JIT
are relocated to the top of the data structure.

Close sysprog21#169
  • Loading branch information
Yen-Fu Chen committed Aug 14, 2023
1 parent 5208f60 commit 34b7057
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 53 deletions.
57 changes: 31 additions & 26 deletions src/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
} \
}
Expand All @@ -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);
})

Expand All @@ -152,15 +150,13 @@ 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"); \
} \
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"); \
Expand All @@ -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)})
Expand All @@ -212,43 +208,53 @@ 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);
})

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");
}
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");
Expand All @@ -259,15 +265,13 @@ 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");
}
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");
Expand All @@ -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

Expand Down Expand Up @@ -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");
Expand All @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
26 changes: 17 additions & 9 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,4 +394,4 @@ uint32_t csr_csrrc(riscv_t *rv, uint32_t csr, uint32_t val)
*c &= ~val;
return out;
}
#endif
#endif
29 changes: 15 additions & 14 deletions src/riscv_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
12 changes: 11 additions & 1 deletion tools/gen-jit-template.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@
"sb",
"sh",
"sw",
"flw",
"fsw",
"clw",
"csw",
"cjal",
Expand All @@ -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)


Expand All @@ -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)
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit 34b7057

Please sign in to comment.