diff --git a/ChangeLog.md b/ChangeLog.md index f59f373..33def58 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -13,6 +13,37 @@ NOTE: X-commit messages below refer to git commits in the following --- +- Some details of CSR access behavior have been corrected: + - For Vector Extension version 0.8, access to vxsat and vxrm now requires both + mstatus.FS and mstatus.VS to be non-zero; previously, only non-zero + mstatus.FS was required. Note that from Vector Extension version 0.9 + onwards, only mstatus.VS is required because these two fields are now + aliased in the new vcsr CSR instead of the fcsr CSR. +- An issue has been fixed in which an incorrect exception was raised on an + access error during a page table walk. +- Some Vector Extension issues have been corrected: + - Behavior of vpopc.m and vfirst.m has been corrected when vl==0. + - Executing vsetvl/vsetvli instructions now sets vector state to dirty. + - Behavior of whole-register operations when vstart!=0 has been corrected. + - Vector indexed segment load instructions now raise an Illegal Instruction + if the destination vector register overlaps either source or mask. + - Decodes for vqmaccus and vqmaccsu instructions have been exchanged to match + the specification + - Implementations of vmv.s.x, vfmv.f.s and vfmv.s.f have been corrected to + prevent Illegal Instruction exceptions being reported for odd-numbered + vector registers for non-zero LMUL. These instructions should ignore LMUL. + - Instruction vfmv.s.f has been corrected to validate that the argument is + NaN-boxed when required. +- The vector version master branch currently has these differences compared to + the previous 0.8 version: + - V-commit bdb8b55: mstatus.VS and sstatus.VS fields have moved to bits 10:9; + - V-commit b25b643: new CSR vcsr has been added and fields VXSAT and VXRM + fields relocated there from CSR fcsr + +Date 2020-February-06 +Release 20200206.0 +=== + - Bit Manipulation Extension - Corrected sign extension for addwu, subwu, addiwu and slliu.w that were incorrectly changed in the last fix. @@ -52,7 +83,7 @@ Release 20200110.0 === - Bit Manipulation Extension - - Added sign extension for *w insructions on 64-bit processors. + - Added sign extension for *w instructions on 64-bit processors. - Command line argument 'memory' allows regions of memory to be defined using a string of form "low:high:permission" diff --git a/LICENSE.pdf b/LICENSE.pdf index 8436829..af4025f 100644 Binary files a/LICENSE.pdf and b/LICENSE.pdf differ diff --git a/README.md b/README.md index 10b6763..b69dfa2 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ A Complete, Fully Functional, Configurable RISC-V Simulator === Author: Imperas Software, Ltd., using OVP Open Standard APIs -Date : 06 Feb 2020 -Version: 20200206.0 +Date : 12 Feb 2020 +Version: 20200212.0 License: Model source included under Apache 2.0 open source license License: Simulator riscvOVPsim licensed under Open Virtual Platforms (OVP) Fixed Platform Kits license RISC-V Specifications currently supported: diff --git a/bin/Linux64/riscvOVPsim.exe b/bin/Linux64/riscvOVPsim.exe index 2661e38..208bf9c 100755 Binary files a/bin/Linux64/riscvOVPsim.exe and b/bin/Linux64/riscvOVPsim.exe differ diff --git a/bin/Windows64/riscvOVPsim.exe b/bin/Windows64/riscvOVPsim.exe index 328bd9c..fed71a3 100755 Binary files a/bin/Windows64/riscvOVPsim.exe and b/bin/Windows64/riscvOVPsim.exe differ diff --git a/doc/OVP_Model_Specific_Information_riscv_RV64GCV.pdf b/doc/OVP_Model_Specific_Information_riscv_RV64GCV.pdf index 3c7be76..8d0031d 100644 Binary files a/doc/OVP_Model_Specific_Information_riscv_RV64GCV.pdf and b/doc/OVP_Model_Specific_Information_riscv_RV64GCV.pdf differ diff --git a/doc/riscvOVPsim_User_Guide.pdf b/doc/riscvOVPsim_User_Guide.pdf index 624067f..d777a38 100644 Binary files a/doc/riscvOVPsim_User_Guide.pdf and b/doc/riscvOVPsim_User_Guide.pdf differ diff --git a/source/riscvCSR.c b/source/riscvCSR.c index ed42594..610dc8c 100644 --- a/source/riscvCSR.c +++ b/source/riscvCSR.c @@ -143,7 +143,28 @@ static RISCV_CSR_WRITEFN(misaW) { // Do vx CSRs require mstatus.FS!=0? // inline static Bool vxRequiresFS(riscvP riscv) { - return riscvVFSupport(riscv, RVVF_VXSAT_VXRM_IN_FCSR); + return riscvVFSupport(riscv, RVVF_VS_STATUS_8); +} + +// +// Are vxsat and vxrm visible in fcsr? (Vector Version 0.8 only) +// +inline static Bool vxFieldsInFCSR(riscvP riscv) { + return !riscvVFSupport(riscv, RVVF_VCSR_PRESENT); +} + +// +// Return floating point rounding mode master value +// +inline static Uns8 getMasterFRM(riscvP riscv) { + return RD_CSR_FIELD(riscv, fcsr, frm); +} + +// +// Return floating point rounding mode master value +// +inline static void setMasterFRM(riscvP riscv, Uns8 frm) { + WR_CSR_FIELD(riscv, fcsr, frm, frm); } // @@ -170,7 +191,7 @@ inline static vmiFPRC mapFRMToRC(Uns8 frm) { // static vmiFPRC updateCurrentRMValid(riscvP riscv) { - vmiFPRC rc = mapFRMToRC(RD_CSR_FIELD(riscv, fcsr, frm)); + vmiFPRC rc = mapFRMToRC(getMasterFRM(riscv)); Bool oldInvalid = (riscv->currentArch & ISA_RM_INVALID); Bool newInvalid = (rc==-1); @@ -285,7 +306,7 @@ static RISCV_CSR_READFN(frmR) { CSR_REG_DECL(frm) = {u32 : {bits:0}}; // compose register value - frm.u32.fields.frm = RD_CSR_FIELD(riscv, fcsr, frm); + frm.u32.fields.frm = getMasterFRM(riscv); // return composed value return frm.u32.bits; @@ -294,13 +315,13 @@ static RISCV_CSR_READFN(frmR) { // // Update model rounding mode controls // -static void refreshFPCR(riscvP riscv, Uns8 oldRM) { - - Uns8 newRM = RD_CSR_FIELD(riscv, fcsr, frm); +static void setFPRoundingMode(riscvP riscv, Uns8 oldRM, Uns8 newRM) { // update floating point rounding mode if(oldRM!=newRM) { + setMasterFRM(riscv, newRM); + vmiFPRC rc = updateCurrentRMValid(riscv); if(rc!=-1) { @@ -312,9 +333,6 @@ static void refreshFPCR(riscvP riscv, Uns8 oldRM) { vmirtSetFPControlWord((vmiProcessorP)riscv, cw); } } - - // update fixed point rounding mode alias - WR_CSR_FIELD(riscv, vxrm, rm, RD_CSR_FIELD(riscv, fcsr, vxrm)); } // @@ -322,15 +340,12 @@ static void refreshFPCR(riscvP riscv, Uns8 oldRM) { // static RISCV_CSR_WRITEFN(frmW) { - Uns8 oldRM = RD_CSR_FIELD(riscv, fcsr, frm); + Uns8 oldRM = getMasterFRM(riscv); CSR_REG_DECL(frm) = {u32 : {bits : newValue & WM32_frm}}; - // compose register value - WR_CSR_FIELD(riscv, fcsr, frm, frm.u32.fields.frm); - // handle change to rounding mode - refreshFPCR(riscv, oldRM); + setFPRoundingMode(riscv, oldRM, frm.u32.fields.frm); // return written value return frm.u32.bits; @@ -343,7 +358,6 @@ static RISCV_CSR_READFN(fcsrR) { // construct effective flags from CSR and JIT flags vmiFPFlags vmiFlags = getFPFlags(riscv); - Uns8 vxsat = getSatFlags(riscv); // compose flags in register value WR_CSR_FIELD(riscv, fcsr, NX, vmiFlags.f.P); @@ -352,8 +366,16 @@ static RISCV_CSR_READFN(fcsrR) { WR_CSR_FIELD(riscv, fcsr, DZ, vmiFlags.f.Z); WR_CSR_FIELD(riscv, fcsr, NV, vmiFlags.f.I); - // compose vxsat in register value - WR_CSR_FIELD(riscv, fcsr, vxsat, vxsat); + // handle vxsat and vxrm if these are visible in fcsr (Vector Version 0.8 + // only) + if(vxFieldsInFCSR(riscv)) { + + // get fixed point saturation alias + WR_CSR_FIELD(riscv, fcsr, vxsat, getSatFlags(riscv)); + + // get fixed point rounding mode alias + WR_CSR_FIELD(riscv, fcsr, vxrm, RD_CSR_FIELD(riscv, vxrm, rm)); + } // return composed value return RD_CSR(riscv, fcsr); @@ -365,7 +387,7 @@ static RISCV_CSR_READFN(fcsrR) { static RISCV_CSR_WRITEFN(fcsrW) { Uns64 mask = RD_CSR_MASK(riscv, fcsr); - Uns8 oldRM = RD_CSR_FIELD(riscv, fcsr, frm); + Uns8 oldRM = getMasterFRM(riscv); vmiFPFlags vmiFlags = {bits: 0}; // update the CSR @@ -381,11 +403,19 @@ static RISCV_CSR_WRITEFN(fcsrW) { // assign CSR flags and clear JIT flags (floating point) setFPFlags(riscv, vmiFlags); - // assign CSR flags and clear JIT flags (fixed point) - setSatFlags(riscv, RD_CSR_FIELD(riscv, fcsr, vxsat)); - // handle change to rounding modes - refreshFPCR(riscv, oldRM); + setFPRoundingMode(riscv, oldRM, RD_CSR_FIELD(riscv, fcsr, frm)); + + // handle updates to vxsat and vxrm if these are visible in fcsr (Vector + // Version 0.8 only) + if(vxFieldsInFCSR(riscv)) { + + // assign CSR flags and clear JIT flags (fixed point) + setSatFlags(riscv, RD_CSR_FIELD(riscv, fcsr, vxsat)); + + // update fixed point rounding mode alias + WR_CSR_FIELD(riscv, vxrm, rm, RD_CSR_FIELD(riscv, fcsr, vxrm)); + } // return written value return RD_CSR(riscv, fcsr); @@ -406,6 +436,42 @@ typedef enum extStatusE { ES_DIRTY = 3 } extStatus; +// +// Is mstatus.VS in Vector Version 0.8 location (bits 24:23)? +// +inline static Bool statusVS8(riscvP riscv) { + return riscvVFSupport(riscv, RVVF_VS_STATUS_8); +} + +// +// Is mstatus.VS in Vector Version 0.9 location (bits 10:9)? +// +inline static Bool statusVS9(riscvP riscv) { + return riscvVFSupport(riscv, RVVF_VS_STATUS_9); +} + +// +// Return current value of mstatus.VS +// +static Uns8 getStatusVS(riscvP riscv) { + if(statusVS8(riscv)) { + return RD_CSR_FIELD(riscv, mstatus, VS_8); + } else { + return RD_CSR_FIELD(riscv, mstatus, VS_9); + } +} + +// +// Set current value of mstatus.VS +// +static void setStatusVS(riscvP riscv, Uns8 VS) { + if(statusVS8(riscv)) { + WR_CSR_FIELD(riscv, mstatus, VS_8, VS); + } else { + WR_CSR_FIELD(riscv, mstatus, VS_9, VS); + } +} + // // Consolidate floating point and fixed point flags on CSR view // @@ -436,7 +502,7 @@ static Uns64 statusR(riscvP riscv) { // get FS, VS and XS fields (after consolidation) Uns8 FS = RD_CSR_FIELD(riscv, mstatus, FS); - Uns8 VS = RD_CSR_FIELD(riscv, mstatus, VS); + Uns8 VS = getStatusVS(riscv); Uns8 XS = RD_CSR_FIELD(riscv, mstatus, XS); // if fs_always_dirty is set, force mstatus.FS and mstatus.VS to be either @@ -452,7 +518,7 @@ static Uns64 statusR(riscvP riscv) { // handle mstatus.VS if(VS) { VS = ES_DIRTY; - WR_CSR_FIELD(riscv, mstatus, VS, VS); + setStatusVS(riscv, VS); } } @@ -1405,10 +1471,17 @@ static RISCV_CSR_WRITEFN(pmpaddrW) { // // Is vlenb register present? // -static RISCV_CSR_PRESENTFN(vlenbP) { +inline static RISCV_CSR_PRESENTFN(vlenbP) { return riscvVFSupport(riscv, RVVF_VLENB_PRESENT); } +// +// Is cvsr register present? +// +inline static RISCV_CSR_PRESENTFN(vcsrP) { + return riscvVFSupport(riscv, RVVF_VCSR_PRESENT); +} + // // Return maximum vector length for the current vector type settings // @@ -1425,8 +1498,13 @@ static Uns32 getMaxVL(riscvP riscv) { // static RISCV_CSR_WRITEFN(vxrmW) { - // update alias in fcsr - WR_CSR_FIELD(riscv, fcsr, vxrm, newValue); + // update alias in fcsr if required + if(vxFieldsInFCSR(riscv)) { + WR_CSR_FIELD(riscv, fcsr, vxrm, newValue); + } + + // update alias in vcsr + WR_CSR_FIELD(riscv, vcsr, vxrm, newValue); // update fixed point rounding mode alias WR_CSR_FIELD(riscv, vxrm, rm, newValue); @@ -1457,6 +1535,81 @@ static RISCV_CSR_WRITEFN(vxsatW) { return vxsat; } +// +// Read vcsr +// +static RISCV_CSR_READFN(vcsrR) { + + // initially clear register + WR_CSR(riscv, vcsr, 0); + + // update floating point fields only if enabled + if(riscv->currentArch & ISA_DF) { + + // construct effective flags from CSR and JIT flags + vmiFPFlags vmiFlags = getFPFlags(riscv); + + // compose flags in register value + WR_CSR_FIELD(riscv, vcsr, NX, vmiFlags.f.P); + WR_CSR_FIELD(riscv, vcsr, UF, vmiFlags.f.U); + WR_CSR_FIELD(riscv, vcsr, OF, vmiFlags.f.O); + WR_CSR_FIELD(riscv, vcsr, DZ, vmiFlags.f.Z); + WR_CSR_FIELD(riscv, vcsr, NV, vmiFlags.f.I); + + // compose frm in register value (mastered in fcsr) + WR_CSR_FIELD(riscv, vcsr, frm, getMasterFRM(riscv)); + } + + // get fixed point saturation alias + WR_CSR_FIELD(riscv, vcsr, vxsat, getSatFlags(riscv)); + + // get fixed point rounding mode alias + WR_CSR_FIELD(riscv, vcsr, vxrm, RD_CSR_FIELD(riscv, vxrm, rm)); + + // return composed value + return RD_CSR(riscv, vcsr); +} + +// +// Write vcsr +// +static RISCV_CSR_WRITEFN(vcsrW) { + + Uns64 mask = RD_CSR_MASK(riscv, vcsr); + Uns8 oldRM = getMasterFRM(riscv); + + // update the CSR + WR_CSR(riscv, vcsr, newValue & mask); + + // update floating point fields only if enabled + if(riscv->currentArch & ISA_DF) { + + vmiFPFlags vmiFlags = {bits: 0}; + + // extract flags from register value + vmiFlags.f.P = RD_CSR_FIELD(riscv, vcsr, NX); + vmiFlags.f.U = RD_CSR_FIELD(riscv, vcsr, UF); + vmiFlags.f.O = RD_CSR_FIELD(riscv, vcsr, OF); + vmiFlags.f.Z = RD_CSR_FIELD(riscv, vcsr, DZ); + vmiFlags.f.I = RD_CSR_FIELD(riscv, vcsr, NV); + + // assign CSR flags and clear JIT flags (floating point) + setFPFlags(riscv, vmiFlags); + + // handle change to rounding modes + setFPRoundingMode(riscv, oldRM, RD_CSR_FIELD(riscv, vcsr, frm)); + } + + // assign CSR flags and clear JIT flags (fixed point) + setSatFlags(riscv, RD_CSR_FIELD(riscv, vcsr, vxsat)); + + // update fixed point rounding mode alias + WR_CSR_FIELD(riscv, vxrm, rm, RD_CSR_FIELD(riscv, vcsr, vxrm)); + + // return written value + return RD_CSR(riscv, vcsr); +} + // // Refresh the vector polymorphic block key // @@ -1715,93 +1868,94 @@ void riscvSetVL(riscvP riscv, Uns64 vl) { // static const riscvCSRAttrs csrs[CSR_ID(LAST)] = { - // name num arch access version attrs description present wState rCB rwCB wCB - CSR_ATTR_P__ (ustatus, 0x000, ISA_N, 0, 1_10, 0,0,0, "User Status", 0, 0, ustatusR, 0, ustatusW ), - CSR_ATTR_P__ (fflags, 0x001, ISA_DF, 0, 1_10, 0,0,0, "Floating-Point Flags", 0, riscvWFS, fflagsR, 0, fflagsW ), - CSR_ATTR_P__ (frm, 0x002, ISA_DF, 0, 1_10, 1,0,0, "Floating-Point Rounding Mode", 0, riscvWFS, frmR, 0, frmW ), - CSR_ATTR_P__ (fcsr, 0x003, ISA_DFV, ISA_FS, 1_10, 1,0,0, "Floating-Point Control and Status", 0, riscvWFS, fcsrR, 0, fcsrW ), - CSR_ATTR_P__ (uie, 0x004, ISA_N, 0, 1_10, 1,0,0, "User Interrupt Enable", 0, 0, uieR, 0, uieW ), - CSR_ATTR_T__ (utvec, 0x005, ISA_N, 0, 1_10, 0,0,0, "User Trap-Vector Base-Address", 0, 0, 0, 0, utvecW ), - CSR_ATTR_TV_ (vstart, 0x008, ISA_V, 0, 1_10, 0,0,0, "Vector Start Index", 0, riscvWVStart,0, 0, 0 ), - CSR_ATTR_TC_ (vxsat, 0x009, ISA_V, ISA_FS, 1_10, 0,0,0, "Fixed-Point Saturate Flag", 0, riscvWFSVS, vxsatR, 0, vxsatW ), - CSR_ATTR_TC_ (vxrm, 0x00A, ISA_V, ISA_FS, 1_10, 0,0,0, "Fixed-Point Rounding Mode", 0, riscvWFSVS, 0, 0, vxrmW ), - CSR_ATTR_T__ (uscratch, 0x040, ISA_N, 0, 1_10, 0,0,0, "User Scratch", 0, 0, 0, 0, 0 ), - CSR_ATTR_TV_ (uepc, 0x041, ISA_N, 0, 1_10, 0,0,0, "User Exception Program Counter", 0, 0, uepcR, 0, 0 ), - CSR_ATTR_TV_ (ucause, 0x042, ISA_N, 0, 1_10, 0,0,0, "User Cause", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (utval, 0x043, ISA_N, 0, 1_10, 0,0,0, "User Trap Value", 0, 0, 0, 0, 0 ), - CSR_ATTR_P__ (uip, 0x044, ISA_N, 0, 1_10, 0,0,0, "User Interrupt Pending", 0, 0, uipR, uipRW, uipW ), - CSR_ATTR_P__ (cycle, 0xC00, 0, 0, 1_10, 0,1,0, "Cycle Counter", 0, 0, mcycleR, 0, 0 ), - CSR_ATTR_P__ (time, 0xC01, 0, 0, 1_10, 0,1,0, "Timer", 0, 0, mtimeR, 0, 0 ), - CSR_ATTR_P__ (instret, 0xC02, 0, 0, 1_10, 0,1,0, "Instructions Retired", 0, 0, minstretR, 0, 0 ), - CSR_ATTR_P__3_31 (hpmcounter, 0xC00, 0, 0, 1_10, 0,0,0, "Performance Monitor Counter ", 0, 0, mhpmR, 0, mhpmW ), - CSR_ATTR_T__ (vl, 0xC20, ISA_V, 0, 1_10, 0,0,0, "Vector Length", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (vtype, 0xC21, ISA_V, 0, 1_10, 0,0,0, "Vector Type", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (vlenb, 0xC22, ISA_V, 0, 1_10, 0,0,0, "Vector Length in Bytes", vlenbP, 0, 0, 0, 0 ), - CSR_ATTR_P__ (cycleh, 0xC80, ISA_XLEN_32, 0, 1_10, 0,1,0, "Cycle Counter High", 0, 0, mcyclehR, 0, 0 ), - CSR_ATTR_P__ (timeh, 0xC81, ISA_XLEN_32, 0, 1_10, 0,1,0, "Timer High", 0, 0, mtimehR, 0, 0 ), - CSR_ATTR_P__ (instreth, 0xC82, ISA_XLEN_32, 0, 1_10, 0,1,0, "Instructions Retired High", 0, 0, minstrethR, 0, 0 ), - CSR_ATTR_P__3_31 (hpmcounterh, 0xC80, ISA_XLEN_32, 0, 1_10, 0,0,0, "Performance Monitor High ", 0, 0, mhpmR, 0, mhpmW ), - - // name num arch access version attrs description present wState rCB rwCB wCB - CSR_ATTR_P__ (sstatus, 0x100, ISA_S, 0, 1_10, 0,0,0, "Supervisor Status", 0, riscvRstFS, sstatusR, 0, sstatusW ), - CSR_ATTR_TV_ (sedeleg, 0x102, ISA_SandN, 0, 1_10, 0,0,0, "Supervisor Exception Delegation", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (sideleg, 0x103, ISA_SandN, 0, 1_10, 1,0,0, "Supervisor Interrupt Delegation", 0, 0, 0, 0, sidelegW ), - CSR_ATTR_P__ (sie, 0x104, ISA_S, 0, 1_10, 1,0,0, "Supervisor Interrupt Enable", 0, 0, sieR, 0, sieW ), - CSR_ATTR_T__ (stvec, 0x105, ISA_S, 0, 1_10, 0,0,0, "Supervisor Trap-Vector Base-Address", 0, 0, 0, 0, stvecW ), - CSR_ATTR_TV_ (scounteren, 0x106, ISA_S, 0, 1_10, 0,0,0, "Supervisor Counter Enable", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (sscratch, 0x140, ISA_S, 0, 1_10, 0,0,0, "Supervisor Scratch", 0, 0, 0, 0, 0 ), - CSR_ATTR_TV_ (sepc, 0x141, ISA_S, 0, 1_10, 0,0,0, "Supervisor Exception Program Counter", 0, 0, sepcR, 0, 0 ), - CSR_ATTR_TV_ (scause, 0x142, ISA_S, 0, 1_10, 0,0,0, "Supervisor Cause", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (stval, 0x143, ISA_S, 0, 1_10, 0,0,0, "Supervisor Trap Value", 0, 0, 0, 0, 0 ), - CSR_ATTR_P__ (sip, 0x144, ISA_S, 0, 1_10, 0,0,0, "Supervisor Interrupt Pending", 0, 0, sipR, sipRW, sipW ), - CSR_ATTR_T__ (satp, 0x180, ISA_S, 0, 1_10, 0,0,1, "Supervisor Address Translation and Protection", 0, 0, 0, 0, satpW ), - - // name num arch access version attrs description present wState rCB rwCB wCB - CSR_ATTR_T__ (mvendorid, 0xF11, 0, 0, 1_10, 0,0,0, "Vendor ID", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (marchid, 0xF12, 0, 0, 1_10, 0,0,0, "Architecture ID", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (mimpid, 0xF13, 0, 0, 1_10, 0,0,0, "Implementation ID", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (mhartid, 0xF14, 0, 0, 1_10, 0,0,0, "Hardware Thread ID", 0, 0, 0, 0, 0 ), - CSR_ATTR_TV_ (mstatus, 0x300, 0, 0, 1_10, 0,0,0, "Machine Status", 0, riscvRstFS, mstatusR, 0, mstatusW ), - CSR_ATTR_T__ (misa, 0x301, 0, 0, 1_10, 1,0,0, "ISA and Extensions", 0, 0, 0, 0, misaW ), - CSR_ATTR_TV_ (medeleg, 0x302, ISA_SorN, 0, 1_10, 0,0,0, "Machine Exception Delegation", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (mideleg, 0x303, ISA_SorN, 0, 1_10, 1,0,0, "Machine Interrupt Delegation", 0, 0, 0, 0, midelegW ), - CSR_ATTR_T__ (mie, 0x304, 0, 0, 1_10, 1,0,0, "Machine Interrupt Enable", 0, 0, 0, 0, mieW ), - CSR_ATTR_T__ (mtvec, 0x305, 0, 0, 1_10, 0,0,0, "Machine Trap-Vector Base-Address", 0, 0, 0, 0, mtvecW ), - CSR_ATTR_TV_ (mcounteren, 0x306, ISA_SorU, 0, 1_10, 0,0,0, "Machine Counter Enable", 0, 0, 0, 0, 0 ), - CSR_ATTR_TV_ (mcountinhibit,0x320, 0, 0, 1_11, 0,0,0, "Machine Counter Inhibit", 0, 0, 0, 0, mcountinhibitW), - CSR_ATTR_T__ (mscratch, 0x340, 0, 0, 1_10, 0,0,0, "Machine Scratch", 0, 0, 0, 0, 0 ), - CSR_ATTR_TV_ (mepc, 0x341, 0, 0, 1_10, 0,0,0, "Machine Exception Program Counter", 0, 0, mepcR, 0, 0 ), - CSR_ATTR_TV_ (mcause, 0x342, 0, 0, 1_10, 0,0,0, "Machine Cause", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (mtval, 0x343, 0, 0, 1_10, 0,0,0, "Machine Trap Value", 0, 0, 0, 0, 0 ), - CSR_ATTR_T__ (mip, 0x344, 0, 0, 1_10, 0,0,0, "Machine Interrupt Pending", 0, 0, mipR, mipRW, mipW ), - - // name num arch access version attrs description present wState rCB rwCB wCB - CSR_ATTR_P__ (pmpcfg0, 0x3A0, 0, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 0", 0, 0, pmpcfgR, 0, pmpcfgW ), - CSR_ATTR_P__ (pmpcfg1, 0x3A1, ISA_XLEN_32, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 1", 0, 0, pmpcfgR, 0, pmpcfgW ), - CSR_ATTR_P__ (pmpcfg2, 0x3A2, 0, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 2", 0, 0, pmpcfgR, 0, pmpcfgW ), - CSR_ATTR_P__ (pmpcfg3, 0x3A3, ISA_XLEN_32, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 3", 0, 0, pmpcfgR, 0, pmpcfgW ), - CSR_ATTR_P__0_15 (pmpaddr, 0x3B0, 0, 0, 1_10, 0,0,0, "Physical Memory Protection Address ", 0, 0, pmpaddrR, 0, pmpaddrW ), - - // name num arch access version attrs description present wState rCB rwCB wCB - CSR_ATTR_P__ (mcycle, 0xB00, 0, 0, 1_10, 0,1,0, "Machine Cycle Counter", 0, 0, mcycleR, 0, mcycleW ), - CSR_ATTR_P__ (minstret, 0xB02, 0, 0, 1_10, 0,1,0, "Machine Instructions Retired", 0, 0, minstretR, 0, minstretW ), - CSR_ATTR_P__3_31 (mhpmcounter, 0xB00, 0, 0, 1_10, 0,0,0, "Machine Performance Monitor Counter ", 0, 0, mhpmR, 0, mhpmW ), - CSR_ATTR_P__ (mcycleh, 0xB80, ISA_XLEN_32, 0, 1_10, 0,1,0, "Machine Cycle Counter High", 0, 0, mcyclehR, 0, mcyclehW ), - CSR_ATTR_P__ (minstreth, 0xB82, ISA_XLEN_32, 0, 1_10, 0,1,0, "Machine Instructions Retired High", 0, 0, minstrethR, 0, minstrethW ), - CSR_ATTR_P__3_31 (mhpmcounterh, 0xB80, ISA_XLEN_32, 0, 1_10, 0,0,0, "Machine Performance Monitor Counter High ", 0, 0, mhpmR, 0, mhpmW ), - CSR_ATTR_P__3_31 (mhpmevent, 0x320, 0, 0, 1_10, 0,0,0, "Machine Performance Monitor Event Select ", 0, 0, mhpmR, 0, mhpmW ), - - // name num arch access version attrs description present wState rCB rwCB wCB - CSR_ATTR_NIP (tselect, 0x7A0, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Register Select" ), - CSR_ATTR_NIP (tdata1, 0x7A1, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Data 1" ), - CSR_ATTR_NIP (tdata2, 0x7A2, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Data 2" ), - CSR_ATTR_NIP (tdata3, 0x7A3, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Data 3" ), - - // name num arch access version attrs description present wState rCB rwCB wCB + // name num arch access version attrs description present wState rCB rwCB wCB + CSR_ATTR_P__ (ustatus, 0x000, ISA_N, 0, 1_10, 0,0,0, "User Status", 0, 0, ustatusR, 0, ustatusW ), + CSR_ATTR_P__ (fflags, 0x001, ISA_DF, 0, 1_10, 0,0,0, "Floating-Point Flags", 0, riscvWFS, fflagsR, 0, fflagsW ), + CSR_ATTR_P__ (frm, 0x002, ISA_DF, 0, 1_10, 1,0,0, "Floating-Point Rounding Mode", 0, riscvWFS, frmR, 0, frmW ), + CSR_ATTR_P__ (fcsr, 0x003, ISA_DFV, ISA_FS, 1_10, 1,0,0, "Floating-Point Control and Status", 0, riscvWFS, fcsrR, 0, fcsrW ), + CSR_ATTR_P__ (uie, 0x004, ISA_N, 0, 1_10, 1,0,0, "User Interrupt Enable", 0, 0, uieR, 0, uieW ), + CSR_ATTR_T__ (utvec, 0x005, ISA_N, 0, 1_10, 0,0,0, "User Trap-Vector Base-Address", 0, 0, 0, 0, utvecW ), + CSR_ATTR_TV_ (vstart, 0x008, ISA_V, 0, 1_10, 0,0,0, "Vector Start Index", 0, riscvWVStart,0, 0, 0 ), + CSR_ATTR_TC_ (vxsat, 0x009, ISA_V, ISA_FSandV, 1_10, 0,0,0, "Fixed-Point Saturate Flag", 0, riscvWFSVS, vxsatR, 0, vxsatW ), + CSR_ATTR_TC_ (vxrm, 0x00A, ISA_V, ISA_FSandV, 1_10, 0,0,0, "Fixed-Point Rounding Mode", 0, riscvWFSVS, 0, 0, vxrmW ), + CSR_ATTR_T__ (vcsr, 0x00F, ISA_V, 0, 1_10, 1,0,0, "Vector Control and Status", vcsrP, riscvWVCSR, vcsrR, 0, vcsrW ), + CSR_ATTR_T__ (uscratch, 0x040, ISA_N, 0, 1_10, 0,0,0, "User Scratch", 0, 0, 0, 0, 0 ), + CSR_ATTR_TV_ (uepc, 0x041, ISA_N, 0, 1_10, 0,0,0, "User Exception Program Counter", 0, 0, uepcR, 0, 0 ), + CSR_ATTR_TV_ (ucause, 0x042, ISA_N, 0, 1_10, 0,0,0, "User Cause", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (utval, 0x043, ISA_N, 0, 1_10, 0,0,0, "User Trap Value", 0, 0, 0, 0, 0 ), + CSR_ATTR_P__ (uip, 0x044, ISA_N, 0, 1_10, 0,0,0, "User Interrupt Pending", 0, 0, uipR, uipRW, uipW ), + CSR_ATTR_P__ (cycle, 0xC00, 0, 0, 1_10, 0,1,0, "Cycle Counter", 0, 0, mcycleR, 0, 0 ), + CSR_ATTR_P__ (time, 0xC01, 0, 0, 1_10, 0,1,0, "Timer", 0, 0, mtimeR, 0, 0 ), + CSR_ATTR_P__ (instret, 0xC02, 0, 0, 1_10, 0,1,0, "Instructions Retired", 0, 0, minstretR, 0, 0 ), + CSR_ATTR_P__3_31 (hpmcounter, 0xC00, 0, 0, 1_10, 0,0,0, "Performance Monitor Counter ", 0, 0, mhpmR, 0, mhpmW ), + CSR_ATTR_T__ (vl, 0xC20, ISA_V, 0, 1_10, 0,0,0, "Vector Length", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (vtype, 0xC21, ISA_V, 0, 1_10, 0,0,0, "Vector Type", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (vlenb, 0xC22, ISA_V, 0, 1_10, 0,0,0, "Vector Length in Bytes", vlenbP, 0, 0, 0, 0 ), + CSR_ATTR_P__ (cycleh, 0xC80, ISA_XLEN_32, 0, 1_10, 0,1,0, "Cycle Counter High", 0, 0, mcyclehR, 0, 0 ), + CSR_ATTR_P__ (timeh, 0xC81, ISA_XLEN_32, 0, 1_10, 0,1,0, "Timer High", 0, 0, mtimehR, 0, 0 ), + CSR_ATTR_P__ (instreth, 0xC82, ISA_XLEN_32, 0, 1_10, 0,1,0, "Instructions Retired High", 0, 0, minstrethR, 0, 0 ), + CSR_ATTR_P__3_31 (hpmcounterh, 0xC80, ISA_XLEN_32, 0, 1_10, 0,0,0, "Performance Monitor High ", 0, 0, mhpmR, 0, mhpmW ), + + // name num arch access version attrs description present wState rCB rwCB wCB + CSR_ATTR_P__ (sstatus, 0x100, ISA_S, 0, 1_10, 0,0,0, "Supervisor Status", 0, riscvRstFS, sstatusR, 0, sstatusW ), + CSR_ATTR_TV_ (sedeleg, 0x102, ISA_SandN, 0, 1_10, 0,0,0, "Supervisor Exception Delegation", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (sideleg, 0x103, ISA_SandN, 0, 1_10, 1,0,0, "Supervisor Interrupt Delegation", 0, 0, 0, 0, sidelegW ), + CSR_ATTR_P__ (sie, 0x104, ISA_S, 0, 1_10, 1,0,0, "Supervisor Interrupt Enable", 0, 0, sieR, 0, sieW ), + CSR_ATTR_T__ (stvec, 0x105, ISA_S, 0, 1_10, 0,0,0, "Supervisor Trap-Vector Base-Address", 0, 0, 0, 0, stvecW ), + CSR_ATTR_TV_ (scounteren, 0x106, ISA_S, 0, 1_10, 0,0,0, "Supervisor Counter Enable", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (sscratch, 0x140, ISA_S, 0, 1_10, 0,0,0, "Supervisor Scratch", 0, 0, 0, 0, 0 ), + CSR_ATTR_TV_ (sepc, 0x141, ISA_S, 0, 1_10, 0,0,0, "Supervisor Exception Program Counter", 0, 0, sepcR, 0, 0 ), + CSR_ATTR_TV_ (scause, 0x142, ISA_S, 0, 1_10, 0,0,0, "Supervisor Cause", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (stval, 0x143, ISA_S, 0, 1_10, 0,0,0, "Supervisor Trap Value", 0, 0, 0, 0, 0 ), + CSR_ATTR_P__ (sip, 0x144, ISA_S, 0, 1_10, 0,0,0, "Supervisor Interrupt Pending", 0, 0, sipR, sipRW, sipW ), + CSR_ATTR_T__ (satp, 0x180, ISA_S, 0, 1_10, 0,0,1, "Supervisor Address Translation and Protection", 0, 0, 0, 0, satpW ), + + // name num arch access version attrs description present wState rCB rwCB wCB + CSR_ATTR_T__ (mvendorid, 0xF11, 0, 0, 1_10, 0,0,0, "Vendor ID", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (marchid, 0xF12, 0, 0, 1_10, 0,0,0, "Architecture ID", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (mimpid, 0xF13, 0, 0, 1_10, 0,0,0, "Implementation ID", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (mhartid, 0xF14, 0, 0, 1_10, 0,0,0, "Hardware Thread ID", 0, 0, 0, 0, 0 ), + CSR_ATTR_TV_ (mstatus, 0x300, 0, 0, 1_10, 0,0,0, "Machine Status", 0, riscvRstFS, mstatusR, 0, mstatusW ), + CSR_ATTR_T__ (misa, 0x301, 0, 0, 1_10, 1,0,0, "ISA and Extensions", 0, 0, 0, 0, misaW ), + CSR_ATTR_TV_ (medeleg, 0x302, ISA_SorN, 0, 1_10, 0,0,0, "Machine Exception Delegation", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (mideleg, 0x303, ISA_SorN, 0, 1_10, 1,0,0, "Machine Interrupt Delegation", 0, 0, 0, 0, midelegW ), + CSR_ATTR_T__ (mie, 0x304, 0, 0, 1_10, 1,0,0, "Machine Interrupt Enable", 0, 0, 0, 0, mieW ), + CSR_ATTR_T__ (mtvec, 0x305, 0, 0, 1_10, 0,0,0, "Machine Trap-Vector Base-Address", 0, 0, 0, 0, mtvecW ), + CSR_ATTR_TV_ (mcounteren, 0x306, ISA_SorU, 0, 1_10, 0,0,0, "Machine Counter Enable", 0, 0, 0, 0, 0 ), + CSR_ATTR_TV_ (mcountinhibit,0x320, 0, 0, 1_11, 0,0,0, "Machine Counter Inhibit", 0, 0, 0, 0, mcountinhibitW), + CSR_ATTR_T__ (mscratch, 0x340, 0, 0, 1_10, 0,0,0, "Machine Scratch", 0, 0, 0, 0, 0 ), + CSR_ATTR_TV_ (mepc, 0x341, 0, 0, 1_10, 0,0,0, "Machine Exception Program Counter", 0, 0, mepcR, 0, 0 ), + CSR_ATTR_TV_ (mcause, 0x342, 0, 0, 1_10, 0,0,0, "Machine Cause", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (mtval, 0x343, 0, 0, 1_10, 0,0,0, "Machine Trap Value", 0, 0, 0, 0, 0 ), + CSR_ATTR_T__ (mip, 0x344, 0, 0, 1_10, 0,0,0, "Machine Interrupt Pending", 0, 0, mipR, mipRW, mipW ), + + // name num arch access version attrs description present wState rCB rwCB wCB + CSR_ATTR_P__ (pmpcfg0, 0x3A0, 0, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 0", 0, 0, pmpcfgR, 0, pmpcfgW ), + CSR_ATTR_P__ (pmpcfg1, 0x3A1, ISA_XLEN_32, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 1", 0, 0, pmpcfgR, 0, pmpcfgW ), + CSR_ATTR_P__ (pmpcfg2, 0x3A2, 0, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 2", 0, 0, pmpcfgR, 0, pmpcfgW ), + CSR_ATTR_P__ (pmpcfg3, 0x3A3, ISA_XLEN_32, 0, 1_10, 0,0,0, "Physical Memory Protection Configuration 3", 0, 0, pmpcfgR, 0, pmpcfgW ), + CSR_ATTR_P__0_15 (pmpaddr, 0x3B0, 0, 0, 1_10, 0,0,0, "Physical Memory Protection Address ", 0, 0, pmpaddrR, 0, pmpaddrW ), + + // name num arch access version attrs description present wState rCB rwCB wCB + CSR_ATTR_P__ (mcycle, 0xB00, 0, 0, 1_10, 0,1,0, "Machine Cycle Counter", 0, 0, mcycleR, 0, mcycleW ), + CSR_ATTR_P__ (minstret, 0xB02, 0, 0, 1_10, 0,1,0, "Machine Instructions Retired", 0, 0, minstretR, 0, minstretW ), + CSR_ATTR_P__3_31 (mhpmcounter, 0xB00, 0, 0, 1_10, 0,0,0, "Machine Performance Monitor Counter ", 0, 0, mhpmR, 0, mhpmW ), + CSR_ATTR_P__ (mcycleh, 0xB80, ISA_XLEN_32, 0, 1_10, 0,1,0, "Machine Cycle Counter High", 0, 0, mcyclehR, 0, mcyclehW ), + CSR_ATTR_P__ (minstreth, 0xB82, ISA_XLEN_32, 0, 1_10, 0,1,0, "Machine Instructions Retired High", 0, 0, minstrethR, 0, minstrethW ), + CSR_ATTR_P__3_31 (mhpmcounterh, 0xB80, ISA_XLEN_32, 0, 1_10, 0,0,0, "Machine Performance Monitor Counter High ", 0, 0, mhpmR, 0, mhpmW ), + CSR_ATTR_P__3_31 (mhpmevent, 0x320, 0, 0, 1_10, 0,0,0, "Machine Performance Monitor Event Select ", 0, 0, mhpmR, 0, mhpmW ), + + // name num arch access version attrs description present wState rCB rwCB wCB + CSR_ATTR_NIP (tselect, 0x7A0, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Register Select" ), + CSR_ATTR_NIP (tdata1, 0x7A1, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Data 1" ), + CSR_ATTR_NIP (tdata2, 0x7A2, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Data 2" ), + CSR_ATTR_NIP (tdata3, 0x7A3, 0, 0, 1_10, 0,0,0, "Debug/Trace Trigger Data 3" ), + + // name num arch access version attrs description present wState rCB rwCB wCB // TODO: these are undefined in all modes - CSR_ATTR_NIP (dcsr, 0x7B0, 0, 0, 1_10, 0,0,0, "Debug Control and Status" ), - CSR_ATTR_NIP (dpc, 0x7B1, 0, 0, 1_10, 0,0,0, "Debug PC" ), - CSR_ATTR_NIP (dscratch, 0x7B2, 0, 0, 1_10, 0,0,0, "Debug Scratch" ), + CSR_ATTR_NIP (dcsr, 0x7B0, 0, 0, 1_10, 0,0,0, "Debug Control and Status" ), + CSR_ATTR_NIP (dpc, 0x7B1, 0, 0, 1_10, 0,0,0, "Debug PC" ), + CSR_ATTR_NIP (dscratch, 0x7B2, 0, 0, 1_10, 0,0,0, "Debug Scratch" ), }; @@ -1855,6 +2009,22 @@ static Bool checkCSRImplemented(riscvCSRAttrsCP attrs, riscvP riscv) { return !attrs->presentCB || attrs->presentCB(attrs, riscv); } +// +// Return the features required for access to the given CSR +// +static riscvArchitecture getRequiredCSRFeatures( + riscvCSRAttrsCP attrs, + riscvP riscv +) { + riscvArchitecture required = attrs->arch; + + if((required==ISA_DFV) && !vxFieldsInFCSR(riscv)) { + required &= ~ISA_V; + } + + return required; +} + // // Is this CSR supported, either architecturally (if normal is True) or for // the purposes of a gdb access (if normal is False)? If not, return missing @@ -1862,14 +2032,14 @@ static Bool checkCSRImplemented(riscvCSRAttrsCP attrs, riscvP riscv) { // static riscvArchitecture getMissingCSRFeatures( riscvCSRAttrsCP attrs, + riscvP riscv, + riscvArchitecture required, riscvArchitecture actual ) { - riscvArchitecture required = attrs->arch & ~ISA_and; - - if(attrs->arch & ISA_and) { + if(required & ISA_and) { // all specified features are required - return required & ~actual; + return required & ~(actual|ISA_and); } else { @@ -1888,8 +2058,10 @@ static Bool checkCSRPresent( riscvArchitecture actual, Bool normal ) { + riscvArchitecture required = getRequiredCSRFeatures(attrs, riscv); + return ( - (!normal || !getMissingCSRFeatures(attrs, actual)) && + (!normal || !getMissingCSRFeatures(attrs, riscv, required, actual)) && checkCSRImplemented(attrs, riscv) ); } @@ -2533,11 +2705,23 @@ void riscvCSRInit(riscvP riscv, Uns32 index) { SET_CSR_FIELD_MASK_1(riscv, mstatus, FS); } - // initialize V-extension write masks (NOTE: vector extension requires - // mstatus.FS to enable access to vxsat and vxrm and their aliases in fcsr) - if((arch&ISA_V) && vxRequiresFS(riscv)) { - SET_CSR_FIELD_MASK_1(riscv, mstatus, FS); - SET_CSR_FIELD_MASK_1(riscv, mstatus, VS); + // initialize V-extension write masks + if(arch&ISA_V) { + + // enable FS field if required (NOTE: Vector Extension 0.8 requires + // mstatus.FS to enable access to vxsat and vxrm and their aliases in + // fcsr) + if(vxRequiresFS(riscv)) { + SET_CSR_FIELD_MASK_1(riscv, mstatus, FS); + } + + // enable mstatus.VS write mask in either 0.8 or 0.9 version location + // if required + if(statusVS8(riscv)) { + SET_CSR_FIELD_MASK_1(riscv, mstatus, VS_8); + } else if(statusVS9(riscv)) { + SET_CSR_FIELD_MASK_1(riscv, mstatus, VS_9); + } } //-------------------------------------------------------------------------- @@ -2713,15 +2897,40 @@ void riscvCSRInit(riscvP riscv, Uns32 index) { Uns32 fcsrMask = 0; - // fields are enabled by both floating point and vector extensions - if(arch&ISA_DF) {fcsrMask |= WM32_fcsr_f;} - if(arch&ISA_V) {fcsrMask |= WM32_fcsr_v;} + // enable floating point fields if required + if(arch&ISA_DF) { + fcsrMask |= WM32_fcsr_f; + } + + // enable fixed point fields if vcsr is not present + if((arch&ISA_V) && !riscvVFSupport(riscv, RVVF_VCSR_PRESENT)) { + fcsrMask |= WM32_fcsr_v; + } SET_CSR_MASK_V(riscv, fcsr, fcsrMask); // set initial rounding-mode-valid state updateCurrentRMValid(riscv); + //-------------------------------------------------------------------------- + // vcsr mask + //-------------------------------------------------------------------------- + + if((arch&ISA_V) && riscvVFSupport(riscv, RVVF_VCSR_PRESENT)) { + + Uns32 vcsrMask = 0; + + // enable floating point fields if required + if(arch&ISA_DF) { + vcsrMask |= WM32_vcsr_f; + } + + // enable fixed point fields + vcsrMask |= WM32_vcsr_v; + + SET_CSR_MASK_V(riscv, vcsr, vcsrMask); + } + //-------------------------------------------------------------------------- // vlenb //-------------------------------------------------------------------------- @@ -2944,18 +3153,27 @@ static void emitWarnUnimplementedCSR(riscvCSRAttrsCP attrs, riscvP riscv) { } // -// If a CSR is inaccessible because required architectural featues are absent +// If a CSR is inaccessible because required architectural features are absent // or disabled, return a bitmask of those features // -static riscvArchitecture getInaccessibleCSRFeatures( +static riscvArchitecture getInaccessibleCSRFeaturesMT( riscvP riscv, riscvCSRAttrsCP attrs ) { - if(attrs->access && vxRequiresFS(riscv)) { - return ~riscv->currentArch & attrs->access; - } else { - return getMissingCSRFeatures(attrs, riscv->currentArch); + riscvArchitecture required = getRequiredCSRFeatures(attrs, riscv); + riscvArchitecture current = riscv->currentArch; + riscvArchitecture access = attrs->access; + + // switch to access requirements if required + if(access && vxRequiresFS(riscv)) { + required = access; } + + // validate required feature presence + riscvEmitBlockMask(riscv, required); + + // return any missing features + return getMissingCSRFeatures(attrs, riscv, required, current); } // @@ -2978,7 +3196,7 @@ riscvCSRAttrsCP riscvValidateCSRAccess( ILLEGAL_INSTRUCTION_MESSAGE(riscv, "CSR_UNIMP", "Unimplemented CSR"); return 0; - } else if((missing=getInaccessibleCSRFeatures(riscv, attrs))) { + } else if((missing=getInaccessibleCSRFeaturesMT(riscv, attrs))) { // CSR requires missing or disabled features riscvRequireArchPresentMT(riscv, missing); diff --git a/source/riscvCSR.h b/source/riscvCSR.h index ba61173..5cb9867 100644 --- a/source/riscvCSR.h +++ b/source/riscvCSR.h @@ -105,6 +105,7 @@ typedef enum riscvCSRIdE { CSR_ID (vstart), // 0x008 CSR_ID (vxsat), // 0x009 CSR_ID (vxrm), // 0x00A + CSR_ID (vcsr), // 0x00F CSR_ID (uscratch), // 0x040 CSR_ID (uepc), // 0x041 CSR_ID (ucause), // 0x042 @@ -448,7 +449,7 @@ typedef struct { Uns32 _u1 : 1; Uns32 MPIE : 1; // Machine mode interrupt enable (stacked) Uns32 SPP : 1; // Supervisor previous mode - Uns32 _u2 : 2; + Uns32 VS_9 : 2; // Vector Extension dirty state (version 0.9) Uns32 MPP : 2; // Machine previous mode Uns32 FS : 2; // Floating point dirty state Uns32 XS : 2; // User extension dirty state @@ -458,7 +459,7 @@ typedef struct { Uns32 TVM : 1; // Trap virtual memory (requires S extension) Uns32 TW : 1; // Timeout wait (requires S extension) Uns32 TSR : 1; // Trap SRET (requires S extension) - Uns32 VS : 2; // Vector Extension dirty state + Uns32 VS_8 : 2; // Vector Extension dirty state (version 0.8) Uns32 _u3 : 6; Uns32 SD : 1; // Dirty state summary bit (read only) } CSR_REG_TYPE_32(status); @@ -474,7 +475,7 @@ typedef struct { Uns64 _u1 : 1; Uns64 MPIE : 1; // Machine mode interrupt enable (stacked) Uns64 SPP : 1; // Supervisor previous mode - Uns64 _u2 : 2; + Uns32 VS_9 : 2; // Vector Extension dirty state (version 0.9) Uns64 MPP : 2; // Machine previous mode Uns64 FS : 2; // Floating point dirty state Uns64 XS : 2; // User extension dirty state @@ -484,7 +485,7 @@ typedef struct { Uns64 TVM : 1; // Trap virtual memory (requires S extension) Uns64 TW : 1; // Timeout wait (requires S extension) Uns64 TSR : 1; // Trap SRET (requires S extension) - Uns32 VS : 2; // Vector Extension dirty state + Uns32 VS_8 : 2; // Vector Extension dirty state (version 0.8) Uns64 _u3 : 7; Uns64 UXL : 2; // TODO: User mode XLEN Uns64 SXL : 2; // TODO: Supervisor mode XLEN @@ -505,12 +506,13 @@ typedef CSR_REG_TYPE(status) CSR_REG_TYPE(mstatus); #define ustatus_AMASK 0x0000000000000011ULL // define bit masks -#define WM_mstatus_FS (3<<13) -#define WM_mstatus_TVM (1<<20) -#define WM_mstatus_TW (1<<21) -#define WM_mstatus_TSR (1<<22) -#define WM_mstatus_VS (3<<23) -#define WM_mstatus_IE 0xf +#define WM_mstatus_FS (3<<13) +#define WM_mstatus_TVM (1<<20) +#define WM_mstatus_TW (1<<21) +#define WM_mstatus_TSR (1<<22) +#define WM_mstatus_VS_8 (3<<23) +#define WM_mstatus_VS_9 (3<<9) +#define WM_mstatus_IE 0xf // ----------------------------------------------------------------------------- // fflags (id 0x001) @@ -560,8 +562,8 @@ typedef struct { Uns32 DZ : 1; Uns32 NV : 1; Uns32 frm : 3; - Uns32 vxsat : 1; - Uns32 vxrm : 2; + Uns32 vxsat : 1; // Vector Version 0.8 only + Uns32 vxrm : 2; // Vector Version 0.8 only Uns32 _u0 : 21; } CSR_REG_TYPE_32(fcsr); @@ -1071,6 +1073,31 @@ CSR_REG_STRUCT_DECL_32(vxrm); #define WM32_vxrm 0x00000003 #define WM64_vxrm 0x00000003 +// ----------------------------------------------------------------------------- +// vcsr (id 0x00F) +// ----------------------------------------------------------------------------- + +// 32-bit view +typedef struct { + Uns32 NX : 1; + Uns32 UF : 1; + Uns32 OF : 1; + Uns32 DZ : 1; + Uns32 NV : 1; + Uns32 frm : 3; + Uns32 vxsat : 1; + Uns32 vxrm : 2; + Uns32 _u0 : 21; +} CSR_REG_TYPE_32(vcsr); + +// define 32 bit type +CSR_REG_STRUCT_DECL_32(vcsr); + +// write masks +#define WM32_vcsr_f 0x0ff +#define WM32_vcsr_v 0x700 +#define WM32_vcsr_frm_msb 0x080 + // ----------------------------------------------------------------------------- // vl (id 0xC20) // ----------------------------------------------------------------------------- @@ -1141,6 +1168,7 @@ typedef struct riscvCSRsS { CSR_REG_DECL(vstart); // 0x008 CSR_REG_DECL(vxsat); // 0x009 CSR_REG_DECL(vxrm); // 0x00A + CSR_REG_DECL(vcsr); // 0x00E CSR_REG_DECL(uscratch); // 0x040 CSR_REG_DECL(uepc); // 0x041 CSR_REG_DECL(ucause); // 0x042 @@ -1195,6 +1223,7 @@ typedef struct riscvCSRMasksS { CSR_REG_DECL(fcsr); // 0x003 CSR_REG_DECL(utvec); // 0x005 CSR_REG_DECL(vstart); // 0x008 + CSR_REG_DECL(vcsr); // 0x00F CSR_REG_DECL(uepc); // 0x041 CSR_REG_DECL(ucause); // 0x042 diff --git a/source/riscvDecode.c b/source/riscvDecode.c index 22890fa..c20e72d 100644 --- a/source/riscvDecode.c +++ b/source/riscvDecode.c @@ -1693,7 +1693,7 @@ const static decodeEntry32 decodePost20191004[] = { DECODE32_ENTRY( VMSBC_VV, "|010011|.|.....|.....|000|.....|1010111|"), DECODE32_ENTRY( VQMACCU_VV, "|111100|.|.....|.....|000|.....|1010111|"), DECODE32_ENTRY( VQMACC_VV, "|111101|.|.....|.....|000|.....|1010111|"), - DECODE32_ENTRY( VQMACCSU_VV, "|111110|.|.....|.....|000|.....|1010111|"), + DECODE32_ENTRY( VQMACCSU_VV, "|111111|.|.....|.....|000|.....|1010111|"), // V-extension MVV-type instructions // |funct6|m| vs2| vs1|MVV| vs3| opcode| @@ -1716,8 +1716,8 @@ const static decodeEntry32 decodePost20191004[] = { DECODE32_ENTRY( VMSBC_VX, "|010011|.|.....|.....|100|.....|1010111|"), DECODE32_ENTRY( VQMACCU_VX, "|111100|.|.....|.....|100|.....|1010111|"), DECODE32_ENTRY( VQMACC_VX, "|111101|.|.....|.....|100|.....|1010111|"), - DECODE32_ENTRY( VQMACCSU_VX, "|111110|.|.....|.....|100|.....|1010111|"), - DECODE32_ENTRY( VQMACCUS_VX, "|111111|.|.....|.....|100|.....|1010111|"), + DECODE32_ENTRY( VQMACCUS_VX, "|111110|.|.....|.....|100|.....|1010111|"), + DECODE32_ENTRY( VQMACCSU_VX, "|111111|.|.....|.....|100|.....|1010111|"), // V-extension MVX-type instructions // |funct6|m| vs2| rs1|MVX| vs3| opcode| diff --git a/source/riscvDoc.c b/source/riscvDoc.c index 3d4d92e..cb2658d 100644 --- a/source/riscvDoc.c +++ b/source/riscvDoc.c @@ -1073,8 +1073,17 @@ void riscvDoc(riscvP rootProcessor) { vmidocAddText( Version, - "Unstable master version as of 14 December 2019 (commit " - RVVV_MASTER_TAG"), currently identical to version 0.8." + "Unstable master version as of 8 February 2020 (commit " + RVVV_MASTER_TAG"), with these changes compared to version 0.8:" + ); + vmidocAddText( + Version, + "- mstatus.VS and sstatus.VS fields have moved to bits 10:9;" + ); + vmidocAddText( + Version, + "- new CSR vcsr has been added and fields VXSAT and VXRM " + "fields relocated there from CSR fcsr." ); } } diff --git a/source/riscvMorph.c b/source/riscvMorph.c index 9d030f7..1594078 100644 --- a/source/riscvMorph.c +++ b/source/riscvMorph.c @@ -217,8 +217,15 @@ inline static Bool unitStrideOnly(riscvP riscv) { // // Should vxsat and vxrm be treated as members of fcsr for dirty state update? // -inline static Bool vxSatRMInFCSR(riscvP riscv) { - return riscvVFSupport(riscv, RVVF_VXSAT_VXRM_IN_FCSR); +inline static Bool vxSatRMSetFSDirty(riscvP riscv) { + return riscvVFSupport(riscv, RVVF_VS_STATUS_8); +} + +// +// Is vcsr register present? +// +inline static Bool isVCSRPresent(riscvP riscv) { + return riscvVFSupport(riscv, RVVF_VCSR_PRESENT); } // @@ -418,6 +425,18 @@ Bool riscvRequireArchPresentMT(riscvP riscv, riscvArchitecture feature) { return !absent; } +// +// Emit blockMask check for the given feature set +// +void riscvEmitBlockMask(riscvP riscv, riscvArchitecture features) { + + features &= ~ISA_and; + + if(features) { + emitBlockMask(riscv, features); + } +} + // // Validate that the given required feature is enabled (using blockMask if // necessary) @@ -607,6 +626,20 @@ inline static Bool writeAnyFS(riscvP riscv) { return riscv->configInfo.mstatus_fs_mode==RVFS_WRITE_ANY; } +// +// Is mstatus.VS in Vector Version 0.8 location (bits 24:23)? +// +inline static Bool statusVS8(riscvP riscv) { + return riscvVFSupport(riscv, RVVF_VS_STATUS_8); +} + +// +// Is mstatus.VS in Vector Version 0.9 location (bits 10:9)? +// +inline static Bool statusVS9(riscvP riscv) { + return riscvVFSupport(riscv, RVVF_VS_STATUS_9); +} + // // Indicate that this instruction may update mstatus (by changing mstatus.FS) // @@ -623,7 +656,7 @@ inline static void mayWriteMStatusFS(riscvP riscv) { // inline static void mayWriteMStatusVS(riscvP riscv) { - if(RD_CSR_MASK_FIELD(riscv, mstatus, VS) && !alwaysDirtyFS(riscv)) { + if((statusVS8(riscv) || statusVS9(riscv)) && !alwaysDirtyFS(riscv)) { vmimtRegReadImpl("mstatus"); vmimtRegWriteImpl("mstatus"); } @@ -653,7 +686,16 @@ static void updateFS(riscvP riscv) { // static void updateVS(riscvP riscv) { - if(RD_CSR_MASK_FIELD(riscv, mstatus, VS) && !alwaysDirtyFS(riscv)) { + Uns32 WM_mstatus_VS = 0; + + // get mask of dirty bits for mstatus.VS in either 0.8 or 0.9 location + if(statusVS8(riscv)) { + WM_mstatus_VS = WM_mstatus_VS_8; + } else if(statusVS9(riscv)) { + WM_mstatus_VS = WM_mstatus_VS_9; + } + + if(WM_mstatus_VS && !alwaysDirtyFS(riscv)) { riscvBlockStateP blockState = riscv->blockState; @@ -2432,7 +2474,7 @@ inline static Bool isSNaN64(Uns64 value) { // Return VMI register for the given abstract register which may require a NaN // box test if it is floating point (internal routine) // -static vmiReg riscvGetVMIRegFSInt( +static vmiReg getVMIRegFSInt( riscvMorphStateP state, riscvP riscv, riscvRegDesc r, @@ -2479,7 +2521,7 @@ static vmiReg riscvGetVMIRegFSInt( // box test if it is floating point (public interface) // vmiReg riscvGetVMIRegFS(riscvP riscv, riscvRegDesc r, vmiReg tmp) { - return riscvGetVMIRegFSInt(0, riscv, r, tmp); + return getVMIRegFSInt(0, riscv, r, tmp); } // @@ -2487,11 +2529,11 @@ vmiReg riscvGetVMIRegFS(riscvP riscv, riscvRegDesc r, vmiReg tmp) { // box test if it is floating point (local interface) // inline static vmiReg getVMIRegFS(riscvMorphStateP state, riscvRegDesc r) { - return riscvGetVMIRegFSInt(state, state->riscv, r, VMI_NOREG); + return getVMIRegFSInt(state, state->riscv, r, VMI_NOREG); } // -// Adjust JIT code generator state after write of floating point register +// Adjust JIT code generator state after write of floating point CSR // void riscvWFS(riscvMorphStateP state, Bool useRS1) { @@ -2501,14 +2543,33 @@ void riscvWFS(riscvMorphStateP state, Bool useRS1) { } // -// Adjust JIT code generator state after write of vector register that affects -// floating point state (behavior clearly defined only after version 20191118) +// Adjust JIT code generator state after write of vcsr CSR, which will set +// vector state dirty and floating point state dirty (if floating point is +// enabled) +// +void riscvWVCSR(riscvMorphStateP state, Bool useRS1) { + + riscvP riscv = state->riscv; + + updateVS(riscv); + + if(isFeaturePresentMT(riscv, ISA_FS)) { + updateFS(riscv); + } +} + +// +// Adjust JIT code generator state after write of vector CSR that affects +// floating point state or vector extension state (behavior clearly defined only +// after version 20191118) // void riscvWFSVS(riscvMorphStateP state, Bool useRS1) { riscvP riscv = state->riscv; - if(vxSatRMInFCSR(riscv)) { + if(isVCSRPresent(riscv)) { + updateVS(riscv); + } else if(vxSatRMSetFSDirty(riscv)) { updateFS(riscv); } } @@ -3967,6 +4028,7 @@ typedef enum overlapTypeE { OT_S = 0x1, // destination must not overlap vector source OT_M = 0x2, // destination must not overlap mask source OT_M71 = 0x4, // destination must not overlap mask source (0.7.1 only) + OT_XSM = 0x8, // destination must not overlap any source if segmented OT___ = OT_NA, OT_S_ = OT_S, @@ -4000,43 +4062,45 @@ typedef struct shapeInfoS { // Information for each vector operation shape // static const shapeInfo shapeDetails[RVVW_LAST] = { - [RVVW_111_II] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_IIS] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 1, 1, 0, 0, OT___ }, - [RVVW_111_IIX] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 1, 0, 0, OT___ }, - [RVVW_BBB_II] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 1, OT___ }, - [RVVW_EXT_II] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,1,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_PI] = {{1,1,1}, {0,0,0}, {1,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_SI] = {{1,1,1}, {0,0,0}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_CIN_II] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 1, 0, OT___ }, - [RVVW_CIN_PI] = {{1,1,1}, {0,0,0}, {1,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 1, 0, OT___ }, - [RVVW_212_SI] = {{2,1,2}, {0,0,0}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_121_II] = {{1,2,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 1, 0, 0, 0, 0, OT___ }, - [RVVW_121_IIS] = {{1,2,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 1, 1, 1, 0, 0, OT___ }, - [RVVW_211_IIQ] = {{2,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, - [RVVW_211_II] = {{2,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_211_IIS] = {{2,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 1, 1, 0, 0, OT___ }, - [RVVW_411_II] = {{4,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_221_II] = {{2,2,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_FF] = {{1,1,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_PF] = {{1,1,1}, {1,1,1}, {1,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_SF] = {{1,1,1}, {1,1,1}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_212_SF] = {{2,1,2}, {1,1,1}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_121_FFQ] = {{1,2,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, - [RVVW_211_FFQ] = {{2,1,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, - [RVVW_211_FF] = {{2,1,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_221_FF] = {{2,2,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_FI] = {{1,1,1}, {1,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_IF] = {{1,1,1}, {0,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_21_FIQ] = {{2,1,0}, {1,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, - [RVVW_21_IFQ] = {{2,1,0}, {0,1,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, - [RVVW_12_FIQ] = {{1,2,0}, {1,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, - [RVVW_12_IFQ] = {{1,2,0}, {0,1,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_PP] = {{1,1,1}, {0,0,0}, {1,1,1}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, - [RVVW_111_IP] = {{1,1,1}, {0,0,0}, {0,1,1}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM }, - [RVVW_111_GR] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM }, - [RVVW_111_UP] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM71}, - [RVVW_111_DN] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, 0, 0, 0, 0, 0, 0, 0, OT__M71}, - [RVVW_111_CMP] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {1,0,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM }, + [RVVW_111_II] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_IIXSM] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT_XSM }, + [RVVW_111_IIS] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 1, 1, 0, 0, OT___ }, + [RVVW_111_IIX] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 1, 0, 0, OT___ }, + [RVVW_BBB_II] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 1, OT___ }, + [RVVW_111_IS] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,1,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_SI] = {{1,1,1}, {0,0,0}, {0,0,0}, {1,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_PI] = {{1,1,1}, {0,0,0}, {1,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_SIS] = {{1,1,1}, {0,0,0}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_CIN_II] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 1, 0, OT___ }, + [RVVW_CIN_PI] = {{1,1,1}, {0,0,0}, {1,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 1, 0, OT___ }, + [RVVW_212_SIS] = {{2,1,2}, {0,0,0}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_121_II] = {{1,2,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 1, 0, 0, 0, 0, OT___ }, + [RVVW_121_IIS] = {{1,2,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 1, 1, 1, 0, 0, OT___ }, + [RVVW_211_IIQ] = {{2,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, + [RVVW_211_II] = {{2,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_211_IIS] = {{2,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 1, 1, 0, 0, OT___ }, + [RVVW_411_II] = {{4,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_221_II] = {{2,2,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_FF] = {{1,1,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_PF] = {{1,1,1}, {1,1,1}, {1,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_SFS] = {{1,1,1}, {1,1,1}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_212_SFS] = {{2,1,2}, {1,1,1}, {0,0,0}, {1,0,1}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_121_FFQ] = {{1,2,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, + [RVVW_211_FFQ] = {{2,1,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, + [RVVW_211_FF] = {{2,1,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_221_FF] = {{2,2,1}, {1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_FI] = {{1,1,1}, {1,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_IF] = {{1,1,1}, {0,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_21_FIQ] = {{2,1,0}, {1,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, + [RVVW_21_IFQ] = {{2,1,0}, {0,1,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, + [RVVW_12_FIQ] = {{1,2,0}, {1,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, + [RVVW_12_IFQ] = {{1,2,0}, {0,1,0}, {0,0,0}, {0,0,0}, {0,0,0}, 0, 1, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_PP] = {{1,1,1}, {0,0,0}, {1,1,1}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT___ }, + [RVVW_111_IP] = {{1,1,1}, {0,0,0}, {0,1,1}, {0,0,0}, {0,0,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM }, + [RVVW_111_GR] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM }, + [RVVW_111_UP] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM71}, + [RVVW_111_DN] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, 0, 0, 0, 0, 0, 0, 0, OT__M71}, + [RVVW_111_CMP] = {{1,1,1}, {0,0,0}, {0,0,0}, {0,0,0}, {1,0,0}, 0, 0, 0, 0, 0, 0, 0, OT_SM }, }; // @@ -4406,6 +4470,11 @@ static Bool validateNoOverlap(riscvMorphStateP state, iterDescP id) { } } + // destination must not overlap source or mask if segmented + if((ot&OT_XSM) && state->info.nf) { + ot |= OT_SM; + } + // destination must not overlap the mask for some instructions in // version 0.7.1 only (constraint relaxed from 0.8) if((ot&OT_M71) && riscvVFSupport(riscv, RVVF_STRICT_OVERLAP)) { @@ -4622,7 +4691,7 @@ static void updateVXSat(riscvMorphStateP state) { riscvP riscv = state->riscv; // set mstatus.FS if required - if(writeAnyFS(riscv) && vxSatRMInFCSR(riscv)) { + if(writeAnyFS(riscv) && vxSatRMSetFSDirty(riscv)) { updateFS(riscv); } @@ -4951,20 +5020,6 @@ static void validateVStart( } } -// -// Clamp vstart CSR to maximum value -// -static void clampVStart(riscvMorphStateP state, iterDescP id) { - - vmiReg vstart = CSR_REG_MT(vstart); - - if(state->info.isWhole) { - vmimtMoveRC(64, vstart, getVLMAXOp(id)); - } else { - vmimtMoveExtendRR(64, vstart, 32, CSR_REG_MT(vl), False); - } -} - // // Handle non-zero vstart // @@ -4979,29 +5034,38 @@ static vmiLabelP handleNonZeroVStart( if(!blockState->VStartZeroMt) { - skip = vmimtNewLabel(); + vmiReg vstart = CSR_REG_MT(vstart); - if(!iterVStart) { + if(state->info.isWhole) { - // skip operation if required, vstart clamp not required - validateVStart(state, id, vmi_COND_NL, skip); + vmimtMoveRC(64, vstart, 0); } else { - // skip operation if required, vstart clamp required - vmiLabelP doOp = vmimtNewLabel(); + skip = vmimtNewLabel(); + + if(!iterVStart) { + + // skip operation if required, vstart clamp not required + validateVStart(state, id, vmi_COND_NL, skip); - // go if at least one element should be processed - validateVStart(state, id, vmi_COND_L, doOp); + } else { - // clamp vstart to vl if it is used as an iteration index - clampVStart(state, id); + // skip operation if required, vstart clamp required + vmiLabelP doOp = vmimtNewLabel(); - // go to zero extension operation - vmimtUncondJumpLabel(skip); + // go if at least one element should be processed + validateVStart(state, id, vmi_COND_L, doOp); - // here if at least one element should be processed - vmimtInsertLabel(doOp); + // clamp vstart to vl if it is used as an iteration index + vmimtMoveExtendRR(64, vstart, 32, CSR_REG_MT(vl), False); + + // go to zero extension operation + vmimtUncondJumpLabel(skip); + + // here if at least one element should be processed + vmimtInsertLabel(doOp); + } } } else if(iterVStart) { @@ -5780,7 +5844,12 @@ static vmiCallFn handleVSetVLArg1(riscvMorphStateP state) { // // Indicate vtype and vl are written by this instruction // -static void emitUpdateVTypeVL(void) { +static void emitUpdateVTypeVL(riscvMorphStateP state) { + + // set vector state to dirty + updateVS(state->riscv); + + // indicate written registers vmimtRegWriteImpl("vtype"); vmimtRegWriteImpl("vl"); } @@ -5945,7 +6014,7 @@ static void emitVSetVLRR0SameVL(riscvMorphStateP state) { static RISCV_MORPH_FN(emitVSetVLRRR) { // this instruction updates vtype and vl - emitUpdateVTypeVL(); + emitUpdateVTypeVL(state); // emit VSetVL , , embedded function call emitVSetVLRRRCB(state); @@ -5965,7 +6034,7 @@ static RISCV_MORPH_FN(emitVSetVLRRC) { setVLOption option = getSetVLOption(state); // this instruction updates vtype and vl - emitUpdateVTypeVL(); + emitUpdateVTypeVL(state); if(!SEW) { @@ -6590,8 +6659,9 @@ static void seedXd(riscvMorphStateP state, iterDescP id, Int32 c) { // // Initialization callback for VPOPC // -static RISCV_MORPHV_FN(initVPOPCCB) { +static RISCV_CHECKV_FN(initVPOPCCB) { seedXd(state, id, 0); + return True; } // @@ -6621,8 +6691,9 @@ static RISCV_MORPHV_FN(emitVPOPCCB) { // // Initialization callback for VFIRST // -static RISCV_MORPHV_FN(initVFIRSTCB) { +static RISCV_CHECKV_FN(initVFIRSTCB) { seedXd(state, id, -1); + return True; } // @@ -7853,9 +7924,9 @@ static RISCV_MORPHV_FN(emitVFMVSF) { riscvP riscv = state->riscv; vmiReg vd = id->r[0]; - vmiReg fs1 = id->r[1]; riscvRegDesc fs1A = getRVReg(state, 1); Uns32 sBits = getMinBits(id, getRBits(fs1A)); + vmiReg fs1 = getVMIRegFS(state, setRBits(fs1A, sBits)); // zero target register zeroTail(riscv, id->VLEN, vd); @@ -8348,12 +8419,12 @@ const static riscvMorphAttr dispatchTable[] = { [RV_IT_VSETVL_I] = {morph:emitVSetVLRRC}, // V-extension load/store instructions - [RV_IT_VL_I] = {morph:emitVectorOp, opTCB:emitVLdUCB, checkCB:emitVLdStCheckUCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY}, - [RV_IT_VLS_I] = {morph:emitVectorOp, opTCB:emitVLdSCB, checkCB:emitVLdStCheckSCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY}, - [RV_IT_VLX_I] = {morph:emitVectorOp, opTCB:emitVLdICB, checkCB:emitVLdStCheckXCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY}, - [RV_IT_VS_I] = {morph:emitVectorOp, opTCB:emitVStUCB, checkCB:emitVLdStCheckUCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY}, - [RV_IT_VSS_I] = {morph:emitVectorOp, opTCB:emitVStSCB, checkCB:emitVLdStCheckSCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY}, - [RV_IT_VSX_I] = {morph:emitVectorOp, opTCB:emitVStICB, checkCB:emitVLdStCheckXCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY}, + [RV_IT_VL_I] = {morph:emitVectorOp, opTCB:emitVLdUCB, checkCB:emitVLdStCheckUCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY, vShape:RVVW_111_II }, + [RV_IT_VLS_I] = {morph:emitVectorOp, opTCB:emitVLdSCB, checkCB:emitVLdStCheckSCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY, vShape:RVVW_111_II }, + [RV_IT_VLX_I] = {morph:emitVectorOp, opTCB:emitVLdICB, checkCB:emitVLdStCheckXCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY, vShape:RVVW_111_IIXSM}, + [RV_IT_VS_I] = {morph:emitVectorOp, opTCB:emitVStUCB, checkCB:emitVLdStCheckUCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY, vShape:RVVW_111_II }, + [RV_IT_VSS_I] = {morph:emitVectorOp, opTCB:emitVStSCB, checkCB:emitVLdStCheckSCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY, vShape:RVVW_111_II }, + [RV_IT_VSX_I] = {morph:emitVectorOp, opTCB:emitVStICB, checkCB:emitVLdStCheckXCB, initCB:emitVLdStInitCB, vstart0:RVVS_ANY, vShape:RVVW_111_II }, // V-extension AMO operations (Zvamo) [RV_IT_VAMOADD_R] = {morph:emitVectorOp, opTCB:emitVAMOBinopRRR, checkCB:emitVAMOCheckCB, binop:vmi_ADD, vstart0:RVVS_ANY}, @@ -8452,8 +8523,8 @@ const static riscvMorphAttr dispatchTable[] = { [RV_IT_VQMACCUS_VR] = {morph:emitVectorOp, opTCB:emitVRMAccIntCB, checkCB:emitQMACCheckCB, binop:vmi_ADD, vShape:RVVW_411_II, argType:RVVX_US}, // V-extension IVV-type instructions - [RV_IT_VWREDSUMU_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_ADD, vShape:RVVW_212_SI, argType:RVVX_UU, vstart0:RVVS_ZERO}, - [RV_IT_VWREDSUM_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_ADD, vShape:RVVW_212_SI, argType:RVVX_SS, vstart0:RVVS_ZERO}, + [RV_IT_VWREDSUMU_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_ADD, vShape:RVVW_212_SIS, argType:RVVX_UU, vstart0:RVVS_ZERO}, + [RV_IT_VWREDSUM_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_ADD, vShape:RVVW_212_SIS, argType:RVVX_SS, vstart0:RVVS_ZERO}, [RV_IT_VDOTU_VV] = {morph:emitVectorOp, checkCB:emitEDIVCheckCB}, [RV_IT_VDOT_VV] = {morph:emitVectorOp, checkCB:emitEDIVCheckCB}, @@ -8497,11 +8568,11 @@ const static riscvMorphAttr dispatchTable[] = { [RV_IT_VFGT_VR] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRFCmpFltCB, fpRel:RVFCMP_GT, vShape:RVVW_111_PF}, // V-extension FVV-type instructions - [RV_IT_VFREDSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_111_SF, vstart0:RVVS_ZERO}, - [RV_IT_VFREDOSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_111_SF, vstart0:RVVS_ZERO}, - [RV_IT_VFREDMIN_VS] = {fpConfig:RVFP_FMIN, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FMIN, vShape:RVVW_111_SF, vstart0:RVVS_ZERO}, - [RV_IT_VFREDMAX_VS] = {fpConfig:RVFP_FMAX, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FMAX, vShape:RVVW_111_SF, vstart0:RVVS_ZERO}, - [RV_IT_VFMV_F_S] = { morph:emitScalarOp, opTCB:emitVFMVFS}, + [RV_IT_VFREDSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_111_SFS, vstart0:RVVS_ZERO}, + [RV_IT_VFREDOSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_111_SFS, vstart0:RVVS_ZERO}, + [RV_IT_VFREDMIN_VS] = {fpConfig:RVFP_FMIN, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FMIN, vShape:RVVW_111_SFS, vstart0:RVVS_ZERO}, + [RV_IT_VFREDMAX_VS] = {fpConfig:RVFP_FMAX, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FMAX, vShape:RVVW_111_SFS, vstart0:RVVS_ZERO}, + [RV_IT_VFMV_F_S] = { morph:emitScalarOp, opTCB:emitVFMVFS, vShape:RVVW_111_IS}, [RV_IT_VFCVT_XUF_V] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRConvertFltCB, vShape:RVVW_111_IF, argType:RVVX_UU}, [RV_IT_VFCVT_XF_V] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRConvertFltCB, vShape:RVVW_111_IF, argType:RVVX_SS}, [RV_IT_VFCVT_FXU_V] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRConvertFltCB, vShape:RVVW_111_FI, argType:RVVX_UU}, @@ -8517,22 +8588,22 @@ const static riscvMorphAttr dispatchTable[] = { [RV_IT_VFNCVT_FX_V] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRConvertFltCB, vShape:RVVW_12_FIQ, argType:RVVX_SS}, [RV_IT_VFNCVT_FF_V] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRConvertFltCB, vShape:RVVW_121_FFQ }, [RV_IT_VFCLASS_V] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRFClassFltCB, vShape:RVVW_111_FF }, - [RV_IT_VFWREDSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_212_SF, vstart0:RVVS_ZERO}, - [RV_IT_VFWREDOSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_212_SF, vstart0:RVVS_ZERO}, + [RV_IT_VFWREDSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_212_SFS, vstart0:RVVS_ZERO}, + [RV_IT_VFWREDOSUM_VS] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, opTCB:emitVRedBinaryFltCB, initCB:initVRedCB, endCB:endVRedCB, fpBinop:vmi_FADD, vShape:RVVW_212_SFS, vstart0:RVVS_ZERO}, [RV_IT_VFDOT_VV] = {fpConfig:RVFP_NORMAL, morph:emitVectorOp, checkCB:emitEDIVCheckCB, vShape:RVVW_111_FF }, // V-extension MVV-type instructions - [RV_IT_VREDSUM_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_ADD, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VREDAND_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_AND, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VREDOR_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_OR, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VREDXOR_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_XOR, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VREDMINU_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_MIN, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VREDMIN_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_IMIN, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VREDMAXU_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_MAX, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VREDMAX_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_IMAX, vShape:RVVW_111_SI, vstart0:RVVS_ZERO}, - [RV_IT_VEXT_X_V] = {morph:emitScalarOp, opTCB:emitVEXTXV, vShape:RVVW_EXT_II, }, - [RV_IT_VPOPC_M] = {morph:emitVectorOp, opTCB:emitVPOPCCB, initCB:initVPOPCCB, vShape:RVVW_111_PP, vstart0:RVVS_ZERO}, - [RV_IT_VFIRST_M] = {morph:emitVectorOp, opTCB:emitVFIRSTCB, initCB:initVFIRSTCB, vShape:RVVW_111_PP, vstart0:RVVS_ZERO}, + [RV_IT_VREDSUM_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_ADD, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VREDAND_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_AND, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VREDOR_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_OR, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VREDXOR_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_XOR, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VREDMINU_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_MIN, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VREDMIN_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_IMIN, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VREDMAXU_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_MAX, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VREDMAX_VS] = {morph:emitVectorOp, opTCB:emitVRedBinaryIntCB, initCB:initVRedCB, endCB:endVRedCB, binop:vmi_IMAX, vShape:RVVW_111_SIS, vstart0:RVVS_ZERO}, + [RV_IT_VEXT_X_V] = {morph:emitScalarOp, opTCB:emitVEXTXV, vShape:RVVW_111_IS, }, + [RV_IT_VPOPC_M] = {morph:emitVectorOp, opTCB:emitVPOPCCB, checkCB:initVPOPCCB, vShape:RVVW_111_PP, vstart0:RVVS_ZERO}, + [RV_IT_VFIRST_M] = {morph:emitVectorOp, opTCB:emitVFIRSTCB, checkCB:initVFIRSTCB, vShape:RVVW_111_PP, vstart0:RVVS_ZERO}, [RV_IT_VMSBF_M] = {morph:emitVectorOp, opTCB:emitVMSBFCB, initCB:initVMSFCB, vShape:RVVW_111_PP, vstart0:RVVS_ZERO}, [RV_IT_VMSOF_M] = {morph:emitVectorOp, opTCB:emitVMSOFCB, initCB:initVMSFCB, vShape:RVVW_111_PP, vstart0:RVVS_ZERO}, [RV_IT_VMSIF_M] = {morph:emitVectorOp, opTCB:emitVMSIFCB, initCB:initVMSFCB, vShape:RVVW_111_PP, vstart0:RVVS_ZERO}, @@ -8581,10 +8652,10 @@ const static riscvMorphAttr dispatchTable[] = { [RV_IT_VNCLIP_VI] = {morph:emitVectorOp, opTCB:emitVIRShiftIntCB, binop:vmi_SAR, vShape:RVVW_121_IIS, argType:RVVX_SS}, // V-extension FVF-type instructions - [RV_IT_VFMV_S_F] = {morph:emitScalarOp, opTCB:emitVFMVSF}, + [RV_IT_VFMV_S_F] = {morph:emitScalarOp, opTCB:emitVFMVSF, vShape:RVVW_111_SI}, // V-extension MVX-type instructions - [RV_IT_VMV_S_X] = {morph:emitScalarOp, opTCB:emitVMVSX}, + [RV_IT_VMV_S_X] = {morph:emitScalarOp, opTCB:emitVMVSX, vShape:RVVW_111_SI}, [RV_IT_VSLIDE1UP_VX] = {morph:emitVectorOp, opTCB:emitVRSLIDE1UPCB, initCB:initVRSLIDE1CB, vShape:RVVW_111_UP}, [RV_IT_VSLIDE1DOWN_VX] = {morph:emitVectorOp, opTCB:emitVRSLIDE1DOWNCB, initCB:initVRSLIDE1CB, vShape:RVVW_111_DN}, @@ -8669,7 +8740,7 @@ VMI_MORPH_FN(riscvMorph) { // handle fixed point vector instructions that have an implicit dependency // on mstatus.FS - if(vxSatRMInFCSR(riscv) && usesVXRM(state.attrs->vShape)) { + if(vxSatRMSetFSDirty(riscv) && usesVXRM(state.attrs->vShape)) { state.info.arch |= ISA_FS; } diff --git a/source/riscvMorph.h b/source/riscvMorph.h index 1da6f59..1ac0c60 100644 --- a/source/riscvMorph.h +++ b/source/riscvMorph.h @@ -65,9 +65,9 @@ void riscvEmitIllegalInstructionMessageDesc(riscvP riscv, illegalDescP desc); Bool riscvRequireArchPresentMT(riscvP riscv, riscvArchitecture feature); // -// Validate that the given required feature is absent +// Emit blockMask check for the given feature set // -Bool riscvRequireArchAbsentMT(riscvP riscv, riscvArchitecture feature); +void riscvEmitBlockMask(riscvP riscv, riscvArchitecture features); //////////////////////////////////////////////////////////////////////////////// @@ -119,12 +119,19 @@ void riscvWriteReg(riscvP riscv, riscvRegDesc r, Bool signExtend); void riscvConfigureFPU(riscvP riscv); // -// Adjust JIT code generator state after write of floating point register +// Adjust JIT code generator state after write of floating point CSR // void riscvWFS(riscvMorphStateP state, Bool useRS1); // -// Adjust JIT code generator state after write of vector register that affects +// Adjust JIT code generator state after write of vcsr CSR, which will set +// vector state dirty and floating point state dirty (if floating point is +// enabled) +// +void riscvWVCSR(riscvMorphStateP state, Bool useRS1); + +// +// Adjust JIT code generator state after write of vector CSR that affects // floating point state (behavior clearly defined only after version 20191118) // void riscvWFSVS(riscvMorphStateP state, Bool useRS1); diff --git a/source/riscvUtils.c b/source/riscvUtils.c index 3c4e132..f3aa306 100644 --- a/source/riscvUtils.c +++ b/source/riscvUtils.c @@ -65,10 +65,20 @@ void riscvSetCurrentArch(riscvP riscv) { } // mstatus.VS=0 disables vector extensions (if implemented) - if(!RD_CSR_MASK_FIELD(riscv, mstatus, VS)) { - // mstatus.VS not implemented - } else if(!RD_CSR_FIELD(riscv, mstatus, VS)) { - arch &= ~ISA_V; + if(arch & ISA_V) { + + Uns32 WM_mstatus_VS = 0; + + // get mask of dirty bits for mstatus.VS in either 0.8 or 0.9 location + if(riscvVFSupport(riscv, RVVF_VS_STATUS_8)) { + WM_mstatus_VS = WM_mstatus_VS_8; + } else if(riscvVFSupport(riscv, RVVF_VS_STATUS_9)) { + WM_mstatus_VS = WM_mstatus_VS_9; + } + + if(WM_mstatus_VS && !(RD_CSR(riscv, mstatus) & WM_mstatus_VS)) { + arch &= ~ISA_V; + } } if(riscv->currentArch != arch) { diff --git a/source/riscvVM.c b/source/riscvVM.c index 7e1dd9a..f1977c3 100644 --- a/source/riscvVM.c +++ b/source/riscvVM.c @@ -483,13 +483,38 @@ static char getAccessChar(memPriv requiredPriv) { switch(requiredPriv) { case MEM_PRIV_R: - result = 'R' ; + result = 'R'; break; case MEM_PRIV_W: - result = 'W' ; + result = 'W'; break; case MEM_PRIV_X: - result = 'X' ; + result = 'X'; + break; + default: + VMI_ABORT("Invalid privilege %u", requiredPriv); // LCOV_EXCL_LINE + break; + } + + return result; +} + +// +// Return fault type based on the original access on a page table walk +// +static riscvException originalAccessFault(memPriv requiredPriv) { + + riscvException result = 0; + + switch(requiredPriv) { + case MEM_PRIV_R: + result = riscv_E_LoadAccessFault; + break; + case MEM_PRIV_W: + result = riscv_E_StoreAMOAccessFault; + break; + case MEM_PRIV_X: + result = riscv_E_InstructionAccessFault; break; default: VMI_ABORT("Invalid privilege %u", requiredPriv); // LCOV_EXCL_LINE @@ -565,9 +590,9 @@ static riscvException handlePTWException( // return appropriate exception if(desc->exception==PTX_LOAD_ACCESS) { - return riscv_E_LoadAccessFault; + return originalAccessFault(requiredPriv); } else if(desc->exception==PTX_STORE_ACCESS) { - return riscv_E_StoreAMOAccessFault; + return originalAccessFault(requiredPriv); } else if(requiredPriv==MEM_PRIV_R) { return riscv_E_LoadPageFault; } else if(requiredPriv==MEM_PRIV_W) { diff --git a/source/riscvVariant.c b/source/riscvVariant.c index 1c8becc..1290bbc 100644 --- a/source/riscvVariant.c +++ b/source/riscvVariant.c @@ -44,8 +44,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 0, [RVVF_SEXT_SLIDE1_SRC] = 0, [RVVF_FP_REQUIRES_FSNZ] = 0, - [RVVF_VXSAT_VXRM_IN_FCSR] = 0, [RVVF_VLENB_PRESENT] = 0, + [RVVF_VCSR_PRESENT] = 0, + [RVVF_VS_STATUS_8] = 0, + [RVVF_VS_STATUS_9] = 0, [RVVF_FP_RESTRICT_WHOLE] = 0, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, @@ -64,8 +66,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 0, [RVVF_SEXT_SLIDE1_SRC] = 0, [RVVF_FP_REQUIRES_FSNZ] = 0, - [RVVF_VXSAT_VXRM_IN_FCSR] = 0, [RVVF_VLENB_PRESENT] = 0, + [RVVF_VCSR_PRESENT] = 0, + [RVVF_VS_STATUS_8] = 0, + [RVVF_VS_STATUS_9] = 0, [RVVF_FP_RESTRICT_WHOLE] = 0, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, @@ -84,8 +88,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 0, [RVVF_SEXT_SLIDE1_SRC] = 0, [RVVF_FP_REQUIRES_FSNZ] = 0, - [RVVF_VXSAT_VXRM_IN_FCSR] = 0, [RVVF_VLENB_PRESENT] = 0, + [RVVF_VCSR_PRESENT] = 0, + [RVVF_VS_STATUS_8] = 0, + [RVVF_VS_STATUS_9] = 0, [RVVF_FP_RESTRICT_WHOLE] = 0, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, @@ -104,8 +110,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 0, [RVVF_SEXT_SLIDE1_SRC] = 0, [RVVF_FP_REQUIRES_FSNZ] = 0, - [RVVF_VXSAT_VXRM_IN_FCSR] = 0, [RVVF_VLENB_PRESENT] = 0, + [RVVF_VCSR_PRESENT] = 0, + [RVVF_VS_STATUS_8] = 0, + [RVVF_VS_STATUS_9] = 0, [RVVF_FP_RESTRICT_WHOLE] = 0, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, @@ -124,8 +132,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 1, [RVVF_SEXT_SLIDE1_SRC] = 1, [RVVF_FP_REQUIRES_FSNZ] = 0, - [RVVF_VXSAT_VXRM_IN_FCSR] = 0, [RVVF_VLENB_PRESENT] = 1, + [RVVF_VCSR_PRESENT] = 0, + [RVVF_VS_STATUS_8] = 0, + [RVVF_VS_STATUS_9] = 0, [RVVF_FP_RESTRICT_WHOLE] = 0, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, @@ -144,8 +154,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 1, [RVVF_SEXT_SLIDE1_SRC] = 1, [RVVF_FP_REQUIRES_FSNZ] = 0, - [RVVF_VXSAT_VXRM_IN_FCSR] = 0, [RVVF_VLENB_PRESENT] = 1, + [RVVF_VCSR_PRESENT] = 0, + [RVVF_VS_STATUS_8] = 0, + [RVVF_VS_STATUS_9] = 0, [RVVF_FP_RESTRICT_WHOLE] = 0, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, @@ -164,8 +176,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 1, [RVVF_SEXT_SLIDE1_SRC] = 1, [RVVF_FP_REQUIRES_FSNZ] = 1, - [RVVF_VXSAT_VXRM_IN_FCSR] = 1, [RVVF_VLENB_PRESENT] = 1, + [RVVF_VCSR_PRESENT] = 0, + [RVVF_VS_STATUS_8] = 1, + [RVVF_VS_STATUS_9] = 0, [RVVF_FP_RESTRICT_WHOLE] = 1, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, @@ -184,8 +198,10 @@ Bool riscvVFSupport(riscvP riscv, riscvVFeature feature) { [RVVF_ADC_SBC_MASK] = 1, [RVVF_SEXT_SLIDE1_SRC] = 1, [RVVF_FP_REQUIRES_FSNZ] = 1, - [RVVF_VXSAT_VXRM_IN_FCSR] = 1, [RVVF_VLENB_PRESENT] = 1, + [RVVF_VCSR_PRESENT] = 1, + [RVVF_VS_STATUS_8] = 0, + [RVVF_VS_STATUS_9] = 1, [RVVF_FP_RESTRICT_WHOLE] = 1, [RVVF_UNIT_STRIDE_ONLY] = 0, [RVVF_VSTART_Z] = 0, diff --git a/source/riscvVariant.h b/source/riscvVariant.h index 6548c0b..87e8c3b 100644 --- a/source/riscvVariant.h +++ b/source/riscvVariant.h @@ -53,29 +53,30 @@ typedef enum riscvArchitectureE { ISA_RM_INVALID = RISCV_FEATURE_BIT(RM_INVALID_CHAR), // MSTATUS FIELDS - ISA_FS = RISCV_FEATURE_BIT(MSTATUS_FS_CHAR), + ISA_FS = RISCV_FEATURE_BIT(MSTATUS_FS_CHAR), // FEATURES A AND B - ISA_and = RISCV_FEATURE_BIT(RISCV_FAND_CHAR), + ISA_and = RISCV_FEATURE_BIT(RISCV_FAND_CHAR), // BASE ISA FEATURES - ISA_A = RISCV_FEATURE_BIT('A'), // atomic instructions - ISA_C = RISCV_FEATURE_BIT('C'), // compressed instructions - ISA_E = RISCV_FEATURE_BIT('E'), // embedded instructions - ISA_D = RISCV_FEATURE_BIT('D'), // double-precision floating point - ISA_F = RISCV_FEATURE_BIT('F'), // single-precision floating point - ISA_I = RISCV_FEATURE_BIT('I'), // RV32I/64I/128I base ISA - ISA_M = RISCV_FEATURE_BIT('M'), // integer multiply/divide instructions - ISA_N = RISCV_FEATURE_BIT('N'), // user-mode interrupts - ISA_S = RISCV_FEATURE_BIT('S'), // supervisor mode implemented - ISA_U = RISCV_FEATURE_BIT('U'), // user mode implemented - ISA_V = RISCV_FEATURE_BIT('V'), // vector extension implemented - ISA_X = RISCV_FEATURE_BIT('X'), // non-standard extensions present - ISA_DF = (ISA_D|ISA_F), // either single or double precision - ISA_DFV = (ISA_D|ISA_F|ISA_V), // either floating point or vector - ISA_SorU = (ISA_S|ISA_U), // either supervisor or user mode - ISA_SorN = (ISA_S|ISA_N), // either supervisor or user interrupts - ISA_SandN = (ISA_S|ISA_N|ISA_and), // both supervisor and user interrupts + ISA_A = RISCV_FEATURE_BIT('A'), // atomic instructions + ISA_C = RISCV_FEATURE_BIT('C'), // compressed instructions + ISA_E = RISCV_FEATURE_BIT('E'), // embedded instructions + ISA_D = RISCV_FEATURE_BIT('D'), // double-precision floating point + ISA_F = RISCV_FEATURE_BIT('F'), // single-precision floating point + ISA_I = RISCV_FEATURE_BIT('I'), // RV32I/64I/128I base ISA + ISA_M = RISCV_FEATURE_BIT('M'), // integer multiply/divide instructions + ISA_N = RISCV_FEATURE_BIT('N'), // user-mode interrupts + ISA_S = RISCV_FEATURE_BIT('S'), // supervisor mode implemented + ISA_U = RISCV_FEATURE_BIT('U'), // user mode implemented + ISA_V = RISCV_FEATURE_BIT('V'), // vector extension implemented + ISA_X = RISCV_FEATURE_BIT('X'), // non-standard extensions present + ISA_DF = (ISA_D|ISA_F), // either single or double precision + ISA_DFV = (ISA_D|ISA_F|ISA_V), // either floating point or vector + ISA_SorU = (ISA_S|ISA_U), // either supervisor or user mode + ISA_SorN = (ISA_S|ISA_N), // either supervisor or user interrupts + ISA_SandN = (ISA_S|ISA_N|ISA_and), // both supervisor and user interrupts + ISA_FSandV = (ISA_FS|ISA_V|ISA_and), // both FS and vector extension RV32 = ISA_XLEN_32, RV32I = ISA_XLEN_32 | ISA_I, @@ -160,7 +161,7 @@ typedef enum riscvPrivVerE { // // Tag of master version // -#define RVVV_MASTER_TAG "9a65519" +#define RVVV_MASTER_TAG "f92ae2c" // // Supported Vector Architecture versions @@ -226,8 +227,10 @@ typedef enum riscvVFeatureE { RVVF_ADC_SBC_MASK, // vadc/vmadc/vsbc/vmsbc use standard mask bit RVVF_SEXT_SLIDE1_SRC, // sign-extend slide1* ssource value? RVVF_FP_REQUIRES_FSNZ, // VFP instructions require mstatus.FS!=0? - RVVF_VXSAT_VXRM_IN_FCSR,// vxsat/vxrm treated as members of fcsr? RVVF_VLENB_PRESENT, // is vlenb register present? + RVVF_VCSR_PRESENT, // is vcsr register present? + RVVF_VS_STATUS_8, // is [ms]status.VS field in version 0.8 location? + RVVF_VS_STATUS_9, // is [ms]status.VS field in version 0.9 location? RVVF_FP_RESTRICT_WHOLE, // whole register load/store/move restricted? RVVF_UNIT_STRIDE_ONLY, // only unit-stride load/store supported? RVVF_VSTART_Z, // is vstart forced to zero? diff --git a/source/riscvVectorTypes.h b/source/riscvVectorTypes.h index b61ac37..1ebdc84 100644 --- a/source/riscvVectorTypes.h +++ b/source/riscvVectorTypes.h @@ -33,15 +33,17 @@ typedef enum riscvVShapeE { // INTEGER ARGUMENTS RVVW_111_II, // SEW + RVVW_111_IIXSM, // SEW, no overlap if segmented RVVW_111_IIS, // SEW, saturating result RVVW_111_IIX, // SEW, uses vxrm RVVW_BBB_II, // SEW8 - RVVW_EXT_II, // SEW, VEXT.X.V - RVVW_111_PI, // SEW, Vd is predicate + RVVW_111_IS, // SEW, src1 is scalar RVVW_111_SI, // SEW, Vd is scalar + RVVW_111_PI, // SEW, Vd is predicate + RVVW_111_SIS, // SEW, Vd and src2 are scalar RVVW_CIN_II, // SEW, mask is carry-in (VADC etc) RVVW_CIN_PI, // SEW, Vd is predicate, mask is carry-in (VMADC etc) - RVVW_212_SI, // 2*SEW = SEW op 2*SEW, Vd is scalar + RVVW_212_SIS, // 2*SEW = SEW op 2*SEW, Vd and src2 are scalar RVVW_121_II, // SEW = 2*SEW op SEW RVVW_121_IIS, // SEW = 2*SEW op SEW, saturating result RVVW_211_IIQ, // 2*SEW = SEW op SEW, implicit widening @@ -53,8 +55,8 @@ typedef enum riscvVShapeE { // FLOATING POINT ARGUMENTS RVVW_111_FF, // SEW RVVW_111_PF, // SEW, Vd is predicate - RVVW_111_SF, // SEW, Vd is scalar - RVVW_212_SF, // 2*SEW = SEW op 2*SEW, Vd is scalar + RVVW_111_SFS, // SEW, Vd and src2 are scalar + RVVW_212_SFS, // 2*SEW = SEW op 2*SEW, Vd and src2 are scalar RVVW_121_FFQ, // SEW = 2*SEW op SEW, implicit widening RVVW_211_FFQ, // 2*SEW = SEW op SEW, implicit widening RVVW_211_FF, // 2*SEW = SEW op SEW