arch-riscv: Add risc-v vector ext v1.0 vset insts support

Change-Id: I84363164ca327151101e8a1c3d8441a66338c909
Co-authored-by: Yang Liu <numbksco@gmail.com>
Co-authored-by: Fan Yang <1209202421@qq.com>

arch-riscv: Add a todo to fix vsetvl stall on decode

Change-Id: Iafb129648fba89009345f0c0ad3710f773379bf6
This commit is contained in:
Xuan Hu
2023-02-21 11:48:54 +08:00
committed by Adrià Armejach
parent 73892c9b47
commit e14e066fde
10 changed files with 386 additions and 1 deletions

View File

@@ -42,6 +42,7 @@ void Decoder::reset()
{
aligned = true;
mid = false;
vConfigDone = true;
machInst = 0;
emi = 0;
}
@@ -49,6 +50,15 @@ void Decoder::reset()
void
Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC)
{
// TODO: Current vsetvl instructions stall decode. Future fixes should
// enable speculation, and this code will be removed.
if (GEM5_UNLIKELY(!this->vConfigDone)) {
DPRINTF(Decode, "Waiting for vset*vl* to be executed\n");
instDone = false;
outOfBytes = false;
return;
}
// The MSB of the upper and lower halves of a machine instruction.
constexpr size_t max_bit = sizeof(machInst) * 8 - 1;
constexpr size_t mid_bit = sizeof(machInst) * 4 - 1;
@@ -78,6 +88,14 @@ Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC)
instDone = compressed(emi);
}
}
if (instDone) {
emi.vl = this->machVl;
emi.vtype8 = this->machVtype & 0xff;
emi.vill = this->machVtype.vill;
if (vconf(emi)) {
this->vConfigDone = false; // set true when vconfig inst execute
}
}
}
StaticInstPtr
@@ -116,5 +134,14 @@ Decoder::decode(PCStateBase &_next_pc)
return decode(emi, next_pc.instAddr());
}
void
Decoder::setVlAndVtype(uint32_t vl, VTYPE vtype)
{
this->machVtype = vtype;
this->machVl = vl;
this->vConfigDone = true;
}
} // namespace RiscvISA
} // namespace gem5

View File

@@ -32,6 +32,7 @@
#include "arch/generic/decode_cache.hh"
#include "arch/generic/decoder.hh"
#include "arch/riscv/insts/vector.hh"
#include "arch/riscv/types.hh"
#include "base/logging.hh"
#include "base/types.hh"
@@ -53,12 +54,16 @@ class Decoder : public InstDecoder
decode_cache::InstMap<ExtMachInst> instMap;
bool aligned;
bool mid;
bool vConfigDone;
protected:
//The extended machine instruction being generated
ExtMachInst emi;
uint32_t machInst;
VTYPE machVtype;
uint32_t machVl;
StaticInstPtr decodeInst(ExtMachInst mach_inst);
/// Decode a machine instruction.
@@ -74,13 +79,18 @@ class Decoder : public InstDecoder
void reset() override;
inline bool compressed(ExtMachInst inst) { return (inst & 0x3) < 0x3; }
inline bool compressed(ExtMachInst inst) { return inst.quadRant < 0x3; }
inline bool vconf(ExtMachInst inst) {
return inst.opcode == 0b1010111u && inst.funct3 == 0b111u;
}
//Use this to give data to the decoder. This should be used
//when there is control flow.
void moreBytes(const PCStateBase &pc, Addr fetchPC) override;
StaticInstPtr decode(PCStateBase &nextPC) override;
void setVlAndVtype(uint32_t vl, VTYPE vtype);
};
} // namespace RiscvISA

View File

@@ -33,3 +33,4 @@ Source('compressed.cc', tags='riscv isa')
Source('mem.cc', tags='riscv isa')
Source('standard.cc', tags='riscv isa')
Source('static_inst.cc', tags='riscv isa')
Source('vector.cc', tags='riscv isa')

View File

@@ -33,6 +33,7 @@
#include <string>
#include "arch/riscv/pcstate.hh"
#include "arch/riscv/regs/misc.hh"
#include "arch/riscv/types.hh"
#include "cpu/exec_context.hh"
#include "cpu/static_inst.hh"

View File

