mem.isa revision 2132
16145SN/A// -*- mode:c++ -*-
28688SN/A
36145SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
46145SN/A// All rights reserved.
56145SN/A//
66145SN/A// Redistribution and use in source and binary forms, with or without
76145SN/A// modification, are permitted provided that the following conditions are
86145SN/A// met: redistributions of source code must retain the above copyright
96145SN/A// notice, this list of conditions and the following disclaimer;
106145SN/A// redistributions in binary form must reproduce the above copyright
116145SN/A// notice, this list of conditions and the following disclaimer in the
126145SN/A// documentation and/or other materials provided with the distribution;
136145SN/A// neither the name of the copyright holders nor the names of its
146145SN/A// contributors may be used to endorse or promote products derived from
156145SN/A// this software without specific prior written permission.
166145SN/A//
176145SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186145SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196145SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206145SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216145SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226145SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236145SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246145SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256145SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266145SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276145SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286145SN/A
296145SN/Aoutput header {{
307039SN/A    /**
317039SN/A     * Base class for general Mips memory-format instructions.
327039SN/A     */
336145SN/A    class Memory : public MipsStaticInst
346145SN/A    {
3512492Sodanrc@yahoo.com.br      protected:
3612492Sodanrc@yahoo.com.br
376145SN/A        /// Memory request flags.  See mem_req_base.hh.
387039SN/A        unsigned memAccessFlags;
399350SN/A        /// Pointer to EAComp object.
4011108Sdavid.hashe@amd.com        const StaticInstPtr eaCompPtr;
4110301SN/A        /// Pointer to MemAcc object.
4210301SN/A        const StaticInstPtr memAccPtr;
4310301SN/A        /// Displacement for EA calculation (signed).
447039SN/A        int32_t disp;
459206SN/A
466145SN/A        /// Constructor
477039SN/A        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
4810920SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
496285SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
509206SN/A            : MipsStaticInst(mnem, _machInst, __opClass),
517039SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
527039SN/A              disp(OFFSET)
536876SN/A        {
546876SN/A        }
557039SN/A
566145SN/A        std::string
577039SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
587039SN/A
599504SN/A      public:
609504SN/A
619504SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
6210837SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
6310837SN/A    };
646285SN/A
6510525SN/A}};
6610918SN/A
6711294Sandreas.hansson@arm.com
6810525SN/Aoutput decoder {{
697039SN/A    std::string
707039SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
717039SN/A    {
727039SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
7310012SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
7410012SN/A    }
757039SN/A
766285SN/A}};
7711523Sdavid.guillen@arm.com
7811523Sdavid.guillen@arm.comdef format LoadAddress(code) {{
7911523Sdavid.guillen@arm.com    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
8011523Sdavid.guillen@arm.com    header_output = BasicDeclare.subst(iop)
8110012SN/A    decoder_output = BasicConstructor.subst(iop)
8211169Sandreas.hansson@arm.com    decode_block = BasicDecode.subst(iop)
836285SN/A    exec_output = BasicExecute.subst(iop)
8411169Sandreas.hansson@arm.com}};
8511168Sandreas.hansson@arm.com
8611168Sandreas.hansson@arm.com
8711168Sandreas.hansson@arm.comdef template LoadStoreDeclare {{
888688SN/A    /**
8911169Sandreas.hansson@arm.com     * Static instruction class for "%(mnemonic)s".
909270SN/A     */
919270SN/A    class %(class_name)s : public %(base_class)s
927562SN/A    {
938436SN/A      protected:
948436SN/A
958436SN/A        /**
968937SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
978937SN/A         */
988937SN/A        class EAComp : public %(base_class)s
9912133Sspwilson2@wisc.edu        {
10012133Sspwilson2@wisc.edu          public:
1018937SN/A            /// Constructor
1028937SN/A            EAComp(MachInst machInst);
1038937SN/A
1047039SN/A            %(BasicExecDeclare)s
1057039SN/A        };
1067039SN/A
1077039SN/A        /**
1086285SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
10910991SN/A         */
11011061SN/A        class MemAcc : public %(base_class)s
11111061SN/A        {
11210991SN/A          public:
11311060SN/A            /// Constructor
11411060SN/A            MemAcc(MachInst machInst);
11511061SN/A
11611060SN/A            %(BasicExecDeclare)s
11711061SN/A        };
1187039SN/A
11912133Sspwilson2@wisc.edu      public:
1207039SN/A
1217039SN/A        /// Constructor.
1227039SN/A        %(class_name)s(MachInst machInst);
1239504SN/A
1249504SN/A        %(BasicExecDeclare)s
1259504SN/A
12610919SN/A        %(InitiateAccDeclare)s
12710837SN/A
12810837SN/A        %(CompleteAccDeclare)s
12910837SN/A    };
13010525SN/A}};
13110706SN/A
1327039SN/A
13310012SN/Adef template InitiateAccDeclare {{
1349300SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
13510918SN/A}};
1369103SN/A
1377039SN/A
13810012SN/Adef template CompleteAccDeclare {{
1398688SN/A    Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
14010920SN/A}};
1416145SN/A
1426145SN/A
14310012SN/Adef template LoadStoreConstructor {{
1446895SN/A    /** TODO: change op_class to AddrGenOp or something (requires
1456895SN/A     * creating new member of OpClass enum in op_class.hh, updating
14610919SN/A     * config files, etc.). */
1476895SN/A    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
1486895SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
14910012SN/A    {
15010919SN/A        %(ea_constructor)s;
15110919SN/A    }
1526895SN/A
1536895SN/A    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
15412492Sodanrc@yahoo.com.br        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
155    {
156        %(memacc_constructor)s;
157    }
158
159    inline %(class_name)s::%(class_name)s(MachInst machInst)
160         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
161                          new EAComp(machInst), new MemAcc(machInst))
162    {
163        %(constructor)s;
164    }
165}};
166
167
168def template EACompExecute {{
169    Fault
170    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
171                                   Trace::InstRecord *traceData) const
172    {
173        Addr EA;
174        Fault fault = NoFault;
175
176        %(fp_enable_check)s;
177        %(op_decl)s;
178        %(op_rd)s;
179        %(code)s;
180
181        if (fault == NoFault) {
182            %(op_wb)s;
183            xc->setEA(EA);
184        }
185
186        return fault;
187    }
188}};
189
190def template LoadMemAccExecute {{
191    Fault
192    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
193                                   Trace::InstRecord *traceData) const
194    {
195        Addr EA;
196        Fault fault = NoFault;
197
198        %(fp_enable_check)s;
199        %(op_decl)s;
200        %(op_rd)s;
201        EA = xc->getEA();
202
203        if (fault == NoFault) {
204            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
205            %(code)s;
206        }
207
208        if (fault == NoFault) {
209            %(op_wb)s;
210        }
211
212        return fault;
213    }
214}};
215
216
217def template LoadExecute {{
218    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
219                                  Trace::InstRecord *traceData) const
220    {
221        Addr EA;
222        Fault fault = NoFault;
223
224        %(fp_enable_check)s;
225        %(op_decl)s;
226        %(op_rd)s;
227        %(ea_code)s;
228
229        if (fault == NoFault) {
230            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
231            %(memacc_code)s;
232        }
233
234        if (fault == NoFault) {
235            %(op_wb)s;
236        }
237
238        return fault;
239    }
240}};
241
242
243def template LoadInitiateAcc {{
244    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
245                                      Trace::InstRecord *traceData) const
246    {
247        Addr EA;
248        Fault fault = NoFault;
249
250        %(fp_enable_check)s;
251        %(op_src_decl)s;
252        %(op_rd)s;
253        %(ea_code)s;
254
255        if (fault == NoFault) {
256            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
257        }
258
259        return fault;
260    }
261}};
262
263
264def template LoadCompleteAcc {{
265    Fault %(class_name)s::completeAcc(uint8_t *data,
266                                      %(CPU_exec_context)s *xc,
267                                      Trace::InstRecord *traceData) const
268    {
269        Fault fault = NoFault;
270
271        %(fp_enable_check)s;
272        %(op_src_decl)s;
273        %(op_dest_decl)s;
274
275        memcpy(&Mem, data, sizeof(Mem));
276
277        if (fault == NoFault) {
278            %(memacc_code)s;
279        }
280
281        if (fault == NoFault) {
282            %(op_wb)s;
283        }
284
285        return fault;
286    }
287}};
288
289
290def template StoreMemAccExecute {{
291    Fault
292    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
293                                   Trace::InstRecord *traceData) const
294    {
295        Addr EA;
296        Fault fault = NoFault;
297        uint64_t write_result = 0;
298
299        %(fp_enable_check)s;
300        %(op_decl)s;
301        %(op_rd)s;
302        EA = xc->getEA();
303
304        if (fault == NoFault) {
305            %(code)s;
306        }
307
308        if (fault == NoFault) {
309            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
310                              memAccessFlags, &write_result);
311            if (traceData) { traceData->setData(Mem); }
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
326
327def template StoreExecute {{
328    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
329                                  Trace::InstRecord *traceData) const
330    {
331        Addr EA;
332        Fault fault = NoFault;
333        uint64_t write_result = 0;
334
335        %(fp_enable_check)s;
336        %(op_decl)s;
337        %(op_rd)s;
338        %(ea_code)s;
339
340        if (fault == NoFault) {
341            %(memacc_code)s;
342        }
343
344        if (fault == NoFault) {
345            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
346                              memAccessFlags, &write_result);
347            if (traceData) { traceData->setData(Mem); }
348        }
349
350        if (fault == NoFault) {
351            %(postacc_code)s;
352        }
353
354        if (fault == NoFault) {
355            %(op_wb)s;
356        }
357
358        return fault;
359    }
360}};
361
362def template StoreInitiateAcc {{
363    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
364                                      Trace::InstRecord *traceData) const
365    {
366        Addr EA;
367        Fault fault = NoFault;
368        uint64_t write_result = 0;
369
370        %(fp_enable_check)s;
371        %(op_src_decl)s;
372        %(op_dest_decl)s;
373        %(op_rd)s;
374        %(ea_code)s;
375
376        if (fault == NoFault) {
377            %(memacc_code)s;
378        }
379
380        if (fault == NoFault) {
381            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
382                              memAccessFlags, &write_result);
383            if (traceData) { traceData->setData(Mem); }
384        }
385
386        return fault;
387    }
388}};
389
390
391def template StoreCompleteAcc {{
392    Fault %(class_name)s::completeAcc(uint8_t *data,
393                                      %(CPU_exec_context)s *xc,
394                                      Trace::InstRecord *traceData) const
395    {
396        Fault fault = NoFault;
397        uint64_t write_result = 0;
398
399        %(fp_enable_check)s;
400        %(op_dest_decl)s;
401
402        memcpy(&write_result, data, sizeof(write_result));
403
404        if (fault == NoFault) {
405            %(postacc_code)s;
406        }
407
408        if (fault == NoFault) {
409            %(op_wb)s;
410        }
411
412        return fault;
413    }
414}};
415
416// load instructions use Rt as dest, so check for
417// Rt == 31 to detect nops
418def template LoadNopCheckDecode {{
419 {
420     MipsStaticInst *i = new %(class_name)s(machInst);
421     if (RT == 0) {
422         i = makeNop(i);
423     }
424     return i;
425 }
426}};
427
428def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
429                     mem_flags = [], inst_flags = []) {{
430    (header_output, decoder_output, decode_block, exec_output) = \
431        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
432                      decode_template = LoadNopCheckDecode,
433                      exec_template_base = 'Load')
434}};
435
436
437def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
438                     mem_flags = [], inst_flags = []) {{
439    (header_output, decoder_output, decode_block, exec_output) = \
440        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
441                      exec_template_base = 'Store')
442}};
443
444//FP loads are offloaded to these formats for now ...
445def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }},
446                      mem_flags = [], inst_flags = []) {{
447    (header_output, decoder_output, decode_block, exec_output) = \
448        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
449                      decode_template = LoadNopCheckDecode,
450                      exec_template_base = 'Load')
451}};
452
453
454//FP stores are offloaded to these formats for now ...
455def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }},
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 = LoadNopCheckDecode,
460                      exec_template_base = 'Store')
461}};
462
463