mem.isa revision 12234
15124Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27087Snate@binkert.org
37087Snate@binkert.org// Copyright (c) 2003-2005 The Regents of The University of Michigan
47087Snate@binkert.org// All rights reserved.
57087Snate@binkert.org//
67087Snate@binkert.org// Redistribution and use in source and binary forms, with or without
77087Snate@binkert.org// modification, are permitted provided that the following conditions are
87087Snate@binkert.org// met: redistributions of source code must retain the above copyright
97087Snate@binkert.org// notice, this list of conditions and the following disclaimer;
107087Snate@binkert.org// redistributions in binary form must reproduce the above copyright
117087Snate@binkert.org// notice, this list of conditions and the following disclaimer in the
127087Snate@binkert.org// documentation and/or other materials provided with the distribution;
137087Snate@binkert.org// neither the name of the copyright holders nor the names of its
145124Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
155124Sgblack@eecs.umich.edu// this software without specific prior written permission.
165124Sgblack@eecs.umich.edu//
175124Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185124Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195124Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205124Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215124Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225124Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235124Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245124Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255124Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265124Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275124Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285124Sgblack@eecs.umich.edu//
295124Sgblack@eecs.umich.edu// Authors: Steve Reinhardt
305124Sgblack@eecs.umich.edu//          Kevin Lim
315124Sgblack@eecs.umich.edu
325124Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
335124Sgblack@eecs.umich.edu//
345124Sgblack@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store
355124Sgblack@eecs.umich.edu//
365124Sgblack@eecs.umich.edu
375124Sgblack@eecs.umich.eduoutput header {{
385124Sgblack@eecs.umich.edu    /**
395124Sgblack@eecs.umich.edu     * Base class for general Alpha memory-format instructions.
405124Sgblack@eecs.umich.edu     */
415124Sgblack@eecs.umich.edu    class Memory : public AlphaStaticInst
425124Sgblack@eecs.umich.edu    {
438961Sgblack@eecs.umich.edu      protected:
445124Sgblack@eecs.umich.edu
458740Sgblack@eecs.umich.edu        /// Memory request flags.  See mem_req_base.hh.
465124Sgblack@eecs.umich.edu        Request::Flags memAccessFlags;
475124Sgblack@eecs.umich.edu
488232Snate@binkert.org        /// Constructor
498740Sgblack@eecs.umich.edu        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
505124Sgblack@eecs.umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass)
515124Sgblack@eecs.umich.edu        {
525124Sgblack@eecs.umich.edu        }
5310417Sandreas.hansson@arm.com
545124Sgblack@eecs.umich.edu        std::string
558806Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
568806Sgblack@eecs.umich.edu    };
578806Sgblack@eecs.umich.edu
588806Sgblack@eecs.umich.edu    /**
598806Sgblack@eecs.umich.edu     * Base class for memory-format instructions using a 32-bit
608806Sgblack@eecs.umich.edu     * displacement (i.e. most of them).
618806Sgblack@eecs.umich.edu     */
628806Sgblack@eecs.umich.edu    class MemoryDisp32 : public Memory
638806Sgblack@eecs.umich.edu    {
648806Sgblack@eecs.umich.edu      protected:
658806Sgblack@eecs.umich.edu        /// Displacement for EA calculation (signed).
668806Sgblack@eecs.umich.edu        int32_t disp;
678806Sgblack@eecs.umich.edu
688806Sgblack@eecs.umich.edu        /// Constructor.
698806Sgblack@eecs.umich.edu        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
708806Sgblack@eecs.umich.edu            : Memory(mnem, _machInst, __opClass),
718806Sgblack@eecs.umich.edu              disp(MEMDISP)
728806Sgblack@eecs.umich.edu        {
738806Sgblack@eecs.umich.edu        }
748806Sgblack@eecs.umich.edu    };
758806Sgblack@eecs.umich.edu
768806Sgblack@eecs.umich.edu
778806Sgblack@eecs.umich.edu    /**
788806Sgblack@eecs.umich.edu     * Base class for a few miscellaneous memory-format insts
798740Sgblack@eecs.umich.edu     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
808806Sgblack@eecs.umich.edu     * None of these instructions has a destination register either.
815858Sgblack@eecs.umich.edu     */
828806Sgblack@eecs.umich.edu    class MemoryNoDisp : public Memory
838806Sgblack@eecs.umich.edu    {
845858Sgblack@eecs.umich.edu      protected:
858806Sgblack@eecs.umich.edu        /// Constructor
868806Sgblack@eecs.umich.edu        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
878806Sgblack@eecs.umich.edu            : Memory(mnem, _machInst, __opClass)
888806Sgblack@eecs.umich.edu        {
895681Sgblack@eecs.umich.edu        }
908806Sgblack@eecs.umich.edu
918806Sgblack@eecs.umich.edu        std::string
928806Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
935124Sgblack@eecs.umich.edu    };
945909Sgblack@eecs.umich.edu}};
955909Sgblack@eecs.umich.edu
965909Sgblack@eecs.umich.edu
975909Sgblack@eecs.umich.eduoutput decoder {{
985909Sgblack@eecs.umich.edu    std::string
995909Sgblack@eecs.umich.edu    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1005909Sgblack@eecs.umich.edu    {
1015909Sgblack@eecs.umich.edu        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1025909Sgblack@eecs.umich.edu                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1035909Sgblack@eecs.umich.edu    }
1045909Sgblack@eecs.umich.edu
1055909Sgblack@eecs.umich.edu    std::string
10611320Ssteve.reinhardt@amd.com    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
10710417Sandreas.hansson@arm.com    {
1085858Sgblack@eecs.umich.edu        return csprintf("%-10s (r%d)", mnemonic, RB);
1095858Sgblack@eecs.umich.edu    }
1108806Sgblack@eecs.umich.edu}};
1118806Sgblack@eecs.umich.edu
1128806Sgblack@eecs.umich.edudef format LoadAddress(code) {{
1138806Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1148806Sgblack@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
1158806Sgblack@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
1168806Sgblack@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
1175858Sgblack@eecs.umich.edu    exec_output = BasicExecute.subst(iop)
1185858Sgblack@eecs.umich.edu}};
11910417Sandreas.hansson@arm.com
1205858Sgblack@eecs.umich.edu
1215858Sgblack@eecs.umich.edudef template LoadStoreDeclare {{
1225858Sgblack@eecs.umich.edu    /**
1235858Sgblack@eecs.umich.edu     * Static instruction class for "%(mnemonic)s".
1248740Sgblack@eecs.umich.edu     */
12510417Sandreas.hansson@arm.com    class %(class_name)s : public %(base_class)s
1268740Sgblack@eecs.umich.edu    {
1278740Sgblack@eecs.umich.edu      public:
1288740Sgblack@eecs.umich.edu
1298740Sgblack@eecs.umich.edu        /// Constructor.
1308740Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst);
1318740Sgblack@eecs.umich.edu
1328740Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
1338740Sgblack@eecs.umich.edu
1348740Sgblack@eecs.umich.edu        %(EACompDeclare)s
13510417Sandreas.hansson@arm.com
1365858Sgblack@eecs.umich.edu        %(InitiateAccDeclare)s
1378740Sgblack@eecs.umich.edu
13811218Sswapnilh@cs.wisc.edu        %(CompleteAccDeclare)s
13911218Sswapnilh@cs.wisc.edu    };
14011218Sswapnilh@cs.wisc.edu}};
1418740Sgblack@eecs.umich.edu
1428740Sgblack@eecs.umich.edu
1438740Sgblack@eecs.umich.edudef template EACompDeclare {{
1448740Sgblack@eecs.umich.edu    Fault eaComp(ExecContext *, Trace::InstRecord *) const;
1458740Sgblack@eecs.umich.edu}};
1468740Sgblack@eecs.umich.edu
1478740Sgblack@eecs.umich.edudef template InitiateAccDeclare {{
1488740Sgblack@eecs.umich.edu    Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
1498740Sgblack@eecs.umich.edu}};
1508740Sgblack@eecs.umich.edu
1518740Sgblack@eecs.umich.edu
1528740Sgblack@eecs.umich.edudef template CompleteAccDeclare {{
1538740Sgblack@eecs.umich.edu    Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
1545858Sgblack@eecs.umich.edu}};
1558740Sgblack@eecs.umich.edu
1568740Sgblack@eecs.umich.edudef template LoadStoreConstructor {{
1578740Sgblack@eecs.umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst)
1588740Sgblack@eecs.umich.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
1598740Sgblack@eecs.umich.edu    {
1608740Sgblack@eecs.umich.edu        %(constructor)s;
1618740Sgblack@eecs.umich.edu    }
1628740Sgblack@eecs.umich.edu}};
1638740Sgblack@eecs.umich.edu
1645858Sgblack@eecs.umich.edudef template EACompExecute {{
1655858Sgblack@eecs.umich.edu    Fault %(class_name)s::eaComp(ExecContext *xc,
1665237Sgblack@eecs.umich.edu                                 Trace::InstRecord *traceData) const
1675909Sgblack@eecs.umich.edu    {
1685909Sgblack@eecs.umich.edu        Addr EA;
1695909Sgblack@eecs.umich.edu        Fault fault = NoFault;
1705909Sgblack@eecs.umich.edu
1715909Sgblack@eecs.umich.edu        %(fp_enable_check)s;
1725909Sgblack@eecs.umich.edu        %(op_decl)s;
1735909Sgblack@eecs.umich.edu        %(op_rd)s;
1745909Sgblack@eecs.umich.edu        %(ea_code)s;
1756048Sgblack@eecs.umich.edu
17610417Sandreas.hansson@arm.com        if (fault == NoFault) {
1776048Sgblack@eecs.umich.edu            %(op_wb)s;
1786048Sgblack@eecs.umich.edu            xc->setEA(EA);
1796048Sgblack@eecs.umich.edu        }
1806048Sgblack@eecs.umich.edu
1816048Sgblack@eecs.umich.edu        return fault;
1826048Sgblack@eecs.umich.edu    }
1836048Sgblack@eecs.umich.edu}};
1846048Sgblack@eecs.umich.edu
1856048Sgblack@eecs.umich.edu
1866048Sgblack@eecs.umich.edudef template LoadExecute {{
1876048Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(ExecContext *xc,
1886048Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
1896048Sgblack@eecs.umich.edu    {
1906048Sgblack@eecs.umich.edu        Addr EA;
1916048Sgblack@eecs.umich.edu        Fault fault = NoFault;
1926048Sgblack@eecs.umich.edu
1936048Sgblack@eecs.umich.edu        %(fp_enable_check)s;
1946048Sgblack@eecs.umich.edu        %(op_decl)s;
1956048Sgblack@eecs.umich.edu        %(op_rd)s;
1966048Sgblack@eecs.umich.edu        %(ea_code)s;
1976048Sgblack@eecs.umich.edu
1986222Sgblack@eecs.umich.edu        if (fault == NoFault) {
1996222Sgblack@eecs.umich.edu            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
2006222Sgblack@eecs.umich.edu            %(memacc_code)s;
2016222Sgblack@eecs.umich.edu        }
2026222Sgblack@eecs.umich.edu
2036222Sgblack@eecs.umich.edu        if (fault == NoFault) {
2046222Sgblack@eecs.umich.edu            %(op_wb)s;
2056222Sgblack@eecs.umich.edu        }
2066048Sgblack@eecs.umich.edu
2076048Sgblack@eecs.umich.edu        return fault;
2086048Sgblack@eecs.umich.edu    }
2096222Sgblack@eecs.umich.edu}};
2106048Sgblack@eecs.umich.edu
2116048Sgblack@eecs.umich.edu
2126048Sgblack@eecs.umich.edudef template LoadInitiateAcc {{
2136048Sgblack@eecs.umich.edu    Fault %(class_name)s::initiateAcc(ExecContext *xc,
2146048Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
2156048Sgblack@eecs.umich.edu    {
2166048Sgblack@eecs.umich.edu        Addr EA;
2176048Sgblack@eecs.umich.edu        Fault fault = NoFault;
2186048Sgblack@eecs.umich.edu
2196048Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2206222Sgblack@eecs.umich.edu        %(op_src_decl)s;
2216222Sgblack@eecs.umich.edu        %(op_rd)s;
2226222Sgblack@eecs.umich.edu        %(ea_code)s;
2236222Sgblack@eecs.umich.edu
2246222Sgblack@eecs.umich.edu        if (fault == NoFault) {
2256222Sgblack@eecs.umich.edu            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
2266222Sgblack@eecs.umich.edu        }
2276222Sgblack@eecs.umich.edu
2286048Sgblack@eecs.umich.edu        return fault;
2296048Sgblack@eecs.umich.edu    }
2306048Sgblack@eecs.umich.edu}};
2316222Sgblack@eecs.umich.edu
2326048Sgblack@eecs.umich.edu
2336048Sgblack@eecs.umich.edudef template LoadCompleteAcc {{
2346048Sgblack@eecs.umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
2356048Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
2366048Sgblack@eecs.umich.edu    {
2376048Sgblack@eecs.umich.edu        Fault fault = NoFault;
2386048Sgblack@eecs.umich.edu
2396048Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2406048Sgblack@eecs.umich.edu        %(op_decl)s;
2416048Sgblack@eecs.umich.edu
2427720Sgblack@eecs.umich.edu        getMem(pkt, Mem, traceData);
2437720Sgblack@eecs.umich.edu
2446048Sgblack@eecs.umich.edu        if (fault == NoFault) {
2456048Sgblack@eecs.umich.edu            %(memacc_code)s;
2466048Sgblack@eecs.umich.edu        }
2476048Sgblack@eecs.umich.edu
2486048Sgblack@eecs.umich.edu        if (fault == NoFault) {
2496048Sgblack@eecs.umich.edu            %(op_wb)s;
2506048Sgblack@eecs.umich.edu        }
25110100Sandreas@sandberg.pp.se
25210100Sandreas@sandberg.pp.se        return fault;
25310100Sandreas@sandberg.pp.se    }
2546048Sgblack@eecs.umich.edu}};
2556048Sgblack@eecs.umich.edu
2566048Sgblack@eecs.umich.edu
25710100Sandreas@sandberg.pp.sedef template StoreExecute {{
2586048Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(ExecContext *xc,
25910100Sandreas@sandberg.pp.se                                  Trace::InstRecord *traceData) const
26010100Sandreas@sandberg.pp.se    {
26110100Sandreas@sandberg.pp.se        Addr EA;
2626048Sgblack@eecs.umich.edu        Fault fault = NoFault;
2636048Sgblack@eecs.umich.edu
2646048Sgblack@eecs.umich.edu        %(fp_enable_check)s;
26510100Sandreas@sandberg.pp.se        %(op_decl)s;
2666048Sgblack@eecs.umich.edu        %(op_rd)s;
2676048Sgblack@eecs.umich.edu        %(ea_code)s;
2686048Sgblack@eecs.umich.edu
2696048Sgblack@eecs.umich.edu        if (fault == NoFault) {
2706048Sgblack@eecs.umich.edu            %(memacc_code)s;
2716048Sgblack@eecs.umich.edu        }
2726048Sgblack@eecs.umich.edu
2736048Sgblack@eecs.umich.edu        if (fault == NoFault) {
2746048Sgblack@eecs.umich.edu            fault = writeMemAtomic(xc, traceData, Mem, EA,
2756048Sgblack@eecs.umich.edu                    memAccessFlags, NULL);
2766048Sgblack@eecs.umich.edu        }
2776048Sgblack@eecs.umich.edu
2786048Sgblack@eecs.umich.edu        if (fault == NoFault) {
2796048Sgblack@eecs.umich.edu            %(postacc_code)s;
2809763Sandreas@sandberg.pp.se        }
2819763Sandreas@sandberg.pp.se
2829765Sandreas@sandberg.pp.se        if (fault == NoFault) {
2839765Sandreas@sandberg.pp.se            %(op_wb)s;
2849765Sandreas@sandberg.pp.se        }
2856140Sgblack@eecs.umich.edu
2866140Sgblack@eecs.umich.edu        return fault;
2876048Sgblack@eecs.umich.edu    }
2887720Sgblack@eecs.umich.edu}};
2897720Sgblack@eecs.umich.edu
2907720Sgblack@eecs.umich.edudef template StoreCondExecute {{
2916048Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(ExecContext *xc,
2926048Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
2936049Sgblack@eecs.umich.edu    {
29410417Sandreas.hansson@arm.com        Addr EA;
2956049Sgblack@eecs.umich.edu        Fault fault = NoFault;
2966049Sgblack@eecs.umich.edu        uint64_t write_result = 0;
2976049Sgblack@eecs.umich.edu
2986049Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2996049Sgblack@eecs.umich.edu        %(op_decl)s;
3006140Sgblack@eecs.umich.edu        %(op_rd)s;
3016049Sgblack@eecs.umich.edu        %(ea_code)s;
3026049Sgblack@eecs.umich.edu
3036049Sgblack@eecs.umich.edu        if (fault == NoFault) {
3046049Sgblack@eecs.umich.edu            %(memacc_code)s;
3056049Sgblack@eecs.umich.edu        }
3066049Sgblack@eecs.umich.edu
3076049Sgblack@eecs.umich.edu        if (fault == NoFault) {
3086049Sgblack@eecs.umich.edu            fault = writeMemAtomic(xc, traceData, Mem, EA,
3097720Sgblack@eecs.umich.edu                    memAccessFlags, &write_result);
3106049Sgblack@eecs.umich.edu        }
3115124Sgblack@eecs.umich.edu
3125124Sgblack@eecs.umich.edu        if (fault == NoFault) {
313            %(postacc_code)s;
314        }
315
316        if (fault == NoFault) {
317            %(op_wb)s;
318        }
319
320        return fault;
321    }
322}};
323
324def template StoreInitiateAcc {{
325    Fault %(class_name)s::initiateAcc(ExecContext *xc,
326                                      Trace::InstRecord *traceData) const
327    {
328        Addr EA;
329        Fault fault = NoFault;
330
331        %(fp_enable_check)s;
332        %(op_decl)s;
333        %(op_rd)s;
334        %(ea_code)s;
335
336        if (fault == NoFault) {
337            %(memacc_code)s;
338        }
339
340        if (fault == NoFault) {
341            fault = writeMemTiming(xc, traceData, Mem, EA,
342                    memAccessFlags, NULL);
343        }
344
345        return fault;
346    }
347}};
348
349
350def template StoreCompleteAcc {{
351    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
352                                      Trace::InstRecord *traceData) const
353    {
354        return NoFault;
355    }
356}};
357
358
359def template StoreCondCompleteAcc {{
360    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
361                                      Trace::InstRecord *traceData) const
362    {
363        Fault fault = NoFault;
364
365        %(fp_enable_check)s;
366        %(op_dest_decl)s;
367
368        uint64_t write_result = pkt->req->getExtraData();
369
370        if (fault == NoFault) {
371            %(postacc_code)s;
372        }
373
374        if (fault == NoFault) {
375            %(op_wb)s;
376        }
377
378        return fault;
379    }
380}};
381
382
383def template MiscExecute {{
384    Fault %(class_name)s::execute(ExecContext *xc,
385                                  Trace::InstRecord *traceData) const
386    {
387        Addr EA M5_VAR_USED;
388        Fault fault = NoFault;
389
390        %(fp_enable_check)s;
391        %(op_decl)s;
392        %(op_rd)s;
393        %(ea_code)s;
394
395        warn_once("Prefetch instructions in Alpha do not do anything\n");
396        if (fault == NoFault) {
397            %(memacc_code)s;
398        }
399
400        return NoFault;
401    }
402}};
403
404// Prefetches in Alpha don't actually do anything
405// They just build an effective address and complete
406def template MiscInitiateAcc {{
407    Fault %(class_name)s::initiateAcc(ExecContext *xc,
408                                      Trace::InstRecord *traceData) const
409    {
410        warn("initiateAcc undefined: Misc instruction does not support split "
411             "access method!");
412        return NoFault;
413    }
414}};
415
416
417def template MiscCompleteAcc {{
418    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
419                                      Trace::InstRecord *traceData) const
420    {
421        warn("completeAcc undefined: Misc instruction does not support split "
422             "access method!");
423
424        return NoFault;
425    }
426}};
427
428
429// load instructions use Ra as dest, so check for
430// Ra == 31 to detect nops
431def template LoadNopCheckDecode {{
432 {
433     AlphaStaticInst *i = new %(class_name)s(machInst);
434     if (RA == 31) {
435         i = makeNop(i);
436     }
437     return i;
438 }
439}};
440
441
442// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
443def template LoadPrefetchCheckDecode {{
444 {
445     if (RA != 31) {
446         return new %(class_name)s(machInst);
447     }
448     else {
449         return new %(class_name)sPrefetch(machInst);
450     }
451 }
452}};
453
454
455let {{
456def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
457                  postacc_code = '', base_class = 'MemoryDisp32',
458                  decode_template = BasicDecode, exec_template_base = ''):
459    # Make sure flags are in lists (convert to lists if not).
460    mem_flags = makeList(mem_flags)
461    inst_flags = makeList(inst_flags)
462
463    iop = InstObjParams(name, Name, base_class,
464                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
465                        inst_flags)
466
467    if mem_flags:
468        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
469        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
470        iop.constructor += s
471
472    # select templates
473
474    # The InitiateAcc template is the same for StoreCond templates as the
475    # corresponding Store template..
476    StoreCondInitiateAcc = StoreInitiateAcc
477
478    fullExecTemplate = eval(exec_template_base + 'Execute')
479    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
480    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
481
482    # (header_output, decoder_output, decode_block, exec_output)
483    return (LoadStoreDeclare.subst(iop),
484            LoadStoreConstructor.subst(iop),
485            decode_template.subst(iop),
486            fullExecTemplate.subst(iop)
487            + EACompExecute.subst(iop)
488            + initiateAccTemplate.subst(iop)
489            + completeAccTemplate.subst(iop))
490}};
491
492def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
493                     mem_flags = [], inst_flags = []) {{
494    (header_output, decoder_output, decode_block, exec_output) = \
495        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
496                      decode_template = LoadNopCheckDecode,
497                      exec_template_base = 'Load')
498}};
499
500
501// Note that the flags passed in apply only to the prefetch version
502def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
503                          mem_flags = [], pf_flags = [], inst_flags = []) {{
504    # declare the load instruction object and generate the decode block
505    (header_output, decoder_output, decode_block, exec_output) = \
506        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
507                      decode_template = LoadPrefetchCheckDecode,
508                      exec_template_base = 'Load')
509
510    # Declare the prefetch instruction object.
511
512    # Make sure flag args are lists so we can mess with them.
513    mem_flags = makeList(mem_flags)
514    pf_flags = makeList(pf_flags)
515    inst_flags = makeList(inst_flags)
516
517    pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
518    pf_inst_flags = inst_flags
519
520    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
521        LoadStoreBase(name, Name + 'Prefetch', ea_code, ';',
522                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
523
524    header_output += pf_header_output
525    decoder_output += pf_decoder_output
526    exec_output += pf_exec_output
527}};
528
529
530def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
531                 mem_flags = [], inst_flags = []) {{
532    (header_output, decoder_output, decode_block, exec_output) = \
533        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
534                      exec_template_base = 'Store')
535}};
536
537
538def format StoreCond(memacc_code, postacc_code,
539                     ea_code = {{ EA = Rb + disp; }},
540                     mem_flags = [], inst_flags = []) {{
541    (header_output, decoder_output, decode_block, exec_output) = \
542        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
543                      postacc_code, exec_template_base = 'StoreCond')
544}};
545
546
547// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
548def format MiscPrefetch(ea_code, memacc_code,
549                        mem_flags = [], inst_flags = []) {{
550    (header_output, decoder_output, decode_block, exec_output) = \
551        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
552                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
553}};
554
555
556