diff options
Diffstat (limited to 'src/arch/riscv/isa')
-rw-r--r-- | src/arch/riscv/isa/base.isa | 18 | ||||
-rw-r--r-- | src/arch/riscv/isa/bitfields.isa | 2 | ||||
-rw-r--r-- | src/arch/riscv/isa/decoder.isa | 43 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/amo.isa | 206 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/basic.isa | 5 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/formats.isa | 4 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/fp.isa | 12 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/mem.isa | 8 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/standard.isa | 449 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/type.isa | 319 | ||||
-rw-r--r-- | src/arch/riscv/isa/includes.isa | 1 |
11 files changed, 506 insertions, 561 deletions
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<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); } 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<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) +}};
\ 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 <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) -}}; 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 <cfenv> #include <cmath> #include <string> +#include <vector> #include "arch/generic/memhelpers.hh" #include "arch/riscv/faults.hh" |