basicmem.isa revision 3385
12315SN/A////////////////////////////////////////////////////////////////////
28733Sgeoffrey.blake@arm.com//
39913Ssteve.reinhardt@amd.com// Mem instructions
48733Sgeoffrey.blake@arm.com//
58733Sgeoffrey.blake@arm.com
68733Sgeoffrey.blake@arm.comoutput header {{
78733Sgeoffrey.blake@arm.com        /**
88733Sgeoffrey.blake@arm.com         * Base class for memory operations.
98733Sgeoffrey.blake@arm.com         */
108733Sgeoffrey.blake@arm.com        class Mem : public SparcStaticInst
118733Sgeoffrey.blake@arm.com        {
128733Sgeoffrey.blake@arm.com          protected:
138733Sgeoffrey.blake@arm.com
148733Sgeoffrey.blake@arm.com            // Constructor
152332SN/A            Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
162315SN/A                SparcStaticInst(mnem, _machInst, __opClass)
172315SN/A            {
182315SN/A            }
192315SN/A
202315SN/A            std::string generateDisassembly(Addr pc,
212315SN/A                    const SymbolTable *symtab) const;
222315SN/A        };
232315SN/A
242315SN/A        /**
252315SN/A         * Class for memory operations which use an immediate offset.
262315SN/A         */
272315SN/A        class MemImm : public Mem
282315SN/A        {
292315SN/A          protected:
302315SN/A
312315SN/A            // Constructor
322315SN/A            MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
332315SN/A                Mem(mnem, _machInst, __opClass)
342315SN/A            {
352315SN/A                imm = sext<13>(SIMM13);
362315SN/A            }
372315SN/A
382315SN/A            std::string generateDisassembly(Addr pc,
392315SN/A                    const SymbolTable *symtab) const;
402689SN/A
412689SN/A            int32_t imm;
428733Sgeoffrey.blake@arm.com        };
432315SN/A}};
442315SN/A
452315SN/Aoutput decoder {{
462315SN/A        std::string Mem::generateDisassembly(Addr pc,
472315SN/A                const SymbolTable *symtab) const
488888Sgeoffrey.blake@arm.com        {
498793Sgblack@eecs.umich.edu            std::stringstream response;
502315SN/A            bool load = flags[IsLoad];
516658Snate@binkert.org            bool save = flags[IsStore];
522315SN/A
538733Sgeoffrey.blake@arm.com            printMnemonic(response, mnemonic);
549913Ssteve.reinhardt@amd.com            if(save)
552683SN/A            {
568229Snate@binkert.org                printReg(response, _srcRegIdx[0]);
572680SN/A                ccprintf(response, ", ");
588733Sgeoffrey.blake@arm.com            }
598733Sgeoffrey.blake@arm.com            ccprintf(response, "[ ");
608793Sgblack@eecs.umich.edu            printReg(response, _srcRegIdx[!save ? 0 : 1]);
612315SN/A            ccprintf(response, " + ");
622315SN/A            printReg(response, _srcRegIdx[!save ? 1 : 2]);
632315SN/A            ccprintf(response, " ]");
642315SN/A            if(load)
658733Sgeoffrey.blake@arm.com            {
662315SN/A                ccprintf(response, ", ");
678733Sgeoffrey.blake@arm.com                printReg(response, _destRegIdx[0]);
682315SN/A            }
698733Sgeoffrey.blake@arm.com
708733Sgeoffrey.blake@arm.com            return response.str();
718733Sgeoffrey.blake@arm.com        }
728733Sgeoffrey.blake@arm.com
738733Sgeoffrey.blake@arm.com        std::string MemImm::generateDisassembly(Addr pc,
749023Sgblack@eecs.umich.edu                const SymbolTable *symtab) const
758733Sgeoffrey.blake@arm.com        {
768733Sgeoffrey.blake@arm.com            std::stringstream response;
778733Sgeoffrey.blake@arm.com            bool load = flags[IsLoad];
788733Sgeoffrey.blake@arm.com            bool save = flags[IsStore];
798733Sgeoffrey.blake@arm.com
808733Sgeoffrey.blake@arm.com            printMnemonic(response, mnemonic);
818733Sgeoffrey.blake@arm.com            if(save)
828733Sgeoffrey.blake@arm.com            {
838733Sgeoffrey.blake@arm.com                printReg(response, _srcRegIdx[0]);
848733Sgeoffrey.blake@arm.com                ccprintf(response, ", ");
858733Sgeoffrey.blake@arm.com            }
868733Sgeoffrey.blake@arm.com            ccprintf(response, "[ ");
878733Sgeoffrey.blake@arm.com            printReg(response, _srcRegIdx[!save ? 0 : 1]);
888733Sgeoffrey.blake@arm.com            if(imm >= 0)
898733Sgeoffrey.blake@arm.com                ccprintf(response, " + 0x%x ]", imm);
908733Sgeoffrey.blake@arm.com            else
918733Sgeoffrey.blake@arm.com                ccprintf(response, " + -0x%x ]", -imm);
928733Sgeoffrey.blake@arm.com            if(load)
938733Sgeoffrey.blake@arm.com            {
948733Sgeoffrey.blake@arm.com                ccprintf(response, ", ");
958733Sgeoffrey.blake@arm.com                printReg(response, _destRegIdx[0]);
968733Sgeoffrey.blake@arm.com            }
978733Sgeoffrey.blake@arm.com
988733Sgeoffrey.blake@arm.com            return response.str();
998733Sgeoffrey.blake@arm.com        }
1008733Sgeoffrey.blake@arm.com
1018733Sgeoffrey.blake@arm.com}};
1028733Sgeoffrey.blake@arm.com
1038733Sgeoffrey.blake@arm.comdef template LoadExecute {{
1048733Sgeoffrey.blake@arm.com        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
1058733Sgeoffrey.blake@arm.com                Trace::InstRecord *traceData) const
1068733Sgeoffrey.blake@arm.com        {
1078733Sgeoffrey.blake@arm.com            Fault fault = NoFault;
1088733Sgeoffrey.blake@arm.com            Addr EA;
1098733Sgeoffrey.blake@arm.com            %(op_decl)s;
1108733Sgeoffrey.blake@arm.com            %(op_rd)s;
1118733Sgeoffrey.blake@arm.com            %(priv_check)s;
1128733Sgeoffrey.blake@arm.com            %(ea_code)s;
1138733Sgeoffrey.blake@arm.com            DPRINTF(Sparc, "The address is 0x%x\n", EA);
1148733Sgeoffrey.blake@arm.com            fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
1158733Sgeoffrey.blake@arm.com            %(code)s;
1168733Sgeoffrey.blake@arm.com            if(fault == NoFault)
1178733Sgeoffrey.blake@arm.com            {
1189023Sgblack@eecs.umich.edu                //Write the resulting state to the execution context
1198733Sgeoffrey.blake@arm.com                %(op_wb)s;
1208733Sgeoffrey.blake@arm.com            }
1218733Sgeoffrey.blake@arm.com
1228733Sgeoffrey.blake@arm.com            return fault;
1238733Sgeoffrey.blake@arm.com        }
1248733Sgeoffrey.blake@arm.com
1252315SN/A        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
1262315SN/A                Trace::InstRecord * traceData) const
1272315SN/A        {
1288733Sgeoffrey.blake@arm.com            Fault fault = NoFault;
1298733Sgeoffrey.blake@arm.com            Addr EA;
1308733Sgeoffrey.blake@arm.com            uint%(mem_acc_size)s_t Mem;
1318733Sgeoffrey.blake@arm.com            %(ea_decl)s;
1328733Sgeoffrey.blake@arm.com            %(ea_rd)s;
1338733Sgeoffrey.blake@arm.com            %(priv_check)s;
1348733Sgeoffrey.blake@arm.com            %(ea_code)s;
1358733Sgeoffrey.blake@arm.com            fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
1368733Sgeoffrey.blake@arm.com            return fault;
1378733Sgeoffrey.blake@arm.com        }
1388733Sgeoffrey.blake@arm.com
1398733Sgeoffrey.blake@arm.com        Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
1402332SN/A                Trace::InstRecord * traceData) const
1412332SN/A        {
1422332SN/A            Fault fault = NoFault;
1432332SN/A            %(code_decl)s;
1442332SN/A            %(code_rd)s;
1452315SN/A            Mem = pkt->get<typeof(Mem)>();
1462315SN/A            %(code)s;
1478733Sgeoffrey.blake@arm.com            if(fault == NoFault)
1488733Sgeoffrey.blake@arm.com            {
1492315SN/A                %(code_wb)s;
1502315SN/A            }
1512315SN/A            return fault;
1522315SN/A        }
1532315SN/A}};
1542315SN/A
1552315SN/Adef template StoreExecute {{
1562315SN/A        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
1572315SN/A                Trace::InstRecord *traceData) const
1582315SN/A        {
1592315SN/A            Fault fault = NoFault;
1602315SN/A            uint64_t write_result = 0;
1612315SN/A            Addr EA;
1628733Sgeoffrey.blake@arm.com            %(op_decl)s;
1638733Sgeoffrey.blake@arm.com            %(op_rd)s;
1642315SN/A            %(priv_check)s;
1652315SN/A            %(ea_code)s;
1662315SN/A            DPRINTF(Sparc, "The address is 0x%x\n", EA);
1672315SN/A            %(code)s;
1682315SN/A
1692315SN/A            if(fault == NoFault)
1702315SN/A            {
1712315SN/A                fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
1722315SN/A            }
1732315SN/A            if(fault == NoFault)
1742315SN/A            {
1752315SN/A                //Write the resulting state to the execution context
1762315SN/A                %(op_wb)s;
1772315SN/A            }
1788733Sgeoffrey.blake@arm.com
1798733Sgeoffrey.blake@arm.com            return fault;
1808733Sgeoffrey.blake@arm.com        }
1818733Sgeoffrey.blake@arm.com
1828733Sgeoffrey.blake@arm.com        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
1838733Sgeoffrey.blake@arm.com                Trace::InstRecord * traceData) const
1848733Sgeoffrey.blake@arm.com        {
1852354SN/A            Fault fault = NoFault;
1868733Sgeoffrey.blake@arm.com            uint64_t write_result = 0;
1872354SN/A            Addr EA;
1882332SN/A            %(op_decl)s;
1892332SN/A            %(op_rd)s;
1902332SN/A            %(priv_check)s;
1912315SN/A            %(ea_code)s;
1928733Sgeoffrey.blake@arm.com            DPRINTF(Sparc, "The address is 0x%x\n", EA);
1938733Sgeoffrey.blake@arm.com            %(code)s;
1948733Sgeoffrey.blake@arm.com            if(fault == NoFault)
1958733Sgeoffrey.blake@arm.com            {
1968733Sgeoffrey.blake@arm.com                fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
1978733Sgeoffrey.blake@arm.com            }
1988733Sgeoffrey.blake@arm.com            if(fault == NoFault)
1998733Sgeoffrey.blake@arm.com            {
2008733Sgeoffrey.blake@arm.com                //Write the resulting state to the execution context
2012315SN/A                %(op_wb)s;
2022315SN/A            }
2032315SN/A            return fault;
2042315SN/A        }
2052315SN/A
2062683SN/A        Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
2078888Sgeoffrey.blake@arm.com                Trace::InstRecord * traceData) const
2088888Sgeoffrey.blake@arm.com        {
2098888Sgeoffrey.blake@arm.com            return NoFault;
2102315SN/A        }
2112332SN/A}};
2122332SN/A
2132332SN/Adef template LoadStoreExecute {{
2142315SN/A        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2158733Sgeoffrey.blake@arm.com                Trace::InstRecord *traceData) const
2168733Sgeoffrey.blake@arm.com        {
2172315SN/A            Fault fault = NoFault;
2188733Sgeoffrey.blake@arm.com            uint64_t write_result = 0;
2192315SN/A            Addr EA;
2202315SN/A            %(op_decl)s;
2212332SN/A            %(op_rd)s;
2228733Sgeoffrey.blake@arm.com            %(priv_check)s;
2238733Sgeoffrey.blake@arm.com            %(ea_code)s;
2242732SN/A            DPRINTF(Sparc, "The address is 0x%x\n", EA);
2252315SN/A            xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
2262315SN/A            %(code)s;
2272315SN/A
2282315SN/A            if(fault == NoFault)
2292315SN/A            {
2302315SN/A                xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
2312315SN/A                //Write the resulting state to the execution context
2328733Sgeoffrey.blake@arm.com                %(op_wb)s;
2332315SN/A            }
2342315SN/A
2352315SN/A            return fault;
2362332SN/A        }
2378733Sgeoffrey.blake@arm.com}};
2388733Sgeoffrey.blake@arm.com
2392332SN/Adef template MemDeclare {{
2408733Sgeoffrey.blake@arm.com        /**
2418733Sgeoffrey.blake@arm.com         * Static instruction class for "%(mnemonic)s".
2428733Sgeoffrey.blake@arm.com         */
2432332SN/A        class %(class_name)s : public %(base_class)s
2449023Sgblack@eecs.umich.edu        {
2459023Sgblack@eecs.umich.edu          public:
2468733Sgeoffrey.blake@arm.com
2478733Sgeoffrey.blake@arm.com            /// Constructor.
2488733Sgeoffrey.blake@arm.com            %(class_name)s(ExtMachInst machInst);
2498733Sgeoffrey.blake@arm.com
2508733Sgeoffrey.blake@arm.com            %(BasicExecDeclare)s
2518733Sgeoffrey.blake@arm.com
2528887Sgeoffrey.blake@arm.com            %(InitiateAccDeclare)s
2538733Sgeoffrey.blake@arm.com
2548733Sgeoffrey.blake@arm.com            %(CompleteAccDeclare)s
2558733Sgeoffrey.blake@arm.com        };
2568832SAli.Saidi@ARM.com}};
2572679SN/A
2582315SN/Adef template InitiateAccDeclare {{
2598733Sgeoffrey.blake@arm.com    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
2602315SN/A}};
2618733Sgeoffrey.blake@arm.com
2628733Sgeoffrey.blake@arm.comdef template CompleteAccDeclare {{
2638733Sgeoffrey.blake@arm.com    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
2648733Sgeoffrey.blake@arm.com}};
2658733Sgeoffrey.blake@arm.com
2668733Sgeoffrey.blake@arm.com
2678733Sgeoffrey.blake@arm.comlet {{
2688733Sgeoffrey.blake@arm.com    # XXX Need to take care of pstate.hpriv as well. The lower ASIs are split
2698733Sgeoffrey.blake@arm.com    # into ones that are available in priv and hpriv, and those that are only
2708733Sgeoffrey.blake@arm.com    # available in hpriv
2712315SN/A    privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
2728733Sgeoffrey.blake@arm.com                return new PrivilegedAction;
2738733Sgeoffrey.blake@arm.com            if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2))
2742315SN/A                return new PrivilegedAction;'''
2758733Sgeoffrey.blake@arm.com
2768733Sgeoffrey.blake@arm.com    def doMemFormat(code, execute, priv, name, Name, opt_flags):
2778733Sgeoffrey.blake@arm.com        addrCalcReg = 'EA = Rs1 + Rs2;'
2788733Sgeoffrey.blake@arm.com        addrCalcImm = 'EA = Rs1 + imm;'
2798733Sgeoffrey.blake@arm.com        ea_iop = InstObjParams(name, Name, 'Mem',
2808733Sgeoffrey.blake@arm.com                addrCalcReg, opt_flags, {"priv_check": priv})
2818733Sgeoffrey.blake@arm.com        ea_iop_imm = InstObjParams(name, Name, 'MemImm',
2828733Sgeoffrey.blake@arm.com                addrCalcImm, opt_flags, {"priv_check": priv})
2838733Sgeoffrey.blake@arm.com        code_iop = InstObjParams(name, Name, 'Mem', code, opt_flags)
2848733Sgeoffrey.blake@arm.com        iop = InstObjParams(name, Name, 'Mem', code,
2858733Sgeoffrey.blake@arm.com                opt_flags, {"ea_code": addrCalcReg,
2868733Sgeoffrey.blake@arm.com                "priv_check": priv})
2878733Sgeoffrey.blake@arm.com        (iop.ea_decl,
2888949Sandreas.hansson@arm.com         iop.ea_rd,
2898733Sgeoffrey.blake@arm.com         iop.ea_wb) = (ea_iop.op_decl, ea_iop.op_rd, ea_iop.op_wb)
2908733Sgeoffrey.blake@arm.com        (iop.code_decl,
2918733Sgeoffrey.blake@arm.com         iop.code_rd,
2928733Sgeoffrey.blake@arm.com         iop.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
2938733Sgeoffrey.blake@arm.com        iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code,
2948733Sgeoffrey.blake@arm.com                opt_flags, {"ea_code": addrCalcImm,
2958733Sgeoffrey.blake@arm.com                "priv_check": priv})
2968733Sgeoffrey.blake@arm.com        (iop_imm.ea_decl,
2978733Sgeoffrey.blake@arm.com         iop_imm.ea_rd,
2988733Sgeoffrey.blake@arm.com         iop_imm.ea_wb) = (ea_iop_imm.op_decl, ea_iop_imm.op_rd, ea_iop_imm.op_wb)
2998733Sgeoffrey.blake@arm.com        (iop_imm.code_decl,
3008733Sgeoffrey.blake@arm.com         iop_imm.code_rd,
3018733Sgeoffrey.blake@arm.com         iop_imm.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
3028733Sgeoffrey.blake@arm.com        header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
3038733Sgeoffrey.blake@arm.com        decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
3048733Sgeoffrey.blake@arm.com        decode_block = ROrImmDecode.subst(iop)
3058733Sgeoffrey.blake@arm.com        exec_output = execute.subst(iop) + execute.subst(iop_imm)
3068733Sgeoffrey.blake@arm.com        return (header_output, decoder_output, exec_output, decode_block)
3078733Sgeoffrey.blake@arm.com}};
3088733Sgeoffrey.blake@arm.com
3098733Sgeoffrey.blake@arm.comdef format LoadAlt(code, *opt_flags) {{
3108733Sgeoffrey.blake@arm.com        (header_output,
3118733Sgeoffrey.blake@arm.com         decoder_output,
3128733Sgeoffrey.blake@arm.com         exec_output,
3139023Sgblack@eecs.umich.edu         decode_block) = doMemFormat(code, LoadExecute,
3148733Sgeoffrey.blake@arm.com            privelegedString, name, Name, opt_flags)
3158733Sgeoffrey.blake@arm.com}};
3168733Sgeoffrey.blake@arm.com
3178733Sgeoffrey.blake@arm.comdef format StoreAlt(code, *opt_flags) {{
3189023Sgblack@eecs.umich.edu        (header_output,
3198733Sgeoffrey.blake@arm.com         decoder_output,
3209023Sgblack@eecs.umich.edu         exec_output,
3218733Sgeoffrey.blake@arm.com         decode_block) = doMemFormat(code, StoreExecute,
3228733Sgeoffrey.blake@arm.com            privilegedString, name, Name, opt_flags)
3238733Sgeoffrey.blake@arm.com}};
3248733Sgeoffrey.blake@arm.com
3258733Sgeoffrey.blake@arm.comdef format Load(code, *opt_flags) {{
3268733Sgeoffrey.blake@arm.com        (header_output,
3278733Sgeoffrey.blake@arm.com         decoder_output,
3288733Sgeoffrey.blake@arm.com         exec_output,
3298733Sgeoffrey.blake@arm.com         decode_block) = doMemFormat(code,
3308733Sgeoffrey.blake@arm.com             LoadExecute, '', name, Name, opt_flags)
3318733Sgeoffrey.blake@arm.com}};
3328733Sgeoffrey.blake@arm.com
3338733Sgeoffrey.blake@arm.comdef format Store(code, *opt_flags) {{
3348733Sgeoffrey.blake@arm.com        (header_output,
3358733Sgeoffrey.blake@arm.com         decoder_output,
3368733Sgeoffrey.blake@arm.com         exec_output,
3378733Sgeoffrey.blake@arm.com         decode_block) = doMemFormat(code,
3388733Sgeoffrey.blake@arm.com             StoreExecute, '', name, Name, opt_flags)
3398733Sgeoffrey.blake@arm.com}};
3408733Sgeoffrey.blake@arm.com
3418733Sgeoffrey.blake@arm.comdef format LoadStore(code, *opt_flags) {{
3422323SN/A        (header_output,
3432315SN/A         decoder_output,
3449023Sgblack@eecs.umich.edu         exec_output,
3459023Sgblack@eecs.umich.edu         decode_block) = doMemFormat(code,
3462315SN/A             LoadStoreExecute, '', name, Name, opt_flags)
3478733Sgeoffrey.blake@arm.com}};
3488733Sgeoffrey.blake@arm.com