Skip to content

Commit

Permalink
Enable misaligned memory access
Browse files Browse the repository at this point in the history
  • Loading branch information
qwe661234 committed Apr 8, 2023
1 parent 8d6908f commit 21a4036
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 100 deletions.
133 changes: 33 additions & 100 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ static void rv_exception_default_handler(riscv_t *rv)
RV_EXCEPTION_LIST
#undef _

/* wrap load/store and insn misaligned handler */
#define RV_EXC_MISAGLIN_HANDLER(mask_or_pc, type, compress, IO) \
IIF(IO) \
(if (!rv->io.allow_misalign && unlikely(addr & (mask_or_pc))), \
if (unlikely(insn_is_misaligned(rv->PC)))) \
{ \
rv->compressed = compress; \
IIF(IO) \
(rv_except_##type##_misaligned(rv, addr), \
rv_except_##type##_misaligned(rv, mask_or_pc)); \
return false; \
}

/* Get current time in microsecnds and update csr_time register */
static inline void update_time(riscv_t *rv)
{
Expand Down Expand Up @@ -310,11 +323,7 @@ RVOP(jal, {
if (ir->rd)
rv->X[ir->rd] = pc + ir->insn_len;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
return true;
})

Expand All @@ -333,11 +342,7 @@ RVOP(jalr, {
if (ir->rd)
rv->X[ir->rd] = pc + ir->insn_len;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
return true;
})

Expand All @@ -352,11 +357,7 @@ RVOP(beq, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -373,11 +374,7 @@ RVOP(bne, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -394,11 +391,7 @@ RVOP(blt, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -415,11 +408,7 @@ RVOP(bge, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -436,11 +425,7 @@ RVOP(bltu, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -457,11 +442,7 @@ RVOP(bgeu, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -476,22 +457,14 @@ RVOP(lb, {
/* LH: Load Halfword */
RVOP(lh, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 1)) {
rv->compressed = false;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(1, load, false, 1);
rv->X[ir->rd] = sign_extend_h(rv->io.mem_read_s(rv, addr));
})

/* LW: Load Word */
RVOP(lw, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = false;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(3, load, false, 1);
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
})

Expand All @@ -501,11 +474,7 @@ RVOP(lbu, { rv->X[ir->rd] = rv->io.mem_read_b(rv, rv->X[ir->rs1] + ir->imm); })
/* LHU: Load Halfword Unsigned */
RVOP(lhu, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 1)) {
rv->compressed = false;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(1, load, false, 1);
rv->X[ir->rd] = rv->io.mem_read_s(rv, addr);
})

Expand All @@ -515,22 +484,14 @@ RVOP(sb, { rv->io.mem_write_b(rv, rv->X[ir->rs1] + ir->imm, rv->X[ir->rs2]); })
/* SH: Store Halfword */
RVOP(sh, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 1)) {
rv->compressed = false;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(1, store, false, 1);
rv->io.mem_write_s(rv, addr, rv->X[ir->rs2]);
})

/* SW: Store Word */
RVOP(sw, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = false;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(3, store, false, 1);
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
})

Expand Down Expand Up @@ -1088,11 +1049,7 @@ RVOP(caddi4spn, { rv->X[ir->rd] = rv->X[2] + (uint16_t) ir->imm; })
*/
RVOP(clw, {
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(3, load, true, 1);
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
})

Expand All @@ -1103,11 +1060,7 @@ RVOP(clw, {
*/
RVOP(csw, {
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(3, store, true, 1);
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
})

Expand All @@ -1126,11 +1079,7 @@ RVOP(caddi, { rv->X[ir->rd] += (int16_t) ir->imm; })
RVOP(cjal, {
rv->X[1] = rv->PC + ir->insn_len;
rv->PC += ir->imm;
if (unlikely(rv->PC & 0x1)) {
rv->compressed = true;
rv_except_insn_misaligned(rv, rv->PC);
return false;
}
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
return true;
})

Expand Down Expand Up @@ -1198,11 +1147,7 @@ RVOP(cand, { rv->X[ir->rd] = rv->X[ir->rs1] & rv->X[ir->rs2]; })
*/
RVOP(cj, {
rv->PC += ir->imm;
if (unlikely(rv->PC & 0x1)) {
rv->compressed = true;
rv_except_insn_misaligned(rv, rv->PC);
return false;
}
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
return true;
})

Expand Down Expand Up @@ -1249,11 +1194,7 @@ RVOP(cslli, { rv->X[ir->rd] <<= (uint8_t) ir->imm; })
/* C.LWSP */
RVOP(clwsp, {
const uint32_t addr = rv->X[rv_reg_sp] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(3, load, true, 1);
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
})

Expand All @@ -1279,11 +1220,7 @@ RVOP(cjalr, {
const int32_t jump_to = rv->X[ir->rs1];
rv->X[rv_reg_ra] = rv->PC + ir->insn_len;
rv->PC = jump_to;
if (unlikely(rv->PC & 0x1)) {
rv->compressed = true;
rv_except_insn_misaligned(rv, rv->PC);
return false;
}
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
return true;
})

Expand All @@ -1299,11 +1236,7 @@ RVOP(cadd, { rv->X[ir->rd] = rv->X[ir->rs1] + rv->X[ir->rs2]; })
/* C.SWSP */
RVOP(cswsp, {
const uint32_t addr = rv->X[2] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISAGLIN_HANDLER(3, store, true, 1);
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
})
#endif
Expand Down
10 changes: 10 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ static char *signature_out_file;
/* target executable */
static const char *opt_prog_name = "a.out";

/* enable misaligned memory access */
static bool opt_misaligned = false;

#define MEMIO(op) on_mem_##op
#define IO_HANDLER_IMPL(type, op, RW) \
static IIF(RW)( \
Expand Down Expand Up @@ -123,6 +126,12 @@ static bool parse_args(int argc, char **args)
signature_out_file = args[++i];
continue;
}

if (!strcmp(arg, "--misalign")) {
opt_misaligned = true;
continue;
}

/* otherwise, error */
fprintf(stderr, "Unknown argument '%s'\n", arg);
return false;
Expand Down Expand Up @@ -192,6 +201,7 @@ int main(int argc, char **args)
/* system */
.on_ecall = ecall_handler,
.on_ebreak = ebreak_handler,
.allow_misalign = opt_misaligned,
};

state_t *state = state_new();
Expand Down
3 changes: 3 additions & 0 deletions src/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ typedef struct {
/* system */
riscv_on_ecall on_ecall;
riscv_on_ebreak on_ebreak;

/* enable misaligned memory access */
bool allow_misalign;
} riscv_io_t;

/* create a RISC-V emulator */
Expand Down

0 comments on commit 21a4036

Please sign in to comment.