8686 read _address prev_proc "_address"
8787 read address prev_proc "address"
8888 read breakpoint_address prev_proc "breakpoint_address"
89- read csr_mideleg prev_proc "csr_mideleg"
9089 read csr_mie prev_proc "csr_mie"
9190 read csr_minstret prev_proc "csr_minstret"
9291 read csr_mip prev_proc "csr_mip"
@@ -196,7 +195,8 @@ poll_interrupts:
196195# check if interrupts should fire
197196# this runs at the start of the first worker each tick, if certain CSRs are modified, and after an xRET instruction
198197fire_interrupts:
199- #% do reset_locals()
198+ #% set trap_locals = ["$$mxdeleg"]
199+ #% do declare_locals(trap_locals)
200200 op and csr_mip csr_mip 0b10111111111111111111111111111111 # clear interrupt_flags.fire
201201
202202 # fire interrupt i if bit i is set in both mip and mie
@@ -205,6 +205,9 @@ fire_interrupts:
205205 # if no interrupts would be fired, short-circuit
206206 jump main equal $interrupts 0
207207
208+ # read mideleg for later
209+ read $$mxdeleg {{CSRS}} "{{ 'mideleg'|csr }}"
210+
208211 # in U-mode, interrupts are always enabled
209212 jump fire_interrupts__ok lessThan privilege_mode 0b01
210213
@@ -217,7 +220,7 @@ fire_interrupts:
217220 # in M-mode, don't take delegated interrupts
218221 jump fire_interrupts__ok lessThan privilege_mode 0b11
219222
220- op not $mask csr_mideleg
223+ op not $mask $$mxdeleg
221224 op and $interrupts $interrupts $mask
222225
223226fire_interrupts__ok:
@@ -391,19 +394,13 @@ state->reset:
391394 set state "reset"
392395 jump reset always
393396
394- #% set trap_locals = ['$$mxdeleg']
395-
396397interrupt:
397398#% do declare_locals(trap_locals)
398399 # the highest bit set in mcause is the bit in (mip & mie) that triggered the interrupt
399400 # so convert mcause to the actual trap code via floor(log_2(mcause)) = ln(mcause) // ln(2)
400401 op log mcause mcause
401402 op idiv mcause mcause {{LN_2}}
402403
403- # check mideleg
404- # we can't use the original mcause value as a bitmask for this because it may also have lower bits set
405- op shr $$mxdeleg csr_mideleg mcause
406-
407404 # set interrupt bit
408405 op or mcause mcause 0x80000000
409406
@@ -418,13 +415,14 @@ trap:
418415#% do declare_locals(trap_locals)
419416 # check medeleg
420417 read $$mxdeleg {{CSRS}} "{{ 'medeleg'|csr }}"
421- op shr $$mxdeleg $$mxdeleg mcause
422418
423419trap__check_mxdeleg:
424420 # don't trap from M-mode to S-mode
425421 jump trap__machine greaterThan privilege_mode 0b01
426422
427423 # if not in M-mode, trap to S-mode if the corresponding mxdeleg bit is set, else trap to M-mode
424+ # this is safe for interrupt mcause values: https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.19
425+ op shr $$mxdeleg $$mxdeleg mcause
428426 op and $$mxdeleg $$mxdeleg 0b1
429427 jump trap__machine equal $$mxdeleg 0
430428
@@ -2465,25 +2463,19 @@ csr_write_medeleg:
24652463 # reserved ---- -- - -
24662464 # M-mode ecall -
24672465 op and result result 0b00000000000011001011001111111111
2468-
2469- # we only need to read medeleg in one place, so it's more compact to store it in CSRS
24702466 jump csr_write_csrs always
24712467
2472- csr_read_mideleg:
2473- #% do declare_locals(modify_csr_locals)
2474- set rd csr_mideleg
2475- set @counter $$modify_csr_op
2476-
24772468csr_write_mideleg:
2469+ #% do declare_locals(modify_csr_locals)
24782470 # get new writable fields
2479- # MEI -
2480- # SEI -
2481- # MTI -
2482- # STI -
2483- # MSI -
2484- # SSI -
2485- op and csr_mideleg result 0b00000000000000000000101010101010
2486- jump end_instruction_with_rd_and_fire_interrupts always
2471+ # MEI -
2472+ # SEI -
2473+ # MTI -
2474+ # STI -
2475+ # MSI -
2476+ # SSI -
2477+ op and result result 0b00000000000000000000101010101010
2478+ jump csr_write_csrs always
24872479
24882480csr_read_sip:
24892481#% do declare_locals(modify_csr_locals)
@@ -2817,7 +2809,6 @@ jump csr_read_csrs always
28172809jump csr_read_cycle always
28182810jump csr_read_cycleh always
28192811jump csr_read_hpmcounter always
2820- jump csr_read_mideleg always
28212812jump csr_read_mie always
28222813jump csr_read_minstret always
28232814jump csr_read_minstreth always
0 commit comments