@@ -0,0 +1,126 @@
/*
* Copyright (c) 2022 PLCT Lab
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "arch/riscv/insts/vector.hh"
#include <sstream>
#include <string>
#include "arch/riscv/insts/static_inst.hh"
#include "arch/riscv/utility.hh"
#include "cpu/static_inst.hh"
namespace gem5
{
namespace RiscvISA
{
/**
* This function translates the 3-bit value of vlmul bits to the corresponding
* lmul value as specified in RVV 1.0 spec p11-12 chapter 3.4.2.
*
* I.e.,
* vlmul = -3 -> LMUL = 1/8
* vlmul = -2 -> LMUL = 1/4
* vlmul = -1 -> LMUL = 1/2
* vlmul = 0 -> LMUL = 1
* vlmul = 1 -> LMUL = 2
* vlmul = 2 -> LMUL = 4
* vlmul = 3 -> LMUL = 8
*
**/
float
getVflmul(uint32_t vlmul_encoding) {
int vlmul = sext<3>(vlmul_encoding & 7);
float vflmul = vlmul >= 0 ? 1 << vlmul : 1.0 / (1 << -vlmul);
return vflmul;
}
uint32_t
getVlmax(VTYPE vtype, uint32_t vlen) {
uint32_t sew = getSew(vtype.vsew);
// vlmax is defined in RVV 1.0 spec p12 chapter 3.4.2.
uint32_t vlmax = (vlen/sew) * getVflmul(vtype.vlmul);
return vlmax;
}
std::string
VConfOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
if (bit31 && bit30 == 0) {
ss << registerName(srcRegIdx(0)) << ", " << registerName(srcRegIdx(1));
} else if (bit31 && bit30) {
ss << uimm << ", " << generateZimmDisassembly();
} else {
ss << registerName(srcRegIdx(0)) << ", " << generateZimmDisassembly();
}
return ss.str();
}
std::string
VConfOp::generateZimmDisassembly() const
{
std::stringstream s;
// VSETIVLI uses ZIMM10 and VSETVLI uses ZIMM11
uint64_t zimm = (bit31 && bit30) ? zimm10 : zimm11;
bool frac_lmul = bits(zimm, 2);
int sew = 1 << (bits(zimm, 5, 3) + 3);
int lmul = bits(zimm, 1, 0);
auto vta = bits(zimm, 6) == 1 ? "ta" : "tu";
auto vma = bits(zimm, 7) == 1 ? "ma" : "mu";
s << "e" << sew;
if (frac_lmul) {
std::string lmul_str = "";
switch(lmul){
case 3:
lmul_str = "f2";
break;
case 2:
lmul_str = "f4";
break;
case 1:
lmul_str = "f8";
break;
default:
panic("Unsupport fractional LMUL");
}
s << ", m" << lmul_str;
} else {
s << ", m" << (1 << lmul);
}
s << ", " << vta << ", " << vma;
return s.str();
}
} // namespace RiscvISA
} // namespace gem5

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2022 PLCT Lab
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_RISCV_INSTS_VECTOR_HH__
#define __ARCH_RISCV_INSTS_VECTOR_HH__
#include <string>
#include "arch/riscv/insts/static_inst.hh"
#include "arch/riscv/regs/misc.hh"
#include "arch/riscv/regs/vector.hh"
#include "arch/riscv/utility.hh"
#include "cpu/exec_context.hh"
#include "cpu/static_inst.hh"
namespace gem5
{
namespace RiscvISA
{
float
getVflmul(uint32_t vlmul_encoding);
inline uint32_t getSew(uint32_t vsew) {
assert(vsew <= 3);
return (8 << vsew);
}
uint32_t
getVlmax(VTYPE vtype, uint32_t vlen);
/**
* Base class for Vector Config operations
*/
class VConfOp : public RiscvStaticInst
{
protected:
uint64_t bit30;
uint64_t bit31;
uint64_t zimm10;
uint64_t zimm11;
uint64_t uimm;
VConfOp(const char *mnem, ExtMachInst _extMachInst, OpClass __opClass)
: RiscvStaticInst(mnem, _extMachInst, __opClass),
bit30(_extMachInst.bit30), bit31(_extMachInst.bit31),
zimm10(_extMachInst.zimm_vsetivli),
zimm11(_extMachInst.zimm_vsetvli),
uimm(_extMachInst.uimm_vsetivli)
{}
std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
std::string generateZimmDisassembly() const;
};
} // namespace RiscvISA
} // namespace gem5
#endif // __ARCH_RISCV_INSTS_VECTOR_HH__

