Skip to content

Commit 21a4036

Browse files
committed
Enable misaligned memory access
1 parent 8d6908f commit 21a4036

File tree

3 files changed

+46
-100
lines changed

3 files changed

+46
-100
lines changed

src/emulate.c

+33-100
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ static void rv_exception_default_handler(riscv_t *rv)
9090
RV_EXCEPTION_LIST
9191
#undef _
9292

93+
/* wrap load/store and insn misaligned handler */
94+
#define RV_EXC_MISAGLIN_HANDLER(mask_or_pc, type, compress, IO) \
95+
IIF(IO) \
96+
(if (!rv->io.allow_misalign && unlikely(addr & (mask_or_pc))), \
97+
if (unlikely(insn_is_misaligned(rv->PC)))) \
98+
{ \
99+
rv->compressed = compress; \
100+
IIF(IO) \
101+
(rv_except_##type##_misaligned(rv, addr), \
102+
rv_except_##type##_misaligned(rv, mask_or_pc)); \
103+
return false; \
104+
}
105+
93106
/* Get current time in microsecnds and update csr_time register */
94107
static inline void update_time(riscv_t *rv)
95108
{
@@ -310,11 +323,7 @@ RVOP(jal, {
310323
if (ir->rd)
311324
rv->X[ir->rd] = pc + ir->insn_len;
312325
/* check instruction misaligned */
313-
if (unlikely(insn_is_misaligned(rv->PC))) {
314-
rv->compressed = false;
315-
rv_except_insn_misaligned(rv, pc);
316-
return false;
317-
}
326+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
318327
return true;
319328
})
320329

@@ -333,11 +342,7 @@ RVOP(jalr, {
333342
if (ir->rd)
334343
rv->X[ir->rd] = pc + ir->insn_len;
335344
/* check instruction misaligned */
336-
if (unlikely(insn_is_misaligned(rv->PC))) {
337-
rv->compressed = false;
338-
rv_except_insn_misaligned(rv, pc);
339-
return false;
340-
}
345+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
341346
return true;
342347
})
343348

@@ -352,11 +357,7 @@ RVOP(beq, {
352357
}
353358
rv->PC += ir->imm;
354359
/* check instruction misaligned */
355-
if (unlikely(insn_is_misaligned(rv->PC))) {
356-
rv->compressed = false;
357-
rv_except_insn_misaligned(rv, pc);
358-
return false;
359-
}
360+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
360361
if (ir->branch_taken)
361362
return ir->branch_taken->impl(rv, ir->branch_taken);
362363
return true;
@@ -373,11 +374,7 @@ RVOP(bne, {
373374
}
374375
rv->PC += ir->imm;
375376
/* check instruction misaligned */
376-
if (unlikely(insn_is_misaligned(rv->PC))) {
377-
rv->compressed = false;
378-
rv_except_insn_misaligned(rv, pc);
379-
return false;
380-
}
377+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
381378
if (ir->branch_taken)
382379
return ir->branch_taken->impl(rv, ir->branch_taken);
383380
return true;
@@ -394,11 +391,7 @@ RVOP(blt, {
394391
}
395392
rv->PC += ir->imm;
396393
/* check instruction misaligned */
397-
if (unlikely(insn_is_misaligned(rv->PC))) {
398-
rv->compressed = false;
399-
rv_except_insn_misaligned(rv, pc);
400-
return false;
401-
}
394+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
402395
if (ir->branch_taken)
403396
return ir->branch_taken->impl(rv, ir->branch_taken);
404397
return true;
@@ -415,11 +408,7 @@ RVOP(bge, {
415408
}
416409
rv->PC += ir->imm;
417410
/* check instruction misaligned */
418-
if (unlikely(insn_is_misaligned(rv->PC))) {
419-
rv->compressed = false;
420-
rv_except_insn_misaligned(rv, pc);
421-
return false;
422-
}
411+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
423412
if (ir->branch_taken)
424413
return ir->branch_taken->impl(rv, ir->branch_taken);
425414
return true;
@@ -436,11 +425,7 @@ RVOP(bltu, {
436425
}
437426
rv->PC += ir->imm;
438427
/* check instruction misaligned */
439-
if (unlikely(insn_is_misaligned(rv->PC))) {
440-
rv->compressed = false;
441-
rv_except_insn_misaligned(rv, pc);
442-
return false;
443-
}
428+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
444429
if (ir->branch_taken)
445430
return ir->branch_taken->impl(rv, ir->branch_taken);
446431
return true;
@@ -457,11 +442,7 @@ RVOP(bgeu, {
457442
}
458443
rv->PC += ir->imm;
459444
/* check instruction misaligned */
460-
if (unlikely(insn_is_misaligned(rv->PC))) {
461-
rv->compressed = false;
462-
rv_except_insn_misaligned(rv, pc);
463-
return false;
464-
}
445+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
465446
if (ir->branch_taken)
466447
return ir->branch_taken->impl(rv, ir->branch_taken);
467448
return true;
@@ -476,22 +457,14 @@ RVOP(lb, {
476457
/* LH: Load Halfword */
477458
RVOP(lh, {
478459
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
479-
if (unlikely(addr & 1)) {
480-
rv->compressed = false;
481-
rv_except_load_misaligned(rv, addr);
482-
return false;
483-
}
460+
RV_EXC_MISAGLIN_HANDLER(1, load, false, 1);
484461
rv->X[ir->rd] = sign_extend_h(rv->io.mem_read_s(rv, addr));
485462
})
486463

487464
/* LW: Load Word */
488465
RVOP(lw, {
489466
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
490-
if (unlikely(addr & 3)) {
491-
rv->compressed = false;
492-
rv_except_load_misaligned(rv, addr);
493-
return false;
494-
}
467+
RV_EXC_MISAGLIN_HANDLER(3, load, false, 1);
495468
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
496469
})
497470

@@ -501,11 +474,7 @@ RVOP(lbu, { rv->X[ir->rd] = rv->io.mem_read_b(rv, rv->X[ir->rs1] + ir->imm); })
501474
/* LHU: Load Halfword Unsigned */
502475
RVOP(lhu, {
503476
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
504-
if (unlikely(addr & 1)) {
505-
rv->compressed = false;
506-
rv_except_load_misaligned(rv, addr);
507-
return false;
508-
}
477+
RV_EXC_MISAGLIN_HANDLER(1, load, false, 1);
509478
rv->X[ir->rd] = rv->io.mem_read_s(rv, addr);
510479
})
511480

@@ -515,22 +484,14 @@ RVOP(sb, { rv->io.mem_write_b(rv, rv->X[ir->rs1] + ir->imm, rv->X[ir->rs2]); })
515484
/* SH: Store Halfword */
516485
RVOP(sh, {
517486
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
518-
if (unlikely(addr & 1)) {
519-
rv->compressed = false;
520-
rv_except_store_misaligned(rv, addr);
521-
return false;
522-
}
487+
RV_EXC_MISAGLIN_HANDLER(1, store, false, 1);
523488
rv->io.mem_write_s(rv, addr, rv->X[ir->rs2]);
524489
})
525490

526491
/* SW: Store Word */
527492
RVOP(sw, {
528493
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
529-
if (unlikely(addr & 3)) {
530-
rv->compressed = false;
531-
rv_except_store_misaligned(rv, addr);
532-
return false;
533-
}
494+
RV_EXC_MISAGLIN_HANDLER(3, store, false, 1);
534495
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
535496
})
536497

@@ -1088,11 +1049,7 @@ RVOP(caddi4spn, { rv->X[ir->rd] = rv->X[2] + (uint16_t) ir->imm; })
10881049
*/
10891050
RVOP(clw, {
10901051
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
1091-
if (unlikely(addr & 3)) {
1092-
rv->compressed = true;
1093-
rv_except_load_misaligned(rv, addr);
1094-
return false;
1095-
}
1052+
RV_EXC_MISAGLIN_HANDLER(3, load, true, 1);
10961053
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
10971054
})
10981055

@@ -1103,11 +1060,7 @@ RVOP(clw, {
11031060
*/
11041061
RVOP(csw, {
11051062
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
1106-
if (unlikely(addr & 3)) {
1107-
rv->compressed = true;
1108-
rv_except_store_misaligned(rv, addr);
1109-
return false;
1110-
}
1063+
RV_EXC_MISAGLIN_HANDLER(3, store, true, 1);
11111064
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
11121065
})
11131066

@@ -1126,11 +1079,7 @@ RVOP(caddi, { rv->X[ir->rd] += (int16_t) ir->imm; })
11261079
RVOP(cjal, {
11271080
rv->X[1] = rv->PC + ir->insn_len;
11281081
rv->PC += ir->imm;
1129-
if (unlikely(rv->PC & 0x1)) {
1130-
rv->compressed = true;
1131-
rv_except_insn_misaligned(rv, rv->PC);
1132-
return false;
1133-
}
1082+
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
11341083
return true;
11351084
})
11361085

@@ -1198,11 +1147,7 @@ RVOP(cand, { rv->X[ir->rd] = rv->X[ir->rs1] & rv->X[ir->rs2]; })
11981147
*/
11991148
RVOP(cj, {
12001149
rv->PC += ir->imm;
1201-
if (unlikely(rv->PC & 0x1)) {
1202-
rv->compressed = true;
1203-
rv_except_insn_misaligned(rv, rv->PC);
1204-
return false;
1205-
}
1150+
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
12061151
return true;
12071152
})
12081153

@@ -1249,11 +1194,7 @@ RVOP(cslli, { rv->X[ir->rd] <<= (uint8_t) ir->imm; })
12491194
/* C.LWSP */
12501195
RVOP(clwsp, {
12511196
const uint32_t addr = rv->X[rv_reg_sp] + ir->imm;
1252-
if (unlikely(addr & 3)) {
1253-
rv->compressed = true;
1254-
rv_except_load_misaligned(rv, addr);
1255-
return false;
1256-
}
1197+
RV_EXC_MISAGLIN_HANDLER(3, load, true, 1);
12571198
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
12581199
})
12591200

@@ -1279,11 +1220,7 @@ RVOP(cjalr, {
12791220
const int32_t jump_to = rv->X[ir->rs1];
12801221
rv->X[rv_reg_ra] = rv->PC + ir->insn_len;
12811222
rv->PC = jump_to;
1282-
if (unlikely(rv->PC & 0x1)) {
1283-
rv->compressed = true;
1284-
rv_except_insn_misaligned(rv, rv->PC);
1285-
return false;
1286-
}
1223+
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
12871224
return true;
12881225
})
12891226

@@ -1299,11 +1236,7 @@ RVOP(cadd, { rv->X[ir->rd] = rv->X[ir->rs1] + rv->X[ir->rs2]; })
12991236
/* C.SWSP */
13001237
RVOP(cswsp, {
13011238
const uint32_t addr = rv->X[2] + ir->imm;
1302-
if (unlikely(addr & 3)) {
1303-
rv->compressed = true;
1304-
rv_except_store_misaligned(rv, addr);
1305-
return false;
1306-
}
1239+
RV_EXC_MISAGLIN_HANDLER(3, store, true, 1);
13071240
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
13081241
})
13091242
#endif

src/main.c

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ static char *signature_out_file;
2525
/* target executable */
2626
static const char *opt_prog_name = "a.out";
2727

28+
/* enable misaligned memory access */
29+
static bool opt_misaligned = false;
30+
2831
#define MEMIO(op) on_mem_##op
2932
#define IO_HANDLER_IMPL(type, op, RW) \
3033
static IIF(RW)( \
@@ -123,6 +126,12 @@ static bool parse_args(int argc, char **args)
123126
signature_out_file = args[++i];
124127
continue;
125128
}
129+
130+
if (!strcmp(arg, "--misalign")) {
131+
opt_misaligned = true;
132+
continue;
133+
}
134+
126135
/* otherwise, error */
127136
fprintf(stderr, "Unknown argument '%s'\n", arg);
128137
return false;
@@ -192,6 +201,7 @@ int main(int argc, char **args)
192201
/* system */
193202
.on_ecall = ecall_handler,
194203
.on_ebreak = ebreak_handler,
204+
.allow_misalign = opt_misaligned,
195205
};
196206

197207
state_t *state = state_new();

src/riscv.h

+3
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ typedef struct {
107107
/* system */
108108
riscv_on_ecall on_ecall;
109109
riscv_on_ebreak on_ebreak;
110+
111+
/* enable misaligned memory access */
112+
bool allow_misalign;
110113
} riscv_io_t;
111114

112115
/* create a RISC-V emulator */

0 commit comments

Comments
 (0)