Skip to content

Commit 0b9d294

Browse files
authored
Merge pull request sysprog21#63 from Risheng1128/pr
Avoid duplications in RISC-V exception handlers
2 parents e56edb2 + d6c8f7c commit 0b9d294

File tree

1 file changed

+48
-152
lines changed

1 file changed

+48
-152
lines changed

src/emulate.c

Lines changed: 48 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -24,160 +24,56 @@ 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+
/* RISC-V exception code list */
28+
#define GET_EXCEPTION_CODE(type) rv_exception_code_##type
29+
#define RV_EXCEPTION_LIST \
30+
_(insn_misaligned) /* Instruction address misaligned */ \
31+
_(insn_fault) /* Instruction access fault */ \
32+
_(illegal_insn) /* Illegal instruction */ \
33+
_(breakpoint) /* Breakpoint */ \
34+
_(load_misaligned) /* Load address misaligned */ \
35+
_(load_fault) /* Load access fault */ \
36+
_(store_misaligned) /* Store/AMO address misaligned */
37+
38+
enum {
39+
#define _(type) GET_EXCEPTION_CODE(type),
40+
RV_EXCEPTION_LIST
41+
#undef _
42+
};
43+
44+
#define EXCEPTION_HANDLER_IMPL(type) \
45+
UNUSED static void rv_except_##type(struct riscv_t *rv, uint32_t mtval) \
46+
{ \
47+
/* mtvec (Machine Trap-Vector Base Address Register) \
48+
* mtvec[MXLEN-1:2]: vector base address \
49+
* mtvec[1:0] : vector mode \
50+
*/ \
51+
const uint32_t base = rv->csr_mtvec & ~0x3; \
52+
const uint32_t mode = rv->csr_mtvec & 0x3; \
53+
/* Exception Code */ \
54+
const uint32_t code = GET_EXCEPTION_CODE(type); \
55+
/* mepc (Machine Exception Program Counter) \
56+
* mtval (Machine Trap Value Register) \
57+
*/ \
58+
rv->csr_mepc = rv->PC; \
59+
rv->csr_mtval = mtval; \
60+
switch (mode) { \
61+
case 0: /* DIRECT: All exceptions set PC to base */ \
62+
rv->PC = base; \
63+
break; \
64+
/* VECTORED: Asynchronous interrupts set PC to base + 4 * code */ \
65+
case 1: \
66+
rv->PC = base + 4 * code; \
67+
break; \
68+
} \
69+
/* mcause (Machine Cause Register): store exception code */ \
70+
rv->csr_mcause = code; \
5271
}
5372

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-
}
73+
/* RISC-V exception handlers */
74+
#define _(type) EXCEPTION_HANDLER_IMPL(type)
75+
RV_EXCEPTION_LIST
76+
#undef _
18177

18278
/* RV32I Base Instruction Set
18379
*

0 commit comments

Comments
 (0)