mem.isa revision 11729:f37b5fcd66fe
14309Sgblack@eecs.umich.edu// -*- mode:c++ -*- 24309Sgblack@eecs.umich.edu 35426Sgblack@eecs.umich.edu// Copyright (c) 2015 RISC-V Foundation 44309Sgblack@eecs.umich.edu// Copyright (c) 2016 The University of Virginia 54309Sgblack@eecs.umich.edu// All rights reserved. 64309Sgblack@eecs.umich.edu// 74309Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 84309Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 94309Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 104309Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 114309Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 124309Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 134309Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 144309Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 154309Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 164309Sgblack@eecs.umich.edu// this software without specific prior written permission. 174309Sgblack@eecs.umich.edu// 184309Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 194309Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 204309Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 214309Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 224309Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 234309Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 244309Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 254309Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 264309Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 274309Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 284309Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 294309Sgblack@eecs.umich.edu// 304309Sgblack@eecs.umich.edu// Authors: Alec Roelke 314309Sgblack@eecs.umich.edu 324309Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 334309Sgblack@eecs.umich.edu// 344309Sgblack@eecs.umich.edu// Memory operation instructions 354309Sgblack@eecs.umich.edu// 364309Sgblack@eecs.umich.eduoutput header {{ 374309Sgblack@eecs.umich.edu class Load : public RiscvStaticInst 384309Sgblack@eecs.umich.edu { 394309Sgblack@eecs.umich.edu public: 404309Sgblack@eecs.umich.edu /// Displacement for EA calculation (signed). 414309Sgblack@eecs.umich.edu int64_t ldisp; 424309Sgblack@eecs.umich.edu 434309Sgblack@eecs.umich.edu protected: 444309Sgblack@eecs.umich.edu /// Memory request flags. See mem_req_base.hh. 454309Sgblack@eecs.umich.edu Request::Flags memAccessFlags; 464309Sgblack@eecs.umich.edu 474309Sgblack@eecs.umich.edu /// Constructor 484309Sgblack@eecs.umich.edu Load(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 494309Sgblack@eecs.umich.edu : RiscvStaticInst(mnem, _machInst, __opClass), ldisp(IMM12) 504309Sgblack@eecs.umich.edu { 514309Sgblack@eecs.umich.edu if (IMMSIGN > 0) 524309Sgblack@eecs.umich.edu ldisp |= ~((uint64_t)0xFFF); 534309Sgblack@eecs.umich.edu } 544309Sgblack@eecs.umich.edu 554309Sgblack@eecs.umich.edu std::string 564309Sgblack@eecs.umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 574309Sgblack@eecs.umich.edu }; 584533Sgblack@eecs.umich.edu 594679Sgblack@eecs.umich.edu class Store : public RiscvStaticInst 604679Sgblack@eecs.umich.edu { 614679Sgblack@eecs.umich.edu public: 624533Sgblack@eecs.umich.edu /// Displacement for EA calculation (signed). 634533Sgblack@eecs.umich.edu int64_t sdisp; 644537Sgblack@eecs.umich.edu 654533Sgblack@eecs.umich.edu protected: 664528Sgblack@eecs.umich.edu /// Memory request flags. See mem_req_base.hh. 675666Sgblack@eecs.umich.edu Request::Flags memAccessFlags; 685666Sgblack@eecs.umich.edu 695666Sgblack@eecs.umich.edu /// Constructor 704528Sgblack@eecs.umich.edu Store(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 714528Sgblack@eecs.umich.edu : RiscvStaticInst(mnem, _machInst, __opClass), sdisp(IMM5) 724528Sgblack@eecs.umich.edu { 734528Sgblack@eecs.umich.edu sdisp |= IMM7 << 5; 744605Sgblack@eecs.umich.edu if (IMMSIGN > 0) 755666Sgblack@eecs.umich.edu sdisp |= ~((uint64_t)0xFFF); 765666Sgblack@eecs.umich.edu } 774528Sgblack@eecs.umich.edu 786345Sgblack@eecs.umich.edu std::string 796345Sgblack@eecs.umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 806345Sgblack@eecs.umich.edu }; 816345Sgblack@eecs.umich.edu 826345Sgblack@eecs.umich.edu}}; 836345Sgblack@eecs.umich.edu 844615Sgblack@eecs.umich.edu 855854Sgblack@eecs.umich.eduoutput decoder {{ 866345Sgblack@eecs.umich.edu std::string 875854Sgblack@eecs.umich.edu Load::generateDisassembly(Addr pc, const SymbolTable *symtab) const 886345Sgblack@eecs.umich.edu { 896345Sgblack@eecs.umich.edu std::stringstream ss; 904615Sgblack@eecs.umich.edu ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " << ldisp << 915671Sgblack@eecs.umich.edu '(' << regName(_srcRegIdx[0]) << ')'; 926345Sgblack@eecs.umich.edu return ss.str(); 936345Sgblack@eecs.umich.edu } 945291Sgblack@eecs.umich.edu 955428Sgblack@eecs.umich.edu std::string 965674Sgblack@eecs.umich.edu Store::generateDisassembly(Addr pc, const SymbolTable *symtab) const 975899Sgblack@eecs.umich.edu { 985936Sgblack@eecs.umich.edu std::stringstream ss; 995428Sgblack@eecs.umich.edu ss << mnemonic << ' ' << regName(_srcRegIdx[1]) << ", " << sdisp << 1005428Sgblack@eecs.umich.edu '(' << regName(_srcRegIdx[0]) << ')'; 1015294Sgblack@eecs.umich.edu return ss.str(); 1026345Sgblack@eecs.umich.edu } 1035291Sgblack@eecs.umich.edu}}; 1045294Sgblack@eecs.umich.edu 1056345Sgblack@eecs.umich.edudef template LoadStoreDeclare {{ 1065294Sgblack@eecs.umich.edu /** 1074615Sgblack@eecs.umich.edu * Static instruction class for "%(mnemonic)s". 1084615Sgblack@eecs.umich.edu */ 1096345Sgblack@eecs.umich.edu class %(class_name)s : public %(base_class)s 1106345Sgblack@eecs.umich.edu { 1116345Sgblack@eecs.umich.edu public: 1126345Sgblack@eecs.umich.edu /// Constructor. 1136345Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst machInst); 1146345Sgblack@eecs.umich.edu 1156517Sgblack@eecs.umich.edu %(BasicExecDeclare)s 1166517Sgblack@eecs.umich.edu 1175161Sgblack@eecs.umich.edu %(EACompDeclare)s 1185161Sgblack@eecs.umich.edu 1196345Sgblack@eecs.umich.edu %(InitiateAccDeclare)s 1204615Sgblack@eecs.umich.edu 1216345Sgblack@eecs.umich.edu %(CompleteAccDeclare)s 1226345Sgblack@eecs.umich.edu }; 1234615Sgblack@eecs.umich.edu}}; 1244953Sgblack@eecs.umich.edu 1254615Sgblack@eecs.umich.edudef template EACompDeclare {{ 1264615Sgblack@eecs.umich.edu Fault 1274863Sgblack@eecs.umich.edu eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1284863Sgblack@eecs.umich.edu}}; 1295326Sgblack@eecs.umich.edu 1305326Sgblack@eecs.umich.edudef template InitiateAccDeclare {{ 1315326Sgblack@eecs.umich.edu Fault 1325326Sgblack@eecs.umich.edu initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1335326Sgblack@eecs.umich.edu}}; 1345326Sgblack@eecs.umich.edu 1355326Sgblack@eecs.umich.edu 1365326Sgblack@eecs.umich.edudef template CompleteAccDeclare {{ 1375326Sgblack@eecs.umich.edu Fault 1384863Sgblack@eecs.umich.edu completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 1394863Sgblack@eecs.umich.edu}}; 1404863Sgblack@eecs.umich.edu 1414863Sgblack@eecs.umich.edudef template LoadStoreConstructor {{ 1424863Sgblack@eecs.umich.edu %(class_name)s::%(class_name)s(ExtMachInst machInst): 1434620Sgblack@eecs.umich.edu %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 1445149Sgblack@eecs.umich.edu { 1455149Sgblack@eecs.umich.edu %(constructor)s; 1466345Sgblack@eecs.umich.edu } 1475294Sgblack@eecs.umich.edu}}; 1485294Sgblack@eecs.umich.edu 1496345Sgblack@eecs.umich.edudef template EACompExecute {{ 1505149Sgblack@eecs.umich.edu Fault 1515906Sgblack@eecs.umich.edu %(class_name)s::eaComp(CPU_EXEC_CONTEXT *xc, 1525906Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 1536345Sgblack@eecs.umich.edu { 1546345Sgblack@eecs.umich.edu Addr EA; 1554615Sgblack@eecs.umich.edu Fault fault = NoFault; 1566457Sgblack@eecs.umich.edu 1576457Sgblack@eecs.umich.edu %(op_decl)s; 1586457Sgblack@eecs.umich.edu %(op_rd)s; 1596457Sgblack@eecs.umich.edu %(ea_code)s; 1605854Sgblack@eecs.umich.edu 1616345Sgblack@eecs.umich.edu if (fault == NoFault) { 1625241Sgblack@eecs.umich.edu %(op_wb)s; 1635426Sgblack@eecs.umich.edu xc->setEA(EA); 1645426Sgblack@eecs.umich.edu } 1654686Sgblack@eecs.umich.edu 1664686Sgblack@eecs.umich.edu return fault; 1674686Sgblack@eecs.umich.edu } 1684953Sgblack@eecs.umich.edu}}; 1694686Sgblack@eecs.umich.edu 1704686Sgblack@eecs.umich.edulet {{ 1714686Sgblack@eecs.umich.edudef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 1724686Sgblack@eecs.umich.edu base_class, postacc_code='', decode_template=BasicDecode, 1734953Sgblack@eecs.umich.edu exec_template_base=''): 1744953Sgblack@eecs.umich.edu # Make sure flags are in lists (convert to lists if not). 1754686Sgblack@eecs.umich.edu mem_flags = makeList(mem_flags) 1764686Sgblack@eecs.umich.edu inst_flags = makeList(inst_flags) # + ['IsNonSpeculative'] 1774686Sgblack@eecs.umich.edu 1784686Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, base_class, 1795682Sgblack@eecs.umich.edu { 'ea_code':ea_code, 'memacc_code':memacc_code, 1805682Sgblack@eecs.umich.edu 'postacc_code':postacc_code }, inst_flags) 1815682Sgblack@eecs.umich.edu 1826345Sgblack@eecs.umich.edu if mem_flags: 1835682Sgblack@eecs.umich.edu mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 1846799Sgblack@eecs.umich.edu s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 1856799Sgblack@eecs.umich.edu iop.constructor += s 1866799Sgblack@eecs.umich.edu 1874615Sgblack@eecs.umich.edu # select templates 1884615Sgblack@eecs.umich.edu 1894615Sgblack@eecs.umich.edu # The InitiateAcc template is the same for StoreCond templates as the 1904615Sgblack@eecs.umich.edu # corresponding Store template.. 1914615Sgblack@eecs.umich.edu StoreCondInitiateAcc = StoreInitiateAcc 1924615Sgblack@eecs.umich.edu 1934615Sgblack@eecs.umich.edu fullExecTemplate = eval(exec_template_base + 'Execute') 1945930Sgblack@eecs.umich.edu initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 1955291Sgblack@eecs.umich.edu completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 1965291Sgblack@eecs.umich.edu 1975291Sgblack@eecs.umich.edu # (header_output, decoder_output, decode_block, exec_output) 1985291Sgblack@eecs.umich.edu return (LoadStoreDeclare.subst(iop), 1995291Sgblack@eecs.umich.edu LoadStoreConstructor.subst(iop), 2005291Sgblack@eecs.umich.edu decode_template.subst(iop), 2015161Sgblack@eecs.umich.edu fullExecTemplate.subst(iop) + 2025161Sgblack@eecs.umich.edu EACompExecute.subst(iop) + 2035161Sgblack@eecs.umich.edu initiateAccTemplate.subst(iop) + 2045161Sgblack@eecs.umich.edu completeAccTemplate.subst(iop)) 2055161Sgblack@eecs.umich.edu}}; 2065008Sgblack@eecs.umich.edu 2075008Sgblack@eecs.umich.edudef template LoadExecute {{ 2085008Sgblack@eecs.umich.edu Fault 2095008Sgblack@eecs.umich.edu %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 2105008Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 2115667Sgblack@eecs.umich.edu { 2125667Sgblack@eecs.umich.edu Addr EA; 2135667Sgblack@eecs.umich.edu Fault fault = NoFault; 2145667Sgblack@eecs.umich.edu 2155667Sgblack@eecs.umich.edu %(op_decl)s; 2165676Sgblack@eecs.umich.edu %(op_rd)s; 2175676Sgblack@eecs.umich.edu %(ea_code)s; 2185676Sgblack@eecs.umich.edu 2195676Sgblack@eecs.umich.edu if (fault == NoFault) { 2205676Sgblack@eecs.umich.edu fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 2215082Sgblack@eecs.umich.edu %(memacc_code)s; 2226345Sgblack@eecs.umich.edu } 2235082Sgblack@eecs.umich.edu 2245082Sgblack@eecs.umich.edu if (fault == NoFault) { 2256618Sgblack@eecs.umich.edu %(op_wb)s; 2266618Sgblack@eecs.umich.edu } 2275082Sgblack@eecs.umich.edu 2284528Sgblack@eecs.umich.edu return fault; 2295666Sgblack@eecs.umich.edu } 2305666Sgblack@eecs.umich.edu}}; 2315666Sgblack@eecs.umich.edu 2324528Sgblack@eecs.umich.edudef template LoadInitiateAcc {{ 233 Fault 234 %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc, 235 Trace::InstRecord *traceData) const 236 { 237 Addr EA; 238 Fault fault = NoFault; 239 240 %(op_src_decl)s; 241 %(op_rd)s; 242 %(ea_code)s; 243 244 if (fault == NoFault) { 245 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 246 } 247 248 return fault; 249 } 250}}; 251 252def template LoadCompleteAcc {{ 253 Fault 254 %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc, 255 Trace::InstRecord *traceData) const 256 { 257 Fault fault = NoFault; 258 259 %(op_decl)s; 260 %(op_rd)s; 261 262 getMem(pkt, Mem, traceData); 263 264 if (fault == NoFault) { 265 %(memacc_code)s; 266 } 267 268 if (fault == NoFault) { 269 %(op_wb)s; 270 } 271 272 return fault; 273 } 274}}; 275 276def template StoreExecute {{ 277 Fault 278 %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 279 Trace::InstRecord *traceData) const 280 { 281 Addr EA; 282 Fault fault = NoFault; 283 284 %(op_decl)s; 285 %(op_rd)s; 286 %(ea_code)s; 287 288 if (fault == NoFault) { 289 %(memacc_code)s; 290 } 291 292 if (fault == NoFault) { 293 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 294 nullptr); 295 } 296 297 if (fault == NoFault) { 298 %(postacc_code)s; 299 } 300 301 if (fault == NoFault) { 302 %(op_wb)s; 303 } 304 305 return fault; 306 } 307}}; 308 309def template StoreInitiateAcc {{ 310 Fault 311 %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc, 312 Trace::InstRecord *traceData) const 313 { 314 Addr EA; 315 Fault fault = NoFault; 316 317 %(op_decl)s; 318 %(op_rd)s; 319 %(ea_code)s; 320 321 if (fault == NoFault) { 322 %(memacc_code)s; 323 } 324 325 if (fault == NoFault) { 326 fault = writeMemTiming(xc, traceData, Mem, EA, 327 memAccessFlags, nullptr); 328 } 329 330 if (fault == NoFault) { 331 %(op_wb)s; 332 } 333 334 return fault; 335 } 336}}; 337 338def template StoreCompleteAcc {{ 339 Fault 340 %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc, 341 Trace::InstRecord *traceData) const 342 { 343 return NoFault; 344 } 345}}; 346 347def template StoreCondExecute {{ 348 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 349 Trace::InstRecord *traceData) const 350 { 351 Addr EA; 352 Fault fault = NoFault; 353 uint64_t result; 354 355 %(op_decl)s; 356 %(op_rd)s; 357 %(ea_code)s; 358 359 if (fault == NoFault) { 360 %(memacc_code)s; 361 } 362 363 if (fault == NoFault) { 364 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 365 &result); 366 // RISC-V has the opposite convention gem5 has for success flags, 367 // so we invert the result here. 368 result = !result; 369 } 370 371 if (fault == NoFault) { 372 %(postacc_code)s; 373 } 374 375 if (fault == NoFault) { 376 %(op_wb)s; 377 } 378 379 return fault; 380 } 381}}; 382 383def template StoreCondCompleteAcc {{ 384 Fault %(class_name)s::completeAcc(Packet *pkt, CPU_EXEC_CONTEXT *xc, 385 Trace::InstRecord *traceData) const 386 { 387 Fault fault = NoFault; 388 389 %(op_dest_decl)s; 390 391 // RISC-V has the opposite convention gem5 has for success flags, 392 // so we invert the result here. 393 uint64_t result = !pkt->req->getExtraData(); 394 395 if (fault == NoFault) { 396 %(postacc_code)s; 397 } 398 399 if (fault == NoFault) { 400 %(op_wb)s; 401 } 402 403 return fault; 404 } 405}}; 406 407def format Load(memacc_code, ea_code = {{EA = Rs1 + ldisp;}}, mem_flags=[], 408 inst_flags=[]) {{ 409 (header_output, decoder_output, decode_block, exec_output) = \ 410 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 411 'Load', exec_template_base='Load') 412}}; 413 414def format Store(memacc_code, ea_code={{EA = Rs1 + sdisp;}}, mem_flags=[], 415 inst_flags=[]) {{ 416 (header_output, decoder_output, decode_block, exec_output) = \ 417 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 418 'Store', exec_template_base='Store') 419}}; 420 421def format StoreCond(memacc_code, postacc_code, ea_code={{EA = Rs1;}}, 422 mem_flags=[], inst_flags=[], aq=0, rl=0) {{ 423 if aq: 424 mem_flags = makeList(mem_flags) + ["ACQUIRE"] 425 if rl: 426 mem_flags = makeList(mem_flags) + ["RELEASE"] 427 (header_output, decoder_output, decode_block, exec_output) = LoadStoreBase( 428 name, Name, ea_code, memacc_code, mem_flags, inst_flags, 'Store', 429 postacc_code, exec_template_base='StoreCond') 430}}; 431 432def format LoadReserved(memacc_code, ea_code={{EA = Rs1;}}, mem_flags=[], 433 inst_flags=[], aq=0, rl=0) {{ 434 if aq: 435 mem_flags = makeList(mem_flags) + ["ACQUIRE"] 436 if rl: 437 mem_flags = makeList(mem_flags) + ["RELEASE"] 438 (header_output, decoder_output, decode_block, exec_output) = LoadStoreBase( 439 name, Name, ea_code, memacc_code, mem_flags, inst_flags, 'Load', 440 exec_template_base='Load') 441}}; 442