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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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"
|
||||
|
||||
126
src/arch/riscv/insts/vector.cc
Normal file
126
src/arch/riscv/insts/vector.cc
Normal 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
|
||||
88
src/arch/riscv/insts/vector.hh
Normal file
88
src/arch/riscv/insts/vector.hh
Normal 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__
|
||||
@@ -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({{
|
||||
|
||||
@@ -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"
|
||||
|
||||
96
src/arch/riscv/isa/formats/vector_conf.isa
Normal file
96
src/arch/riscv/isa/formats/vector_conf.isa
Normal 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;
|
||||
}
|
||||
}};
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user