diff options
Diffstat (limited to 'src/arch/riscv')
-rw-r--r-- | src/arch/riscv/isa.cc | 118 | ||||
-rw-r--r-- | src/arch/riscv/isa.hh | 1 | ||||
-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 | ||||
-rw-r--r-- | src/arch/riscv/registers.hh | 221 | ||||
-rw-r--r-- | src/arch/riscv/utility.hh | 15 |
15 files changed, 738 insertions, 684 deletions
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<MiscReg> miscRegFile; - std::map<int, std::string> 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<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" 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 <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__ 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 <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) { |