Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2022-12-22 22:51:33 -06:00
commit 98b824c4c4
24 changed files with 2207 additions and 64 deletions

View File

@ -120,7 +120,7 @@
`define LOGR ((`RADIX==2) ? 32'h1 : 32'h2)
`define RK (`DIVCOPIES*`LOGR) // r*k used for intdiv preproc
`define LOGK ($clog2(`DIVCOPIES))
`define LOGRK ($clog2(`RADIX*`DIVCOPIES)) // log2(R*k)
`define LOGRK ($clog2(`RK)) // log2(r*k)
// FPDUR = ceil(DIVRESLEN/(LOGR*DIVCOPIES))
// one iteration is required for the integer bit for minimally redundent radix-4
`define FPDUR ((`DIVN+1+(`LOGR*`DIVCOPIES))/(`LOGR*`DIVCOPIES)+(`RADIX/4))

View File

@ -67,14 +67,14 @@ module fdivsqrt(
logic WZeroM, AZeroM, BZeroM, AZeroE, BZeroE;
logic SpecialCaseM;
logic [`DIVBLEN:0] nE, nM, mM;
logic OTFCSwapE, ALTBM, As;
logic CalcOTFCSwapE, OTFCSwapE, ALTBM, As;
logic DivStartE;
logic [`XLEN-1:0] ForwardedSrcAM;
fdivsqrtpreproc fdivsqrtpreproc(
.clk, .IFDivStartE, .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE),
.Sqrt(SqrtE), .Ym(YmE), .XZeroE, .X, .DPreproc, .ForwardedSrcAM,
.nE, .nM, .mM, .OTFCSwapE, .ALTBM, .AZeroM, .BZeroM, .AZeroE, .BZeroE, .As,
.nE, .nM, .mM, .CalcOTFCSwapE, .OTFCSwapE, .ALTBM, .AZeroM, .BZeroM, .AZeroE, .BZeroE, .As,
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E);
fdivsqrtfsm fdivsqrtfsm(
.clk, .reset, .FmtE, .XsE, .SqrtE, .nE,
@ -85,11 +85,11 @@ module fdivsqrt(
fdivsqrtiter fdivsqrtiter(
.clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .MDUE, .SqrtE, // .SqrtM,
.X,.DPreproc, .FirstWS(WS), .FirstWC(WC),
.IFDivStartE, .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE, .OTFCSwapE,
.IFDivStartE, .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE, .CalcOTFCSwapE, .OTFCSwapE,
.FDivBusyE);
fdivsqrtpostproc fdivsqrtpostproc(
.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun,
.SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAM,
.nM, .ALTBM, .mM, .BZeroM, .As,
.nM, .ALTBM, .mM, .BZeroM, .As, .OTFCSwapEM(OTFCSwapE),
.QmM, .WZeroM, .DivSM, .FPIntDivResultM);
endmodule

View File

@ -38,7 +38,7 @@ module fdivsqrtiter(
input logic XZeroE, YZeroE,
input logic SqrtE, MDUE,
// input logic SqrtM,
input logic OTFCSwapE,
input logic CalcOTFCSwapE, OTFCSwapE,
input logic [`DIVb+3:0] X,
input logic [`DIVb-1:0] DPreproc,
output logic [`DIVb-1:0] D,
@ -81,9 +81,9 @@ module fdivsqrtiter(
flopen #(`DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]);
// UOTFC Result U and UM registers/initialization mux
// Initialize U to 1.0 and UM to 0 for square root; U to 0 and UM to -1 for division
assign initU = (SqrtE & ~(MDUE)) ? {1'b1, {(`DIVb){1'b0}}} : 0;
assign initUM = (SqrtE & ~(MDUE)) ? 0 : {1'b1, {(`DIVb){1'b0}}};
// Initialize U to 1.0 and UM to 0 for square root or negative-result int division; U to 0 and UM to -1 otherwise
assign initU = ((MDUE & CalcOTFCSwapE) | (SqrtE & ~(MDUE))) ? {1'b1, {(`DIVb){1'b0}}} : 0;
assign initUM = ((MDUE & CalcOTFCSwapE) | (SqrtE & ~(MDUE))) ? 0 : {1'b1, {(`DIVb){1'b0}}};
mux2 #(`DIVb+1) Umux(UNext[`DIVCOPIES-1], initU, IFDivStartE, UMux);
mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, IFDivStartE, UMMux);
flopen #(`DIVb+1) UReg(clk, IFDivStartE|FDivBusyE, UMux, U[0]);