View File

@@ -2012,6 +2012,39 @@ decode QUADRANT default Unknown::unknown() {
}
}
0x15: decode FUNCT3 {
0x7: decode BIT31 {
format VConfOp {
0x0: vsetvli({{
uint64_t rd_bits = RD;
uint64_t rs1_bits = RS1;
uint64_t requested_vl = Rs1_ud;
uint64_t requested_vtype = zimm11;
Rd_ud = 0;
}}, VectorConfigOp, IsDirectControl, IsCondControl);
0x1: decode BIT30 {
0x0: vsetvl({{
uint64_t rd_bits = RD;
uint64_t rs1_bits = RS1;
uint64_t requested_vl = Rs1_ud;
uint64_t requested_vtype = Rs2_ud;
Rd_ud = 0;
}}, VectorConfigOp, IsDirectControl, IsCondControl);
0x1: vsetivli({{
uint64_t rd_bits = RD;
uint64_t rs1_bits = -1;
uint64_t requested_vl = uimm;
uint64_t requested_vtype = zimm10;
Rd_ud = 0;
}}, VectorConfigOp, IsDirectControl, IsCondControl);
}
}
}
}
0x18: decode FUNCT3 {
format BOp {
0x0: beq({{

View File

@@ -37,6 +37,7 @@
##include "fp.isa"
##include "amo.isa"
##include "bs.isa"
##include "vector_conf.isa"
// Include formats for nonstandard extensions
##include "compressed.isa"

View File

@@ -0,0 +1,96 @@
// -*- mode:c++ -*-
// Copyright (c) 2022 PLCT Lab
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
def format VConfOp(code, *flags) {{
iop = InstObjParams(name, Name, 'VConfOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = VConfExecute.subst(iop)
}};
def template VConfExecute {{
Fault
%(class_name)s::execute(ExecContext *xc,
trace::InstRecord *traceData) const
{
auto tc = xc->tcBase();
%(op_decl)s;
%(op_rd)s;
%(code)s;
tc->setMiscReg(MISCREG_VSTART, 0);
uint32_t vlen = xc->readMiscReg(MISCREG_VLENB) * 8;
uint32_t vlmax = getVlmax(xc->readMiscReg(MISCREG_VTYPE), vlen);
VTYPE new_vtype = requested_vtype;
if (xc->readMiscReg(MISCREG_VTYPE) != new_vtype) {
vlmax = getVlmax(new_vtype, vlen);
float vflmul = getVflmul(new_vtype.vlmul);
uint32_t sew = getSew(new_vtype.vsew);
uint32_t new_vill =
!(vflmul >= 0.125 && vflmul <= 8) ||
sew > std::min(vflmul, 1.0f) * ELEN ||
bits(requested_vtype, 30, 8) != 0;
if (new_vill) {
vlmax = 0;
new_vtype = 0;
new_vtype.vill = 1;
}
xc->setMiscReg(MISCREG_VTYPE, new_vtype);
}
uint32_t current_vl = xc->readMiscReg(MISCREG_VL);
uint32_t new_vl = 0;
if (vlmax == 0) {
new_vl = 0;
} else if (rd_bits == 0 && rs1_bits == 0) {
new_vl = current_vl > vlmax ? vlmax : current_vl;
} else if (rd_bits != 0 && rs1_bits == 0) {
new_vl = vlmax;
} else if (rs1_bits != 0) {
new_vl = requested_vl > vlmax ? vlmax : requested_vl;
}
xc->setMiscReg(MISCREG_VL, new_vl);
tc->getDecoderPtr()->as<Decoder>().setVlAndVtype(new_vl, new_vtype);
Rd = new_vl;
%(op_wb)s;
return NoFault;
}
}};

View File

@@ -34,6 +34,7 @@
//
output header {{
#include <functional>
#include <iomanip>
#include <sstream>
#include <string>
@@ -45,6 +46,7 @@ output header {{
#include <softfloat.h>
#include <specialize.h>
#include "arch/riscv/decoder.hh"
#include "arch/riscv/insts/amo.hh"
#include "arch/riscv/insts/bs.hh"
#include "arch/riscv/insts/compressed.hh"