Skip to content

Commit d54dd15

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

File tree

3 files changed

+45
-100
lines changed

3 files changed

+45
-100
lines changed

src/emulate.c

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

93+
#define RV_EXC_MISAGLIN_HANDLER(mask_or_pc, type, compress, IO) \
94+
IIF(IO) \
95+
(if (!rv->io.allow_misalign && unlikely(addr & (mask_or_pc))), \
96+
if (unlikely(insn_is_misaligned(rv->PC)))) \
97+
{ \
98+
rv->compressed = compress; \
99+
IIF(IO) \
100+
(rv_except_##type##_misaligned(rv, addr), \
101+
rv_except_##type##_misaligned(rv, mask_or_pc)); \
102+
return false; \
103+
}
104+
93105
/* Get current time in microsecnds and update csr_time register */
94106
static inline void update_time(riscv_t *rv)
95107
{
@@ -310,11 +322,7 @@ RVOP(jal, {
310322
if (ir->rd)
311323
rv->X[ir->rd] = pc + ir->insn_len;
312324
/* 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-
}
325+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
318326
return true;
319327
})
320328

@@ -333,11 +341,7 @@ RVOP(jalr, {
333341
if (ir->rd)
334342
rv->X[ir->rd] = pc + ir->insn_len;
335343
/* 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-
}
344+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
341345
return true;
342346
})
343347

@@ -352,11 +356,7 @@ RVOP(beq, {
352356
}
353357
rv->PC += ir->imm;
354358
/* 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-
}
359+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
360360
if (ir->branch_taken)
361361
return ir->branch_taken->impl(rv, ir->branch_taken);
362362
return true;
@@ -373,11 +373,7 @@ RVOP(bne, {
373373
}
374374
rv->PC += ir->imm;
375375
/* 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-
}
376+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
381377
if (ir->branch_taken)
382378
return ir->branch_taken->impl(rv, ir->branch_taken);
383379
return true;
@@ -394,11 +390,7 @@ RVOP(blt, {
394390
}
395391
rv->PC += ir->imm;
396392
/* 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-
}
393+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
402394
if (ir->branch_taken)
403395
return ir->branch_taken->impl(rv, ir->branch_taken);
404396
return true;
@@ -415,11 +407,7 @@ RVOP(bge, {
415407
}
416408
rv->PC += ir->imm;
417409
/* 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-
}
410+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
423411
if (ir->branch_taken)
424412
return ir->branch_taken->impl(rv, ir->branch_taken);
425413
return true;
@@ -436,11 +424,7 @@ RVOP(bltu, {
436424
}
437425
rv->PC += ir->imm;
438426
/* 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-
}
427+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
444428
if (ir->branch_taken)
445429
return ir->branch_taken->impl(rv, ir->branch_taken);
446430
return true;
@@ -457,11 +441,7 @@ RVOP(bgeu, {
457441
}
458442
rv->PC += ir->imm;
459443
/* 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-
}
444+
RV_EXC_MISAGLIN_HANDLER(pc, insn, false, 0);
465445
if (ir->branch_taken)
466446
return ir->branch_taken->impl(rv, ir->branch_taken);
467447
return true;
@@ -476,22 +456,14 @@ RVOP(lb, {
476456
/* LH: Load Halfword */
477457
RVOP(lh, {
478458
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-
}
459+
RV_EXC_MISAGLIN_HANDLER(1, load, false, 1);
484460
rv->X[ir->rd] = sign_extend_h(rv->io.mem_read_s(rv, addr));
485461
})
486462

487463
/* LW: Load Word */
488464
RVOP(lw, {
489465
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-
}
466+
RV_EXC_MISAGLIN_HANDLER(3, load, false, 1);
495467
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
496468
})
497469

@@ -501,11 +473,7 @@ RVOP(lbu, { rv->X[ir->rd] = rv->io.mem_read_b(rv, rv->X[ir->rs1] + ir->imm); })
501473
/* LHU: Load Halfword Unsigned */
502474
RVOP(lhu, {
503475
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-
}
476+
RV_EXC_MISAGLIN_HANDLER(1, load, false, 1);
509477
rv->X[ir->rd] = rv->io.mem_read_s(rv, addr);
510478
})
511479

@@ -515,22 +483,14 @@ RVOP(sb, { rv->io.mem_write_b(rv, rv->X[ir->rs1] + ir->imm, rv->X[ir->rs2]); })
515483
/* SH: Store Halfword */
516484
RVOP(sh, {
517485
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-
}
486+
RV_EXC_MISAGLIN_HANDLER(1, store, false, 1);
523487
rv->io.mem_write_s(rv, addr, rv->X[ir->rs2]);
524488
})
525489

526490
/* SW: Store Word */
527491
RVOP(sw, {
528492
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-
}
493+
RV_EXC_MISAGLIN_HANDLER(3, store, false, 1);
534494
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
535495
})
536496

@@ -1088,11 +1048,7 @@ RVOP(caddi4spn, { rv->X[ir->rd] = rv->X[2] + (uint16_t) ir->imm; })
10881048
*/
10891049
RVOP(clw, {
10901050
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-
}
1051+
RV_EXC_MISAGLIN_HANDLER(3, load, true, 1);
10961052
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
10971053
})
10981054

@@ -1103,11 +1059,7 @@ RVOP(clw, {
11031059
*/
11041060
RVOP(csw, {
11051061
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-
}
1062+
RV_EXC_MISAGLIN_HANDLER(3, store, true, 1);
11111063
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
11121064
})
11131065

@@ -1126,11 +1078,7 @@ RVOP(caddi, { rv->X[ir->rd] += (int16_t) ir->imm; })
11261078
RVOP(cjal, {
11271079
rv->X[1] = rv->PC + ir->insn_len;
11281080
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-
}
1081+
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
11341082
return true;
11351083
})
11361084

@@ -1198,11 +1146,7 @@ RVOP(cand, { rv->X[ir->rd] = rv->X[ir->rs1] & rv->X[ir->rs2]; })
11981146
*/
11991147
RVOP(cj, {
12001148
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-
}
1149+
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
12061150
return true;
12071151
})
12081152

@@ -1249,11 +1193,7 @@ RVOP(cslli, { rv->X[ir->rd] <<= (uint8_t) ir->imm; })
12491193
/* C.LWSP */
12501194
RVOP(clwsp, {
12511195
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-
}
1196+
RV_EXC_MISAGLIN_HANDLER(3, load, true, 1);
12571197
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
12581198
})
12591199

@@ -1279,11 +1219,7 @@ RVOP(cjalr, {
12791219
const int32_t jump_to = rv->X[ir->rs1];
12801220
rv->X[rv_reg_ra] = rv->PC + ir->insn_len;
12811221
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-
}
1222+
RV_EXC_MISAGLIN_HANDLER(rv->PC, insn, true, 0);
12871223
return true;
12881224
})
12891225

@@ -1299,11 +1235,7 @@ RVOP(cadd, { rv->X[ir->rd] = rv->X[ir->rs1] + rv->X[ir->rs2]; })
12991235
/* C.SWSP */
13001236
RVOP(cswsp, {
13011237
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-
}
1238+
RV_EXC_MISAGLIN_HANDLER(3, store, true, 1);
13071239
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
13081240
})
13091241
#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 memory misaligned 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 memory misaligned access */
112+
bool allow_misalign;
110113
} riscv_io_t;
111114

112115
/* create a RISC-V emulator */

0 commit comments

Comments
 (0)