arch-riscv: Restructure ISA description

This patch restructures the RISC-V ISA description to use fewer classes
and improve its ability to be extended with nonstandard extensions in
the future. It also cleans up the disassembly for some of the CSR and
system instructions by removing source and destination registers for
instructions that don't have any.

[Fix class UImmOp to have an "imm" member rather than "uimm".]
[Update disassembly generation for new RegId class.]

Change-Id: Iec1c782020126e5e8e73460b84e31c7b5a5971d9
Reviewed-on: https://gem5-review.googlesource.com/3800
Maintainer: Alec Roelke <ar4jc@virginia.edu>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
Alec Roelke
2017-06-15 15:33:25 -04:00
parent 91f965dd57
commit 63d4005a29
15 changed files with 738 additions and 684 deletions

View File

@@ -47,112 +47,6 @@ namespace RiscvISA
ISA::ISA(Params *p) : SimObject(p)
{
miscRegNames = {
{MISCREG_USTATUS, "ustatus"},
{MISCREG_UIE, "uie"},
{MISCREG_UTVEC, "utvec"},
{MISCREG_USCRATCH, "uscratch"},
{MISCREG_UEPC, "uepc"},
{MISCREG_UCAUSE, "ucause"},
{MISCREG_UBADADDR, "ubadaddr"},
{MISCREG_UIP, "uip"},
{MISCREG_FFLAGS, "fflags"},
{MISCREG_FRM, "frm"},
{MISCREG_FCSR, "fcsr"},
{MISCREG_CYCLE, "cycle"},
{MISCREG_TIME, "time"},
{MISCREG_INSTRET, "instret"},
{MISCREG_CYCLEH, "cycleh"},
{MISCREG_TIMEH, "timeh"},
{MISCREG_INSTRETH, "instreth"},
{MISCREG_SSTATUS, "sstatus"},
{MISCREG_SEDELEG, "sedeleg"},
{MISCREG_SIDELEG, "sideleg"},
{MISCREG_SIE, "sie"},
{MISCREG_STVEC, "stvec"},
{MISCREG_SSCRATCH, "sscratch"},
{MISCREG_SEPC, "sepc"},
{MISCREG_SCAUSE, "scause"},
{MISCREG_SBADADDR, "sbadaddr"},
{MISCREG_SIP, "sip"},
{MISCREG_SPTBR, "sptbr"},
{MISCREG_HSTATUS, "hstatus"},
{MISCREG_HEDELEG, "hedeleg"},
{MISCREG_HIDELEG, "hideleg"},
{MISCREG_HIE, "hie"},
{MISCREG_HTVEC, "htvec"},
{MISCREG_HSCRATCH, "hscratch"},
{MISCREG_HEPC, "hepc"},
{MISCREG_HCAUSE, "hcause"},
{MISCREG_HBADADDR, "hbadaddr"},
{MISCREG_HIP, "hip"},
{MISCREG_MVENDORID, "mvendorid"},
{MISCREG_MARCHID, "marchid"},
{MISCREG_MIMPID, "mimpid"},
{MISCREG_MHARTID, "mhartid"},
{MISCREG_MSTATUS, "mstatus"},
{MISCREG_MISA, "misa"},
{MISCREG_MEDELEG, "medeleg"},
{MISCREG_MIDELEG, "mideleg"},
{MISCREG_MIE, "mie"},
{MISCREG_MTVEC, "mtvec"},
{MISCREG_MSCRATCH, "mscratch"},
{MISCREG_MEPC, "mepc"},
{MISCREG_MCAUSE, "mcause"},
{MISCREG_MBADADDR, "mbadaddr"},
{MISCREG_MIP, "mip"},
{MISCREG_MBASE, "mbase"},
{MISCREG_MBOUND, "mbound"},
{MISCREG_MIBASE, "mibase"},
{MISCREG_MIBOUND, "mibound"},
{MISCREG_MDBASE, "mdbase"},
{MISCREG_MDBOUND, "mdbound"},
{MISCREG_MCYCLE, "mcycle"},
{MISCREG_MINSTRET, "minstret"},
{MISCREG_MUCOUNTEREN, "mucounteren"},
{MISCREG_MSCOUNTEREN, "mscounteren"},
{MISCREG_MHCOUNTEREN, "mhcounteren"},
{MISCREG_TSELECT, "tselect"},
{MISCREG_TDATA1, "tdata1"},
{MISCREG_TDATA2, "tdata2"},
{MISCREG_TDATA3, "tdata3"},
{MISCREG_DCSR, "dcsr"},
{MISCREG_DPC, "dpc"},
{MISCREG_DSCRATCH, "dscratch"}
};
for (int i = 0; i < NumHpmcounter; i++)
{
int hpmcounter = MISCREG_HPMCOUNTER_BASE + i;
std::stringstream ss;
ss << "hpmcounter" << hpmcounter;
miscRegNames[hpmcounter] = ss.str();
}
for (int i = 0; i < NumHpmcounterh; i++)
{
int hpmcounterh = MISCREG_HPMCOUNTERH_BASE + i;
std::stringstream ss;
ss << "hpmcounterh" << hpmcounterh;
miscRegNames[hpmcounterh] = ss.str();
}
for (int i = 0; i < NumMhpmcounter; i++)
{
int mhpmcounter = MISCREG_MHPMCOUNTER_BASE + i;
std::stringstream ss;
ss << "mhpmcounter" << mhpmcounter;
miscRegNames[mhpmcounter] = ss.str();
}
for (int i = 0; i < NumMhpmevent; i++)
{
int mhpmevent = MISCREG_MHPMEVENT_BASE + i;
std::stringstream ss;
ss << "mhpmcounterh" << mhpmevent;
miscRegNames[mhpmevent] = ss.str();
}
miscRegFile.resize(NumMiscRegs);
clear();
}
@@ -178,7 +72,7 @@ MiscReg
ISA::readMiscRegNoEffect(int misc_reg) const
{
DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
miscRegNames.at(misc_reg), miscRegFile[misc_reg]);
MiscRegNames.at(misc_reg), miscRegFile[misc_reg]);
switch (misc_reg) {
case MISCREG_FFLAGS:
return bits(miscRegFile[MISCREG_FCSR], 4, 0);
@@ -216,19 +110,19 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
switch (misc_reg) {
case MISCREG_INSTRET:
DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
miscRegNames[misc_reg], miscRegFile[misc_reg]);
MiscRegNames.at(misc_reg), miscRegFile[misc_reg]);
return tc->getCpuPtr()->totalInsts();
case MISCREG_CYCLE:
DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
miscRegNames[misc_reg], miscRegFile[misc_reg]);
MiscRegNames.at(misc_reg), miscRegFile[misc_reg]);
return tc->getCpuPtr()->curCycle();
case MISCREG_INSTRETH:
DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
miscRegNames[misc_reg], miscRegFile[misc_reg]);
MiscRegNames.at(misc_reg), miscRegFile[misc_reg]);
return tc->getCpuPtr()->totalInsts() >> 32;
case MISCREG_CYCLEH:
DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
miscRegNames[misc_reg], miscRegFile[misc_reg]);
MiscRegNames.at(misc_reg), miscRegFile[misc_reg]);
return tc->getCpuPtr()->curCycle() >> 32;
case MISCREG_MHARTID:
return 0; // TODO: make this the hardware thread or cpu id
@@ -241,7 +135,7 @@ void
ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
DPRINTF(RiscvMisc, "Setting CSR %s to 0x%016llx.\n",
miscRegNames[misc_reg], val);
MiscRegNames.at(misc_reg), val);
switch (misc_reg) {
case MISCREG_FFLAGS:
miscRegFile[MISCREG_FCSR] &= ~0x1F;

View File

@@ -59,7 +59,6 @@ class ISA : public SimObject
{
protected:
std::vector<MiscReg> miscRegFile;
std::map<int, std::string> miscRegNames;
public:
typedef RiscvISAParams Params;

View File

@@ -50,9 +50,6 @@ output header {{
OpClass __opClass) : StaticInst(mnem, _machInst, __opClass)
{}
std::string
regName(RegId reg) const;
virtual std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
@@ -64,18 +61,3 @@ output header {{
}
};
}};
//Ouputs to decoder.cc
output decoder {{
std::string
RiscvStaticInst::regName(RegId reg) const
{
if (reg.isIntReg()) {
return std::string(RegisterNames[reg.index()]);
} else if (reg.isFloatReg()) {
return std::string("f") + std::to_string(reg.index());
} else {
return csprintf("%s{%i}", reg.className(), reg.index());
}
}
}};

View File

@@ -74,7 +74,7 @@ def bitfield UJIMMBITS19TO12 <19:12>;
// System
def bitfield FUNCT12 <31:20>;
def bitfield ZIMM <19:15>;
def bitfield CSRIMM <19:15>;
// Floating point
def bitfield FD <11:7>;

View File

@@ -467,7 +467,7 @@ decode OPCODE default Unknown::unknown() {
}
}
format FPR4Op {
format FPROp {
0x43: decode FUNCT2 {
0x0: fmadd_s({{
uint32_t temp;
@@ -680,10 +680,8 @@ decode OPCODE default Unknown::unknown() {
}
}}, FloatMultOp);
}
}
0x53: decode FUNCT7 {
format FPROp {
0x53: decode FUNCT7 {
0x0: fadd_s({{
uint32_t temp;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
@@ -1274,8 +1272,9 @@ decode OPCODE default Unknown::unknown() {
}}, FloatCvtOp);
}
}
0x63: decode FUNCT3 {
format SBOp {
format BOp {
0x0: beq({{
if (Rs1 == Rs2) {
NPC = PC + imm;
@@ -1328,13 +1327,13 @@ decode OPCODE default Unknown::unknown() {
}}, IsIndirectControl, IsUncondControl, IsCall);
}
0x6f: UJOp::jal({{
0x6f: JOp::jal({{
Rd = NPC;
NPC = PC + imm;
}}, IsDirectControl, IsUncondControl, IsCall);
0x73: decode FUNCT3 {
format IOp {
format SystemOp {
0x0: decode FUNCT12 {
0x0: ecall({{
fault = std::make_shared<SyscallFault>();
@@ -1346,36 +1345,38 @@ decode OPCODE default Unknown::unknown() {
fault = std::make_shared<UnimplementedFault>("eret");
}}, No_OpClass);
}
}
format CSROp {
0x1: csrrw({{
Rd = xc->readMiscReg(FUNCT12);
xc->setMiscReg(FUNCT12, Rs1);
Rd = xc->readMiscReg(csr);
xc->setMiscReg(csr, Rs1);
}}, IsNonSpeculative, No_OpClass);
0x2: csrrs({{
Rd = xc->readMiscReg(FUNCT12);
Rd = xc->readMiscReg(csr);
if (Rs1 != 0) {
xc->setMiscReg(FUNCT12, Rd | Rs1);
xc->setMiscReg(csr, Rd | Rs1);
}
}}, IsNonSpeculative, No_OpClass);
0x3: csrrc({{
Rd = xc->readMiscReg(FUNCT12);
Rd = xc->readMiscReg(csr);
if (Rs1 != 0) {
xc->setMiscReg(FUNCT12, Rd & ~Rs1);
xc->setMiscReg(csr, Rd & ~Rs1);
}
}}, IsNonSpeculative, No_OpClass);
0x5: csrrwi({{
Rd = xc->readMiscReg(FUNCT12);
xc->setMiscReg(FUNCT12, ZIMM);
Rd = xc->readMiscReg(csr);
xc->setMiscReg(csr, uimm);
}}, IsNonSpeculative, No_OpClass);
0x6: csrrsi({{
Rd = xc->readMiscReg(FUNCT12);
if (ZIMM != 0) {
xc->setMiscReg(FUNCT12, Rd | ZIMM);
Rd = xc->readMiscReg(csr);
if (uimm != 0) {
xc->setMiscReg(csr, Rd | uimm);
}
}}, IsNonSpeculative, No_OpClass);
0x7: csrrci({{
Rd = xc->readMiscReg(FUNCT12);
if (ZIMM != 0) {
xc->setMiscReg(FUNCT12, Rd & ~ZIMM);
Rd = xc->readMiscReg(csr);
if (uimm != 0) {
xc->setMiscReg(csr, Rd & ~uimm);
}
}}, IsNonSpeculative, No_OpClass);
}

View File

@@ -96,8 +96,8 @@ output decoder {{
const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", ("
<< regName(_srcRegIdx[0]) << ')';
ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", ("
<< registerName(_srcRegIdx[0]) << ')';
return ss.str();
}
@@ -105,9 +105,9 @@ output decoder {{
const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", "
<< regName(_srcRegIdx[1]) << ", ("
<< regName(_srcRegIdx[0]) << ')';
ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", "
<< registerName(_srcRegIdx[1]) << ", ("
<< registerName(_srcRegIdx[0]) << ')';
return ss.str();
}
@@ -115,9 +115,9 @@ output decoder {{
const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", "
<< regName(_srcRegIdx[1]) << ", ("
<< regName(_srcRegIdx[0]) << ')';
ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", "
<< registerName(_srcRegIdx[1]) << ", ("
<< registerName(_srcRegIdx[0]) << ')';
return ss.str();
}
@@ -130,22 +130,6 @@ output decoder {{
}
}};
def template LRSCDeclare {{
class %(class_name)s : public %(base_class)s
{
public:
%(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
%(EACompDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template AtomicMemOpDeclare {{
/**
* Static instruction class for an AtomicMemOp operation
@@ -238,35 +222,6 @@ def template AtomicMemOpStoreConstructor {{
}
}};
def template AtomicMemOpMacroDecode {{
return new %(class_name)s(machInst);
}};
def template LoadReservedExecute {{
Fault
%(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template StoreCondExecute {{
Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
@@ -358,9 +313,9 @@ def template AtomicMemOpStoreExecute {{
}
}};
def template LRSCEACompExecute {{
def template AtomicMemOpEACompExecute {{
Fault
%(class_name)s::eaComp(CPU_EXEC_CONTEXT *xc,
%(class_name)s::%(class_name)s%(op_name)s::eaComp(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
@@ -379,95 +334,6 @@ def template LRSCEACompExecute {{
}
}};
def template AtomicMemOpLoadEACompExecute {{
Fault %(class_name)s::%(class_name)sLoad::eaComp(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(op_wb)s;
xc->setEA(EA);
}
return fault;
}
}};
def template AtomicMemOpStoreEACompExecute {{
Fault %(class_name)s::%(class_name)sStore::eaComp(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(op_wb)s;
xc->setEA(EA);
}
return fault;
}
}};
def template LoadReservedInitiateAcc {{
Fault
%(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_src_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
}
return fault;
}
}};
def template StoreCondInitiateAcc {{
Fault
%(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = writeMemTiming(xc, traceData, Mem, EA,
memAccessFlags, nullptr);
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template AtomicMemOpLoadInitiateAcc {{
Fault %(class_name)s::%(class_name)sLoad::initiateAcc(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
@@ -515,30 +381,6 @@ def template AtomicMemOpStoreInitiateAcc {{
}
}};
def template LoadReservedCompleteAcc {{
Fault
%(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
getMem(pkt, Mem, traceData);
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template StoreCondCompleteAcc {{
Fault %(class_name)s::completeAcc(Packet *pkt, CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
@@ -604,13 +446,13 @@ def format LoadReserved(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}},
iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \
'|'.join(['Request::%s' % flag for flag in mem_flags]) + ';'
header_output = LRSCDeclare.subst(iop)
header_output = LoadStoreDeclare.subst(iop)
decoder_output = LRSCConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = LoadReservedExecute.subst(iop) \
+ LRSCEACompExecute.subst(iop) \
+ LoadReservedInitiateAcc.subst(iop) \
+ LoadReservedCompleteAcc.subst(iop)
exec_output = LoadExecute.subst(iop) \
+ EACompExecute.subst(iop) \
+ LoadInitiateAcc.subst(iop) \
+ LoadCompleteAcc.subst(iop)
}};
def format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}},
@@ -623,12 +465,12 @@ def format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}},
iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \
'|'.join(['Request::%s' % flag for flag in mem_flags]) + ';'
header_output = LRSCDeclare.subst(iop)
header_output = LoadStoreDeclare.subst(iop)
decoder_output = LRSCConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = StoreCondExecute.subst(iop) \
+ LRSCEACompExecute.subst(iop) \
+ StoreCondInitiateAcc.subst(iop) \
+ EACompExecute.subst(iop) \
+ StoreInitiateAcc.subst(iop) \
+ StoreCondCompleteAcc.subst(iop)
}};
@@ -637,24 +479,26 @@ def format AtomicMemOp(load_code, store_code, ea_code, load_flags=[],
macro_iop = InstObjParams(name, Name, 'AtomicMemOp', ea_code, inst_flags)
header_output = AtomicMemOpDeclare.subst(macro_iop)
decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop)
decode_block = AtomicMemOpMacroDecode.subst(macro_iop)
decode_block = BasicDecode.subst(macro_iop)
exec_output = ''
load_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsLoad"]
load_iop = InstObjParams(name, Name, 'AtomicMemOpMicro',
{'ea_code': ea_code, 'code': load_code}, load_inst_flags)
{'ea_code': ea_code, 'code': load_code, 'op_name': 'Load'},
load_inst_flags)
decoder_output += AtomicMemOpLoadConstructor.subst(load_iop)
exec_output += AtomicMemOpLoadExecute.subst(load_iop) \
+ AtomicMemOpLoadEACompExecute.subst(load_iop) \
+ AtomicMemOpEACompExecute.subst(load_iop) \
+ AtomicMemOpLoadInitiateAcc.subst(load_iop) \
+ AtomicMemOpLoadCompleteAcc.subst(load_iop)
store_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsStore"]
store_iop = InstObjParams(name, Name, 'AtomicMemOpMicro',
{'ea_code': ea_code, 'code': store_code}, store_inst_flags)
{'ea_code': ea_code, 'code': store_code, 'op_name': 'Store'},
store_inst_flags)
decoder_output += AtomicMemOpStoreConstructor.subst(store_iop)
exec_output += AtomicMemOpStoreExecute.subst(store_iop) \
+ AtomicMemOpStoreEACompExecute.subst(store_iop) \
+ AtomicMemOpEACompExecute.subst(store_iop) \
+ AtomicMemOpStoreInitiateAcc.subst(store_iop) \
+ AtomicMemOpStoreCompleteAcc.subst(store_iop)
}};

View File

@@ -85,11 +85,6 @@ def template BasicDecode {{
return new %(class_name)s(machInst);
}};
// Basic decode template, passing mnemonic in as string arg to constructor.
def template BasicDecodeWithMnemonic {{
return new %(class_name)s("%(mnemonic)s", machInst);
}};
// The most basic instruction format...
def format BasicOp(code, *flags) {{
iop = InstObjParams(name, Name, 'RiscvStaticInst', code, flags)

View File

@@ -1,7 +1,7 @@
// -*- mode:c++ -*-
// Copyright (c) 2015 RISC-V Foundation
// Copyright (c) 2016 The University of Virginia
// Copyright (c) 2016-2017 The University of Virginia
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
##include "basic.isa"
//Include the type formats
##include "type.isa"
##include "standard.isa"
##include "mem.isa"
##include "fp.isa"
##include "amo.isa"

View File

@@ -1,7 +1,7 @@
// -*- mode:c++ -*-
// Copyright (c) 2015 Riscv Developers
// Copyright (c) 2016 The University of Virginia
// Copyright (c) 2016-2017 The University of Virginia
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -120,15 +120,7 @@ def template FloatExecute {{
}};
def format FPROp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'ROp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = FloatExecute.subst(iop)
}};
def format FPR4Op(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'ROp', code, opt_flags)
iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)

View File

@@ -87,8 +87,8 @@ output decoder {{
Load::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " << ldisp <<
'(' << regName(_srcRegIdx[0]) << ')';
ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " <<
ldisp << '(' << registerName(_srcRegIdx[0]) << ')';
return ss.str();
}
@@ -96,8 +96,8 @@ output decoder {{
Store::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_srcRegIdx[1]) << ", " << sdisp <<
'(' << regName(_srcRegIdx[0]) << ')';
ss << mnemonic << ' ' << registerName(_srcRegIdx[1]) << ", " <<
sdisp << '(' << registerName(_srcRegIdx[0]) << ')';
return ss.str();
}
}};

View File

@@ -0,0 +1,449 @@
// -*- mode:c++ -*-
// Copyright (c) 2015 RISC-V Foundation
// Copyright (c) 2016-2017 The University of Virginia
// 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.
//
// Authors: Alec Roelke
////////////////////////////////////////////////////////////////////
//
// Integer instructions
//
output header {{
/**
* Base class for operations that work only on registers
*/
class RegOp : public RiscvStaticInst
{
protected:
/// Constructor
RegOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass)
{}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for operations with signed immediates
*/
class ImmOp : public RiscvStaticInst
{
protected:
int64_t imm;
/// Constructor
ImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
{}
virtual std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
};
/**
* Base class for operations with unsigned immediates
*/
class UImmOp : public RiscvStaticInst
{
protected:
uint64_t imm;
/// Constructor
UImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
{}
virtual std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
};
/**
* Base class for operations with branching
*/
class BranchOp : public ImmOp
{
protected:
/// Constructor
BranchOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: ImmOp(mnem, _machInst, __opClass)
{}
using StaticInst::branchTarget;
virtual RiscvISA::PCState
branchTarget(ThreadContext *tc) const
{
return StaticInst::branchTarget(tc);
}
virtual RiscvISA::PCState
branchTarget(const RiscvISA::PCState &branchPC) const
{
return StaticInst::branchTarget(branchPC);
}
virtual std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
};
/**
* Base class for system operations
*/
class SystemOp : public RiscvStaticInst
{
public:
/// Constructor
SystemOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass)
{}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return mnemonic;
}
};
/**
* Base class for CSR operations
*/
class CSROp : public RiscvStaticInst
{
protected:
uint64_t csr;
uint64_t uimm;
public:
/// Constructor
CSROp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass),
csr(FUNCT12), uimm(CSRIMM)
{}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
//Outputs to decoder.cc
output decoder {{
std::string
RegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " <<
registerName(_srcRegIdx[0]) << ", " <<
registerName(_srcRegIdx[1]);
return ss.str();
}
std::string
CSROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", ";
if (_numSrcRegs > 0)
ss << registerName(_srcRegIdx[0]) << ", ";
ss << MiscRegNames.at(csr);
return ss.str();
}
}};
def template ImmDeclare {{
//
// Static instruction class for "%(mnemonic)s".
//
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const override;
};
}};
def template ImmConstructor {{
%(class_name)s::%(class_name)s(MachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
%(imm_code)s;
}
}};
def template ImmExecute {{
Fault
%(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (fault == NoFault) {
%(code)s;
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
std::string
%(class_name)s::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::vector<RegId> indices = {%(regs)s};
std::stringstream ss;
ss << mnemonic << ' ';
for (const RegId& idx: indices)
ss << registerName(idx) << ", ";
ss << imm;
return ss.str();
}
}};
def template BranchDeclare {{
//
// Static instruction class for "%(mnemonic)s".
//
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
RiscvISA::PCState
branchTarget(const RiscvISA::PCState &branchPC) const override;
using StaticInst::branchTarget;
};
}};
def template BranchExecute {{
Fault
%(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (fault == NoFault) {
%(code)s;
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
RiscvISA::PCState
%(class_name)s::branchTarget(const RiscvISA::PCState &branchPC) const
{
return branchPC.pc() + imm;
}
std::string
%(class_name)s::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::vector<RegId> indices = {%(regs)s};
std::stringstream ss;
ss << mnemonic << ' ';
for (const RegId& idx: indices)
ss << registerName(idx) << ", ";
ss << imm;
return ss.str();
}
}};
def template JumpDeclare {{
//
// Static instruction class for "%(mnemonic)s".
//
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
RiscvISA::PCState
branchTarget(ThreadContext *tc) const override;
using StaticInst::branchTarget;
};
}};
def template JumpExecute {{
Fault
%(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (fault == NoFault) {
%(code)s;
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
RiscvISA::PCState
%(class_name)s::branchTarget(ThreadContext *tc) const
{
PCState pc = tc->pcState();
pc.set((tc->readIntReg(_srcRegIdx[0].index()) + imm)&~0x1);
return pc;
}
std::string
%(class_name)s::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::vector<RegId> indices = {%(regs)s};
std::stringstream ss;
ss << mnemonic << ' ';
for (const RegId& idx: indices)
ss << registerName(idx) << ", ";
ss << imm;
return ss.str();
}
}};
def format ROp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format IOp(code, *opt_flags) {{
imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
regs = ['_destRegIdx[0]','_srcRegIdx[0]']
iop = InstObjParams(name, Name, 'ImmOp',
{'code': code, 'imm_code': imm_code,
'regs': ','.join(regs)}, opt_flags)
header_output = ImmDeclare.subst(iop)
decoder_output = ImmConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ImmExecute.subst(iop)
}};
def format BOp(code, *opt_flags) {{
imm_code = """
imm |= BIMM12BIT11 << 11;
imm |= BIMM12BITS4TO1 << 1;
imm |= BIMM12BITS10TO5 << 5;
if (IMMSIGN > 0)
imm |= ~((uint64_t)0xFFF);
"""
regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
iop = InstObjParams(name, Name, 'BranchOp',
{'code': code, 'imm_code': imm_code,
'regs': ','.join(regs)}, opt_flags)
header_output = BranchDeclare.subst(iop)
decoder_output = ImmConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BranchExecute.subst(iop)
}};
def format Jump(code, *opt_flags) {{
imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
regs = ['_destRegIdx[0]','_srcRegIdx[0]']
iop = InstObjParams(name, Name, 'BranchOp',
{'code': code, 'imm_code': imm_code,
'regs': ','.join(regs)}, opt_flags)
header_output = JumpDeclare.subst(iop)
decoder_output = ImmConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = JumpExecute.subst(iop)
}};
def format UOp(code, *opt_flags) {{
imm_code = 'imm = (int32_t)(IMM20 << 12);'
regs = ['_destRegIdx[0]']
iop = InstObjParams(name, Name, 'ImmOp',
{'code': code, 'imm_code': imm_code,
'regs': ','.join(regs)}, opt_flags)
header_output = ImmDeclare.subst(iop)
decoder_output = ImmConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ImmExecute.subst(iop)
}};
def format JOp(code, *opt_flags) {{
imm_code = """
imm |= UJIMMBITS19TO12 << 12;
imm |= UJIMMBIT11 << 11;
imm |= UJIMMBITS10TO1 << 1;
if (IMMSIGN > 0)
imm |= ~((uint64_t)0xFFFFF);
"""
pc = 'pc.set(pc.pc() + imm);'
regs = ['_destRegIdx[0]']
iop = InstObjParams(name, Name, 'BranchOp',
{'code': code, 'imm_code': imm_code,
'regs': ','.join(regs)}, opt_flags)
header_output = BranchDeclare.subst(iop)
decoder_output = ImmConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BranchExecute.subst(iop)
}};
def format SystemOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format CSROp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View File

@@ -1,319 +0,0 @@
// -*- mode:c++ -*-
// Copyright (c) 2015 RISC-V Foundation
// Copyright (c) 2016 The University of Virginia
// 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.
//
// Authors: Alec Roelke
////////////////////////////////////////////////////////////////////
//
// Integer instructions
//
output header {{
#include <iostream>
/**
* Base class for R-type operations
*/
class ROp : public RiscvStaticInst
{
protected:
/// Constructor
ROp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass)
{}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for I-type operations
*/
class IOp : public RiscvStaticInst
{
protected:
int64_t imm;
/// Constructor
IOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass),imm(IMM12)
{
if (IMMSIGN > 0)
imm |= ~((uint64_t)0x7FF);
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Class for jalr instructions
*/
class Jump : public IOp
{
protected:
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
: IOp(mnem, _machInst, __opClass)
{}
RiscvISA::PCState
branchTarget(ThreadContext *tc) const;
using StaticInst::branchTarget;
using IOp::generateDisassembly;
};
/**
* Base class for S-type operations
*/
class SOp : public RiscvStaticInst
{
protected:
int64_t imm;
/// Constructor
SOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass),imm(0)
{
imm |= IMM5;
imm |= IMM7 << 5;
if (IMMSIGN > 0)
imm |= ~((uint64_t)0x7FF);
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for SB-type operations
*/
class SBOp : public RiscvStaticInst
{
protected:
int64_t imm;
/// Constructor
SBOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass),imm(0)
{
imm |= BIMM12BIT11 << 11;
imm |= BIMM12BITS4TO1 << 1;
imm |= BIMM12BITS10TO5 << 5;
if (IMMSIGN > 0)
imm |= ~((uint64_t)0xFFF);
}
RiscvISA::PCState
branchTarget(const RiscvISA::PCState &branchPC) const;
using StaticInst::branchTarget;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for U-type operations
*/
class UOp : public RiscvStaticInst
{
protected:
int64_t imm;
/// Constructor
UOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
{
int32_t temp = IMM20 << 12;
imm = temp;
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for UJ-type operations
*/
class UJOp : public RiscvStaticInst
{
protected:
int64_t imm;
/// Constructor
UJOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass),imm(0)
{
imm |= UJIMMBITS19TO12 << 12;
imm |= UJIMMBIT11 << 11;
imm |= UJIMMBITS10TO1 << 1;
if (IMMSIGN > 0)
imm |= ~((uint64_t)0xFFFFF);
}
RiscvISA::PCState
branchTarget(const RiscvISA::PCState &branchPC) const;
using StaticInst::branchTarget;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
//Outputs to decoder.cc
output decoder {{
std::string
ROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " <<
regName(_srcRegIdx[0]) << ", " << regName(_srcRegIdx[1]);
return ss.str();
}
std::string
IOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " <<
regName(_srcRegIdx[0]) << ", " << imm;
return ss.str();
}
RiscvISA::PCState
Jump::branchTarget(ThreadContext *tc) const
{
PCState pc = tc->pcState();
IntReg Rs1 = tc->readIntReg(_srcRegIdx[0].index());
pc.set((Rs1 + imm)&~0x1);
return pc;
}
std::string
SOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_srcRegIdx[1]) << ", " << imm <<
'(' << regName(_srcRegIdx[0]) << ')';
return ss.str();
}
RiscvISA::PCState
SBOp::branchTarget(const RiscvISA::PCState &branchPC) const
{
return branchPC.pc() + imm;
}
std::string
SBOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_srcRegIdx[0]) << ", " <<
regName(_srcRegIdx[1]) << ", " << imm;
return ss.str();
}
std::string
UOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " << imm;
return ss.str();
}
RiscvISA::PCState
UJOp::branchTarget(const RiscvISA::PCState &branchPC) const
{
return branchPC.pc() + imm;
}
std::string
UJOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " << imm;
return ss.str();
}
}};
def format ROp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'ROp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format IOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'IOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format Jump(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'Jump', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format SOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format SBOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SBOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format UOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'UOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format UJOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'UJOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View File

@@ -71,6 +71,7 @@ output exec {{
#include <cfenv>
#include <cmath>
#include <string>
#include <vector>
#include "arch/generic/memhelpers.hh"
#include "arch/riscv/faults.hh"

View File

@@ -49,6 +49,7 @@
#include <map>
#include <string>
#include <vector>
#include "arch/generic/types.hh"
#include "arch/generic/vec_reg.hh"
@@ -91,29 +92,37 @@ const int StackPointerReg = 2;
const int GlobalPointerReg = 3;
const int ThreadPointerReg = 4;
const int FramePointerReg = 8;
const int ReturnValueRegs[] = {10, 11};
const std::vector<int> ReturnValueRegs = {10, 11};
const int ReturnValueReg = ReturnValueRegs[0];
const int ArgumentRegs[] = {10, 11, 12, 13, 14, 15, 16, 17};
const std::vector<int> ArgumentRegs = {10, 11, 12, 13, 14, 15, 16, 17};
const int AMOTempReg = 32;
const char* const RegisterNames[] = {"zero", "ra", "sp", "gp",
const std::vector<std::string> IntRegNames = {
"zero", "ra", "sp", "gp",
"tp", "t0", "t1", "t2",
"s0", "s1", "a0", "a1",
"a2", "a3", "a4", "a5",
"a6", "a7", "s2", "s3",
"s4", "s5", "s6", "s7",
"s8", "s9", "s10", "s11",
"t3", "t4", "t5", "t6"};
"t3", "t4", "t5", "t6"
};
const std::vector<std::string> FloatRegNames = {
"ft0", "ft1", "ft2", "ft3",
"ft4", "ft5", "ft6", "ft7",
"fs0", "fs1", "fa0", "fa1",
"fa2", "fa3", "fa4", "fa5",
"fa6", "fa7", "fs2", "fs3",
"fs4", "fs5", "fs6", "fs7",
"fs8", "fs9", "fs10", "fs11",
"ft8", "ft9", "ft10", "ft11"
};
const int SyscallNumReg = ArgumentRegs[7];
const int SyscallArgumentRegs[] = {ArgumentRegs[0], ArgumentRegs[1],
const std::vector<int> SyscallArgumentRegs = {ArgumentRegs[0], ArgumentRegs[1],
ArgumentRegs[2], ArgumentRegs[3]};
const int SyscallPseudoReturnReg = ReturnValueRegs[0];
const int NumHpmcounter = 29;
const int NumHpmcounterh = 29;
const int NumMhpmcounter = 29;
const int NumMhpmevent = 29;
enum MiscRegIndex {
MISCREG_USTATUS = 0x000,
MISCREG_UIE = 0x004,
@@ -196,6 +205,200 @@ enum MiscRegIndex {
MISCREG_DSCRATCH = 0x7B2
};
const std::map<int, std::string> MiscRegNames = {
{MISCREG_USTATUS, "ustatus"},
{MISCREG_UIE, "uie"},
{MISCREG_UTVEC, "utvec"},
{MISCREG_USCRATCH, "uscratch"},
{MISCREG_UEPC, "uepc"},
{MISCREG_UCAUSE, "ucause"},
{MISCREG_UBADADDR, "ubadaddr"},
{MISCREG_UIP, "uip"},
{MISCREG_FFLAGS, "fflags"},
{MISCREG_FRM, "frm"},
{MISCREG_FCSR, "fcsr"},
{MISCREG_CYCLE, "cycle"},
{MISCREG_TIME, "time"},
{MISCREG_INSTRET, "instret"},
{MISCREG_HPMCOUNTER_BASE + 0, "hpmcounter03"},
{MISCREG_HPMCOUNTER_BASE + 1, "hpmcounter04"},
{MISCREG_HPMCOUNTER_BASE + 2, "hpmcounter05"},
{MISCREG_HPMCOUNTER_BASE + 3, "hpmcounter06"},
{MISCREG_HPMCOUNTER_BASE + 4, "hpmcounter07"},
{MISCREG_HPMCOUNTER_BASE + 5, "hpmcounter08"},
{MISCREG_HPMCOUNTER_BASE + 6, "hpmcounter09"},
{MISCREG_HPMCOUNTER_BASE + 7, "hpmcounter10"},
{MISCREG_HPMCOUNTER_BASE + 8, "hpmcounter11"},
{MISCREG_HPMCOUNTER_BASE + 9, "hpmcounter12"},
{MISCREG_HPMCOUNTER_BASE + 10, "hpmcounter13"},
{MISCREG_HPMCOUNTER_BASE + 11, "hpmcounter14"},
{MISCREG_HPMCOUNTER_BASE + 12, "hpmcounter15"},
{MISCREG_HPMCOUNTER_BASE + 13, "hpmcounter16"},
{MISCREG_HPMCOUNTER_BASE + 14, "hpmcounter17"},
{MISCREG_HPMCOUNTER_BASE + 15, "hpmcounter18"},
{MISCREG_HPMCOUNTER_BASE + 16, "hpmcounter19"},
{MISCREG_HPMCOUNTER_BASE + 17, "hpmcounter20"},
{MISCREG_HPMCOUNTER_BASE + 18, "hpmcounter21"},
{MISCREG_HPMCOUNTER_BASE + 19, "hpmcounter22"},
{MISCREG_HPMCOUNTER_BASE + 20, "hpmcounter23"},
{MISCREG_HPMCOUNTER_BASE + 21, "hpmcounter24"},
{MISCREG_HPMCOUNTER_BASE + 22, "hpmcounter25"},
{MISCREG_HPMCOUNTER_BASE + 23, "hpmcounter26"},
{MISCREG_HPMCOUNTER_BASE + 24, "hpmcounter27"},
{MISCREG_HPMCOUNTER_BASE + 25, "hpmcounter28"},
{MISCREG_HPMCOUNTER_BASE + 26, "hpmcounter29"},
{MISCREG_HPMCOUNTER_BASE + 27, "hpmcounter30"},
{MISCREG_HPMCOUNTER_BASE + 28, "hpmcounter31"},
{MISCREG_CYCLEH, "cycleh"},
{MISCREG_TIMEH, "timeh"},
{MISCREG_INSTRETH, "instreth"},
{MISCREG_HPMCOUNTERH_BASE + 0, "hpmcounterh03"},
{MISCREG_HPMCOUNTERH_BASE + 1, "hpmcounterh04"},
{MISCREG_HPMCOUNTERH_BASE + 2, "hpmcounterh05"},
{MISCREG_HPMCOUNTERH_BASE + 3, "hpmcounterh06"},
{MISCREG_HPMCOUNTERH_BASE + 4, "hpmcounterh07"},
{MISCREG_HPMCOUNTERH_BASE + 5, "hpmcounterh08"},
{MISCREG_HPMCOUNTERH_BASE + 6, "hpmcounterh09"},
{MISCREG_HPMCOUNTERH_BASE + 7, "hpmcounterh10"},
{MISCREG_HPMCOUNTERH_BASE + 8, "hpmcounterh11"},
{MISCREG_HPMCOUNTERH_BASE + 9, "hpmcounterh12"},
{MISCREG_HPMCOUNTERH_BASE + 10, "hpmcounterh13"},
{MISCREG_HPMCOUNTERH_BASE + 11, "hpmcounterh14"},
{MISCREG_HPMCOUNTERH_BASE + 12, "hpmcounterh15"},
{MISCREG_HPMCOUNTERH_BASE + 13, "hpmcounterh16"},
{MISCREG_HPMCOUNTERH_BASE + 14, "hpmcounterh17"},
{MISCREG_HPMCOUNTERH_BASE + 15, "hpmcounterh18"},
{MISCREG_HPMCOUNTERH_BASE + 16, "hpmcounterh19"},
{MISCREG_HPMCOUNTERH_BASE + 17, "hpmcounterh20"},
{MISCREG_HPMCOUNTERH_BASE + 18, "hpmcounterh21"},
{MISCREG_HPMCOUNTERH_BASE + 19, "hpmcounterh22"},
{MISCREG_HPMCOUNTERH_BASE + 20, "hpmcounterh23"},
{MISCREG_HPMCOUNTERH_BASE + 21, "hpmcounterh24"},
{MISCREG_HPMCOUNTERH_BASE + 22, "hpmcounterh25"},
{MISCREG_HPMCOUNTERH_BASE + 23, "hpmcounterh26"},
{MISCREG_HPMCOUNTERH_BASE + 24, "hpmcounterh27"},
{MISCREG_HPMCOUNTERH_BASE + 25, "hpmcounterh28"},
{MISCREG_HPMCOUNTERH_BASE + 26, "hpmcounterh29"},
{MISCREG_HPMCOUNTERH_BASE + 27, "hpmcounterh30"},
{MISCREG_HPMCOUNTERH_BASE + 28, "hpmcounterh31"},
{MISCREG_SSTATUS, "sstatus"},
{MISCREG_SEDELEG, "sedeleg"},
{MISCREG_SIDELEG, "sideleg"},
{MISCREG_SIE, "sie"},
{MISCREG_STVEC, "stvec"},
{MISCREG_SSCRATCH, "sscratch"},
{MISCREG_SEPC, "sepc"},
{MISCREG_SCAUSE, "scause"},
{MISCREG_SBADADDR, "sbadaddr"},
{MISCREG_SIP, "sip"},
{MISCREG_SPTBR, "sptbr"},
{MISCREG_HSTATUS, "hstatus"},
{MISCREG_HEDELEG, "hedeleg"},
{MISCREG_HIDELEG, "hideleg"},
{MISCREG_HIE, "hie"},
{MISCREG_HTVEC, "htvec"},
{MISCREG_HSCRATCH, "hscratch"},
{MISCREG_HEPC, "hepc"},
{MISCREG_HCAUSE, "hcause"},
{MISCREG_HBADADDR, "hbadaddr"},
{MISCREG_HIP, "hip"},
{MISCREG_MVENDORID, "mvendorid"},
{MISCREG_MARCHID, "marchid"},
{MISCREG_MIMPID, "mimpid"},
{MISCREG_MHARTID, "mhartid"},
{MISCREG_MSTATUS, "mstatus"},
{MISCREG_MISA, "misa"},
{MISCREG_MEDELEG, "medeleg"},
{MISCREG_MIDELEG, "mideleg"},
{MISCREG_MIE, "mie"},
{MISCREG_MTVEC, "mtvec"},
{MISCREG_MSCRATCH, "mscratch"},
{MISCREG_MEPC, "mepc"},
{MISCREG_MCAUSE, "mcause"},
{MISCREG_MBADADDR, "mbadaddr"},
{MISCREG_MIP, "mip"},
{MISCREG_MBASE, "mbase"},
{MISCREG_MBOUND, "mbound"},
{MISCREG_MIBASE, "mibase"},
{MISCREG_MIBOUND, "mibound"},
{MISCREG_MDBASE, "mdbase"},
{MISCREG_MDBOUND, "mdbound"},
{MISCREG_MCYCLE, "mcycle"},
{MISCREG_MINSTRET, "minstret"},
{MISCREG_MHPMCOUNTER_BASE + 0, "mhpmcounter03"},
{MISCREG_MHPMCOUNTER_BASE + 1, "mhpmcounter04"},
{MISCREG_MHPMCOUNTER_BASE + 2, "mhpmcounter05"},
{MISCREG_MHPMCOUNTER_BASE + 3, "mhpmcounter06"},
{MISCREG_MHPMCOUNTER_BASE + 4, "mhpmcounter07"},
{MISCREG_MHPMCOUNTER_BASE + 5, "mhpmcounter08"},
{MISCREG_MHPMCOUNTER_BASE + 6, "mhpmcounter09"},
{MISCREG_MHPMCOUNTER_BASE + 7, "mhpmcounter10"},
{MISCREG_MHPMCOUNTER_BASE + 8, "mhpmcounter11"},
{MISCREG_MHPMCOUNTER_BASE + 9, "mhpmcounter12"},
{MISCREG_MHPMCOUNTER_BASE + 10, "mhpmcounter13"},
{MISCREG_MHPMCOUNTER_BASE + 11, "mhpmcounter14"},
{MISCREG_MHPMCOUNTER_BASE + 12, "mhpmcounter15"},
{MISCREG_MHPMCOUNTER_BASE + 13, "mhpmcounter16"},
{MISCREG_MHPMCOUNTER_BASE + 14, "mhpmcounter17"},
{MISCREG_MHPMCOUNTER_BASE + 15, "mhpmcounter18"},
{MISCREG_MHPMCOUNTER_BASE + 16, "mhpmcounter19"},
{MISCREG_MHPMCOUNTER_BASE + 17, "mhpmcounter20"},
{MISCREG_MHPMCOUNTER_BASE + 18, "mhpmcounter21"},
{MISCREG_MHPMCOUNTER_BASE + 19, "mhpmcounter22"},
{MISCREG_MHPMCOUNTER_BASE + 20, "mhpmcounter23"},
{MISCREG_MHPMCOUNTER_BASE + 21, "mhpmcounter24"},
{MISCREG_MHPMCOUNTER_BASE + 22, "mhpmcounter25"},
{MISCREG_MHPMCOUNTER_BASE + 23, "mhpmcounter26"},
{MISCREG_MHPMCOUNTER_BASE + 24, "mhpmcounter27"},
{MISCREG_MHPMCOUNTER_BASE + 25, "mhpmcounter28"},
{MISCREG_MHPMCOUNTER_BASE + 26, "mhpmcounter29"},
{MISCREG_MHPMCOUNTER_BASE + 27, "mhpmcounter30"},
{MISCREG_MHPMCOUNTER_BASE + 28, "mhpmcounter31"},
{MISCREG_MUCOUNTEREN, "mucounteren"},
{MISCREG_MSCOUNTEREN, "mscounteren"},
{MISCREG_MHCOUNTEREN, "mhcounteren"},
{MISCREG_MHPMEVENT_BASE + 0, "mhpmevent03"},
{MISCREG_MHPMEVENT_BASE + 1, "mhpmevent04"},
{MISCREG_MHPMEVENT_BASE + 2, "mhpmevent05"},
{MISCREG_MHPMEVENT_BASE + 3, "mhpmevent06"},
{MISCREG_MHPMEVENT_BASE + 4, "mhpmevent07"},
{MISCREG_MHPMEVENT_BASE + 5, "mhpmevent08"},
{MISCREG_MHPMEVENT_BASE + 6, "mhpmevent09"},
{MISCREG_MHPMEVENT_BASE + 7, "mhpmevent10"},
{MISCREG_MHPMEVENT_BASE + 8, "mhpmevent11"},
{MISCREG_MHPMEVENT_BASE + 9, "mhpmevent12"},
{MISCREG_MHPMEVENT_BASE + 10, "mhpmevent13"},
{MISCREG_MHPMEVENT_BASE + 11, "mhpmevent14"},
{MISCREG_MHPMEVENT_BASE + 12, "mhpmevent15"},
{MISCREG_MHPMEVENT_BASE + 13, "mhpmevent16"},
{MISCREG_MHPMEVENT_BASE + 14, "mhpmevent17"},
{MISCREG_MHPMEVENT_BASE + 15, "mhpmevent18"},
{MISCREG_MHPMEVENT_BASE + 16, "mhpmevent19"},
{MISCREG_MHPMEVENT_BASE + 17, "mhpmevent20"},
{MISCREG_MHPMEVENT_BASE + 18, "mhpmevent21"},
{MISCREG_MHPMEVENT_BASE + 19, "mhpmevent22"},
{MISCREG_MHPMEVENT_BASE + 20, "mhpmevent23"},
{MISCREG_MHPMEVENT_BASE + 21, "mhpmevent24"},
{MISCREG_MHPMEVENT_BASE + 22, "mhpmevent25"},
{MISCREG_MHPMEVENT_BASE + 23, "mhpmevent26"},
{MISCREG_MHPMEVENT_BASE + 24, "mhpmevent27"},
{MISCREG_MHPMEVENT_BASE + 25, "mhpmevent28"},
{MISCREG_MHPMEVENT_BASE + 26, "mhpmevent29"},
{MISCREG_MHPMEVENT_BASE + 27, "mhpmevent30"},
{MISCREG_MHPMEVENT_BASE + 28, "mhpmevent31"},
{MISCREG_TSELECT, "tselect"},
{MISCREG_TDATA1, "tdata1"},
{MISCREG_TDATA2, "tdata2"},
{MISCREG_TDATA3, "tdata3"},
{MISCREG_DCSR, "dcsr"},
{MISCREG_DPC, "dpc"},
{MISCREG_DSCRATCH, "dscratch"}
};
}
#endif // __ARCH_RISCV_REGISTERS_HH__

View File

@@ -12,7 +12,7 @@
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2016 The University of Virginia
* Copyright (c) 2016-2017 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -48,8 +48,11 @@
#include <cmath>
#include <cstdint>
#include <string>
#include "arch/riscv/registers.hh"
#include "base/types.hh"
#include "cpu/reg_class.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
@@ -126,6 +129,16 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
dest->pcState(src->pcState());
}
inline std::string
registerName(RegId reg)
{
if (reg.isIntReg()) {
return IntRegNames[reg.index()];
} else {
return FloatRegNames[reg.index()];
}
}
inline void
skipFunction(ThreadContext *tc)
{