fcsr/fflags/frm csr reg. handling started ...

master
kaqu 2 years ago
parent b48e50305a
commit 0e38f54ac0
  1. 5
      debugger/dbgeval.py
  2. 69
      libmodules/fpu_decode.py
  3. 58
      libmodules/instruction_decode.py
  4. 11
      libmodules/register_file.py
  5. 13
      libmodules/risq5defs.py
  6. 22
      software/source/flwstw.c

@ -32,7 +32,10 @@ csr_description = {
0xF11 : "mvendorid",
0xF12 : "marchid",
0xF13 : "mimpid",
0xF14 : "mhartid"
0xF14 : "mhartid",
0x001 : "fflags",
0x002 : "frm",
0x003 : "fcsr"
}
def flag(val, c1, c2):

@ -135,19 +135,22 @@ class Risq5FPUDecoder(Module):
# 1. Verify valid ranges 1st!
If(((regs.fs1[0:31] == 0x7FFFFFFF) | (regs.fs2[0:31] == 0x7FFFFFFF))
| ((self.sign1 ^ self.sign2) & ((self.e1 == -1) & (self.e2 == -1))),
NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
#NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x10), # NV: Invalid operation
NextValue(regs.frd_wrport.dat_w, 0x7FFFFFFF), # NAN
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(self.e1 == -1, # Infinity
NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
#NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x04), # OF: Overflow
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Return infinity
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(self.e2 == -1, # Infinity
NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
#NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x04), # OF: Overflow
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Return infinity
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
@ -283,8 +286,10 @@ class Risq5FPUDecoder(Module):
NextValue(regs.frd_wrport.dat_w, Cat(self.m3[0:23], self.e3+127, self.sign3)),
If((self.m3[0:23] != 0) | ((self.e3+127) != 0), # Not zero?
If((self.e3 + 127) == 1, # FLT_MIN range
NextValue(regs.fcs, regs.fcs | 0x02), # UF: Underflow
If(regs.fcs[5:8] == 0x01, # RTZ rounding
#NextValue(regs.fcs, regs.fcs | 0x02), # UF: Underflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x02), # UF: Underflow
#If(regs.fcs[5:8] == 0x01, # RTZ rounding
If(regs.csr[risq5defs.CSR_fcsr][5:8] == 0x01, # RTZ rounding
NextValue(regs.frd_wrport.dat_w, 0), # FLT_MIN -> Round to zero -> 0.0!
)
)
@ -298,19 +303,22 @@ class Risq5FPUDecoder(Module):
NextValue(self.FPU_state, 1),
# 0. Verify valid ranges 1st!
If((regs.fs1[0:31] == 0x7FFFFFFF) | (regs.fs2[0:31] == 0x7FFFFFFF),
NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
#NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x10), # NV: Invalid operation
NextValue(regs.frd_wrport.dat_w, 0x7FFFFFFF), # NAN
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(self.e1 == -1, # Infinity
NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
#NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x04), # OF: Overflow
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Return infinity
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(self.e2 == -1, # Infinity
NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
#NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x04), # OF: Overflow
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Return infinity
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
@ -390,25 +398,29 @@ class Risq5FPUDecoder(Module):
NextValue(self.FPU_state, 1),
# 0. Verify valid ranges 1st!
If((regs.fs1[0:31] == 0x7FFFFFFF) | (regs.fs2[0:31] == 0x7FFFFFFF) | ((regs.fs1[0:31] == 0) & (regs.fs2[0:31] == 0)),
NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
#NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x10), # NV: Invalid operation
NextValue(regs.frd_wrport.dat_w, 0x7FFFFFFF), # NAN
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(self.e1 == -1, # Infinity
NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
#NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x04), # OF: Overflow
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Return infinity
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(self.e2 == -1, # Infinity
NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
#NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x04), # OF: Overflow
NextValue(regs.frd_wrport.dat_w, regs.fs2), # Return infinity
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(regs.fs2 == 0, # Division by zero?
NextValue(regs.fcs, regs.fcs | 0x08), # DZ: Division by zero
#NextValue(regs.fcs, regs.fcs | 0x08), # DZ: Division by zero
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x08), # DZ: Division by zero
If(self.sign3,
NextValue(regs.frd_wrport.dat_w, 0xFF800000), # - Infinity
).Else(
@ -452,13 +464,15 @@ class Risq5FPUDecoder(Module):
NextValue(self.FPU_state, 1),
# 1. Verify valid ranges 1st!
If((regs.fs1[0:31] == 0x7FFFFFFF) | self.sign1,
NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
#NextValue(regs.fcs, regs.fcs | 0x10), # NV: Invalid operation
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x10), # NV: Invalid operation
NextValue(regs.frd_wrport.dat_w, 0x7FFFFFFF), # NAN
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
NextState("FPU_IDLE")
).Elif(self.e1 == -1, # Infinity
NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
#NextValue(regs.fcs, regs.fcs | 0x04), # OF: Overflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x04), # OF: Overflow
NextValue(regs.frd_wrport.dat_w, regs.fs1), # Return +/- infinity
NextValue(self.fwrite, 1),
NextValue(self.fready, 1),
@ -491,8 +505,10 @@ class Risq5FPUDecoder(Module):
NextValue(self.FPU_state, 3),
NextValue(regs.frd_wrport.dat_w, self.s32), # Just map value straight ...
If((self.s32[0:31] != 0) & self.s32[23:31] == 1, # FLT_MIN range & not zero (already!)
NextValue(regs.fcs, regs.fcs | 0x02), # UF: Underflow
If(regs.fcs[5:8] == 0x01, # RTZ rounding
#NextValue(regs.fcs, regs.fcs | 0x02), # UF: Underflow
NextValue(regs.csr[risq5defs.CSR_fcsr], regs.csr[risq5defs.CSR_fcsr] | 0x02), # UF: Underflow
#If(regs.fcs[5:8] == 0x01, # RTZ rounding
If(regs.csr[risq5defs.CSR_fcsr][5:8] == 0x01, # RTZ rounding
NextValue(regs.frd_wrport.dat_w, 0), # FLT_MIN -> Round to zero -> 0.0!
)
),
@ -585,15 +601,18 @@ class Risq5FPUDecoder(Module):
FPU_fsm.act("FCVT_W_S1",
If(self.e1 < 0, # 0..1 range special treatment
If((regs.fcs[5:8] == 0x0) | (regs.fcs[5:8] == 0x4), # rte/Round to nearest, ties to even or rmm/Round to nearest, ties to max magnitude
#If((regs.fcs[5:8] == 0x0) | (regs.fcs[5:8] == 0x4), # rte/Round to nearest, ties to even or rmm/Round to nearest, ties to max magnitude
If((regs.csr[risq5defs.CSR_fcsr][5:8] == 0x0) | (regs.csr[risq5defs.CSR_fcsr][5:8] == 0x4), # rte/Round to nearest, ties to even or rmm/Round to nearest, ties to max magnitude
If(self.e1 < -1,
NextValue(regs.rd_wrport.dat_w, 0), # Just return zero!
).Else(
NextValue(regs.rd_wrport.dat_w, 1),
)
).Elif((regs.fcs[5:8] == 0x2) | (regs.fcs[5:8] == 0x1), # rdn/Round down towards -inf or rtz/Round to zero => Trunc (do nothing)
#).Elif((regs.fcs[5:8] == 0x2) | (regs.fcs[5:8] == 0x1), # rdn/Round down towards -inf or rtz/Round to zero => Trunc (do nothing)
).Elif((regs.csr[risq5defs.CSR_fcsr][5:8] == 0x2) | (regs.csr[risq5defs.CSR_fcsr][5:8] == 0x1), # rdn/Round down towards -inf or rtz/Round to zero => Trunc (do nothing)
NextValue(regs.rd_wrport.dat_w, 0), # Just return zero!
).Elif(regs.fcs[5:8] == 0x3, # rup/Round up towards +inf
#).Elif(regs.fcs[5:8] == 0x3, # rup/Round up towards +inf
).Elif(regs.csr[risq5defs.CSR_fcsr][5:8] == 0x3, # rup/Round up towards +inf
NextValue(regs.rd_wrport.dat_w, 1),
),
NextValue(writepost, 1), # Write required (but integer register)
@ -623,7 +642,8 @@ class Risq5FPUDecoder(Module):
)
)
FPU_fsm.act("FCVT_W_S3",
If(regs.fcs[5:8] == 0x0, # rte/Round to nearest, ties to even
#If(regs.fcs[5:8] == 0x0, # rte/Round to nearest, ties to even
If(regs.csr[risq5defs.CSR_fcsr][5:8] == 0x0, # rte/Round to nearest, ties to even
If(self.m1 == 0x400000, # Excactly 0.5?
If(self.s32[0], # NOT even number?
NextValue(self.s32, self.s32 + 1), # Tie to even!
@ -636,7 +656,8 @@ class Risq5FPUDecoder(Module):
)
# Else (< 0.5): Round downward -> trunc (do nothing)
)
).Elif(regs.fcs[5:8] == 0x2, # rdn/Round down towards -inf
#).Elif(regs.fcs[5:8] == 0x2, # rdn/Round down towards -inf
).Elif(regs.csr[risq5defs.CSR_fcsr][5:8] == 0x2, # rdn/Round down towards -inf
If(self.m1 > 0, # There is a rest ...
If(self.sign1, # Negative: Add to next integer
NextValue(self.s32, self.s32 + 1), # Round upward
@ -644,7 +665,8 @@ class Risq5FPUDecoder(Module):
)
# Positive to -inf: Just cut-off!
)
).Elif(regs.fcs[5:8] == 0x3, # rup/Round up towards +inf
#).Elif(regs.fcs[5:8] == 0x3, # rup/Round up towards +inf
).Elif(regs.csr[risq5defs.CSR_fcsr][5:8] == 0x3, # rup/Round up towards +inf
If(self.m1 > 0, # There is a rest ...
If(self.sign1, # Positive: Add to next integer
NextValue(self.s32, self.s32 + 1), # Round upward
@ -652,7 +674,8 @@ class Risq5FPUDecoder(Module):
)
# Negative to +inf: Just cut-off!
)
).Elif(regs.fcs[5:8] == 0x4, # rmm/Round to nearest, ties to max magnitude
#).Elif(regs.fcs[5:8] == 0x4, # rmm/Round to nearest, ties to max magnitude
).Elif(regs.csr[risq5defs.CSR_fcsr][5:8] == 0x4, # rmm/Round to nearest, ties to max magnitude
If(self.m1 == 0x400000, # Excactly 0.5?
NextValue(self.s32, self.s32 + 1), # Tie to inf (no matter what sign?!)
NextValue(self.lm3, self.lm3 + 1), # Just track valule for unsigned result ...

@ -265,20 +265,62 @@ class Risq5Decoder(Module):
).Elif((regs.op == 0x73) & (regs.f3 != 0x00), # I-Type (4) CSR access
# CSRs: mstatus,mip,mie,mcause,mtvec,mtval,mepc,mscratch (Machine mode [level 3] registers)
# misa,mvendorid,marchid,mimpid,mhartid (Identification registers)
NextValue(regs.rd_wrport.dat_w, regs.csr[regs.csrindex]), # rd (former value)
If(regs.imm_i == risq5defs.CSR_frm_id, # FPU special: Rounding mode
NextValue(regs.rd_wrport.dat_w, regs.csr[risq5defs.CSR_fcsr][5:8]), # fcsr[5:8]='frm'!
).Elif(regs.imm_i == risq5defs.CSR_fflags_id, # FPU special: Exception flags
NextValue(regs.rd_wrport.dat_w, regs.csr[risq5defs.CSR_fcsr][0:5]), # fcsr[0:5]='fflags'!
).Else( # Any other ...
NextValue(regs.rd_wrport.dat_w, regs.csr[regs.csrindex]), # rd (former value)
),
If(regs.csrindex < risq5defs.CSR_misa, # Write only non-static regs!
If(regs.f3 == 0x03, # csrrc rd, csr, rs1 (csr read & clear)
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] & ~regs.xs1u), # csr (new value)
If(regs.f3 == 0x03, # csrrc rd, csr, rs1 (csr read & clear)
If(regs.imm_i == risq5defs.CSR_frm_id, # FPU special: Rounding mode
NextValue(regs.csr[risq5defs.CSR_fcsr][5:8], regs.csr[risq5defs.CSR_fcsr][5:8] & ~regs.xs1u[0:3]), # fcsr[5:8]='frm'!
).Elif(regs.imm_i == risq5defs.CSR_fflags_id, # FPU special: Exception flags
NextValue(regs.csr[risq5defs.CSR_fcsr][0:5], regs.csr[risq5defs.CSR_fcsr][0:5] & ~regs.xs1u[0:5]), # fcsr[0:5]='fflags'!
).Else( # Any other ...
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] & ~regs.xs1u), # csr (new value)
)
).Elif(regs.f3 == 0x07, # csrrci rd, csr, imm_i4 (csr read & clear immediate)
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] & ~regs.rs1), # csr (new value)
If(regs.imm_i == risq5defs.CSR_frm_id, # FPU special: Rounding mode
NextValue(regs.csr[risq5defs.CSR_fcsr][5:8], regs.csr[risq5defs.CSR_fcsr][5:8] & ~regs.rs1[0:3]), # fcsr[5:8]='frm'!
).Elif(regs.imm_i == risq5defs.CSR_fflags_id, # FPU special: Exception flags
NextValue(regs.csr[risq5defs.CSR_fcsr][0:5], regs.csr[risq5defs.CSR_fcsr][0:5] & ~regs.rs1[0:5]), # fcsr[0:5]='fflags'!
).Else( # Any other ...
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] & ~regs.rs1), # csr (new value)
)
).Elif(regs.f3 == 0x02, # csrrs rd, <csr>, rs1 (csr read & set)
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] | regs.xs1u), # csr (new value)
If(regs.imm_i == risq5defs.CSR_frm_id, # FPU special: Rounding mode
NextValue(regs.csr[risq5defs.CSR_fcsr][5:8], regs.csr[risq5defs.CSR_fcsr][5:8] | regs.xs1u[0:3]), # fcsr[5:8]='frm'!
).Elif(regs.imm_i == risq5defs.CSR_fflags_id, # FPU special: Exception flags
NextValue(regs.csr[risq5defs.CSR_fcsr][0:5], regs.csr[risq5defs.CSR_fcsr][0:5] | regs.xs1u[0:5]), # fcsr[0:5]='fflags'!
).Else( # Any other ...
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] | regs.xs1u), # csr (new value)
)
).Elif(regs.f3 == 0x06, # csrrsi rd, csr, imm_i4 (csr read & set immediate)
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] | regs.rs1), # csr (new value)
If(regs.imm_i == risq5defs.CSR_frm_id, # FPU special: Rounding mode
NextValue(regs.csr[risq5defs.CSR_fcsr][5:8], regs.csr[risq5defs.CSR_fcsr][5:8] | regs.rs1[0:3]), # fcsr[5:8]='frm'!
).Elif(regs.imm_i == risq5defs.CSR_fflags_id, # FPU special: Exception flags
NextValue(regs.csr[risq5defs.CSR_fcsr][0:5], regs.csr[risq5defs.CSR_fcsr][0:5] | regs.rs1[0:5]), # fcsr[0:5]='fflags'!
).Else( # Any other ...
NextValue(regs.csr[regs.csrindex], regs.csr[regs.csrindex] | regs.rs1), # csr (new value)
)
).Elif(regs.f3 == 0x01, # csrrw rd, csr, rs1 (csr read & write)
NextValue(regs.csr[regs.csrindex], regs.xs1u), # csr (new value)
If(regs.imm_i == risq5defs.CSR_frm_id, # FPU special: Rounding mode
NextValue(regs.csr[risq5defs.CSR_fcsr][5:8], regs.xs1u[0:3]), # fcsr[5:8]='frm'!
).Elif(regs.imm_i == risq5defs.CSR_fflags_id, # FPU special: Exception flags
NextValue(regs.csr[risq5defs.CSR_fcsr][0:5], regs.xs1u[0:5]), # fcsr[0:5]='fflags'!
).Else( # Any other ...
NextValue(regs.csr[regs.csrindex], regs.xs1u), # csr (new value)
)
).Elif(regs.f3 == 0x05, # csrrwi rd, csr, imm_i4 (csr read & write immediate)
NextValue(regs.csr[regs.csrindex], regs.rs1), # csr (new value)
If(regs.imm_i == risq5defs.CSR_frm_id, # FPU special: Rounding mode
NextValue(regs.csr[risq5defs.CSR_fcsr][5:8], regs.rs1[0:3]), # fcsr[5:8]='frm'!
).Elif(regs.imm_i == risq5defs.CSR_fflags_id, # FPU special: Exception flags
NextValue(regs.csr[risq5defs.CSR_fcsr][0:5], regs.rs1[0:5]), # fcsr[0:5]='fflags'!
).Else( # Any other ...
NextValue(regs.csr[regs.csrindex], regs.rs1), # csr (new value)
)
),
),
NextValue(writepost, 1), # Trigger write rd

@ -187,9 +187,9 @@ class Risq5RegisterFile(Module):
]
# ------------------------- CSRs ----------------------------------------------------
self.csr = Array(Signal(32) for _ in range(15)) # csr[0..12]
self.csr = Array(Signal(32) for _ in range(15+3+1)) # csr[0..14 + 3*FPU + dummy]
# Translate CSR ID codes -> Index
self.csrindex = Signal(4, reset_less=True) # 0..15
self.csrindex = Signal(5, reset_less=True) # 0..31
self.comb += [
If( self.imm_i == risq5defs.CSR_mstatus_id, self.csrindex.eq(risq5defs.CSR_mstatus) # mstatus (Interrupt enable & stati)
).Elif(self.imm_i == risq5defs.CSR_mip_id, self.csrindex.eq(risq5defs.CSR_mip) # mip (Machine interrupt pending)
@ -199,6 +199,10 @@ class Risq5RegisterFile(Module):
).Elif(self.imm_i == risq5defs.CSR_mtval_id, self.csrindex.eq(risq5defs.CSR_mtval) # mtval (Machine trap value)
).Elif(self.imm_i == risq5defs.CSR_mepc_id, self.csrindex.eq(risq5defs.CSR_mepc) # mepc (Machine exception pc)
).Elif(self.imm_i == risq5defs.CSR_mscratch_id, self.csrindex.eq(risq5defs.CSR_mscratch) # mscratch (Machine scratch)
# F-Extension
).Elif(self.imm_i == risq5defs.CSR_fflags_id, self.csrindex.eq(risq5defs.CSR_fflags) # INACTIVE! fflags (FPU exception flags)
).Elif(self.imm_i == risq5defs.CSR_frm_id, self.csrindex.eq(risq5defs.CSR_frm) # INACTIVE! frm (FPU rounding mode)
).Elif(self.imm_i == risq5defs.CSR_fcsr_id, self.csrindex.eq(risq5defs.CSR_fcsr) # fcsr (FPU control & status register)
# Statics start here (=> Index >= CSR_misa, no write then)
).Elif(self.imm_i == risq5defs.CSR_misa_id, self.csrindex.eq(risq5defs.CSR_misa) # misa (Machine ISA)
# Signed->Unsigned (cut off hi-bit ;)
@ -209,8 +213,7 @@ class Risq5RegisterFile(Module):
).Elif(self.imm_i[0:11] == risq5defs.CSR_0xBC0_id, self.csrindex.eq(risq5defs.CSR_0xBC0) # Custom shadow register (for vex?!)
).Elif(self.imm_i[0:11] == risq5defs.CSR_0xFC0_id, self.csrindex.eq(risq5defs.CSR_0xFC0) # Custom shadow register (for vex?!)
).Else(self.csrindex.eq(risq5defs.CSR_dummy)), # Dummy bit bucket ...
]
]
if __name__ == "__main__":
print("***** Register file is passive ... ;) *****")

@ -19,6 +19,7 @@ CSR_mtval = 5 # 0x343 mtval (Machine trap value)
CSR_mepc = 6 # 0x341 mepc (Machine exception pc)
CSR_mscratch = 7 #0x340 mscratch (Machine scratch)
CSR_0xBC0 = 8 # 0xBC0 custom shadow register (read/write)
# Static parts (read only)
CSR_misa = 9 # 0x301 misa (Machine ISA)
CSR_mvendorid = 10 # 0xF11 mvendorid (Machine vendor ID)
@ -26,6 +27,13 @@ CSR_marchid = 11 # 0xF12 marchid (Machine base microarchitecture)
CSR_mimpid = 12 # 0xF13 mimpid (Machine base microarchitecture version)
CSR_mhartid = 13 # 0xF14 mhartid (Machine hardware thread ('core') ID)
CSR_0xFC0 = 14 # 0xFC0 custom shadow register
# F-Extension
CSR_fflags = 15 # 0x001 fflags
CSR_frm = 16 # 0x002 frm
CSR_fcsr = 17 # 0x003 fcsr
# Sentinel
CSR_dummy = 15 # Shall never occurr ...
# RISC-V opcode defs.
@ -47,6 +55,11 @@ CSR_mimpid_id = 0x713 # mimpid (Machine base microarchitecture version)
CSR_mhartid_id = 0x714 # mhartid (Machine hardware thread ('core') ID)
CSR_0xFC0_id = 0x7C0 # custom shadow register (read only)
# F-Extension
CSR_fflags_id = 0x001 # fflags (FPU exception flags)
CSR_frm_id = 0x002 # frm (FPU rounding mode)
CSR_fcsr_id = 0x003 # fcsr (FPU control & status register)
# mstatus bits used
MSTATUS_MIE = 3 # Machine mode: Interrupt enable
MSTATUS_MPIE = 7 # Machine mode: Previous interrupt enable bit status (before trap)

@ -5,6 +5,28 @@ static void start(void)
auipc ra,0 # Store current pc \n\
lui sp,%hi(0x40192000) # Setup stack pointer \n\
addi sp,sp,%lo(0x40192000) # s.a. \n\
mv x3,x0 # Clear \n\
addi x3,x3,0x55 # rm=010 flags=10101 \n\
fscsr x0,x3 # Swap csr \n\
frcsr x3 # 003 x3=fcs (csrrs rd,fcsr,x0) \n\
frflags x3 # 001 x3=exception flags (OF etc., csrrs rd,fflags,x0) \n\
frrm x3 # 002 x3=rounding mode (rtz etc., csrrs rd,frm,x0) \n\
#fscsr x3,x0 # 003 x3=fcs,fcs=x0 (csrrw rd,fcsr,rs1) \n\
fsrmi x0,3 # 002 x3=round.mod., rm=3 (csrrwi rd,frm,rs1) \n\
frrm x3 # 002 x3=rounding mode (rtz etc., csrrs rd,frm,x0) \n\
fsflagsi x0,0x18 # 001 x3=except.flags, (csrrwi rd,frm,rs1) \n\
frflags x3 # 001 x3=exception flags (OF etc., csrrs rd,fflags,x0) \n\
mv x3,x0 # Clear \n\
addi x3,x3,0x1F # flags=10101 \n\
fsflags x0,x3 # 001 x3=except.flags (csrrw rd,fflags,rs1) \n\
frflags x3 # 001 x3=except.flags (csrrw rd,fflags,rs1) \n\
mv x3,x0 # Clear \n\
addi x3,x3,0x7 # rm=111 \n\
fsrm x0,x3 # 002 x3=round.mod., rm=x0 (csrrw rd,frm,rs1) \n\
frrm x3 # 002 x3=rounding mode (rtz etc., csrrs rd,frm,x0) \n\
frcsr x3 # Control \n\
frflags x3 # \n\
nop # end \n\
repeat: lui x3,%hi(0xFF800000) # -INF \n\
fmv.s.x f3,x3 # x3 -> f3 \n\
fclass.s x3,f3 # x3 = fclass(f3) \n\

Loading…
Cancel
Save