mem.isa revision 2665
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.
282665Ssaidi@eecs.umich.edu//
292665Ssaidi@eecs.umich.edu// Authors: Gabe Black
302665Ssaidi@eecs.umich.edu//          Korey Sewell
312022SN/A
322649Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
332649Ssaidi@eecs.umich.edu//
342649Ssaidi@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store
352649Ssaidi@eecs.umich.edu//
362649Ssaidi@eecs.umich.edu
372022SN/Aoutput header {{
382124SN/A    /**
392124SN/A     * Base class for general Mips memory-format instructions.
402124SN/A     */
412124SN/A    class Memory : public MipsStaticInst
422124SN/A    {
432124SN/A      protected:
442124SN/A
452124SN/A        /// Memory request flags.  See mem_req_base.hh.
462124SN/A        unsigned memAccessFlags;
472124SN/A        /// Pointer to EAComp object.
482124SN/A        const StaticInstPtr eaCompPtr;
492124SN/A        /// Pointer to MemAcc object.
502124SN/A        const StaticInstPtr memAccPtr;
512239SN/A
522124SN/A        /// Displacement for EA calculation (signed).
532124SN/A        int32_t disp;
542124SN/A
552124SN/A        /// Constructor
562124SN/A        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
572124SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
582124SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
592124SN/A            : MipsStaticInst(mnem, _machInst, __opClass),
602124SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
612124SN/A              disp(OFFSET)
622022SN/A        {
632239SN/A            //If Bit 15 is 1 then Sign Extend
642239SN/A            int32_t temp = disp & 0x00008000;
652239SN/A
662239SN/A            if (temp > 0) {
672239SN/A                disp |= 0xFFFF0000;
682239SN/A            }
692124SN/A        }
702022SN/A
712124SN/A        std::string
722124SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
732022SN/A
742124SN/A      public:
752124SN/A
762124SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
772124SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
782124SN/A    };
792124SN/A
802022SN/A}};
812022SN/A
822124SN/A
832022SN/Aoutput decoder {{
842124SN/A    std::string
852124SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
862124SN/A    {
872124SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
882239SN/A                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
892124SN/A    }
902124SN/A
912022SN/A}};
922022SN/A
932124SN/Adef format LoadAddress(code) {{
942124SN/A    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
952124SN/A    header_output = BasicDeclare.subst(iop)
962124SN/A    decoder_output = BasicConstructor.subst(iop)
972124SN/A    decode_block = BasicDecode.subst(iop)
982124SN/A    exec_output = BasicExecute.subst(iop)
992022SN/A}};
1002022SN/A
1012124SN/A
1022124SN/Adef template LoadStoreDeclare {{
1032124SN/A    /**
1042124SN/A     * Static instruction class for "%(mnemonic)s".
1052124SN/A     */
1062124SN/A    class %(class_name)s : public %(base_class)s
1072124SN/A    {
1082124SN/A      protected:
1092124SN/A
1102124SN/A        /**
1112124SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1122124SN/A         */
1132124SN/A        class EAComp : public %(base_class)s
1142124SN/A        {
1152124SN/A          public:
1162124SN/A            /// Constructor
1172124SN/A            EAComp(MachInst machInst);
1182124SN/A
1192124SN/A            %(BasicExecDeclare)s
1202124SN/A        };
1212124SN/A
1222124SN/A        /**
1232124SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1242124SN/A         */
1252124SN/A        class MemAcc : public %(base_class)s
1262124SN/A        {
1272124SN/A          public:
1282124SN/A            /// Constructor
1292124SN/A            MemAcc(MachInst machInst);
1302124SN/A
1312124SN/A            %(BasicExecDeclare)s
1322124SN/A        };
1332124SN/A
1342124SN/A      public:
1352124SN/A
1362124SN/A        /// Constructor.
1372124SN/A        %(class_name)s(MachInst machInst);
1382124SN/A
1392124SN/A        %(BasicExecDeclare)s
1402124SN/A
1412124SN/A        %(InitiateAccDeclare)s
1422124SN/A
1432124SN/A        %(CompleteAccDeclare)s
1442124SN/A    };
1452022SN/A}};
1462022SN/A
1472124SN/A
1482124SN/Adef template InitiateAccDeclare {{
1492132SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1502022SN/A}};
1512124SN/A
1522124SN/A
1532124SN/Adef template CompleteAccDeclare {{
1542132SN/A    Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
1552124SN/A}};
1562124SN/A
1572124SN/A
1582124SN/Adef template LoadStoreConstructor {{
1592124SN/A    /** TODO: change op_class to AddrGenOp or something (requires
1602124SN/A     * creating new member of OpClass enum in op_class.hh, updating
1612124SN/A     * config files, etc.). */
1622124SN/A    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
1632124SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
1642124SN/A    {
1652124SN/A        %(ea_constructor)s;
1662124SN/A    }
1672124SN/A
1682124SN/A    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
1692124SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
1702124SN/A    {
1712124SN/A        %(memacc_constructor)s;
1722124SN/A    }
1732124SN/A
1742124SN/A    inline %(class_name)s::%(class_name)s(MachInst machInst)
1752124SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1762124SN/A                          new EAComp(machInst), new MemAcc(machInst))
1772124SN/A    {
1782124SN/A        %(constructor)s;
1792124SN/A    }
1802124SN/A}};
1812124SN/A
1822124SN/A
1832124SN/Adef template EACompExecute {{
1842132SN/A    Fault
1852124SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
1862124SN/A                                   Trace::InstRecord *traceData) const
1872124SN/A    {
1882124SN/A        Addr EA;
1892132SN/A        Fault fault = NoFault;
1902124SN/A
1912124SN/A        %(fp_enable_check)s;
1922124SN/A        %(op_decl)s;
1932124SN/A        %(op_rd)s;
1942124SN/A        %(code)s;
1952124SN/A
1962124SN/A        if (fault == NoFault) {
1972124SN/A            %(op_wb)s;
1982124SN/A            xc->setEA(EA);
1992124SN/A        }
2002124SN/A
2012124SN/A        return fault;
2022124SN/A    }
2032124SN/A}};
2042124SN/A
2052124SN/Adef template LoadMemAccExecute {{
2062132SN/A    Fault
2072124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2082124SN/A                                   Trace::InstRecord *traceData) const
2092124SN/A    {
2102239SN/A        Addr EA;
2112132SN/A        Fault fault = NoFault;
2122239SN/A
2132239SN/A        %(fp_enable_check)s;
2142239SN/A        %(op_decl)s;
2152239SN/A        %(op_rd)s;
2162239SN/A        EA = xc->getEA();
2172239SN/A
2182239SN/A        if (fault == NoFault) {
2192239SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2202239SN/A            %(code)s;
2212239SN/A        }
2222239SN/A
2232239SN/A        if (fault == NoFault) {
2242239SN/A            %(op_wb)s;
2252239SN/A        }
2262239SN/A
2272124SN/A        return fault;
2282124SN/A    }
2292124SN/A}};
2302124SN/A
2312124SN/A
2322124SN/Adef template LoadExecute {{
2332132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2342124SN/A                                  Trace::InstRecord *traceData) const
2352124SN/A    {
2362124SN/A        Addr EA;
2372132SN/A        Fault fault = NoFault;
2382124SN/A
2392124SN/A        %(fp_enable_check)s;
2402124SN/A        %(op_decl)s;
2412124SN/A        %(op_rd)s;
2422124SN/A        %(ea_code)s;
2432124SN/A
2442124SN/A        if (fault == NoFault) {
2452124SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2462124SN/A            %(memacc_code)s;
2472124SN/A        }
2482124SN/A
2492124SN/A        if (fault == NoFault) {
2502124SN/A            %(op_wb)s;
2512124SN/A        }
2522124SN/A
2532124SN/A        return fault;
2542124SN/A    }
2552124SN/A}};
2562124SN/A
2572124SN/A
2582124SN/Adef template LoadInitiateAcc {{
2592132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2602124SN/A                                      Trace::InstRecord *traceData) const
2612124SN/A    {
2622239SN/A        Addr EA;
2632132SN/A        Fault fault = NoFault;
2642239SN/A
2652239SN/A        %(fp_enable_check)s;
2662239SN/A        %(op_src_decl)s;
2672239SN/A        %(op_rd)s;
2682239SN/A        %(ea_code)s;
2692239SN/A
2702239SN/A        if (fault == NoFault) {
2712239SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2722239SN/A        }
2732239SN/A
2742124SN/A        return fault;
2752124SN/A    }
2762124SN/A}};
2772124SN/A
2782124SN/A
2792124SN/Adef template LoadCompleteAcc {{
2802132SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
2812124SN/A                                      %(CPU_exec_context)s *xc,
2822124SN/A                                      Trace::InstRecord *traceData) const
2832124SN/A    {
2842132SN/A        Fault fault = NoFault;
2852239SN/A
2862239SN/A        %(fp_enable_check)s;
2872506SN/A        %(op_decl)s;
2882239SN/A
2892239SN/A        memcpy(&Mem, data, sizeof(Mem));
2902239SN/A
2912239SN/A        if (fault == NoFault) {
2922239SN/A            %(memacc_code)s;
2932239SN/A        }
2942239SN/A
2952239SN/A        if (fault == NoFault) {
2962239SN/A            %(op_wb)s;
2972239SN/A        }
2982239SN/A
2992124SN/A        return fault;
3002124SN/A    }
3012124SN/A}};
3022124SN/A
3032124SN/A
3042124SN/Adef template StoreMemAccExecute {{
3052132SN/A    Fault
3062124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3072124SN/A                                   Trace::InstRecord *traceData) const
3082124SN/A    {
3092239SN/A        Addr EA;
3102132SN/A        Fault fault = NoFault;
3112239SN/A        uint64_t write_result = 0;
3122239SN/A
3132239SN/A        %(fp_enable_check)s;
3142239SN/A        %(op_decl)s;
3152239SN/A        %(op_rd)s;
3162239SN/A        EA = xc->getEA();
3172239SN/A
3182239SN/A        if (fault == NoFault) {
3192239SN/A            %(code)s;
3202239SN/A        }
3212239SN/A
3222239SN/A        if (fault == NoFault) {
3232239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3242239SN/A                              memAccessFlags, &write_result);
3252239SN/A            if (traceData) { traceData->setData(Mem); }
3262239SN/A        }
3272239SN/A
3282239SN/A        if (fault == NoFault) {
3292239SN/A            %(postacc_code)s;
3302239SN/A        }
3312239SN/A
3322239SN/A        if (fault == NoFault) {
3332239SN/A            %(op_wb)s;
3342239SN/A        }
3352239SN/A
3362124SN/A        return fault;
3372124SN/A    }
3382124SN/A}};
3392124SN/A
3402124SN/A
3412124SN/Adef template StoreExecute {{
3422132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3432124SN/A                                  Trace::InstRecord *traceData) const
3442124SN/A    {
3452124SN/A        Addr EA;
3462132SN/A        Fault fault = NoFault;
3472124SN/A        uint64_t write_result = 0;
3482124SN/A
3492124SN/A        %(fp_enable_check)s;
3502124SN/A        %(op_decl)s;
3512124SN/A        %(op_rd)s;
3522124SN/A        %(ea_code)s;
3532124SN/A
3542124SN/A        if (fault == NoFault) {
3552124SN/A            %(memacc_code)s;
3562124SN/A        }
3572124SN/A
3582124SN/A        if (fault == NoFault) {
3592124SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3602124SN/A                              memAccessFlags, &write_result);
3612124SN/A            if (traceData) { traceData->setData(Mem); }
3622124SN/A        }
3632124SN/A
3642124SN/A        if (fault == NoFault) {
3652124SN/A            %(postacc_code)s;
3662124SN/A        }
3672124SN/A
3682124SN/A        if (fault == NoFault) {
3692124SN/A            %(op_wb)s;
3702124SN/A        }
3712124SN/A
3722124SN/A        return fault;
3732124SN/A    }
3742124SN/A}};
3752124SN/A
3762124SN/Adef template StoreInitiateAcc {{
3772132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3782124SN/A                                      Trace::InstRecord *traceData) const
3792124SN/A    {
3802239SN/A        Addr EA;
3812132SN/A        Fault fault = NoFault;
3822239SN/A        uint64_t write_result = 0;
3832239SN/A
3842239SN/A        %(fp_enable_check)s;
3852506SN/A        %(op_decl)s;
3862239SN/A        %(op_rd)s;
3872239SN/A        %(ea_code)s;
3882239SN/A
3892239SN/A        if (fault == NoFault) {
3902239SN/A            %(memacc_code)s;
3912239SN/A        }
3922239SN/A
3932239SN/A        if (fault == NoFault) {
3942239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3952239SN/A                              memAccessFlags, &write_result);
3962239SN/A            if (traceData) { traceData->setData(Mem); }
3972239SN/A        }
3982239SN/A
3992124SN/A        return fault;
4002124SN/A    }
4012124SN/A}};
4022124SN/A
4032124SN/A
4042124SN/Adef template StoreCompleteAcc {{
4052132SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
4062124SN/A                                      %(CPU_exec_context)s *xc,
4072124SN/A                                      Trace::InstRecord *traceData) const
4082124SN/A    {
4092132SN/A        Fault fault = NoFault;
4102239SN/A        uint64_t write_result = 0;
4112239SN/A
4122239SN/A        %(fp_enable_check)s;
4132239SN/A        %(op_dest_decl)s;
4142239SN/A
4152239SN/A        memcpy(&write_result, data, sizeof(write_result));
4162239SN/A
4172239SN/A        if (fault == NoFault) {
4182239SN/A            %(postacc_code)s;
4192239SN/A        }
4202239SN/A
4212239SN/A        if (fault == NoFault) {
4222239SN/A            %(op_wb)s;
4232239SN/A        }
4242239SN/A
4252124SN/A        return fault;
4262124SN/A    }
4272124SN/A}};
4282124SN/A
4292124SN/A// load instructions use Rt as dest, so check for
4302124SN/A// Rt == 31 to detect nops
4312124SN/Adef template LoadNopCheckDecode {{
4322124SN/A {
4332124SN/A     MipsStaticInst *i = new %(class_name)s(machInst);
4342124SN/A     if (RT == 0) {
4352124SN/A         i = makeNop(i);
4362124SN/A     }
4372124SN/A     return i;
4382124SN/A }
4392124SN/A}};
4402124SN/A
4412124SN/Adef format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4422124SN/A                     mem_flags = [], inst_flags = []) {{
4432124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4442124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4452124SN/A                      decode_template = LoadNopCheckDecode,
4462124SN/A                      exec_template_base = 'Load')
4472124SN/A}};
4482124SN/A
4492124SN/A
4502124SN/Adef format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4512124SN/A                     mem_flags = [], inst_flags = []) {{
4522124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4532124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4542124SN/A                      exec_template_base = 'Store')
4552124SN/A}};
4562124SN/A
4572573SN/A//FP loads are offloaded to these formats for now ...
4582573SN/Adef format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4592573SN/A                     mem_flags = [], inst_flags = []) {{
4602573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4612573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4622573SN/A                      decode_template = BasicDecode,
4632573SN/A                      exec_template_base = 'Load')
4642573SN/A}};
4652573SN/A
4662573SN/A
4672573SN/Adef format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
4682573SN/A                     mem_flags = [], inst_flags = []) {{
4692573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4702573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4712573SN/A                      exec_template_base = 'Store')
4722573SN/A}};
4732573SN/A
4742573SN/A
4752495SN/Adef format UnalignedStore(memacc_code, postacc_code,
4762495SN/A                     ea_code = {{ EA = Rb + disp; }},
4772495SN/A                     mem_flags = [], inst_flags = []) {{
4782495SN/A    (header_output, decoder_output, decode_block, exec_output) = \
4792495SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4802495SN/A                      postacc_code, exec_template_base = 'Store')
4812495SN/A}};
482