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 9// met: redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer; 11// redistributions in binary form must reproduce the above copyright 12// notice, this list of conditions and the following disclaimer in the 13// documentation and/or other materials provided with the distribution; 14// neither the name of the copyright holders nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 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 9// met: redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer; 11// redistributions in binary form must reproduce the above copyright 12// notice, this list of conditions and the following disclaimer in the 13// documentation and/or other materials provided with the distribution; 14// neither the name of the copyright holders nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 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; 134 %(ea_code)s; 135 136 if (fault == NoFault) { 137 %(memacc_code)s; 138 } 139 140 if (fault == NoFault) { 141 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 142 &result); 143 // RISC-V has the opposite convention gem5 has for success flags, 144 // so we invert the result here. 145 result = !result; 146 } 147 148 if (fault == NoFault) { 149 %(postacc_code)s; 150 } 151 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; 252 %(ea_code)s; 253 254 if (fault == NoFault) { 255 %(memacc_code)s; 256 } 257 258 if (fault == NoFault) { 259 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 260 &result); 261 // RISC-V has the opposite convention gem5 has for success flags, 262 // so we invert the result here. 263 result = !result; 264 } 265 266 if (fault == NoFault) { 267 %(postacc_code)s; 268 } 269 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(); 273 274 if (fault == NoFault) { 275 %(postacc_code)s; 276 } 277 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(); 422 423 if (fault == NoFault) { 424 %(postacc_code)s; 425 } 426 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}};
|