amo.isa (11726:11950d45640b) | amo.isa (11965:41e942451f59) |
---|---|
1// -*- mode:c++ -*- 2 3// Copyright (c) 2015 Riscv Developers 4// Copyright (c) 2016 The University of Virginia 5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions are --- 20 unchanged lines hidden (view full) --- 29// 30// Authors: Alec Roelke 31 32//////////////////////////////////////////////////////////////////// 33// 34// Atomic memory operation instructions 35// 36output header {{ | 1// -*- mode:c++ -*- 2 3// Copyright (c) 2015 Riscv Developers 4// Copyright (c) 2016 The University of Virginia 5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions are --- 20 unchanged lines hidden (view full) --- 29// 30// Authors: Alec Roelke 31 32//////////////////////////////////////////////////////////////////// 33// 34// Atomic memory operation instructions 35// 36output header {{ |
37 class LoadReserved : public RiscvStaticInst 38 { 39 protected: 40 Request::Flags memAccessFlags; 41 42 LoadReserved(const char *mnem, ExtMachInst _machInst, 43 OpClass __opClass) 44 : RiscvStaticInst(mnem, _machInst, __opClass) 45 {} 46 47 std::string 48 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 49 }; 50 51 class StoreCond : public RiscvStaticInst 52 { 53 protected: 54 Request::Flags memAccessFlags; 55 56 StoreCond(const char* mnem, ExtMachInst _machInst, OpClass __opClass) 57 : RiscvStaticInst(mnem, _machInst, __opClass) 58 {} 59 60 std::string 61 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 62 }; 63 |
|
37 class AtomicMemOp : public RiscvMacroInst 38 { 39 protected: 40 /// Constructor 41 // Each AtomicMemOp has a load and a store phase 42 AtomicMemOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 43 : RiscvMacroInst(mnem, _machInst, __opClass) 44 {} --- 15 unchanged lines hidden (view full) --- 60 {} 61 62 std::string generateDisassembly(Addr pc, 63 const SymbolTable *symtab) const; 64 }; 65}}; 66 67output decoder {{ | 64 class AtomicMemOp : public RiscvMacroInst 65 { 66 protected: 67 /// Constructor 68 // Each AtomicMemOp has a load and a store phase 69 AtomicMemOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 70 : RiscvMacroInst(mnem, _machInst, __opClass) 71 {} --- 15 unchanged lines hidden (view full) --- 87 {} 88 89 std::string generateDisassembly(Addr pc, 90 const SymbolTable *symtab) const; 91 }; 92}}; 93 94output decoder {{ |
95 std::string LoadReserved::generateDisassembly(Addr pc, 96 const SymbolTable *symtab) const 97 { 98 std::stringstream ss; 99 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", (" 100 << regName(_srcRegIdx[0]) << ')'; 101 return ss.str(); 102 } 103 104 std::string StoreCond::generateDisassembly(Addr pc, 105 const SymbolTable *symtab) const 106 { 107 std::stringstream ss; 108 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " 109 << regName(_srcRegIdx[1]) << ", (" 110 << regName(_srcRegIdx[0]) << ')'; 111 return ss.str(); 112 } 113 |
|
68 std::string AtomicMemOp::generateDisassembly(Addr pc, 69 const SymbolTable *symtab) const 70 { 71 std::stringstream ss; | 114 std::string AtomicMemOp::generateDisassembly(Addr pc, 115 const SymbolTable *symtab) const 116 { 117 std::stringstream ss; |
72 ss << csprintf("0x%08x", machInst) << ' '; | |
73 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " 74 << regName(_srcRegIdx[1]) << ", (" 75 << regName(_srcRegIdx[0]) << ')'; 76 return ss.str(); 77 } 78 79 std::string AtomicMemOpMicro::generateDisassembly(Addr pc, 80 const SymbolTable *symtab) const 81 { 82 std::stringstream ss; 83 ss << csprintf("0x%08x", machInst) << ' ' << mnemonic; 84 return ss.str(); 85 } 86}}; 87 | 118 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " 119 << regName(_srcRegIdx[1]) << ", (" 120 << regName(_srcRegIdx[0]) << ')'; 121 return ss.str(); 122 } 123 124 std::string AtomicMemOpMicro::generateDisassembly(Addr pc, 125 const SymbolTable *symtab) const 126 { 127 std::stringstream ss; 128 ss << csprintf("0x%08x", machInst) << ' ' << mnemonic; 129 return ss.str(); 130 } 131}}; 132 |
133def template LRSCDeclare {{ 134 class %(class_name)s : public %(base_class)s 135 { 136 public: 137 %(class_name)s(ExtMachInst machInst); 138 139 %(BasicExecDeclare)s 140 141 %(EACompDeclare)s 142 143 %(InitiateAccDeclare)s 144 145 %(CompleteAccDeclare)s 146 }; 147}}; 148 |
|
88def template AtomicMemOpDeclare {{ 89 /** 90 * Static instruction class for an AtomicMemOp operation 91 */ 92 class %(class_name)s : public %(base_class)s 93 { 94 public: 95 // Constructor --- 28 unchanged lines hidden (view full) --- 124 125 %(InitiateAccDeclare)s 126 127 %(CompleteAccDeclare)s 128 }; 129 }; 130}}; 131 | 149def template AtomicMemOpDeclare {{ 150 /** 151 * Static instruction class for an AtomicMemOp operation 152 */ 153 class %(class_name)s : public %(base_class)s 154 { 155 public: 156 // Constructor --- 28 unchanged lines hidden (view full) --- 185 186 %(InitiateAccDeclare)s 187 188 %(CompleteAccDeclare)s 189 }; 190 }; 191}}; 192 |
193def template LRSCConstructor {{ 194 %(class_name)s::%(class_name)s(ExtMachInst machInst): 195 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 196 { 197 %(constructor)s; 198 if (AQ) 199 memAccessFlags = memAccessFlags | Request::ACQUIRE; 200 if (RL) 201 memAccessFlags = memAccessFlags | Request::RELEASE; 202 } 203}}; 204 |
|
132def template AtomicMemOpMacroConstructor {{ 133 %(class_name)s::%(class_name)s(ExtMachInst machInst) 134 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 135 { 136 %(constructor)s; 137 microops = {new %(class_name)sLoad(machInst, this), 138 new %(class_name)sStore(machInst, this)}; 139 } --- 24 unchanged lines hidden (view full) --- 164 memAccessFlags = Request::RELEASE; 165 } 166}}; 167 168def template AtomicMemOpMacroDecode {{ 169 return new %(class_name)s(machInst); 170}}; 171 | 205def template AtomicMemOpMacroConstructor {{ 206 %(class_name)s::%(class_name)s(ExtMachInst machInst) 207 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 208 { 209 %(constructor)s; 210 microops = {new %(class_name)sLoad(machInst, this), 211 new %(class_name)sStore(machInst, this)}; 212 } --- 24 unchanged lines hidden (view full) --- 237 memAccessFlags = Request::RELEASE; 238 } 239}}; 240 241def template AtomicMemOpMacroDecode {{ 242 return new %(class_name)s(machInst); 243}}; 244 |
245def template LoadReservedExecute {{ 246 Fault 247 %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 248 Trace::InstRecord *traceData) const 249 { 250 Addr EA; 251 Fault fault = NoFault; 252 253 %(op_decl)s; 254 %(op_rd)s; 255 %(ea_code)s; 256 257 if (fault == NoFault) { 258 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 259 %(memacc_code)s; 260 } 261 262 if (fault == NoFault) { 263 %(op_wb)s; 264 } 265 266 return fault; 267 } 268}}; 269 270def template StoreCondExecute {{ 271 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 272 Trace::InstRecord *traceData) const 273 { 274 Addr EA; 275 Fault fault = NoFault; 276 uint64_t result; 277 278 %(op_decl)s; 279 %(op_rd)s; 280 %(ea_code)s; 281 282 if (fault == NoFault) { 283 %(memacc_code)s; 284 } 285 286 if (fault == NoFault) { 287 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 288 &result); 289 // RISC-V has the opposite convention gem5 has for success flags, 290 // so we invert the result here. 291 result = !result; 292 } 293 294 if (fault == NoFault) { 295 %(postacc_code)s; 296 } 297 298 if (fault == NoFault) { 299 %(op_wb)s; 300 } 301 302 return fault; 303 } 304}}; 305 |
|
172def template AtomicMemOpLoadExecute {{ 173 Fault %(class_name)s::%(class_name)sLoad::execute(CPU_EXEC_CONTEXT *xc, 174 Trace::InstRecord *traceData) const 175 { 176 Addr EA; 177 Fault fault = NoFault; 178 179 %(op_decl)s; --- 39 unchanged lines hidden (view full) --- 219 if (fault == NoFault) { 220 %(op_wb)s; 221 } 222 223 return fault; 224 } 225}}; 226 | 306def template AtomicMemOpLoadExecute {{ 307 Fault %(class_name)s::%(class_name)sLoad::execute(CPU_EXEC_CONTEXT *xc, 308 Trace::InstRecord *traceData) const 309 { 310 Addr EA; 311 Fault fault = NoFault; 312 313 %(op_decl)s; --- 39 unchanged lines hidden (view full) --- 353 if (fault == NoFault) { 354 %(op_wb)s; 355 } 356 357 return fault; 358 } 359}}; 360 |
361def template LRSCEACompExecute {{ 362 Fault 363 %(class_name)s::eaComp(CPU_EXEC_CONTEXT *xc, 364 Trace::InstRecord *traceData) const 365 { 366 Addr EA; 367 Fault fault = NoFault; 368 369 %(op_decl)s; 370 %(op_rd)s; 371 %(ea_code)s; 372 373 if (fault == NoFault) { 374 %(op_wb)s; 375 xc->setEA(EA); 376 } 377 378 return fault; 379 } 380}}; 381 |
|
227def template AtomicMemOpLoadEACompExecute {{ 228 Fault %(class_name)s::%(class_name)sLoad::eaComp(CPU_EXEC_CONTEXT *xc, 229 Trace::InstRecord *traceData) const 230 { 231 Addr EA; 232 Fault fault = NoFault; 233 234 %(op_decl)s; --- 24 unchanged lines hidden (view full) --- 259 %(op_wb)s; 260 xc->setEA(EA); 261 } 262 263 return fault; 264 } 265}}; 266 | 382def template AtomicMemOpLoadEACompExecute {{ 383 Fault %(class_name)s::%(class_name)sLoad::eaComp(CPU_EXEC_CONTEXT *xc, 384 Trace::InstRecord *traceData) const 385 { 386 Addr EA; 387 Fault fault = NoFault; 388 389 %(op_decl)s; --- 24 unchanged lines hidden (view full) --- 414 %(op_wb)s; 415 xc->setEA(EA); 416 } 417 418 return fault; 419 } 420}}; 421 |
422def template LoadReservedInitiateAcc {{ 423 Fault 424 %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc, 425 Trace::InstRecord *traceData) const 426 { 427 Addr EA; 428 Fault fault = NoFault; 429 430 %(op_src_decl)s; 431 %(op_rd)s; 432 %(ea_code)s; 433 434 if (fault == NoFault) { 435 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 436 } 437 438 return fault; 439 } 440}}; 441 442def template StoreCondInitiateAcc {{ 443 Fault 444 %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc, 445 Trace::InstRecord *traceData) const 446 { 447 Addr EA; 448 Fault fault = NoFault; 449 450 %(op_decl)s; 451 %(op_rd)s; 452 %(ea_code)s; 453 454 if (fault == NoFault) { 455 %(memacc_code)s; 456 } 457 458 if (fault == NoFault) { 459 fault = writeMemTiming(xc, traceData, Mem, EA, 460 memAccessFlags, nullptr); 461 } 462 463 if (fault == NoFault) { 464 %(op_wb)s; 465 } 466 467 return fault; 468 } 469}}; 470 |
|
267def template AtomicMemOpLoadInitiateAcc {{ 268 Fault %(class_name)s::%(class_name)sLoad::initiateAcc(CPU_EXEC_CONTEXT *xc, 269 Trace::InstRecord *traceData) const 270 { 271 Addr EA; 272 Fault fault = NoFault; 273 274 %(op_src_decl)s; --- 31 unchanged lines hidden (view full) --- 306 if (fault == NoFault) { 307 %(op_wb)s; 308 } 309 310 return fault; 311 } 312}}; 313 | 471def template AtomicMemOpLoadInitiateAcc {{ 472 Fault %(class_name)s::%(class_name)sLoad::initiateAcc(CPU_EXEC_CONTEXT *xc, 473 Trace::InstRecord *traceData) const 474 { 475 Addr EA; 476 Fault fault = NoFault; 477 478 %(op_src_decl)s; --- 31 unchanged lines hidden (view full) --- 510 if (fault == NoFault) { 511 %(op_wb)s; 512 } 513 514 return fault; 515 } 516}}; 517 |
518def template LoadReservedCompleteAcc {{ 519 Fault 520 %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc, 521 Trace::InstRecord *traceData) const 522 { 523 Fault fault = NoFault; 524 525 %(op_decl)s; 526 %(op_rd)s; 527 528 getMem(pkt, Mem, traceData); 529 530 if (fault == NoFault) { 531 %(memacc_code)s; 532 } 533 534 if (fault == NoFault) { 535 %(op_wb)s; 536 } 537 538 return fault; 539 } 540}}; 541 542def template StoreCondCompleteAcc {{ 543 Fault %(class_name)s::completeAcc(Packet *pkt, CPU_EXEC_CONTEXT *xc, 544 Trace::InstRecord *traceData) const 545 { 546 Fault fault = NoFault; 547 548 %(op_dest_decl)s; 549 550 // RISC-V has the opposite convention gem5 has for success flags, 551 // so we invert the result here. 552 uint64_t result = !pkt->req->getExtraData(); 553 554 if (fault == NoFault) { 555 %(postacc_code)s; 556 } 557 558 if (fault == NoFault) { 559 %(op_wb)s; 560 } 561 562 return fault; 563 } 564}}; 565 |
|
314def template AtomicMemOpLoadCompleteAcc {{ 315 Fault %(class_name)s::%(class_name)sLoad::completeAcc(PacketPtr pkt, 316 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 317 { 318 Fault fault = NoFault; 319 320 %(op_decl)s; 321 %(op_rd)s; --- 15 unchanged lines hidden (view full) --- 337def template AtomicMemOpStoreCompleteAcc {{ 338 Fault %(class_name)s::%(class_name)sStore::completeAcc(PacketPtr pkt, 339 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 340 { 341 return NoFault; 342 } 343}}; 344 | 566def template AtomicMemOpLoadCompleteAcc {{ 567 Fault %(class_name)s::%(class_name)sLoad::completeAcc(PacketPtr pkt, 568 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 569 { 570 Fault fault = NoFault; 571 572 %(op_decl)s; 573 %(op_rd)s; --- 15 unchanged lines hidden (view full) --- 589def template AtomicMemOpStoreCompleteAcc {{ 590 Fault %(class_name)s::%(class_name)sStore::completeAcc(PacketPtr pkt, 591 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 592 { 593 return NoFault; 594 } 595}}; 596 |
597def format LoadReserved(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 598 mem_flags=[], inst_flags=[]) {{ 599 mem_flags = makeList(mem_flags) 600 inst_flags = makeList(inst_flags) 601 iop = InstObjParams(name, Name, 'LoadReserved', 602 {'ea_code': ea_code, 'memacc_code': memacc_code, 603 'postacc_code': postacc_code}, inst_flags) 604 iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 605 '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 606 607 header_output = LRSCDeclare.subst(iop) 608 decoder_output = LRSCConstructor.subst(iop) 609 decode_block = BasicDecode.subst(iop) 610 exec_output = LoadReservedExecute.subst(iop) \ 611 + LRSCEACompExecute.subst(iop) \ 612 + LoadReservedInitiateAcc.subst(iop) \ 613 + LoadReservedCompleteAcc.subst(iop) 614}}; 615 616def format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 617 mem_flags=[], inst_flags=[]) {{ 618 mem_flags = makeList(mem_flags) 619 inst_flags = makeList(inst_flags) 620 iop = InstObjParams(name, Name, 'StoreCond', 621 {'ea_code': ea_code, 'memacc_code': memacc_code, 622 'postacc_code': postacc_code}, inst_flags) 623 iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 624 '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 625 626 header_output = LRSCDeclare.subst(iop) 627 decoder_output = LRSCConstructor.subst(iop) 628 decode_block = BasicDecode.subst(iop) 629 exec_output = StoreCondExecute.subst(iop) \ 630 + LRSCEACompExecute.subst(iop) \ 631 + StoreCondInitiateAcc.subst(iop) \ 632 + StoreCondCompleteAcc.subst(iop) 633}}; 634 |
|
345def format AtomicMemOp(load_code, store_code, ea_code, load_flags=[], 346 store_flags=[], inst_flags=[]) {{ 347 macro_iop = InstObjParams(name, Name, 'AtomicMemOp', ea_code, inst_flags) 348 header_output = AtomicMemOpDeclare.subst(macro_iop) 349 decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop) 350 decode_block = AtomicMemOpMacroDecode.subst(macro_iop) 351 exec_output = '' 352 --- 18 unchanged lines hidden --- | 635def format AtomicMemOp(load_code, store_code, ea_code, load_flags=[], 636 store_flags=[], inst_flags=[]) {{ 637 macro_iop = InstObjParams(name, Name, 'AtomicMemOp', ea_code, inst_flags) 638 header_output = AtomicMemOpDeclare.subst(macro_iop) 639 decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop) 640 decode_block = AtomicMemOpMacroDecode.subst(macro_iop) 641 exec_output = '' 642 --- 18 unchanged lines hidden --- |