amo.isa (12482:35461496d012) | amo.isa (13653:079472978bca) |
---|---|
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 --- 15 unchanged lines hidden (view full) --- 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29// 30// Authors: Alec Roelke 31 | 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 --- 15 unchanged lines hidden (view full) --- 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29// 30// Authors: Alec Roelke 31 |
32//////////////////////////////////////////////////////////////////// 33// 34// Atomic memory operation instructions 35// | 32// Declaration templates |
36def template AtomicMemOpDeclare {{ 37 /** 38 * Static instruction class for an AtomicMemOp operation 39 */ 40 class %(class_name)s : public %(base_class)s 41 { 42 public: 43 // Constructor 44 %(class_name)s(ExtMachInst machInst); 45 46 protected: 47 | 33def template AtomicMemOpDeclare {{ 34 /** 35 * Static instruction class for an AtomicMemOp operation 36 */ 37 class %(class_name)s : public %(base_class)s 38 { 39 public: 40 // Constructor 41 %(class_name)s(ExtMachInst machInst); 42 43 protected: 44 |
48 class %(class_name)sLoad : public %(base_class)sMicro | 45 /* 46 * The main RMW part of an AMO 47 */ 48 class %(class_name)sRMW : public %(base_class)sMicro |
49 { 50 public: 51 // Constructor | 49 { 50 public: 51 // Constructor |
52 %(class_name)sLoad(ExtMachInst machInst, %(class_name)s *_p); | 52 %(class_name)sRMW(ExtMachInst machInst, %(class_name)s *_p); |
53 54 Fault execute(ExecContext *, Trace::InstRecord *) const override; 55 Fault initiateAcc(ExecContext *, 56 Trace::InstRecord *) const override; 57 Fault completeAcc(PacketPtr, ExecContext *, 58 Trace::InstRecord *) const override; 59 }; | 53 54 Fault execute(ExecContext *, Trace::InstRecord *) const override; 55 Fault initiateAcc(ExecContext *, 56 Trace::InstRecord *) const override; 57 Fault completeAcc(PacketPtr, ExecContext *, 58 Trace::InstRecord *) const override; 59 }; |
60 }; 61}}; |
|
60 | 62 |
61 class %(class_name)sStore : public %(base_class)sMicro | 63def template LRSCDeclare {{ 64 /** 65 * Static instruction class for an AtomicMemOp operation 66 */ 67 class %(class_name)s : public %(base_class)s 68 { 69 public: 70 // Constructor 71 %(class_name)s(ExtMachInst machInst); 72 73 protected: 74 75 class %(class_name)sMicro : public %(base_class)sMicro |
62 { 63 public: 64 // Constructor | 76 { 77 public: 78 // Constructor |
65 %(class_name)sStore(ExtMachInst machInst, %(class_name)s *_p); | 79 %(class_name)sMicro(ExtMachInst machInst, %(class_name)s *_p); |
66 67 Fault execute(ExecContext *, Trace::InstRecord *) const override; 68 Fault initiateAcc(ExecContext *, 69 Trace::InstRecord *) const override; 70 Fault completeAcc(PacketPtr, ExecContext *, 71 Trace::InstRecord *) const override; 72 }; 73 }; 74}}; 75 | 80 81 Fault execute(ExecContext *, Trace::InstRecord *) const override; 82 Fault initiateAcc(ExecContext *, 83 Trace::InstRecord *) const override; 84 Fault completeAcc(PacketPtr, ExecContext *, 85 Trace::InstRecord *) const override; 86 }; 87 }; 88}}; 89 |
76def template LRSCConstructor {{ | 90// Constructor templates 91def template LRSCMacroConstructor {{ |
77 %(class_name)s::%(class_name)s(ExtMachInst machInst): 78 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 79 { 80 %(constructor)s; | 92 %(class_name)s::%(class_name)s(ExtMachInst machInst): 93 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 94 { 95 %(constructor)s; |
81 if (AQ) 82 memAccessFlags = memAccessFlags | Request::ACQUIRE; 83 if (RL) 84 memAccessFlags = memAccessFlags | Request::RELEASE; | 96 97 StaticInstPtr rel_fence; 98 StaticInstPtr lrsc; 99 StaticInstPtr acq_fence; 100 101 // set up release fence 102 if (RL) { 103 rel_fence = new MemFenceMicro(machInst, No_OpClass); 104 rel_fence->setFlag(IsFirstMicroop); 105 rel_fence->setFlag(IsMemBarrier); 106 rel_fence->setFlag(IsDelayedCommit); 107 } 108 109 // set up atomic rmw op 110 lrsc = new %(class_name)sMicro(machInst, this); 111 112 if (!RL) { 113 lrsc->setFlag(IsFirstMicroop); 114 } 115 116 if (!AQ) { 117 lrsc->setFlag(IsLastMicroop); 118 } else { 119 lrsc->setFlag(IsDelayedCommit); 120 } 121 122 // set up acquire fence 123 if (AQ) { 124 acq_fence = new MemFenceMicro(machInst, No_OpClass); 125 acq_fence->setFlag(IsLastMicroop); 126 acq_fence->setFlag(IsMemBarrier); 127 } 128 129 if (RL && AQ) { 130 microops = {rel_fence, lrsc, acq_fence}; 131 } else if (RL) { 132 microops = {rel_fence, lrsc}; 133 } else if (AQ) { 134 microops = {lrsc, acq_fence}; 135 } else { 136 microops = {lrsc}; 137 } |
85 } 86}}; 87 | 138 } 139}}; 140 |
141def template LRSCMicroConstructor {{ 142 %(class_name)s::%(class_name)sMicro::%(class_name)sMicro( 143 ExtMachInst machInst, %(class_name)s *_p) 144 : %(base_class)sMicro("%(mnemonic)s", machInst, %(op_class)s) 145 { 146 %(constructor)s; 147 } 148}}; 149 |
|
88def template AtomicMemOpMacroConstructor {{ 89 %(class_name)s::%(class_name)s(ExtMachInst machInst) 90 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 91 { 92 %(constructor)s; | 150def template AtomicMemOpMacroConstructor {{ 151 %(class_name)s::%(class_name)s(ExtMachInst machInst) 152 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 153 { 154 %(constructor)s; |
93 microops = {new %(class_name)sLoad(machInst, this), 94 new %(class_name)sStore(machInst, this)}; | 155 156 StaticInstPtr rel_fence; 157 StaticInstPtr rmw_op; 158 StaticInstPtr acq_fence; 159 160 // set up release fence 161 if (RL) { 162 rel_fence = new MemFenceMicro(machInst, No_OpClass); 163 rel_fence->setFlag(IsFirstMicroop); 164 rel_fence->setFlag(IsMemBarrier); 165 rel_fence->setFlag(IsDelayedCommit); 166 } 167 168 // set up atomic rmw op 169 rmw_op = new %(class_name)sRMW(machInst, this); 170 171 if (!RL) { 172 rmw_op->setFlag(IsFirstMicroop); 173 } 174 175 if (!AQ) { 176 rmw_op->setFlag(IsLastMicroop); 177 } else { 178 rmw_op->setFlag(IsDelayedCommit); 179 } 180 181 // set up acquire fence 182 if (AQ) { 183 acq_fence = new MemFenceMicro(machInst, No_OpClass); 184 acq_fence->setFlag(IsLastMicroop); 185 acq_fence->setFlag(IsMemBarrier); 186 } 187 188 if (RL && AQ) { 189 microops = {rel_fence, rmw_op, acq_fence}; 190 } else if (RL) { 191 microops = {rel_fence, rmw_op}; 192 } else if (AQ) { 193 microops = {rmw_op, acq_fence}; 194 } else { 195 microops = {rmw_op}; 196 } |
95 } 96}}; 97 | 197 } 198}}; 199 |
98def template AtomicMemOpLoadConstructor {{ 99 %(class_name)s::%(class_name)sLoad::%(class_name)sLoad( | 200def template AtomicMemOpRMWConstructor {{ 201 %(class_name)s::%(class_name)sRMW::%(class_name)sRMW( |
100 ExtMachInst machInst, %(class_name)s *_p) 101 : %(base_class)s("%(mnemonic)s[l]", machInst, %(op_class)s) 102 { 103 %(constructor)s; | 202 ExtMachInst machInst, %(class_name)s *_p) 203 : %(base_class)s("%(mnemonic)s[l]", machInst, %(op_class)s) 204 { 205 %(constructor)s; |
104 flags[IsFirstMicroop] = true; 105 flags[IsDelayedCommit] = true; 106 if (AQ) 107 memAccessFlags = Request::ACQUIRE; | 206 207 // overwrite default flags 208 flags[IsMemRef] = true; 209 flags[IsLoad] = false; 210 flags[IsStore] = false; 211 flags[IsAtomic] = true; |
108 } 109}}; 110 | 212 } 213}}; 214 |
111def template AtomicMemOpStoreConstructor {{ 112 %(class_name)s::%(class_name)sStore::%(class_name)sStore( 113 ExtMachInst machInst, %(class_name)s *_p) 114 : %(base_class)s("%(mnemonic)s[s]", machInst, %(op_class)s) | 215// execute() templates 216 217def template LoadReservedExecute {{ 218 Fault 219 %(class_name)s::%(class_name)sMicro::execute( 220 ExecContext *xc, Trace::InstRecord *traceData) const |
115 { | 221 { |
116 %(constructor)s; 117 flags[IsLastMicroop] = true; 118 flags[IsNonSpeculative] = true; 119 if (RL) 120 memAccessFlags = Request::RELEASE; | 222 Addr EA; 223 Fault fault = NoFault; 224 225 %(op_decl)s; 226 %(op_rd)s; 227 %(ea_code)s; 228 229 if (fault == NoFault) { 230 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 231 %(memacc_code)s; 232 } 233 234 if (fault == NoFault) { 235 %(op_wb)s; 236 } 237 238 return fault; |
121 } 122}}; 123 124def template StoreCondExecute {{ | 239 } 240}}; 241 242def template StoreCondExecute {{ |
125 Fault %(class_name)s::execute(ExecContext *xc, | 243 Fault %(class_name)s::%(class_name)sMicro::execute(ExecContext *xc, |
126 Trace::InstRecord *traceData) const 127 { 128 Addr EA; 129 Fault fault = NoFault; 130 uint64_t result; 131 132 %(op_decl)s; 133 %(op_rd)s; --- 18 unchanged lines hidden (view full) --- 152 if (fault == NoFault) { 153 %(op_wb)s; 154 } 155 156 return fault; 157 } 158}}; 159 | 244 Trace::InstRecord *traceData) const 245 { 246 Addr EA; 247 Fault fault = NoFault; 248 uint64_t result; 249 250 %(op_decl)s; 251 %(op_rd)s; --- 18 unchanged lines hidden (view full) --- 270 if (fault == NoFault) { 271 %(op_wb)s; 272 } 273 274 return fault; 275 } 276}}; 277 |
160def template AtomicMemOpLoadExecute {{ 161 Fault %(class_name)s::%(class_name)sLoad::execute(ExecContext *xc, | 278def template AtomicMemOpRMWExecute {{ 279 Fault %(class_name)s::%(class_name)sRMW::execute(ExecContext *xc, |
162 Trace::InstRecord *traceData) const 163 { 164 Addr EA; 165 Fault fault = NoFault; 166 167 %(op_decl)s; 168 %(op_rd)s; 169 %(ea_code)s; | 280 Trace::InstRecord *traceData) const 281 { 282 Addr EA; 283 Fault fault = NoFault; 284 285 %(op_decl)s; 286 %(op_rd)s; 287 %(ea_code)s; |
288 %(amoop_code)s; |
|
170 | 289 |
290 assert(amo_op); 291 |
|
171 if (fault == NoFault) { | 292 if (fault == NoFault) { |
172 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); | 293 fault = amoMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 294 amo_op); 295 %(memacc_code)s; |
173 } 174 175 if (fault == NoFault) { | 296 } 297 298 if (fault == NoFault) { |
176 %(code)s; | 299 %(postacc_code)s; |
177 } 178 179 if (fault == NoFault) { 180 %(op_wb)s; 181 } 182 183 return fault; 184 } 185}}; 186 | 300 } 301 302 if (fault == NoFault) { 303 %(op_wb)s; 304 } 305 306 return fault; 307 } 308}}; 309 |
187def template AtomicMemOpStoreExecute {{ 188 Fault %(class_name)s::%(class_name)sStore::execute(ExecContext *xc, | 310// initiateAcc() templates 311 312def template LoadReservedInitiateAcc {{ 313 Fault 314 %(class_name)s::%(class_name)sMicro::initiateAcc(ExecContext *xc, |
189 Trace::InstRecord *traceData) const 190 { 191 Addr EA; 192 Fault fault = NoFault; 193 | 315 Trace::InstRecord *traceData) const 316 { 317 Addr EA; 318 Fault fault = NoFault; 319 |
320 %(op_src_decl)s; 321 %(op_rd)s; 322 %(ea_code)s; 323 324 if (fault == NoFault) { 325 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 326 } 327 328 return fault; 329 } 330}}; 331 332def template StoreCondInitiateAcc {{ 333 Fault 334 %(class_name)s::%(class_name)sMicro::initiateAcc(ExecContext *xc, 335 Trace::InstRecord *traceData) const 336 { 337 Addr EA; 338 Fault fault = NoFault; 339 |
|
194 %(op_decl)s; 195 %(op_rd)s; 196 %(ea_code)s; 197 198 if (fault == NoFault) { | 340 %(op_decl)s; 341 %(op_rd)s; 342 %(ea_code)s; 343 344 if (fault == NoFault) { |
199 %(code)s; | 345 %(memacc_code)s; |
200 } 201 202 if (fault == NoFault) { | 346 } 347 348 if (fault == NoFault) { |
203 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 204 nullptr); | 349 fault = writeMemTiming(xc, traceData, Mem, EA, 350 memAccessFlags, nullptr); |
205 } 206 207 if (fault == NoFault) { 208 %(op_wb)s; 209 } 210 211 return fault; 212 } 213}}; 214 | 351 } 352 353 if (fault == NoFault) { 354 %(op_wb)s; 355 } 356 357 return fault; 358 } 359}}; 360 |
215def template AtomicMemOpLoadInitiateAcc {{ 216 Fault %(class_name)s::%(class_name)sLoad::initiateAcc(ExecContext *xc, | 361def template AtomicMemOpRMWInitiateAcc {{ 362 Fault 363 %(class_name)s::%(class_name)sRMW::initiateAcc(ExecContext *xc, |
217 Trace::InstRecord *traceData) const 218 { 219 Addr EA; 220 Fault fault = NoFault; 221 222 %(op_src_decl)s; 223 %(op_rd)s; 224 %(ea_code)s; | 364 Trace::InstRecord *traceData) const 365 { 366 Addr EA; 367 Fault fault = NoFault; 368 369 %(op_src_decl)s; 370 %(op_rd)s; 371 %(ea_code)s; |
372 %(amoop_code)s; |
|
225 | 373 |
374 assert(amo_op); 375 |
|
226 if (fault == NoFault) { | 376 if (fault == NoFault) { |
227 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); | 377 fault = initiateMemAMO(xc, traceData, EA, Mem, memAccessFlags, 378 amo_op); |
228 } 229 230 return fault; 231 } 232}}; 233 | 379 } 380 381 return fault; 382 } 383}}; 384 |
234def template AtomicMemOpStoreInitiateAcc {{ 235 Fault %(class_name)s::%(class_name)sStore::initiateAcc( | 385// completeAcc() templates 386 387def template LoadReservedCompleteAcc {{ 388 Fault 389 %(class_name)s::%(class_name)sMicro::completeAcc(PacketPtr pkt, |
236 ExecContext *xc, Trace::InstRecord *traceData) const 237 { | 390 ExecContext *xc, Trace::InstRecord *traceData) const 391 { |
238 Addr EA; | |
239 Fault fault = NoFault; 240 241 %(op_decl)s; 242 %(op_rd)s; | 392 Fault fault = NoFault; 393 394 %(op_decl)s; 395 %(op_rd)s; |
243 %(ea_code)s; | |
244 | 396 |
245 if (fault == NoFault) { 246 %(code)s; 247 } | 397 getMem(pkt, Mem, traceData); |
248 249 if (fault == NoFault) { | 398 399 if (fault == NoFault) { |
250 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 251 nullptr); | 400 %(memacc_code)s; |
252 } 253 254 if (fault == NoFault) { 255 %(op_wb)s; 256 } 257 258 return fault; 259 } 260}}; 261 262def template StoreCondCompleteAcc {{ | 401 } 402 403 if (fault == NoFault) { 404 %(op_wb)s; 405 } 406 407 return fault; 408 } 409}}; 410 411def template StoreCondCompleteAcc {{ |
263 Fault %(class_name)s::completeAcc(Packet *pkt, ExecContext *xc, 264 Trace::InstRecord *traceData) const | 412 Fault %(class_name)s::%(class_name)sMicro::completeAcc(Packet *pkt, 413 ExecContext *xc, Trace::InstRecord *traceData) const |
265 { 266 Fault fault = NoFault; 267 268 %(op_dest_decl)s; 269 270 // RISC-V has the opposite convention gem5 has for success flags, 271 // so we invert the result here. 272 uint64_t result = !pkt->req->getExtraData(); --- 5 unchanged lines hidden (view full) --- 278 if (fault == NoFault) { 279 %(op_wb)s; 280 } 281 282 return fault; 283 } 284}}; 285 | 414 { 415 Fault fault = NoFault; 416 417 %(op_dest_decl)s; 418 419 // RISC-V has the opposite convention gem5 has for success flags, 420 // so we invert the result here. 421 uint64_t result = !pkt->req->getExtraData(); --- 5 unchanged lines hidden (view full) --- 427 if (fault == NoFault) { 428 %(op_wb)s; 429 } 430 431 return fault; 432 } 433}}; 434 |
286def template AtomicMemOpLoadCompleteAcc {{ 287 Fault %(class_name)s::%(class_name)sLoad::completeAcc(PacketPtr pkt, | 435def template AtomicMemOpRMWCompleteAcc {{ 436 Fault %(class_name)s::%(class_name)sRMW::completeAcc(Packet *pkt, |
288 ExecContext *xc, Trace::InstRecord *traceData) const 289 { 290 Fault fault = NoFault; 291 292 %(op_decl)s; 293 %(op_rd)s; 294 295 getMem(pkt, Mem, traceData); 296 297 if (fault == NoFault) { | 437 ExecContext *xc, Trace::InstRecord *traceData) const 438 { 439 Fault fault = NoFault; 440 441 %(op_decl)s; 442 %(op_rd)s; 443 444 getMem(pkt, Mem, traceData); 445 446 if (fault == NoFault) { |
298 %(code)s; | 447 %(memacc_code)s; |
299 } 300 301 if (fault == NoFault) { 302 %(op_wb)s; 303 } 304 305 return fault; 306 } 307}}; 308 | 448 } 449 450 if (fault == NoFault) { 451 %(op_wb)s; 452 } 453 454 return fault; 455 } 456}}; 457 |
309def template AtomicMemOpStoreCompleteAcc {{ 310 Fault %(class_name)s::%(class_name)sStore::completeAcc(PacketPtr pkt, 311 ExecContext *xc, Trace::InstRecord *traceData) const 312 { 313 return NoFault; 314 } 315}}; | 458// LR/SC/AMO decode formats |
316 317def format LoadReserved(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 318 mem_flags=[], inst_flags=[]) {{ | 459 460def format LoadReserved(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 461 mem_flags=[], inst_flags=[]) {{ |
462 macro_ea_code = '' 463 macro_inst_flags = [] 464 macro_iop = InstObjParams(name, Name, 'LoadReserved', macro_ea_code, 465 macro_inst_flags) 466 header_output = LRSCDeclare.subst(macro_iop) 467 decoder_output = LRSCMacroConstructor.subst(macro_iop) 468 decode_block = BasicDecode.subst(macro_iop) 469 470 exec_output = '' 471 |
|
319 mem_flags = makeList(mem_flags) 320 inst_flags = makeList(inst_flags) 321 iop = InstObjParams(name, Name, 'LoadReserved', 322 {'ea_code': ea_code, 'memacc_code': memacc_code, 323 'postacc_code': postacc_code}, inst_flags) 324 iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 325 '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 326 | 472 mem_flags = makeList(mem_flags) 473 inst_flags = makeList(inst_flags) 474 iop = InstObjParams(name, Name, 'LoadReserved', 475 {'ea_code': ea_code, 'memacc_code': memacc_code, 476 'postacc_code': postacc_code}, inst_flags) 477 iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 478 '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 479 |
327 header_output = LoadStoreDeclare.subst(iop) 328 decoder_output = LRSCConstructor.subst(iop) 329 decode_block = BasicDecode.subst(iop) 330 exec_output = LoadExecute.subst(iop) \ 331 + LoadInitiateAcc.subst(iop) \ 332 + LoadCompleteAcc.subst(iop) | 480 decoder_output += LRSCMicroConstructor.subst(iop) 481 decode_block += BasicDecode.subst(iop) 482 exec_output += LoadReservedExecute.subst(iop) \ 483 + LoadReservedInitiateAcc.subst(iop) \ 484 + LoadReservedCompleteAcc.subst(iop) |
333}}; 334 335def format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 336 mem_flags=[], inst_flags=[]) {{ | 485}}; 486 487def format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 488 mem_flags=[], inst_flags=[]) {{ |
489 macro_ea_code = '' 490 macro_inst_flags = [] 491 macro_iop = InstObjParams(name, Name, 'StoreCond', macro_ea_code, 492 macro_inst_flags) 493 header_output = LRSCDeclare.subst(macro_iop) 494 decoder_output = LRSCMacroConstructor.subst(macro_iop) 495 decode_block = BasicDecode.subst(macro_iop) 496 497 exec_output = '' 498 |
|
337 mem_flags = makeList(mem_flags) 338 inst_flags = makeList(inst_flags) 339 iop = InstObjParams(name, Name, 'StoreCond', 340 {'ea_code': ea_code, 'memacc_code': memacc_code, 341 'postacc_code': postacc_code}, inst_flags) 342 iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 343 '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 344 | 499 mem_flags = makeList(mem_flags) 500 inst_flags = makeList(inst_flags) 501 iop = InstObjParams(name, Name, 'StoreCond', 502 {'ea_code': ea_code, 'memacc_code': memacc_code, 503 'postacc_code': postacc_code}, inst_flags) 504 iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 505 '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 506 |
345 header_output = LoadStoreDeclare.subst(iop) 346 decoder_output = LRSCConstructor.subst(iop) 347 decode_block = BasicDecode.subst(iop) 348 exec_output = StoreCondExecute.subst(iop) \ 349 + StoreInitiateAcc.subst(iop) \ | 507 decoder_output += LRSCMicroConstructor.subst(iop) 508 decode_block += BasicDecode.subst(iop) 509 exec_output += StoreCondExecute.subst(iop) \ 510 + StoreCondInitiateAcc.subst(iop) \ |
350 + StoreCondCompleteAcc.subst(iop) 351}}; 352 | 511 + StoreCondCompleteAcc.subst(iop) 512}}; 513 |
353def format AtomicMemOp(load_code, store_code, ea_code, load_flags=[], 354 store_flags=[], inst_flags=[]) {{ 355 macro_iop = InstObjParams(name, Name, 'AtomicMemOp', ea_code, inst_flags) | 514def format AtomicMemOp(memacc_code, amoop_code, postacc_code={{ }}, 515 ea_code={{EA = Rs1;}}, mem_flags=[], inst_flags=[]) {{ 516 macro_ea_code = '' 517 macro_inst_flags = [] 518 macro_iop = InstObjParams(name, Name, 'AtomicMemOp', macro_ea_code, 519 macro_inst_flags) |
356 header_output = AtomicMemOpDeclare.subst(macro_iop) 357 decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop) 358 decode_block = BasicDecode.subst(macro_iop) | 520 header_output = AtomicMemOpDeclare.subst(macro_iop) 521 decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop) 522 decode_block = BasicDecode.subst(macro_iop) |
523 |
|
359 exec_output = '' 360 | 524 exec_output = '' 525 |
361 load_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsLoad"] 362 load_iop = InstObjParams(name, Name, 'AtomicMemOpMicro', 363 {'ea_code': ea_code, 'code': load_code, 'op_name': 'Load'}, 364 load_inst_flags) 365 decoder_output += AtomicMemOpLoadConstructor.subst(load_iop) 366 exec_output += AtomicMemOpLoadExecute.subst(load_iop) \ 367 + AtomicMemOpLoadInitiateAcc.subst(load_iop) \ 368 + AtomicMemOpLoadCompleteAcc.subst(load_iop) | 526 rmw_mem_flags = makeList(mem_flags) 527 rmw_inst_flags = makeList(inst_flags) 528 rmw_iop = InstObjParams(name, Name, 'AtomicMemOpMicro', 529 {'ea_code': ea_code, 530 'memacc_code': memacc_code, 531 'postacc_code': postacc_code, 532 'amoop_code': amoop_code}, 533 rmw_inst_flags) |
369 | 534 |
370 store_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsStore"] 371 store_iop = InstObjParams(name, Name, 'AtomicMemOpMicro', 372 {'ea_code': ea_code, 'code': store_code, 'op_name': 'Store'}, 373 store_inst_flags) 374 decoder_output += AtomicMemOpStoreConstructor.subst(store_iop) 375 exec_output += AtomicMemOpStoreExecute.subst(store_iop) \ 376 + AtomicMemOpStoreInitiateAcc.subst(store_iop) \ 377 + AtomicMemOpStoreCompleteAcc.subst(store_iop) | 535 rmw_iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 536 '|'.join(['Request::%s' % flag for flag in rmw_mem_flags]) + ';' 537 538 decoder_output += AtomicMemOpRMWConstructor.subst(rmw_iop) 539 decode_block += BasicDecode.subst(rmw_iop) 540 exec_output += AtomicMemOpRMWExecute.subst(rmw_iop) \ 541 + AtomicMemOpRMWInitiateAcc.subst(rmw_iop) \ 542 + AtomicMemOpRMWCompleteAcc.subst(rmw_iop) |
378}}; | 543}}; |