View File

@ -35,9 +35,7 @@ module fdivsqrtpostproc(
input logic [`DIVb-1:0] D,
input logic [`DIVb:0] FirstU, FirstUM,
input logic [`DIVb+1:0] FirstC,
input logic Firstun,
input logic SqrtM,
input logic SpecialCaseM,
input logic Firstun, SqrtM, SpecialCaseM, OTFCSwapEM,
input logic [`XLEN-1:0] ForwardedSrcAM,
input logic RemOpM, ALTBM, BZeroM, As,
input logic [`DIVBLEN:0] nM, mM,
@ -54,7 +52,7 @@ module fdivsqrtpostproc(
logic [`DIVBLEN:0] NormShiftM;
logic [`DIVb:0] IntQuotM, NormQuotM;
logic [`DIVb+3:0] IntRemM, NormRemM;
logic [`DIVb+3:0] PreResultM, PreFPIntDivResultM;
logic signed [`DIVb+3:0] PreResultM, PreFPIntDivResultM;
// check for early termination on an exact result. If the result is not exact, the sticky should be set
aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0);
@ -130,11 +128,10 @@ module fdivsqrtpostproc(
NormShiftM = (mM + (`DIVBLEN+1)'(`DIVa));
PreResultM = IntRemM;
end else begin
if (BZeroM) begin
NormShiftM = 0;
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
if (BZeroM | (~ALTBM & OTFCSwapEM)) begin
PreResultM = {3'b111, IntQuotM};
end else begin
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
PreResultM = {3'b000, IntQuotM};
end
//PreResultM = {IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM}; // Suspicious Sign Extender
@ -143,7 +140,7 @@ module fdivsqrtpostproc(
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
assign PreFPIntDivResultM = ($signed(PreResultM) >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)};
assign PreFPIntDivResultM = $signed(PreResultM >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)};
assign FPIntDivResultM = PreFPIntDivResultM[`XLEN-1:0];
assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit

View File

@ -42,7 +42,7 @@ module fdivsqrtpreproc (
input logic [2:0] Funct3E, Funct3M,
input logic MDUE, W64E,
output logic [`DIVBLEN:0] nE, nM, mM,
output logic OTFCSwapE, ALTBM, As, AZeroM, BZeroM, AZeroE, BZeroE,
output logic CalcOTFCSwapE, OTFCSwapE, ALTBM, As, AZeroM, BZeroM, AZeroE, BZeroE,
output logic [`NE+1:0] QeM,
output logic [`DIVb+3:0] X,
output logic [`DIVb-1:0] DPreproc,
@ -56,7 +56,7 @@ module fdivsqrtpreproc (
// Intdiv signals
logic [`DIVb-1:0] IFNormLenX, IFNormLenD;
logic [`XLEN-1:0] PosA, PosB;
logic Bs, CalcOTFCSwapE, ALTBE;
logic Bs, ALTBE;
logic [`XLEN-1:0] A64, B64;
logic [`DIVBLEN:0] mE;
logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX;

View File

@ -32,7 +32,6 @@
module fdivsqrtqsel2 (
input logic [3:0] ps, pc,
input logic swap,
output logic up, uz, un
);
@ -56,11 +55,7 @@ module fdivsqrtqsel2 (
(ps[0]&pc[0])))));
// Produce digit = +1, 0, or -1
assign pos = magnitude & ~sign;
assign up = magnitude & ~sign;
assign uz = ~magnitude;
assign neg = magnitude & sign;
// Check for swap (int div only)
assign un = swap ? pos : neg;
assign up = swap ? neg : pos;
assign un = magnitude & sign;
endmodule

View File

@ -34,7 +34,7 @@ module fdivsqrtqsel4cmp (
input logic [2:0] Dmsbs,
input logic [4:0] Smsbs,
input logic [7:0] WSmsbs, WCmsbs,
input logic SqrtE, j1, OTFCSwapE, MDUE,
input logic SqrtE, j1, MDUE,
output logic [3:0] udigit
);
logic [6:0] Wmsbs;
@ -86,12 +86,9 @@ module fdivsqrtqsel4cmp (
// Compare residual W to selection constants to choose digit
always_comb
if ($signed(Wmsbs) >= $signed(mk2)) udigitsel = 4'b1000; // choose 2
else if ($signed(Wmsbs) >= $signed(mk1)) udigitsel = 4'b0100; // choose 1
else if ($signed(Wmsbs) >= $signed(mk0)) udigitsel = 4'b0000; // choose 0
else if ($signed(Wmsbs) >= $signed(mkm1)) udigitsel = 4'b0010; // choose -1
else udigitsel = 4'b0001; // choose -2
assign udigitswap = {udigitsel[0], udigitsel[1], udigitsel[2], udigitsel[3]};
assign udigit = OTFCSwapE ? udigitswap : udigitsel;
if ($signed(Wmsbs) >= $signed(mk2)) udigit = 4'b1000; // choose 2
else if ($signed(Wmsbs) >= $signed(mk1)) udigit = 4'b0100; // choose 1
else if ($signed(Wmsbs) >= $signed(mk0)) udigit = 4'b0000; // choose 0
else if ($signed(Wmsbs) >= $signed(mkm1)) udigit = 4'b0010; // choose -1
else udigit = 4'b0001; // choose -2
endmodule

View File

@ -60,7 +60,7 @@ module fdivsqrtstage2 (
// 0000 = 0
// 0010 = -1
// 0001 = -2
fdivsqrtqsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], OTFCSwapE, up, uz, un);
fdivsqrtqsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], up, uz, un);
// Sqrt F generation
fdivsqrtfgen2 fgen2(.up, .uz, .C(CNext), .U, .UM, .F);
@ -82,7 +82,7 @@ module fdivsqrtstage2 (
assign CNext = {1'b1, C[`DIVb+1:1]};
// Unified On-The-Fly Converter to accumulate result
fdivsqrtuotfc2 uotfc2(.up, .uz, .C(CNext), .U, .UM, .UNext, .UMNext);
fdivsqrtuotfc2 uotfc2(.up, .un, .swap(OTFCSwapE), .C(CNext), .U, .UM, .UNext, .UMNext);
endmodule

View File

@ -65,7 +65,7 @@ module fdivsqrtstage4 (
assign WCmsbs = WC[`DIVb+3:`DIVb-4];
assign WSmsbs = WS[`DIVb+3:`DIVb-4];
fdivsqrtqsel4cmp qsel4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit, .OTFCSwapE, .MDUE);
fdivsqrtqsel4cmp qsel4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit, .MDUE);
assign un = 1'b0; // unused for radix 4
// F generation logic
@ -94,7 +94,7 @@ module fdivsqrtstage4 (
assign CNext = {2'b11, C[`DIVb+1:2]};
// On-the-fly converter to accumulate result
fdivsqrtuotfc4 fdivsqrtuotfc4(.udigit, .Sqrt(SqrtE), .C(CNext[`DIVb:0]), .U, .UM, .UNext, .UMNext);
fdivsqrtuotfc4 fdivsqrtuotfc4(.udigit, .swap(OTFCSwapE), .Sqrt(SqrtE), .C(CNext[`DIVb:0]), .U, .UM, .UNext, .UMNext);
endmodule

View File

@ -34,7 +34,7 @@
// Unified OTFC, Radix 2 //
///////////////////////////////
module fdivsqrtuotfc2(
input logic up, uz,
input logic up, un, swap,
input logic [`DIVb+1:0] C,
input logic [`DIVb:0] U, UM,
output logic [`DIVb:0] UNext, UMNext
@ -42,20 +42,24 @@ module fdivsqrtuotfc2(
// The on-the-fly converter transfers the divsqrt
// bits to the quotient as they come.
logic [`DIVb:0] K;
logic unSwap, upSwap;
// Check for swap (int div only)
assign unSwap = swap ? up : un;
assign upSwap = swap ? un : up;
assign K = (C[`DIVb:0] & ~(C[`DIVb:0] << 1));
always_comb begin
if (up) begin
if (upSwap) begin
UNext = U | K;
UMNext = U;
end else if (uz) begin
UNext = U;
UMNext = UM | K;
end else begin // If up and uz are not true, then un is
end else if (unSwap) begin
UNext = UM | K;
UMNext = UM;
end
end else begin // If up and un are not true, then uz is
UNext = U;
UMNext = UM | K;
end
end
endmodule

View File

@ -32,7 +32,7 @@
module fdivsqrtuotfc4(
input logic [3:0] udigit,
input logic Sqrt,
input logic Sqrt, swap,
input logic [`DIVb:0] U, UM,
input logic [`DIVb:0] C,
output logic [`DIVb:0] UNext, UMNext
@ -41,25 +41,29 @@ module fdivsqrtuotfc4(
// bits to the quotient as they come.
// Use this otfc for division and square root.
logic [3:0] udigitswap, udigitsel;
logic [`DIVb:0] K1, K2, K3;
assign K1 = (C&~(C << 1)); // K
assign K2 = ((C << 1)&~(C << 2)); // 2K
assign K3 = (C & ~(C << 2)); // 3K
assign udigitswap = {udigit[0], udigit[1], udigit[2], udigit[3]};
assign udigitsel = swap ? udigitswap : udigit;
always_comb begin
if (udigit[3]) begin
if (udigitsel[3]) begin // +2
UNext = U | K2;
UMNext = U | K1;
end else if (udigit[2]) begin
end else if (udigitsel[2]) begin // +1
UNext = U | K1;
UMNext = U;
end else if (udigit[1]) begin
end else if (udigitsel[1]) begin // -1
UNext = UM | K3;
UMNext = UM | K2;
end else if (udigit[0]) begin
end else if (udigitsel[0]) begin // -2
UNext = UM | K2;
UMNext = UM | K1;
end else begin // udigit = 0
end else begin // 0
UNext = U;
UMNext = UM | K3;
end

View File

@ -1805,6 +1805,7 @@ string imperas32f[] = '{
"rv64i_m/privilege/src/WALLY-status-mie-01.S",
"rv64i_m/privilege/src/WALLY-status-sie-01.S",
"rv64i_m/privilege/src/WALLY-status-tw-01.S",
"rv64i_m/privilege/src/WALLY-status-tvm-01.S",
"rv64i_m/privilege/src/WALLY-stvec-01.S",
"rv64i_m/privilege/src/WALLY-trap-01.S",
"rv64i_m/privilege/src/WALLY-trap-s-01.S",
@ -1891,6 +1892,7 @@ string imperas32f[] = '{
"rv32i_m/privilege/src/WALLY-status-mie-01.S",
"rv32i_m/privilege/src/WALLY-status-sie-01.S",
"rv32i_m/privilege/src/WALLY-status-tw-01.S",
"rv32i_m/privilege/src/WALLY-status-tvm-01.S",
"rv32i_m/privilege/src/WALLY-stvec-01.S",
"rv32i_m/privilege/src/WALLY-trap-01.S",
"rv32i_m/privilege/src/WALLY-trap-s-01.S",

View File

@ -2,6 +2,7 @@
80006000 # read SD = 1, FS = 11
00004000 # read written SD = 1, FS = 10
80006000 # read SD = 1, FS = 11
00000002 # mcause from attempting fmv with status.FS cleared
0000000b # mcause from M mode ecall from test termination
deadbeef
deadbeef
@ -1021,4 +1022,3 @@ deadbeef
deadbeef
deadbeef
deadbeef
deadbeef

View File

@ -299,8 +299,7 @@ end_trap_triggers:
// --------------------------------------------------------------------------------------------
//.align 6
.align 2
.align 6
trap_handler_\MODE\():
j trap_unvectored_\MODE\() // for the unvectored implimentation: jump past this table of addresses into the actual handler
// *** ASSUMES that a cause value of 0 for an interrupt is unimplemented

View File

@ -35,8 +35,8 @@ RVTEST_CODE_BEGIN
# ---------------------------------------------------------------------------------------------
j main_code
# Thanks to MTVEC[1:0], trap handler addresses need to be aligned to a 4-byte boundary
.align 2
# 64 byte alignment for vectored traps to align with xtev
.align 6
###################
###################
trap_handler: #####

View File

@ -71,6 +71,10 @@ sw x29, 0(x6) // read dirty FS, SD bits, which should be 11 and 1 respectively
addi x6, x6, 4
addi x16, x16, 4
li x29, 0x6000
csrc mstatus, x29 // clear FS to be 00, disabling floating point
fmv.s ft0, ft0 // should be an illegal instruction with fs set to 00
END_TESTS
TEST_STACK_AND_DATA

View File

@ -0,0 +1,45 @@
///////////////////////////////////////////
//
// WALLY-status-tvm
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-12-22
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
RVTEST_ISA("RV32I")
RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*); def Drvtest_mtrap_routine=True;def TEST_CASE_1=True;def NO_SAIL=True;", status-tvm)
INIT_TESTS
TRAP_HANDLER m//, EXT_SIGNATURE=1 // turn on recording mtval and status bits on traps
li x28, 0x100000
csrs mstatus, x28 // set mstatus.TVM bit to 1
GOTO_S_MODE // go to S mode so the TVM can be triggered
csrw satp, x28 // attempt to write satp should cause illegal instruction with TVM
csrr x28, satp // attempt to read satp should cause illegal instruction with TVM
sfence.vma x0, x0 // attempt to call sfence should cause illegal instruction with TVM
END_TESTS
TEST_STACK_AND_DATA

View File

@ -6,6 +6,8 @@
00000000
00006000 # read SD = 1, FS = 11
80000000
00000002 # mcause from attempting fmv with status.FS cleared
00000000
0000000b # mcause from M mode ecall from test termination
00000000
deadbeef
@ -1020,5 +1022,3 @@ deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef

View File

@ -293,8 +293,7 @@ end_trap_triggers:
//
// --------------------------------------------------------------------------------------------
//.align 6
.align 3
.align 6
trap_handler_\MODE\():
j trap_unvectored_\MODE\() // for the unvectored implimentation: jump past this table of addresses into the actual handler
// *** ASSUMES that a cause value of 0 for an interrupt is unimplemented

View File

@ -35,8 +35,8 @@ RVTEST_CODE_BEGIN
# ---------------------------------------------------------------------------------------------
j main_code
# Thanks to MTVEC[1:0], trap handler addresses need to be aligned to a 4-byte boundary
.align 2
# 64 byte alignment for vectored traps to align with xtev
.align 6
###################
###################
trap_handler: #####

View File

@ -70,6 +70,10 @@ sd x29, 0(x6) // read dirty FS, SD bits, which should be 11 and 1 respectively
addi x6, x6, 8
addi x16, x16, 8
li x29, 0x6000
csrc mstatus, x29 // clear FS to be 00, disabling floating point
fmv.s ft0, ft0 // should be an illegal instruction with fs set to 00
END_TESTS
TEST_STACK_AND_DATA

View File

@ -0,0 +1,45 @@
///////////////////////////////////////////
//
// WALLY-status-tvm
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-12-22
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h"
RVTEST_ISA("RV64I")
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*); def Drvtest_mtrap_routine=True;def TEST_CASE_1=True;def NO_SAIL=True;", status-tvm)
INIT_TESTS
TRAP_HANDLER m//, EXT_SIGNATURE=1 // turn on recording mtval and status bits on traps
li x28, 0x100000
csrs mstatus, x28 // set mstatus.TVM bit to 1
GOTO_S_MODE // go to S mode so the TVM can be triggered
csrw satp, x28 // attempt to write satp should cause illegal instruction with TVM
csrr x28, satp // attempt to read satp should cause illegal instruction with TVM
sfence.vma x0, x0 // attempt to call sfence should cause illegal instruction with TVM
END_TESTS
TEST_STACK_AND_DATA