From: Alec Roelke Date: Thu, 15 Jun 2017 19:33:25 +0000 (-0400) Subject: arch-riscv: Restructure ISA description X-Git-Tag: v19.0.0.0~2700 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=63d4005a29dea37e0219444a3de2cdb25289fdfb;p=gem5.git 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 Reviewed-by: Jason Lowe-Power --- diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index d99954be4..6091068ef 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -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; diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index 578057aa0..18dc1ba4c 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -59,7 +59,6 @@ class ISA : public SimObject { protected: std::vector miscRegFile; - std::map miscRegNames; public: typedef RiscvISAParams Params; diff --git a/src/arch/riscv/isa/base.isa b/src/arch/riscv/isa/base.isa index a7e2fc954..d54d7940b 100644 --- a/src/arch/riscv/isa/base.isa +++ b/src/arch/riscv/isa/base.isa @@ -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()); - } - } -}}; diff --git a/src/arch/riscv/isa/bitfields.isa b/src/arch/riscv/isa/bitfields.isa index 2889afff6..23099a5e8 100644 --- a/src/arch/riscv/isa/bitfields.isa +++ b/src/arch/riscv/isa/bitfields.isa @@ -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>; diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 2b23c1fe4..8056d9615 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -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(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(); @@ -1346,36 +1345,38 @@ decode OPCODE default Unknown::unknown() { fault = std::make_shared("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); } diff --git a/src/arch/riscv/isa/formats/amo.isa b/src/arch/riscv/isa/formats/amo.isa index d60c4e0cd..24e13c984 100644 --- a/src/arch/riscv/isa/formats/amo.isa +++ b/src/arch/riscv/isa/formats/amo.isa @@ -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,29 +313,9 @@ def template AtomicMemOpStoreExecute {{ } }}; -def template LRSCEACompExecute {{ +def template AtomicMemOpEACompExecute {{ Fault - %(class_name)s::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 AtomicMemOpLoadEACompExecute {{ - Fault %(class_name)s::%(class_name)sLoad::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; @@ -399,75 +334,6 @@ def template AtomicMemOpLoadEACompExecute {{ } }}; -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) }}; diff --git a/src/arch/riscv/isa/formats/basic.isa b/src/arch/riscv/isa/formats/basic.isa index 2a0b823bf..4126fcdd4 100644 --- a/src/arch/riscv/isa/formats/basic.isa +++ b/src/arch/riscv/isa/formats/basic.isa @@ -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) diff --git a/src/arch/riscv/isa/formats/formats.isa b/src/arch/riscv/isa/formats/formats.isa index bae3c82ce..e13cac263 100644 --- a/src/arch/riscv/isa/formats/formats.isa +++ b/src/arch/riscv/isa/formats/formats.isa @@ -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" diff --git a/src/arch/riscv/isa/formats/fp.isa b/src/arch/riscv/isa/formats/fp.isa index 97a5a2a50..1f60b9b70 100644 --- a/src/arch/riscv/isa/formats/fp.isa +++ b/src/arch/riscv/isa/formats/fp.isa @@ -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) diff --git a/src/arch/riscv/isa/formats/mem.isa b/src/arch/riscv/isa/formats/mem.isa index 2a00850a2..4ae8eb41a 100644 --- a/src/arch/riscv/isa/formats/mem.isa +++ b/src/arch/riscv/isa/formats/mem.isa @@ -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(); } }}; diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa new file mode 100644 index 000000000..4ef241b2c --- /dev/null +++ b/src/arch/riscv/isa/formats/standard.isa @@ -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 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 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 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) +}}; \ No newline at end of file diff --git a/src/arch/riscv/isa/formats/type.isa b/src/arch/riscv/isa/formats/type.isa deleted file mode 100644 index f6a563699..000000000 --- a/src/arch/riscv/isa/formats/type.isa +++ /dev/null @@ -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 - /** - * 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) -}}; diff --git a/src/arch/riscv/isa/includes.isa b/src/arch/riscv/isa/includes.isa index c830f9085..443db6786 100644 --- a/src/arch/riscv/isa/includes.isa +++ b/src/arch/riscv/isa/includes.isa @@ -71,6 +71,7 @@ output exec {{ #include #include #include +#include #include "arch/generic/memhelpers.hh" #include "arch/riscv/faults.hh" diff --git a/src/arch/riscv/registers.hh b/src/arch/riscv/registers.hh index 6ae1c1691..e2b04ab84 100644 --- a/src/arch/riscv/registers.hh +++ b/src/arch/riscv/registers.hh @@ -49,6 +49,7 @@ #include #include +#include #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 ReturnValueRegs = {10, 11}; const int ReturnValueReg = ReturnValueRegs[0]; -const int ArgumentRegs[] = {10, 11, 12, 13, 14, 15, 16, 17}; +const std::vector ArgumentRegs = {10, 11, 12, 13, 14, 15, 16, 17}; const int AMOTempReg = 32; -const char* const RegisterNames[] = {"zero", "ra", "sp", "gp", +const std::vector 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 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 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 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__ diff --git a/src/arch/riscv/utility.hh b/src/arch/riscv/utility.hh index fc67fc806..38109a208 100644 --- a/src/arch/riscv/utility.hh +++ b/src/arch/riscv/utility.hh @@ -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 #include +#include +#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) {