mem.isa (7045:e21fe6a62b1c) mem.isa (7712:7733c562e5e3)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2003-2005 The Regents of The University of Michigan
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Steve Reinhardt
30// Kevin Lim
31
32////////////////////////////////////////////////////////////////////
33//
34// Memory-format instructions: LoadAddress, Load, Store
35//
36
37output header {{
38 /**
39 * Base class for general Alpha memory-format instructions.
40 */
41 class Memory : public AlphaStaticInst
42 {
43 protected:
44
45 /// Memory request flags. See mem_req_base.hh.
46 Request::Flags memAccessFlags;
47
48 /// Constructor
49 Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
50 : AlphaStaticInst(mnem, _machInst, __opClass)
51 {
52 }
53
54 std::string
55 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
56 };
57
58 /**
59 * Base class for memory-format instructions using a 32-bit
60 * displacement (i.e. most of them).
61 */
62 class MemoryDisp32 : public Memory
63 {
64 protected:
65 /// Displacement for EA calculation (signed).
66 int32_t disp;
67
68 /// Constructor.
69 MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
70 : Memory(mnem, _machInst, __opClass),
71 disp(MEMDISP)
72 {
73 }
74 };
75
76
77 /**
78 * Base class for a few miscellaneous memory-format insts
79 * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
80 * None of these instructions has a destination register either.
81 */
82 class MemoryNoDisp : public Memory
83 {
84 protected:
85 /// Constructor
86 MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
87 : Memory(mnem, _machInst, __opClass)
88 {
89 }
90
91 std::string
92 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
93 };
94}};
95
96
97output decoder {{
98 std::string
99 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
100 {
101 return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
102 flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
103 }
104
105 std::string
106 MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
107 {
108 return csprintf("%-10s (r%d)", mnemonic, RB);
109 }
110}};
111
112def format LoadAddress(code) {{
113 iop = InstObjParams(name, Name, 'MemoryDisp32', code)
114 header_output = BasicDeclare.subst(iop)
115 decoder_output = BasicConstructor.subst(iop)
116 decode_block = BasicDecode.subst(iop)
117 exec_output = BasicExecute.subst(iop)
118}};
119
120
121def template LoadStoreDeclare {{
122 /**
123 * Static instruction class for "%(mnemonic)s".
124 */
125 class %(class_name)s : public %(base_class)s
126 {
127 public:
128
129 /// Constructor.
130 %(class_name)s(ExtMachInst machInst);
131
132 %(BasicExecDeclare)s
133
134 %(EACompDeclare)s
135
136 %(InitiateAccDeclare)s
137
138 %(CompleteAccDeclare)s
139 };
140}};
141
142
143def template EACompDeclare {{
144 Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
145}};
146
147def template InitiateAccDeclare {{
148 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
149}};
150
151
152def template CompleteAccDeclare {{
153 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
154 Trace::InstRecord *) const;
155}};
156
157def template LoadStoreConstructor {{
158 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
159 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
160 {
161 %(constructor)s;
162 }
163}};
164
165def template EACompExecute {{
166 Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
167 Trace::InstRecord *traceData) const
168 {
169 Addr EA;
170 Fault fault = NoFault;
171
172 %(fp_enable_check)s;
173 %(op_decl)s;
174 %(op_rd)s;
175 %(ea_code)s;
176
177 if (fault == NoFault) {
178 %(op_wb)s;
179 xc->setEA(EA);
180 }
181
182 return fault;
183 }
184}};
185
186
187def template LoadExecute {{
188 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
189 Trace::InstRecord *traceData) const
190 {
191 Addr EA;
192 Fault fault = NoFault;
193
194 %(fp_enable_check)s;
195 %(op_decl)s;
196 %(op_rd)s;
197 %(ea_code)s;
198
199 if (fault == NoFault) {
200 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
201 %(memacc_code)s;
202 }
203
204 if (fault == NoFault) {
205 %(op_wb)s;
206 }
207
208 return fault;
209 }
210}};
211
212
213def template LoadInitiateAcc {{
214 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
215 Trace::InstRecord *traceData) const
216 {
217 Addr EA;
218 Fault fault = NoFault;
219
220 %(fp_enable_check)s;
221 %(op_src_decl)s;
222 %(op_rd)s;
223 %(ea_code)s;
224
225 if (fault == NoFault) {
226 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
227 }
228
229 return fault;
230 }
231}};
232
233
234def template LoadCompleteAcc {{
235 Fault %(class_name)s::completeAcc(PacketPtr pkt,
236 %(CPU_exec_context)s *xc,
237 Trace::InstRecord *traceData) const
238 {
239 Fault fault = NoFault;
240
241 %(fp_enable_check)s;
242 %(op_decl)s;
243
244 Mem = pkt->get<typeof(Mem)>();
245
246 if (fault == NoFault) {
247 %(memacc_code)s;
248 }
249
250 if (fault == NoFault) {
251 %(op_wb)s;
252 }
253
254 return fault;
255 }
256}};
257
258
259def template StoreExecute {{
260 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
261 Trace::InstRecord *traceData) const
262 {
263 Addr EA;
264 Fault fault = NoFault;
265
266 %(fp_enable_check)s;
267 %(op_decl)s;
268 %(op_rd)s;
269 %(ea_code)s;
270
271 if (fault == NoFault) {
272 %(memacc_code)s;
273 }
274
275 if (fault == NoFault) {
276 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
277 memAccessFlags, NULL);
278 }
279
280 if (fault == NoFault) {
281 %(postacc_code)s;
282 }
283
284 if (fault == NoFault) {
285 %(op_wb)s;
286 }
287
288 return fault;
289 }
290}};
291
292def template StoreCondExecute {{
293 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
294 Trace::InstRecord *traceData) const
295 {
296 Addr EA;
297 Fault fault = NoFault;
298 uint64_t write_result = 0;
299
300 %(fp_enable_check)s;
301 %(op_decl)s;
302 %(op_rd)s;
303 %(ea_code)s;
304
305 if (fault == NoFault) {
306 %(memacc_code)s;
307 }
308
309 if (fault == NoFault) {
310 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
311 memAccessFlags, &write_result);
312 }
313
314 if (fault == NoFault) {
315 %(postacc_code)s;
316 }
317
318 if (fault == NoFault) {
319 %(op_wb)s;
320 }
321
322 return fault;
323 }
324}};
325
326def template StoreInitiateAcc {{
327 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
328 Trace::InstRecord *traceData) const
329 {
330 Addr EA;
331 Fault fault = NoFault;
332
333 %(fp_enable_check)s;
334 %(op_decl)s;
335 %(op_rd)s;
336 %(ea_code)s;
337
338 if (fault == NoFault) {
339 %(memacc_code)s;
340 }
341
342 if (fault == NoFault) {
343 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
344 memAccessFlags, NULL);
345 }
346
347 return fault;
348 }
349}};
350
351
352def template StoreCompleteAcc {{
353 Fault %(class_name)s::completeAcc(PacketPtr pkt,
354 %(CPU_exec_context)s *xc,
355 Trace::InstRecord *traceData) const
356 {
1// -*- mode:c++ -*-
2
3// Copyright (c) 2003-2005 The Regents of The University of Michigan
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Steve Reinhardt
30// Kevin Lim
31
32////////////////////////////////////////////////////////////////////
33//
34// Memory-format instructions: LoadAddress, Load, Store
35//
36
37output header {{
38 /**
39 * Base class for general Alpha memory-format instructions.
40 */
41 class Memory : public AlphaStaticInst
42 {
43 protected:
44
45 /// Memory request flags. See mem_req_base.hh.
46 Request::Flags memAccessFlags;
47
48 /// Constructor
49 Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
50 : AlphaStaticInst(mnem, _machInst, __opClass)
51 {
52 }
53
54 std::string
55 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
56 };
57
58 /**
59 * Base class for memory-format instructions using a 32-bit
60 * displacement (i.e. most of them).
61 */
62 class MemoryDisp32 : public Memory
63 {
64 protected:
65 /// Displacement for EA calculation (signed).
66 int32_t disp;
67
68 /// Constructor.
69 MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
70 : Memory(mnem, _machInst, __opClass),
71 disp(MEMDISP)
72 {
73 }
74 };
75
76
77 /**
78 * Base class for a few miscellaneous memory-format insts
79 * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
80 * None of these instructions has a destination register either.
81 */
82 class MemoryNoDisp : public Memory
83 {
84 protected:
85 /// Constructor
86 MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
87 : Memory(mnem, _machInst, __opClass)
88 {
89 }
90
91 std::string
92 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
93 };
94}};
95
96
97output decoder {{
98 std::string
99 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
100 {
101 return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
102 flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
103 }
104
105 std::string
106 MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
107 {
108 return csprintf("%-10s (r%d)", mnemonic, RB);
109 }
110}};
111
112def format LoadAddress(code) {{
113 iop = InstObjParams(name, Name, 'MemoryDisp32', code)
114 header_output = BasicDeclare.subst(iop)
115 decoder_output = BasicConstructor.subst(iop)
116 decode_block = BasicDecode.subst(iop)
117 exec_output = BasicExecute.subst(iop)
118}};
119
120
121def template LoadStoreDeclare {{
122 /**
123 * Static instruction class for "%(mnemonic)s".
124 */
125 class %(class_name)s : public %(base_class)s
126 {
127 public:
128
129 /// Constructor.
130 %(class_name)s(ExtMachInst machInst);
131
132 %(BasicExecDeclare)s
133
134 %(EACompDeclare)s
135
136 %(InitiateAccDeclare)s
137
138 %(CompleteAccDeclare)s
139 };
140}};
141
142
143def template EACompDeclare {{
144 Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
145}};
146
147def template InitiateAccDeclare {{
148 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
149}};
150
151
152def template CompleteAccDeclare {{
153 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
154 Trace::InstRecord *) const;
155}};
156
157def template LoadStoreConstructor {{
158 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
159 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
160 {
161 %(constructor)s;
162 }
163}};
164
165def template EACompExecute {{
166 Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
167 Trace::InstRecord *traceData) const
168 {
169 Addr EA;
170 Fault fault = NoFault;
171
172 %(fp_enable_check)s;
173 %(op_decl)s;
174 %(op_rd)s;
175 %(ea_code)s;
176
177 if (fault == NoFault) {
178 %(op_wb)s;
179 xc->setEA(EA);
180 }
181
182 return fault;
183 }
184}};
185
186
187def template LoadExecute {{
188 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
189 Trace::InstRecord *traceData) const
190 {
191 Addr EA;
192 Fault fault = NoFault;
193
194 %(fp_enable_check)s;
195 %(op_decl)s;
196 %(op_rd)s;
197 %(ea_code)s;
198
199 if (fault == NoFault) {
200 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
201 %(memacc_code)s;
202 }
203
204 if (fault == NoFault) {
205 %(op_wb)s;
206 }
207
208 return fault;
209 }
210}};
211
212
213def template LoadInitiateAcc {{
214 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
215 Trace::InstRecord *traceData) const
216 {
217 Addr EA;
218 Fault fault = NoFault;
219
220 %(fp_enable_check)s;
221 %(op_src_decl)s;
222 %(op_rd)s;
223 %(ea_code)s;
224
225 if (fault == NoFault) {
226 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
227 }
228
229 return fault;
230 }
231}};
232
233
234def template LoadCompleteAcc {{
235 Fault %(class_name)s::completeAcc(PacketPtr pkt,
236 %(CPU_exec_context)s *xc,
237 Trace::InstRecord *traceData) const
238 {
239 Fault fault = NoFault;
240
241 %(fp_enable_check)s;
242 %(op_decl)s;
243
244 Mem = pkt->get<typeof(Mem)>();
245
246 if (fault == NoFault) {
247 %(memacc_code)s;
248 }
249
250 if (fault == NoFault) {
251 %(op_wb)s;
252 }
253
254 return fault;
255 }
256}};
257
258
259def template StoreExecute {{
260 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
261 Trace::InstRecord *traceData) const
262 {
263 Addr EA;
264 Fault fault = NoFault;
265
266 %(fp_enable_check)s;
267 %(op_decl)s;
268 %(op_rd)s;
269 %(ea_code)s;
270
271 if (fault == NoFault) {
272 %(memacc_code)s;
273 }
274
275 if (fault == NoFault) {
276 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
277 memAccessFlags, NULL);
278 }
279
280 if (fault == NoFault) {
281 %(postacc_code)s;
282 }
283
284 if (fault == NoFault) {
285 %(op_wb)s;
286 }
287
288 return fault;
289 }
290}};
291
292def template StoreCondExecute {{
293 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
294 Trace::InstRecord *traceData) const
295 {
296 Addr EA;
297 Fault fault = NoFault;
298 uint64_t write_result = 0;
299
300 %(fp_enable_check)s;
301 %(op_decl)s;
302 %(op_rd)s;
303 %(ea_code)s;
304
305 if (fault == NoFault) {
306 %(memacc_code)s;
307 }
308
309 if (fault == NoFault) {
310 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
311 memAccessFlags, &write_result);
312 }
313
314 if (fault == NoFault) {
315 %(postacc_code)s;
316 }
317
318 if (fault == NoFault) {
319 %(op_wb)s;
320 }
321
322 return fault;
323 }
324}};
325
326def template StoreInitiateAcc {{
327 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
328 Trace::InstRecord *traceData) const
329 {
330 Addr EA;
331 Fault fault = NoFault;
332
333 %(fp_enable_check)s;
334 %(op_decl)s;
335 %(op_rd)s;
336 %(ea_code)s;
337
338 if (fault == NoFault) {
339 %(memacc_code)s;
340 }
341
342 if (fault == NoFault) {
343 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
344 memAccessFlags, NULL);
345 }
346
347 return fault;
348 }
349}};
350
351
352def template StoreCompleteAcc {{
353 Fault %(class_name)s::completeAcc(PacketPtr pkt,
354 %(CPU_exec_context)s *xc,
355 Trace::InstRecord *traceData) const
356 {
357 Fault fault = NoFault;
358
359 %(fp_enable_check)s;
360 %(op_dest_decl)s;
361
362 if (fault == NoFault) {
363 %(postacc_code)s;
364 }
365
366 if (fault == NoFault) {
367 %(op_wb)s;
368 }
369
370 return fault;
357 return NoFault;
371 }
372}};
373
374
375def template StoreCondCompleteAcc {{
376 Fault %(class_name)s::completeAcc(PacketPtr pkt,
377 %(CPU_exec_context)s *xc,
378 Trace::InstRecord *traceData) const
379 {
380 Fault fault = NoFault;
381
382 %(fp_enable_check)s;
383 %(op_dest_decl)s;
384
385 uint64_t write_result = pkt->req->getExtraData();
386
387 if (fault == NoFault) {
388 %(postacc_code)s;
389 }
390
391 if (fault == NoFault) {
392 %(op_wb)s;
393 }
394
395 return fault;
396 }
397}};
398
399
400def template MiscExecute {{
401 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
402 Trace::InstRecord *traceData) const
403 {
404 Addr EA;
405 Fault fault = NoFault;
406
407 %(fp_enable_check)s;
408 %(op_decl)s;
409 %(op_rd)s;
410 %(ea_code)s;
411
412 if (fault == NoFault) {
413 %(memacc_code)s;
414 }
415
416 return NoFault;
417 }
418}};
419
420def template MiscInitiateAcc {{
421 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
422 Trace::InstRecord *traceData) const
423 {
424 warn("initiateAcc undefined: Misc instruction does not support split "
425 "access method!");
426 return NoFault;
427 }
428}};
429
430
431def template MiscCompleteAcc {{
432 Fault %(class_name)s::completeAcc(PacketPtr pkt,
433 %(CPU_exec_context)s *xc,
434 Trace::InstRecord *traceData) const
435 {
436 warn("completeAcc undefined: Misc instruction does not support split "
437 "access method!");
438
439 return NoFault;
440 }
441}};
442
443
444// load instructions use Ra as dest, so check for
445// Ra == 31 to detect nops
446def template LoadNopCheckDecode {{
447 {
448 AlphaStaticInst *i = new %(class_name)s(machInst);
449 if (RA == 31) {
450 i = makeNop(i);
451 }
452 return i;
453 }
454}};
455
456
457// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
458def template LoadPrefetchCheckDecode {{
459 {
460 if (RA != 31) {
461 return new %(class_name)s(machInst);
462 }
463 else {
464 return new %(class_name)sPrefetch(machInst);
465 }
466 }
467}};
468
469
470let {{
471def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
472 postacc_code = '', base_class = 'MemoryDisp32',
473 decode_template = BasicDecode, exec_template_base = ''):
474 # Make sure flags are in lists (convert to lists if not).
475 mem_flags = makeList(mem_flags)
476 inst_flags = makeList(inst_flags)
477
478 # Some CPU models execute the memory operation as an atomic unit,
479 # while others want to separate them into an effective address
480 # computation and a memory access operation. As a result, we need
481 # to generate three StaticInst objects. Note that the latter two
482 # are nested inside the larger "atomic" one.
483
484 # Generate InstObjParams for each of the three objects. Note that
485 # they differ only in the set of code objects contained (which in
486 # turn affects the object's overall operand list).
487 iop = InstObjParams(name, Name, base_class,
488 { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
489 inst_flags)
490 memacc_iop = InstObjParams(name, Name, base_class,
491 { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
492 inst_flags)
493
494 if mem_flags:
495 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
496 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
497 iop.constructor += s
498 memacc_iop.constructor += s
499
500 # select templates
501
502 # The InitiateAcc template is the same for StoreCond templates as the
503 # corresponding Store template..
504 StoreCondInitiateAcc = StoreInitiateAcc
505
506 fullExecTemplate = eval(exec_template_base + 'Execute')
507 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
508 completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
509
510 # (header_output, decoder_output, decode_block, exec_output)
511 return (LoadStoreDeclare.subst(iop),
512 LoadStoreConstructor.subst(iop),
513 decode_template.subst(iop),
514 fullExecTemplate.subst(iop)
515 + EACompExecute.subst(iop)
516 + initiateAccTemplate.subst(iop)
517 + completeAccTemplate.subst(iop))
518}};
519
520def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
521 mem_flags = [], inst_flags = []) {{
522 (header_output, decoder_output, decode_block, exec_output) = \
523 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
524 decode_template = LoadNopCheckDecode,
525 exec_template_base = 'Load')
526}};
527
528
529// Note that the flags passed in apply only to the prefetch version
530def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
531 mem_flags = [], pf_flags = [], inst_flags = []) {{
532 # declare the load instruction object and generate the decode block
533 (header_output, decoder_output, decode_block, exec_output) = \
534 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
535 decode_template = LoadPrefetchCheckDecode,
536 exec_template_base = 'Load')
537
538 # Declare the prefetch instruction object.
539
540 # Make sure flag args are lists so we can mess with them.
541 mem_flags = makeList(mem_flags)
542 pf_flags = makeList(pf_flags)
543 inst_flags = makeList(inst_flags)
544
545 pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
546 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
547 'IsDataPrefetch', 'MemReadOp']
548
549 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
550 LoadStoreBase(name, Name + 'Prefetch', ea_code,
551 'xc->prefetch(EA, memAccessFlags);',
552 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
553
554 header_output += pf_header_output
555 decoder_output += pf_decoder_output
556 exec_output += pf_exec_output
557}};
558
559
560def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
561 mem_flags = [], inst_flags = []) {{
562 (header_output, decoder_output, decode_block, exec_output) = \
563 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
564 exec_template_base = 'Store')
565}};
566
567
568def format StoreCond(memacc_code, postacc_code,
569 ea_code = {{ EA = Rb + disp; }},
570 mem_flags = [], inst_flags = []) {{
571 (header_output, decoder_output, decode_block, exec_output) = \
572 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
573 postacc_code, exec_template_base = 'StoreCond')
574}};
575
576
577// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
578def format MiscPrefetch(ea_code, memacc_code,
579 mem_flags = [], inst_flags = []) {{
580 (header_output, decoder_output, decode_block, exec_output) = \
581 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
582 base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
583}};
584
585
358 }
359}};
360
361
362def template StoreCondCompleteAcc {{
363 Fault %(class_name)s::completeAcc(PacketPtr pkt,
364 %(CPU_exec_context)s *xc,
365 Trace::InstRecord *traceData) const
366 {
367 Fault fault = NoFault;
368
369 %(fp_enable_check)s;
370 %(op_dest_decl)s;
371
372 uint64_t write_result = pkt->req->getExtraData();
373
374 if (fault == NoFault) {
375 %(postacc_code)s;
376 }
377
378 if (fault == NoFault) {
379 %(op_wb)s;
380 }
381
382 return fault;
383 }
384}};
385
386
387def template MiscExecute {{
388 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
389 Trace::InstRecord *traceData) const
390 {
391 Addr EA;
392 Fault fault = NoFault;
393
394 %(fp_enable_check)s;
395 %(op_decl)s;
396 %(op_rd)s;
397 %(ea_code)s;
398
399 if (fault == NoFault) {
400 %(memacc_code)s;
401 }
402
403 return NoFault;
404 }
405}};
406
407def template MiscInitiateAcc {{
408 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
409 Trace::InstRecord *traceData) const
410 {
411 warn("initiateAcc undefined: Misc instruction does not support split "
412 "access method!");
413 return NoFault;
414 }
415}};
416
417
418def template MiscCompleteAcc {{
419 Fault %(class_name)s::completeAcc(PacketPtr pkt,
420 %(CPU_exec_context)s *xc,
421 Trace::InstRecord *traceData) const
422 {
423 warn("completeAcc undefined: Misc instruction does not support split "
424 "access method!");
425
426 return NoFault;
427 }
428}};
429
430
431// load instructions use Ra as dest, so check for
432// Ra == 31 to detect nops
433def template LoadNopCheckDecode {{
434 {
435 AlphaStaticInst *i = new %(class_name)s(machInst);
436 if (RA == 31) {
437 i = makeNop(i);
438 }
439 return i;
440 }
441}};
442
443
444// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
445def template LoadPrefetchCheckDecode {{
446 {
447 if (RA != 31) {
448 return new %(class_name)s(machInst);
449 }
450 else {
451 return new %(class_name)sPrefetch(machInst);
452 }
453 }
454}};
455
456
457let {{
458def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
459 postacc_code = '', base_class = 'MemoryDisp32',
460 decode_template = BasicDecode, exec_template_base = ''):
461 # Make sure flags are in lists (convert to lists if not).
462 mem_flags = makeList(mem_flags)
463 inst_flags = makeList(inst_flags)
464
465 # Some CPU models execute the memory operation as an atomic unit,
466 # while others want to separate them into an effective address
467 # computation and a memory access operation. As a result, we need
468 # to generate three StaticInst objects. Note that the latter two
469 # are nested inside the larger "atomic" one.
470
471 # Generate InstObjParams for each of the three objects. Note that
472 # they differ only in the set of code objects contained (which in
473 # turn affects the object's overall operand list).
474 iop = InstObjParams(name, Name, base_class,
475 { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
476 inst_flags)
477 memacc_iop = InstObjParams(name, Name, base_class,
478 { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
479 inst_flags)
480
481 if mem_flags:
482 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
483 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
484 iop.constructor += s
485 memacc_iop.constructor += s
486
487 # select templates
488
489 # The InitiateAcc template is the same for StoreCond templates as the
490 # corresponding Store template..
491 StoreCondInitiateAcc = StoreInitiateAcc
492
493 fullExecTemplate = eval(exec_template_base + 'Execute')
494 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
495 completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
496
497 # (header_output, decoder_output, decode_block, exec_output)
498 return (LoadStoreDeclare.subst(iop),
499 LoadStoreConstructor.subst(iop),
500 decode_template.subst(iop),
501 fullExecTemplate.subst(iop)
502 + EACompExecute.subst(iop)
503 + initiateAccTemplate.subst(iop)
504 + completeAccTemplate.subst(iop))
505}};
506
507def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
508 mem_flags = [], inst_flags = []) {{
509 (header_output, decoder_output, decode_block, exec_output) = \
510 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
511 decode_template = LoadNopCheckDecode,
512 exec_template_base = 'Load')
513}};
514
515
516// Note that the flags passed in apply only to the prefetch version
517def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
518 mem_flags = [], pf_flags = [], inst_flags = []) {{
519 # declare the load instruction object and generate the decode block
520 (header_output, decoder_output, decode_block, exec_output) = \
521 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
522 decode_template = LoadPrefetchCheckDecode,
523 exec_template_base = 'Load')
524
525 # Declare the prefetch instruction object.
526
527 # Make sure flag args are lists so we can mess with them.
528 mem_flags = makeList(mem_flags)
529 pf_flags = makeList(pf_flags)
530 inst_flags = makeList(inst_flags)
531
532 pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
533 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
534 'IsDataPrefetch', 'MemReadOp']
535
536 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
537 LoadStoreBase(name, Name + 'Prefetch', ea_code,
538 'xc->prefetch(EA, memAccessFlags);',
539 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
540
541 header_output += pf_header_output
542 decoder_output += pf_decoder_output
543 exec_output += pf_exec_output
544}};
545
546
547def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
548 mem_flags = [], inst_flags = []) {{
549 (header_output, decoder_output, decode_block, exec_output) = \
550 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
551 exec_template_base = 'Store')
552}};
553
554
555def format StoreCond(memacc_code, postacc_code,
556 ea_code = {{ EA = Rb + disp; }},
557 mem_flags = [], inst_flags = []) {{
558 (header_output, decoder_output, decode_block, exec_output) = \
559 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
560 postacc_code, exec_template_base = 'StoreCond')
561}};
562
563
564// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
565def format MiscPrefetch(ea_code, memacc_code,
566 mem_flags = [], inst_flags = []) {{
567 (header_output, decoder_output, decode_block, exec_output) = \
568 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
569 base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
570}};
571
572