From d048ad34d6d316c065f2d7f072fa0457de4da309 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Mon, 16 Oct 2023 10:07:40 -0700 Subject: [PATCH] arch-riscv: Change to VS bits to DIRTY for rvv insts changing vregs (#376) This is similar to [1] and [2]. Essentially, the VS bits of STATUS CSR keep track of the state of the vector registers. (VS bits == DIRTY) means the content of vector registers have been updated since the last time the VS bits were updated. This chain of changes is supposed to change the VS bits to DIRTY for if any vector register is potentially updated. [1] https://gem5-review.googlesource.com/c/public/gem5/+/65272 [2] https://github.com/gem5/gem5/pull/370 Change-Id: I0427890dadc63b74a470d7405807dcfcad18005b --- src/arch/riscv/isa/templates/vector_arith.isa | 93 +++++++++++++++++++ src/arch/riscv/isa/templates/vector_mem.isa | 35 +++++++ 2 files changed, 128 insertions(+) diff --git a/src/arch/riscv/isa/templates/vector_arith.isa b/src/arch/riscv/isa/templates/vector_arith.isa index 1bc7b110f8..9b5ee0e7fa 100644 --- a/src/arch/riscv/isa/templates/vector_arith.isa +++ b/src/arch/riscv/isa/templates/vector_arith.isa @@ -168,6 +168,9 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -247,6 +250,9 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + auto SEW = vtype_SEW(vtype); auto offset = (VLEN / SEW) * (microIdx % %(ext_div)d); switch (SEW / %(ext_div)d) { @@ -412,6 +418,10 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + const int64_t vlmul = vtype_vlmul(machInst.vtype8); const int32_t t_micro_vlmax = vtype_VLMAX(machInst.vtype8, true); const int32_t micro_vlmax = vlmul < 0 ? t_micro_vlmax : t_micro_vlmax / 2; @@ -451,6 +461,10 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + const int64_t vlmul = vtype_vlmul(machInst.vtype8); const int32_t t_micro_vlmax = vtype_VLMAX(machInst.vtype8, true); const int32_t micro_vlmax = vlmul < 0 ? t_micro_vlmax : t_micro_vlmax / 2; @@ -577,6 +591,9 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + VRM_REQUIRED; %(op_decl)s; @@ -671,6 +688,9 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + VRM_REQUIRED; const int64_t vlmul = vtype_vlmul(machInst.vtype8); @@ -712,6 +732,9 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + VRM_REQUIRED; const int64_t vlmul = vtype_vlmul(machInst.vtype8); @@ -842,6 +865,10 @@ Fault } if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -883,8 +910,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -941,8 +973,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_rd)s; uint64_t Rd = 0; %(vm_decl_rd)s; @@ -1053,9 +1090,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1170,9 +1211,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1265,11 +1310,15 @@ Fault // TODO: If vd is equal to vs2 the instruction is an architectural NOP. MISA misa = xc->readMiscReg(MISCREG_ISA); STATUS status = xc->readMiscReg(MISCREG_STATUS); + if (!misa.rvv || status.vs == VPUStatus::OFF) { return std::make_shared( "RVV is disabled or VPU is off", machInst); } + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; for (size_t i = 0; i < (VLEN / 64); i++) { @@ -1327,6 +1376,9 @@ Fault if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; // TODO: remove it @@ -1388,8 +1440,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1415,8 +1472,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1521,9 +1583,14 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + + if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1562,9 +1629,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1605,9 +1676,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1755,9 +1830,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -1919,9 +1998,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(vm_decl_rd)s; @@ -2084,8 +2167,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + [[maybe_unused]]const uint32_t vlmax = vtype_VLMAX(vtype); %(op_decl)s; @@ -2115,8 +2203,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + [[maybe_unused]]const uint32_t vlmax = vtype_VLMAX(vtype); %(op_decl)s; diff --git a/src/arch/riscv/isa/templates/vector_mem.isa b/src/arch/riscv/isa/templates/vector_mem.isa index 1fe989ffce..2b3b9187bf 100644 --- a/src/arch/riscv/isa/templates/vector_mem.isa +++ b/src/arch/riscv/isa/templates/vector_mem.isa @@ -137,8 +137,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + if(!machInst.vm) { xc->getRegOperand(this, _numSrcRegs - 1, &tmp_v0); v0 = tmp_v0.as(); @@ -204,6 +209,10 @@ Fault %(op_decl)s; %(op_rd)s; + STATUS status = xc->readMiscReg(MISCREG_STATUS); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + RiscvISA::vreg_t tmp_v0; uint8_t *v0; if(!machInst.vm) { @@ -642,6 +651,10 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(ea_code)s; @@ -694,6 +707,10 @@ Fault %(op_decl)s; %(op_rd)s; + STATUS status = xc->readMiscReg(MISCREG_STATUS); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + memcpy(Mem.as(), pkt->getPtr(), pkt->getSize()); size_t elem_per_reg = VLEN / width_EEW(machInst.width); @@ -794,8 +811,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; constexpr uint8_t elem_size = sizeof(Vd[0]); @@ -873,6 +895,10 @@ Fault %(op_decl)s; %(op_rd)s; + STATUS status = xc->readMiscReg(MISCREG_STATUS); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + constexpr uint8_t elem_size = sizeof(Vd[0]); RiscvISA::vreg_t old_vd; @@ -1177,8 +1203,13 @@ Fault return std::make_shared( "RVV is disabled or VPU is off", machInst); } + if (machInst.vill) return std::make_shared("VILL is set", machInst); + + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + %(op_decl)s; %(op_rd)s; %(ea_code)s; @@ -1255,6 +1286,10 @@ Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, trace::InstRecord *traceData) const { + STATUS status = xc->readMiscReg(MISCREG_STATUS); + status.vs = VPUStatus::DIRTY; + xc->setMiscReg(MISCREG_STATUS, status); + using vu = std::make_unsigned_t; %(op_decl)s; %(op_rd)s;