mem.isa revision 2649
12124SN/A// -*- mode:c++ -*-
22124SN/A
32124SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
42124SN/A// All rights reserved.
52022SN/A//
62124SN/A// Redistribution and use in source and binary forms, with or without
72124SN/A// modification, are permitted provided that the following conditions are
82124SN/A// met: redistributions of source code must retain the above copyright
92124SN/A// notice, this list of conditions and the following disclaimer;
102124SN/A// redistributions in binary form must reproduce the above copyright
112124SN/A// notice, this list of conditions and the following disclaimer in the
122124SN/A// documentation and/or other materials provided with the distribution;
132124SN/A// neither the name of the copyright holders nor the names of its
142124SN/A// contributors may be used to endorse or promote products derived from
152124SN/A// this software without specific prior written permission.
162022SN/A//
172124SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182124SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192124SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202124SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212124SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222124SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232124SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242124SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252124SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262124SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272124SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282022SN/A
292649Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
302649Ssaidi@eecs.umich.edu//
312649Ssaidi@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store
322649Ssaidi@eecs.umich.edu//
332649Ssaidi@eecs.umich.edu
342022SN/Aoutput header {{
352124SN/A    /**
362124SN/A     * Base class for general Mips memory-format instructions.
372124SN/A     */
382124SN/A    class Memory : public MipsStaticInst
392124SN/A    {
402124SN/A      protected:
412124SN/A
422124SN/A        /// Memory request flags.  See mem_req_base.hh.
432124SN/A        unsigned memAccessFlags;
442124SN/A        /// Pointer to EAComp object.
452124SN/A        const StaticInstPtr eaCompPtr;
462124SN/A        /// Pointer to MemAcc object.
472124SN/A        const StaticInstPtr memAccPtr;
482239SN/A
492124SN/A        /// Displacement for EA calculation (signed).
502124SN/A        int32_t disp;
512124SN/A
522124SN/A        /// Constructor
532124SN/A        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
542124SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
552124SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
562124SN/A            : MipsStaticInst(mnem, _machInst, __opClass),
572124SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
582124SN/A              disp(OFFSET)
592022SN/A        {
602239SN/A            //If Bit 15 is 1 then Sign Extend
612239SN/A            int32_t temp = disp & 0x00008000;
622239SN/A
632239SN/A            if (temp > 0) {
642239SN/A                disp |= 0xFFFF0000;
652239SN/A            }
662124SN/A        }
672022SN/A
682124SN/A        std::string
692124SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
702022SN/A
712124SN/A      public:
722124SN/A
732124SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
742124SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
752124SN/A    };
762124SN/A
772022SN/A}};
782022SN/A
792124SN/A
802022SN/Aoutput decoder {{
812124SN/A    std::string
822124SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
832124SN/A    {
842124SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
852239SN/A                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
862124SN/A    }
872124SN/A
882022SN/A}};
892022SN/A
902124SN/Adef format LoadAddress(code) {{
912124SN/A    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
922124SN/A    header_output = BasicDeclare.subst(iop)
932124SN/A    decoder_output = BasicConstructor.subst(iop)
942124SN/A    decode_block = BasicDecode.subst(iop)
952124SN/A    exec_output = BasicExecute.subst(iop)
962022SN/A}};
972022SN/A
982124SN/A
992124SN/Adef template LoadStoreDeclare {{
1002124SN/A    /**
1012124SN/A     * Static instruction class for "%(mnemonic)s".
1022124SN/A     */
1032124SN/A    class %(class_name)s : public %(base_class)s
1042124SN/A    {
1052124SN/A      protected:
1062124SN/A
1072124SN/A        /**
1082124SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1092124SN/A         */
1102124SN/A        class EAComp : public %(base_class)s
1112124SN/A        {
1122124SN/A          public:
1132124SN/A            /// Constructor
1142124SN/A            EAComp(MachInst machInst);
1152124SN/A
1162124SN/A            %(BasicExecDeclare)s
1172124SN/A        };
1182124SN/A
1192124SN/A        /**
1202124SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1212124SN/A         */
1222124SN/A        class MemAcc : public %(base_class)s
1232124SN/A        {
1242124SN/A          public:
1252124SN/A            /// Constructor
1262124SN/A            MemAcc(MachInst machInst);
1272124SN/A
1282124SN/A            %(BasicExecDeclare)s
1292124SN/A        };
1302124SN/A
1312124SN/A      public:
1322124SN/A
1332124SN/A        /// Constructor.
1342124SN/A        %(class_name)s(MachInst machInst);
1352124SN/A
1362124SN/A        %(BasicExecDeclare)s
1372124SN/A
1382124SN/A        %(InitiateAccDeclare)s
1392124SN/A
1402124SN/A        %(CompleteAccDeclare)s
1412124SN/A    };
1422022SN/A}};
1432022SN/A
1442124SN/A
1452124SN/Adef template InitiateAccDeclare {{
1462132SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1472022SN/A}};
1482124SN/A
1492124SN/A
1502124SN/Adef template CompleteAccDeclare {{
1512132SN/A    Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
1522124SN/A}};
1532124SN/A
1542124SN/A
1552124SN/Adef template LoadStoreConstructor {{
1562124SN/A    /** TODO: change op_class to AddrGenOp or something (requires
1572124SN/A     * creating new member of OpClass enum in op_class.hh, updating
1582124SN/A     * config files, etc.). */
1592124SN/A    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
1602124SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
1612124SN/A    {
1622124SN/A        %(ea_constructor)s;
1632124SN/A    }
1642124SN/A
1652124SN/A    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
1662124SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
1672124SN/A    {
1682124SN/A        %(memacc_constructor)s;
1692124SN/A    }
1702124SN/A
1712124SN/A    inline %(class_name)s::%(class_name)s(MachInst machInst)
1722124SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1732124SN/A                          new EAComp(machInst), new MemAcc(machInst))
1742124SN/A    {
1752124SN/A        %(constructor)s;
1762124SN/A    }
1772124SN/A}};
1782124SN/A
1792124SN/A
1802124SN/Adef template EACompExecute {{
1812132SN/A    Fault
1822124SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
1832124SN/A                                   Trace::InstRecord *traceData) const
1842124SN/A    {
1852124SN/A        Addr EA;
1862132SN/A        Fault fault = NoFault;
1872124SN/A
1882124SN/A        %(fp_enable_check)s;
1892124SN/A        %(op_decl)s;
1902124SN/A        %(op_rd)s;
1912124SN/A        %(code)s;
1922124SN/A
1932124SN/A        if (fault == NoFault) {
1942124SN/A            %(op_wb)s;
1952124SN/A            xc->setEA(EA);
1962124SN/A        }
1972124SN/A
1982124SN/A        return fault;
1992124SN/A    }
2002124SN/A}};
2012124SN/A
2022124SN/Adef template LoadMemAccExecute {{
2032132SN/A    Fault
2042124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2052124SN/A                                   Trace::InstRecord *traceData) const
2062124SN/A    {
2072239SN/A        Addr EA;
2082132SN/A        Fault fault = NoFault;
2092239SN/A
2102239SN/A        %(fp_enable_check)s;
2112239SN/A        %(op_decl)s;
2122239SN/A        %(op_rd)s;
2132239SN/A        EA = xc->getEA();
2142239SN/A
2152239SN/A        if (fault == NoFault) {
2162239SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2172239SN/A            %(code)s;
2182239SN/A        }
2192239SN/A
2202239SN/A        if (fault == NoFault) {
2212239SN/A            %(op_wb)s;
2222239SN/A        }
2232239SN/A
2242124SN/A        return fault;
2252124SN/A    }
2262124SN/A}};
2272124SN/A
2282124SN/A
2292124SN/Adef template LoadExecute {{
2302132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2312124SN/A                                  Trace::InstRecord *traceData) const
2322124SN/A    {
2332124SN/A        Addr EA;
2342132SN/A        Fault fault = NoFault;
2352124SN/A
2362124SN/A        %(fp_enable_check)s;
2372124SN/A        %(op_decl)s;
2382124SN/A        %(op_rd)s;
2392124SN/A        %(ea_code)s;
2402124SN/A
2412124SN/A        if (fault == NoFault) {
2422124SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2432124SN/A            %(memacc_code)s;
2442124SN/A        }
2452124SN/A
2462124SN/A        if (fault == NoFault) {
2472124SN/A            %(op_wb)s;
2482124SN/A        }
2492124SN/A
2502124SN/A        return fault;
2512124SN/A    }
2522124SN/A}};
2532124SN/A
2542124SN/A
2552124SN/Adef template LoadInitiateAcc {{
2562132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2572124SN/A                                      Trace::InstRecord *traceData) const
2582124SN/A    {
2592239SN/A        Addr EA;
2602132SN/A        Fault fault = NoFault;
2612239SN/A
2622239SN/A        %(fp_enable_check)s;
2632239SN/A        %(op_src_decl)s;
2642239SN/A        %(op_rd)s;
2652239SN/A        %(ea_code)s;
2662239SN/A
2672239SN/A        if (fault == NoFault) {
2682239SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2692239SN/A        }
2702239SN/A
2712124SN/A        return fault;
2722124SN/A    }
2732124SN/A}};
2742124SN/A
2752124SN/A
2762124SN/Adef template LoadCompleteAcc {{
2772132SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
2782124SN/A                                      %(CPU_exec_context)s *xc,
2792124SN/A                                      Trace::InstRecord *traceData) const
2802124SN/A    {
2812132SN/A        Fault fault = NoFault;
2822239SN/A
2832239SN/A        %(fp_enable_check)s;
2842506SN/A        %(op_decl)s;
2852239SN/A
2862239SN/A        memcpy(&Mem, data, sizeof(Mem));
2872239SN/A
2882239SN/A        if (fault == NoFault) {
2892239SN/A            %(memacc_code)s;
2902239SN/A        }
2912239SN/A
2922239SN/A        if (fault == NoFault) {
2932239SN/A            %(op_wb)s;
2942239SN/A        }
2952239SN/A
2962124SN/A        return fault;
2972124SN/A    }
2982124SN/A}};
2992124SN/A
3002124SN/A
3012124SN/Adef template StoreMemAccExecute {{
3022132SN/A    Fault
3032124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3042124SN/A                                   Trace::InstRecord *traceData) const
3052124SN/A    {
3062239SN/A        Addr EA;
3072132SN/A        Fault fault = NoFault;
3082239SN/A        uint64_t write_result = 0;
3092239SN/A
3102239SN/A        %(fp_enable_check)s;
3112239SN/A        %(op_decl)s;
3122239SN/A        %(op_rd)s;
3132239SN/A        EA = xc->getEA();
3142239SN/A
3152239SN/A        if (fault == NoFault) {
3162239SN/A            %(code)s;
3172239SN/A        }
3182239SN/A
3192239SN/A        if (fault == NoFault) {
3202239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3212239SN/A                              memAccessFlags, &write_result);
3222239SN/A            if (traceData) { traceData->setData(Mem); }
3232239SN/A        }
3242239SN/A
3252239SN/A        if (fault == NoFault) {
3262239SN/A            %(postacc_code)s;
3272239SN/A        }
3282239SN/A
3292239SN/A        if (fault == NoFault) {
3302239SN/A            %(op_wb)s;
3312239SN/A        }
3322239SN/A
3332124SN/A        return fault;
3342124SN/A    }
3352124SN/A}};
3362124SN/A
3372124SN/A
3382124SN/Adef template StoreExecute {{
3392132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3402124SN/A                                  Trace::InstRecord *traceData) const
3412124SN/A    {
3422124SN/A        Addr EA;
3432132SN/A        Fault fault = NoFault;
3442124SN/A        uint64_t write_result = 0;
3452124SN/A
3462124SN/A        %(fp_enable_check)s;
3472124SN/A        %(op_decl)s;
3482124SN/A        %(op_rd)s;
3492124SN/A        %(ea_code)s;
3502124SN/A
3512124SN/A        if (fault == NoFault) {
3522124SN/A            %(memacc_code)s;
3532124SN/A        }
3542124SN/A
3552124SN/A        if (fault == NoFault) {
3562124SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3572124SN/A                              memAccessFlags, &write_result);
3582124SN/A            if (traceData) { traceData->setData(Mem); }
3592124SN/A        }
3602124SN/A
3612124SN/A        if (fault == NoFault) {
3622124SN/A            %(postacc_code)s;
3632124SN/A        }
3642124SN/A
3652124SN/A        if (fault == NoFault) {
3662124SN/A            %(op_wb)s;
3672124SN/A        }
3682124SN/A
3692124SN/A        return fault;
3702124SN/A    }
3712124SN/A}};
3722124SN/A
3732124SN/Adef template StoreInitiateAcc {{
3742132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3752124SN/A                                      Trace::InstRecord *traceData) const
3762124SN/A    {
3772239SN/A        Addr EA;
3782132SN/A        Fault fault = NoFault;
3792239SN/A        uint64_t write_result = 0;
3802239SN/A
3812239SN/A        %(fp_enable_check)s;
3822506SN/A        %(op_decl)s;
3832239SN/A        %(op_rd)s;
3842239SN/A        %(ea_code)s;
3852239SN/A
3862239SN/A        if (fault == NoFault) {
3872239SN/A            %(memacc_code)s;
3882239SN/A        }
3892239SN/A
3902239SN/A        if (fault == NoFault) {
3912239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3922239SN/A                              memAccessFlags, &write_result);
3932239SN/A            if (traceData) { traceData->setData(Mem); }
3942239SN/A        }
3952239SN/A
3962124SN/A        return fault;
3972124SN/A    }
3982124SN/A}};
3992124SN/A
4002124SN/A
4012124SN/Adef template StoreCompleteAcc {{
4022132SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
4032124SN/A                                      %(CPU_exec_context)s *xc,
4042124SN/A                                      Trace::InstRecord *traceData) const
4052124SN/A    {
4062132SN/A        Fault fault = NoFault;
4072239SN/A        uint64_t write_result = 0;
4082239SN/A
4092239SN/A        %(fp_enable_check)s;
4102239SN/A        %(op_dest_decl)s;
4112239SN/A
4122239SN/A        memcpy(&write_result, data, sizeof(write_result));
4132239SN/A
4142239SN/A        if (fault == NoFault) {
4152239SN/A            %(postacc_code)s;
4162239SN/A        }
4172239SN/A
4182239SN/A        if (fault == NoFault) {
4192239SN/A            %(op_wb)s;
4202239SN/A        }
4212239SN/A
4222124SN/A        return fault;
4232124SN/A    }
4242124SN/A}};
4252124SN/A
4262124SN/A// load instructions use Rt as dest, so check for
4272124SN/A// Rt == 31 to detect nops
4282124SN/Adef template LoadNopCheckDecode {{
4292124SN/A {
4302124SN/A     MipsStaticInst *i = new %(class_name)s(machInst);
4312124SN/A     if (RT == 0) {
4322124SN/A         i = makeNop(i);
4332124SN/A     }
4342124SN/A     return i;
4352124SN/A }
4362124SN/A}};
4372124SN/A
4382124SN/Adef format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4392124SN/A                     mem_flags = [], inst_flags = []) {{
4402124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4412124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4422124SN/A                      decode_template = LoadNopCheckDecode,
4432124SN/A                      exec_template_base = 'Load')
4442124SN/A}};
4452124SN/A
4462124SN/A
4472124SN/Adef format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4482124SN/A                     mem_flags = [], inst_flags = []) {{
4492124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4502124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4512124SN/A                      exec_template_base = 'Store')
4522124SN/A}};
4532124SN/A
4542573SN/A//FP loads are offloaded to these formats for now ...
4552573SN/Adef format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4562573SN/A                     mem_flags = [], inst_flags = []) {{
4572573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4582573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4592573SN/A                      decode_template = BasicDecode,
4602573SN/A                      exec_template_base = 'Load')
4612573SN/A}};
4622573SN/A
4632573SN/A
4642573SN/Adef format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4652573SN/A                     mem_flags = [], inst_flags = []) {{
4662573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4672573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4682573SN/A                      exec_template_base = 'Store')
4692573SN/A}};
4702573SN/A
4712573SN/A
4722495SN/Adef format UnalignedStore(memacc_code, postacc_code,
4732495SN/A                     ea_code = {{ EA = Rb + disp; }},
4742495SN/A                     mem_flags = [], inst_flags = []) {{
4752495SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4762495SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4772495SN/A                      postacc_code, exec_template_base = 'Store')
4782495SN/A}};
479