Skip to content

Commit c8f034b

Browse files
committed
Avoid duplications in RISC-V exception handlers
Use preprocessor to avoid duplications in exception handlers, and create a list to define the RISC-V exception code.
1 parent 3517f01 commit c8f034b

File tree

2 files changed

+44
-152
lines changed

2 files changed

+44
-152
lines changed

src/emulate.c

Lines changed: 33 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -24,160 +24,41 @@ extern struct target_ops gdbstub_ops;
2424
#include "riscv.h"
2525
#include "riscv_private.h"
2626

27-
static void rv_except_insn_misaligned(struct riscv_t *rv, uint32_t old_pc)
28-
{
29-
/* mtvec (Machine Trap-Vector Base Address Register)
30-
* mtvec[MXLEN-1:2]: vector base address
31-
* mtvec[1:0] : vector mode
32-
*/
33-
const uint32_t base = rv->csr_mtvec & ~0x3;
34-
const uint32_t mode = rv->csr_mtvec & 0x3;
35-
36-
/* Exception Code: Instruction Address Misaligned */
37-
const uint32_t code = 0;
38-
39-
/* mepc (Machine Exception Program Counter)
40-
* mtval (Machine Trap Value Register) : Misaligned Instruction
41-
*/
42-
rv->csr_mepc = old_pc;
43-
rv->csr_mtval = rv->PC;
44-
45-
switch (mode) {
46-
case 0: /* DIRECT: All exceptions set PC to base */
47-
rv->PC = base;
48-
break;
49-
case 1: /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
50-
rv->PC = base + 4 * code;
51-
break;
27+
#define GET_EXCEPTION_CODE(type) rv_exception_code_##type
28+
#define EXCEPTION_HANDLER_IMPL(type) \
29+
static void rv_except_##type(struct riscv_t *rv, uint32_t mtval) \
30+
{ \
31+
/* mtvec (Machine Trap-Vector Base Address Register) \
32+
* mtvec[MXLEN-1:2]: vector base address \
33+
* mtvec[1:0] : vector mode \
34+
*/ \
35+
const uint32_t base = rv->csr_mtvec & ~0x3; \
36+
const uint32_t mode = rv->csr_mtvec & 0x3; \
37+
/* Exception Code */ \
38+
const uint32_t code = GET_EXCEPTION_CODE(type); \
39+
/* mepc (Machine Exception Program Counter) \
40+
* mtval (Machine Trap Value Register) \
41+
*/ \
42+
rv->csr_mepc = rv->PC; \
43+
rv->csr_mtval = mtval; \
44+
switch (mode) { \
45+
case 0: /* DIRECT: All exceptions set PC to base */ \
46+
rv->PC = base; \
47+
break; \
48+
/* VECTORED: Asynchronous interrupts set PC to base + 4 * code */ \
49+
case 1: \
50+
rv->PC = base + 4 * code; \
51+
break; \
52+
} \
53+
/* mcause (Machine Cause Register): store exception code */ \
54+
rv->csr_mcause = code; \
5255
}
5356

54-
/* mcause (Machine Cause Register): store exception code */
55-
rv->csr_mcause = code;
56-
}
57-
58-
static void rv_except_load_misaligned(struct riscv_t *rv, uint32_t addr)
59-
{
60-
/* mtvec (Machine Trap-Vector Base Address Register)
61-
* mtvec[MXLEN-1:2]: vector base address
62-
* mtvec[1:0] : vector mode
63-
*/
64-
const uint32_t base = rv->csr_mtvec & ~0x3;
65-
const uint32_t mode = rv->csr_mtvec & 0x3;
66-
67-
/* Exception Code: Load Address Misaligned */
68-
const uint32_t code = 4;
69-
70-
/* mepc (Machine Exception Program Counter)
71-
* mtval(Machine Trap Value Register) : Misaligned Load Address
72-
*/
73-
rv->csr_mepc = rv->PC;
74-
rv->csr_mtval = addr;
75-
76-
switch (mode) {
77-
case 0: /* DIRECT: All exceptions set PC to base */
78-
rv->PC = base;
79-
break;
80-
case 1: /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
81-
rv->PC = base + 4 * code;
82-
break;
83-
}
84-
85-
/* mcause (Machine Cause Register): store exception code */
86-
rv->csr_mcause = code;
87-
}
88-
89-
static void rv_except_store_misaligned(struct riscv_t *rv, uint32_t addr)
90-
{
91-
/* mtvec (Machine Trap-Vector Base Address Register)
92-
* mtvec[MXLEN-1:2]: vector base address
93-
* mtvec[1:0] : vector mode
94-
*/
95-
const uint32_t base = rv->csr_mtvec & ~0x3;
96-
const uint32_t mode = rv->csr_mtvec & 0x3;
97-
98-
/* Exception Code: Store Address Misaligned */
99-
const uint32_t code = 6;
100-
101-
/* mepc (Machine Exception Program Counter)
102-
* mtval(Machine Trap Value Register) : Misaligned Store Address
103-
*/
104-
rv->csr_mepc = rv->PC;
105-
rv->csr_mtval = addr;
106-
107-
switch (mode) {
108-
case 0: /* DIRECT: All exceptions set PC to base */
109-
rv->PC = base;
110-
break;
111-
case 1: /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
112-
rv->PC = base + 4 * code;
113-
break;
114-
}
115-
116-
/* mcause (Machine Cause Register): store exception code */
117-
rv->csr_mcause = code;
118-
}
119-
120-
static void rv_except_illegal_insn(struct riscv_t *rv, uint32_t insn)
121-
{
122-
/* mtvec (Machine Trap-Vector Base Address Register)
123-
* mtvec[MXLEN-1:2]: vector base address
124-
* mtvec[1:0] : vector mode
125-
*/
126-
const uint32_t base = rv->csr_mtvec & ~0x3;
127-
const uint32_t mode = rv->csr_mtvec & 0x3;
128-
129-
/* Exception Code: Illegal Instruction */
130-
const uint32_t code = 2;
131-
132-
/* mepc (Machine Exception Program Counter)
133-
* mtval(Machine Trap Value Register) : Illegal Instruction
134-
*/
135-
rv->csr_mepc = rv->PC;
136-
rv->csr_mtval = insn;
137-
138-
switch (mode) {
139-
case 0: /* DIRECT: All exceptions set PC to base */
140-
rv->PC = base;
141-
break;
142-
case 1: /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
143-
rv->PC = base + 4 * code;
144-
break;
145-
}
146-
147-
/* mcause (Machine Cause Register): store exception code */
148-
rv->csr_mcause = code;
149-
}
150-
151-
static void rv_except_breakpoint(struct riscv_t *rv, uint32_t old_pc)
152-
{
153-
/* mtvec (Machine Trap-Vector Base Address Register)
154-
* mtvec[MXLEN-1:2]: vector base address
155-
* mtvec[1:0] : vector mode
156-
*/
157-
const uint32_t base = rv->csr_mtvec & ~0x3;
158-
const uint32_t mode = rv->csr_mtvec & 0x3;
159-
160-
/* Exception Code: Breakpoint */
161-
const uint32_t code = 3;
162-
163-
/* mepc (Machine Exception Program Counter)
164-
* mtval(Machine Trap Value Register) : Breakpoint
165-
*/
166-
rv->csr_mepc = old_pc;
167-
rv->csr_mtval = old_pc;
168-
169-
switch (mode) {
170-
case 0: /* DIRECT: All exceptions set PC to base */
171-
rv->PC = base;
172-
break;
173-
case 1: /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
174-
rv->PC = base + 4 * code;
175-
break;
176-
}
177-
178-
/* mcause (Machine Cause Register): store exception code */
179-
rv->csr_mcause = code;
180-
}
57+
EXCEPTION_HANDLER_IMPL(insn_misaligned)
58+
EXCEPTION_HANDLER_IMPL(load_misaligned)
59+
EXCEPTION_HANDLER_IMPL(store_misaligned)
60+
EXCEPTION_HANDLER_IMPL(illegal_insn)
61+
EXCEPTION_HANDLER_IMPL(breakpoint)
18162

18263
/* RV32I Base Instruction Set
18364
*

src/riscv.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ enum {
4242
rv_reg_t6,
4343
};
4444

45+
/* RISC-V exception code list */
46+
enum {
47+
rv_exception_code_insn_misaligned = 0, /* Instruction address misaligned */
48+
rv_exception_code_insn_fault, /* Instruction access fault */
49+
rv_exception_code_illegal_insn, /* Illegal instruction */
50+
rv_exception_code_breakpoint, /* Breakpoint */
51+
rv_exception_code_load_misaligned, /* Load address misaligned */
52+
rv_exception_code_load_fault, /* Load access fault */
53+
rv_exception_code_store_misaligned, /* Store/AMO address misaligned */
54+
};
55+
4556
struct riscv_t;
4657
typedef void *riscv_user_t;
4758

0 commit comments

Comments
 (0)