mem.isa (2632:1bb2f91485ea) mem.isa (2649:2fb859a457a2)
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
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////////////////////////////////////////////////////////////////////
30//
31// Memory-format instructions: LoadAddress, Load, Store
32//
33
29output header {{
30 /**
31 * Base class for general Mips memory-format instructions.
32 */
33 class Memory : public MipsStaticInst
34 {
35 protected:
36
37 /// Memory request flags. See mem_req_base.hh.
38 unsigned memAccessFlags;
39 /// Pointer to EAComp object.
40 const StaticInstPtr eaCompPtr;
41 /// Pointer to MemAcc object.
42 const StaticInstPtr memAccPtr;
43
44 /// Displacement for EA calculation (signed).
45 int32_t disp;
46
47 /// Constructor
48 Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
49 StaticInstPtr _eaCompPtr = nullStaticInstPtr,
50 StaticInstPtr _memAccPtr = nullStaticInstPtr)
51 : MipsStaticInst(mnem, _machInst, __opClass),
52 memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
53 disp(OFFSET)
54 {
55 //If Bit 15 is 1 then Sign Extend
56 int32_t temp = disp & 0x00008000;
57
58 if (temp > 0) {
59 disp |= 0xFFFF0000;
60 }
61 }
62
63 std::string
64 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
65
66 public:
67
68 const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
69 const StaticInstPtr &memAccInst() const { return memAccPtr; }
70 };
71
72}};
73
74
75output decoder {{
76 std::string
77 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
78 {
79 return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
80 flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
81 }
82
83}};
84
85def format LoadAddress(code) {{
86 iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
87 header_output = BasicDeclare.subst(iop)
88 decoder_output = BasicConstructor.subst(iop)
89 decode_block = BasicDecode.subst(iop)
90 exec_output = BasicExecute.subst(iop)
91}};
92
93
94def template LoadStoreDeclare {{
95 /**
96 * Static instruction class for "%(mnemonic)s".
97 */
98 class %(class_name)s : public %(base_class)s
99 {
100 protected:
101
102 /**
103 * "Fake" effective address computation class for "%(mnemonic)s".
104 */
105 class EAComp : public %(base_class)s
106 {
107 public:
108 /// Constructor
109 EAComp(MachInst machInst);
110
111 %(BasicExecDeclare)s
112 };
113
114 /**
115 * "Fake" memory access instruction class for "%(mnemonic)s".
116 */
117 class MemAcc : public %(base_class)s
118 {
119 public:
120 /// Constructor
121 MemAcc(MachInst machInst);
122
123 %(BasicExecDeclare)s
124 };
125
126 public:
127
128 /// Constructor.
129 %(class_name)s(MachInst machInst);
130
131 %(BasicExecDeclare)s
132
133 %(InitiateAccDeclare)s
134
135 %(CompleteAccDeclare)s
136 };
137}};
138
139
140def template InitiateAccDeclare {{
141 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
142}};
143
144
145def template CompleteAccDeclare {{
146 Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
147}};
148
149
150def template LoadStoreConstructor {{
151 /** TODO: change op_class to AddrGenOp or something (requires
152 * creating new member of OpClass enum in op_class.hh, updating
153 * config files, etc.). */
154 inline %(class_name)s::EAComp::EAComp(MachInst machInst)
155 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
156 {
157 %(ea_constructor)s;
158 }
159
160 inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
161 : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
162 {
163 %(memacc_constructor)s;
164 }
165
166 inline %(class_name)s::%(class_name)s(MachInst machInst)
167 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
168 new EAComp(machInst), new MemAcc(machInst))
169 {
170 %(constructor)s;
171 }
172}};
173
174
175def template EACompExecute {{
176 Fault
177 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
178 Trace::InstRecord *traceData) const
179 {
180 Addr EA;
181 Fault fault = NoFault;
182
183 %(fp_enable_check)s;
184 %(op_decl)s;
185 %(op_rd)s;
186 %(code)s;
187
188 if (fault == NoFault) {
189 %(op_wb)s;
190 xc->setEA(EA);
191 }
192
193 return fault;
194 }
195}};
196
197def template LoadMemAccExecute {{
198 Fault
199 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
200 Trace::InstRecord *traceData) const
201 {
202 Addr EA;
203 Fault fault = NoFault;
204
205 %(fp_enable_check)s;
206 %(op_decl)s;
207 %(op_rd)s;
208 EA = xc->getEA();
209
210 if (fault == NoFault) {
211 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
212 %(code)s;
213 }
214
215 if (fault == NoFault) {
216 %(op_wb)s;
217 }
218
219 return fault;
220 }
221}};
222
223
224def template LoadExecute {{
225 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
226 Trace::InstRecord *traceData) const
227 {
228 Addr EA;
229 Fault fault = NoFault;
230
231 %(fp_enable_check)s;
232 %(op_decl)s;
233 %(op_rd)s;
234 %(ea_code)s;
235
236 if (fault == NoFault) {
237 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
238 %(memacc_code)s;
239 }
240
241 if (fault == NoFault) {
242 %(op_wb)s;
243 }
244
245 return fault;
246 }
247}};
248
249
250def template LoadInitiateAcc {{
251 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
252 Trace::InstRecord *traceData) const
253 {
254 Addr EA;
255 Fault fault = NoFault;
256
257 %(fp_enable_check)s;
258 %(op_src_decl)s;
259 %(op_rd)s;
260 %(ea_code)s;
261
262 if (fault == NoFault) {
263 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
264 }
265
266 return fault;
267 }
268}};
269
270
271def template LoadCompleteAcc {{
272 Fault %(class_name)s::completeAcc(uint8_t *data,
273 %(CPU_exec_context)s *xc,
274 Trace::InstRecord *traceData) const
275 {
276 Fault fault = NoFault;
277
278 %(fp_enable_check)s;
279 %(op_decl)s;
280
281 memcpy(&Mem, data, sizeof(Mem));
282
283 if (fault == NoFault) {
284 %(memacc_code)s;
285 }
286
287 if (fault == NoFault) {
288 %(op_wb)s;
289 }
290
291 return fault;
292 }
293}};
294
295
296def template StoreMemAccExecute {{
297 Fault
298 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
299 Trace::InstRecord *traceData) const
300 {
301 Addr EA;
302 Fault fault = NoFault;
303 uint64_t write_result = 0;
304
305 %(fp_enable_check)s;
306 %(op_decl)s;
307 %(op_rd)s;
308 EA = xc->getEA();
309
310 if (fault == NoFault) {
311 %(code)s;
312 }
313
314 if (fault == NoFault) {
315 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
316 memAccessFlags, &write_result);
317 if (traceData) { traceData->setData(Mem); }
318 }
319
320 if (fault == NoFault) {
321 %(postacc_code)s;
322 }
323
324 if (fault == NoFault) {
325 %(op_wb)s;
326 }
327
328 return fault;
329 }
330}};
331
332
333def template StoreExecute {{
334 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
335 Trace::InstRecord *traceData) const
336 {
337 Addr EA;
338 Fault fault = NoFault;
339 uint64_t write_result = 0;
340
341 %(fp_enable_check)s;
342 %(op_decl)s;
343 %(op_rd)s;
344 %(ea_code)s;
345
346 if (fault == NoFault) {
347 %(memacc_code)s;
348 }
349
350 if (fault == NoFault) {
351 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
352 memAccessFlags, &write_result);
353 if (traceData) { traceData->setData(Mem); }
354 }
355
356 if (fault == NoFault) {
357 %(postacc_code)s;
358 }
359
360 if (fault == NoFault) {
361 %(op_wb)s;
362 }
363
364 return fault;
365 }
366}};
367
368def template StoreInitiateAcc {{
369 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
370 Trace::InstRecord *traceData) const
371 {
372 Addr EA;
373 Fault fault = NoFault;
374 uint64_t write_result = 0;
375
376 %(fp_enable_check)s;
377 %(op_decl)s;
378 %(op_rd)s;
379 %(ea_code)s;
380
381 if (fault == NoFault) {
382 %(memacc_code)s;
383 }
384
385 if (fault == NoFault) {
386 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
387 memAccessFlags, &write_result);
388 if (traceData) { traceData->setData(Mem); }
389 }
390
391 return fault;
392 }
393}};
394
395
396def template StoreCompleteAcc {{
397 Fault %(class_name)s::completeAcc(uint8_t *data,
398 %(CPU_exec_context)s *xc,
399 Trace::InstRecord *traceData) const
400 {
401 Fault fault = NoFault;
402 uint64_t write_result = 0;
403
404 %(fp_enable_check)s;
405 %(op_dest_decl)s;
406
407 memcpy(&write_result, data, sizeof(write_result));
408
409 if (fault == NoFault) {
410 %(postacc_code)s;
411 }
412
413 if (fault == NoFault) {
414 %(op_wb)s;
415 }
416
417 return fault;
418 }
419}};
420
421// load instructions use Rt as dest, so check for
422// Rt == 31 to detect nops
423def template LoadNopCheckDecode {{
424 {
425 MipsStaticInst *i = new %(class_name)s(machInst);
426 if (RT == 0) {
427 i = makeNop(i);
428 }
429 return i;
430 }
431}};
432
433def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
434 mem_flags = [], inst_flags = []) {{
435 (header_output, decoder_output, decode_block, exec_output) = \
436 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
437 decode_template = LoadNopCheckDecode,
438 exec_template_base = 'Load')
439}};
440
441
442def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
443 mem_flags = [], inst_flags = []) {{
444 (header_output, decoder_output, decode_block, exec_output) = \
445 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
446 exec_template_base = 'Store')
447}};
448
449//FP loads are offloaded to these formats for now ...
450def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
451 mem_flags = [], inst_flags = []) {{
452 (header_output, decoder_output, decode_block, exec_output) = \
453 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
454 decode_template = BasicDecode,
455 exec_template_base = 'Load')
456}};
457
458
459def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
460 mem_flags = [], inst_flags = []) {{
461 (header_output, decoder_output, decode_block, exec_output) = \
462 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
463 exec_template_base = 'Store')
464}};
465
466
467def format UnalignedStore(memacc_code, postacc_code,
468 ea_code = {{ EA = Rb + disp; }},
469 mem_flags = [], inst_flags = []) {{
470 (header_output, decoder_output, decode_block, exec_output) = \
471 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
472 postacc_code, exec_template_base = 'Store')
473}};
34output header {{
35 /**
36 * Base class for general Mips memory-format instructions.
37 */
38 class Memory : public MipsStaticInst
39 {
40 protected:
41
42 /// Memory request flags. See mem_req_base.hh.
43 unsigned memAccessFlags;
44 /// Pointer to EAComp object.
45 const StaticInstPtr eaCompPtr;
46 /// Pointer to MemAcc object.
47 const StaticInstPtr memAccPtr;
48
49 /// Displacement for EA calculation (signed).
50 int32_t disp;
51
52 /// Constructor
53 Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
54 StaticInstPtr _eaCompPtr = nullStaticInstPtr,
55 StaticInstPtr _memAccPtr = nullStaticInstPtr)
56 : MipsStaticInst(mnem, _machInst, __opClass),
57 memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
58 disp(OFFSET)
59 {
60 //If Bit 15 is 1 then Sign Extend
61 int32_t temp = disp & 0x00008000;
62
63 if (temp > 0) {
64 disp |= 0xFFFF0000;
65 }
66 }
67
68 std::string
69 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
70
71 public:
72
73 const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
74 const StaticInstPtr &memAccInst() const { return memAccPtr; }
75 };
76
77}};
78
79
80output decoder {{
81 std::string
82 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
83 {
84 return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
85 flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
86 }
87
88}};
89
90def format LoadAddress(code) {{
91 iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
92 header_output = BasicDeclare.subst(iop)
93 decoder_output = BasicConstructor.subst(iop)
94 decode_block = BasicDecode.subst(iop)
95 exec_output = BasicExecute.subst(iop)
96}};
97
98
99def template LoadStoreDeclare {{
100 /**
101 * Static instruction class for "%(mnemonic)s".
102 */
103 class %(class_name)s : public %(base_class)s
104 {
105 protected:
106
107 /**
108 * "Fake" effective address computation class for "%(mnemonic)s".
109 */
110 class EAComp : public %(base_class)s
111 {
112 public:
113 /// Constructor
114 EAComp(MachInst machInst);
115
116 %(BasicExecDeclare)s
117 };
118
119 /**
120 * "Fake" memory access instruction class for "%(mnemonic)s".
121 */
122 class MemAcc : public %(base_class)s
123 {
124 public:
125 /// Constructor
126 MemAcc(MachInst machInst);
127
128 %(BasicExecDeclare)s
129 };
130
131 public:
132
133 /// Constructor.
134 %(class_name)s(MachInst machInst);
135
136 %(BasicExecDeclare)s
137
138 %(InitiateAccDeclare)s
139
140 %(CompleteAccDeclare)s
141 };
142}};
143
144
145def template InitiateAccDeclare {{
146 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
147}};
148
149
150def template CompleteAccDeclare {{
151 Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
152}};
153
154
155def template LoadStoreConstructor {{
156 /** TODO: change op_class to AddrGenOp or something (requires
157 * creating new member of OpClass enum in op_class.hh, updating
158 * config files, etc.). */
159 inline %(class_name)s::EAComp::EAComp(MachInst machInst)
160 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
161 {
162 %(ea_constructor)s;
163 }
164
165 inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
166 : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
167 {
168 %(memacc_constructor)s;
169 }
170
171 inline %(class_name)s::%(class_name)s(MachInst machInst)
172 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
173 new EAComp(machInst), new MemAcc(machInst))
174 {
175 %(constructor)s;
176 }
177}};
178
179
180def template EACompExecute {{
181 Fault
182 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
183 Trace::InstRecord *traceData) const
184 {
185 Addr EA;
186 Fault fault = NoFault;
187
188 %(fp_enable_check)s;
189 %(op_decl)s;
190 %(op_rd)s;
191 %(code)s;
192
193 if (fault == NoFault) {
194 %(op_wb)s;
195 xc->setEA(EA);
196 }
197
198 return fault;
199 }
200}};
201
202def template LoadMemAccExecute {{
203 Fault
204 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
205 Trace::InstRecord *traceData) const
206 {
207 Addr EA;
208 Fault fault = NoFault;
209
210 %(fp_enable_check)s;
211 %(op_decl)s;
212 %(op_rd)s;
213 EA = xc->getEA();
214
215 if (fault == NoFault) {
216 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
217 %(code)s;
218 }
219
220 if (fault == NoFault) {
221 %(op_wb)s;
222 }
223
224 return fault;
225 }
226}};
227
228
229def template LoadExecute {{
230 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
231 Trace::InstRecord *traceData) const
232 {
233 Addr EA;
234 Fault fault = NoFault;
235
236 %(fp_enable_check)s;
237 %(op_decl)s;
238 %(op_rd)s;
239 %(ea_code)s;
240
241 if (fault == NoFault) {
242 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
243 %(memacc_code)s;
244 }
245
246 if (fault == NoFault) {
247 %(op_wb)s;
248 }
249
250 return fault;
251 }
252}};
253
254
255def template LoadInitiateAcc {{
256 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
257 Trace::InstRecord *traceData) const
258 {
259 Addr EA;
260 Fault fault = NoFault;
261
262 %(fp_enable_check)s;
263 %(op_src_decl)s;
264 %(op_rd)s;
265 %(ea_code)s;
266
267 if (fault == NoFault) {
268 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
269 }
270
271 return fault;
272 }
273}};
274
275
276def template LoadCompleteAcc {{
277 Fault %(class_name)s::completeAcc(uint8_t *data,
278 %(CPU_exec_context)s *xc,
279 Trace::InstRecord *traceData) const
280 {
281 Fault fault = NoFault;
282
283 %(fp_enable_check)s;
284 %(op_decl)s;
285
286 memcpy(&Mem, data, sizeof(Mem));
287
288 if (fault == NoFault) {
289 %(memacc_code)s;
290 }
291
292 if (fault == NoFault) {
293 %(op_wb)s;
294 }
295
296 return fault;
297 }
298}};
299
300
301def template StoreMemAccExecute {{
302 Fault
303 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
304 Trace::InstRecord *traceData) const
305 {
306 Addr EA;
307 Fault fault = NoFault;
308 uint64_t write_result = 0;
309
310 %(fp_enable_check)s;
311 %(op_decl)s;
312 %(op_rd)s;
313 EA = xc->getEA();
314
315 if (fault == NoFault) {
316 %(code)s;
317 }
318
319 if (fault == NoFault) {
320 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
321 memAccessFlags, &write_result);
322 if (traceData) { traceData->setData(Mem); }
323 }
324
325 if (fault == NoFault) {
326 %(postacc_code)s;
327 }
328
329 if (fault == NoFault) {
330 %(op_wb)s;
331 }
332
333 return fault;
334 }
335}};
336
337
338def template StoreExecute {{
339 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
340 Trace::InstRecord *traceData) const
341 {
342 Addr EA;
343 Fault fault = NoFault;
344 uint64_t write_result = 0;
345
346 %(fp_enable_check)s;
347 %(op_decl)s;
348 %(op_rd)s;
349 %(ea_code)s;
350
351 if (fault == NoFault) {
352 %(memacc_code)s;
353 }
354
355 if (fault == NoFault) {
356 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
357 memAccessFlags, &write_result);
358 if (traceData) { traceData->setData(Mem); }
359 }
360
361 if (fault == NoFault) {
362 %(postacc_code)s;
363 }
364
365 if (fault == NoFault) {
366 %(op_wb)s;
367 }
368
369 return fault;
370 }
371}};
372
373def template StoreInitiateAcc {{
374 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
375 Trace::InstRecord *traceData) const
376 {
377 Addr EA;
378 Fault fault = NoFault;
379 uint64_t write_result = 0;
380
381 %(fp_enable_check)s;
382 %(op_decl)s;
383 %(op_rd)s;
384 %(ea_code)s;
385
386 if (fault == NoFault) {
387 %(memacc_code)s;
388 }
389
390 if (fault == NoFault) {
391 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
392 memAccessFlags, &write_result);
393 if (traceData) { traceData->setData(Mem); }
394 }
395
396 return fault;
397 }
398}};
399
400
401def template StoreCompleteAcc {{
402 Fault %(class_name)s::completeAcc(uint8_t *data,
403 %(CPU_exec_context)s *xc,
404 Trace::InstRecord *traceData) const
405 {
406 Fault fault = NoFault;
407 uint64_t write_result = 0;
408
409 %(fp_enable_check)s;
410 %(op_dest_decl)s;
411
412 memcpy(&write_result, data, sizeof(write_result));
413
414 if (fault == NoFault) {
415 %(postacc_code)s;
416 }
417
418 if (fault == NoFault) {
419 %(op_wb)s;
420 }
421
422 return fault;
423 }
424}};
425
426// load instructions use Rt as dest, so check for
427// Rt == 31 to detect nops
428def template LoadNopCheckDecode {{
429 {
430 MipsStaticInst *i = new %(class_name)s(machInst);
431 if (RT == 0) {
432 i = makeNop(i);
433 }
434 return i;
435 }
436}};
437
438def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
439 mem_flags = [], inst_flags = []) {{
440 (header_output, decoder_output, decode_block, exec_output) = \
441 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
442 decode_template = LoadNopCheckDecode,
443 exec_template_base = 'Load')
444}};
445
446
447def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
448 mem_flags = [], inst_flags = []) {{
449 (header_output, decoder_output, decode_block, exec_output) = \
450 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
451 exec_template_base = 'Store')
452}};
453
454//FP loads are offloaded to these formats for now ...
455def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
456 mem_flags = [], inst_flags = []) {{
457 (header_output, decoder_output, decode_block, exec_output) = \
458 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
459 decode_template = BasicDecode,
460 exec_template_base = 'Load')
461}};
462
463
464def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
465 mem_flags = [], inst_flags = []) {{
466 (header_output, decoder_output, decode_block, exec_output) = \
467 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
468 exec_template_base = 'Store')
469}};
470
471
472def format UnalignedStore(memacc_code, postacc_code,
473 ea_code = {{ EA = Rb + disp; }},
474 mem_flags = [], inst_flags = []) {{
475 (header_output, decoder_output, decode_block, exec_output) = \
476 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
477 postacc_code, exec_template_base = 'Store')
478}};