Deleted Added
sdiff udiff text old ( 2632:1bb2f91485ea ) new ( 2649:2fb859a457a2 )
full compact
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
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}};