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 ---