blockmem.isa revision 7741
13901Ssaidi@eecs.umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan
23388Sgblack@eecs.umich.edu// All rights reserved.
33388Sgblack@eecs.umich.edu//
43388Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
53388Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
63388Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
73388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
83388Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
93388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
103388Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
113388Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
123388Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
133388Sgblack@eecs.umich.edu// this software without specific prior written permission.
143388Sgblack@eecs.umich.edu//
153388Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
163388Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
173388Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
183388Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
193388Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
203388Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
213388Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
223388Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
233388Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
243388Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
253388Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
263388Sgblack@eecs.umich.edu//
273388Sgblack@eecs.umich.edu// Authors: Ali Saidi
283388Sgblack@eecs.umich.edu//          Gabe Black
293388Sgblack@eecs.umich.edu
303270SN/A////////////////////////////////////////////////////////////////////
313270SN/A//
323270SN/A// Block Memory instructions
333270SN/A//
343270SN/A
353270SN/Aoutput header {{
363270SN/A
373270SN/A        class BlockMem : public SparcMacroInst
383270SN/A        {
393270SN/A          protected:
403270SN/A
413270SN/A            // Constructor
423270SN/A            // We make the assumption that all block memory operations
433270SN/A            // Will take 8 instructions to execute
443388Sgblack@eecs.umich.edu            BlockMem(const char *mnem, ExtMachInst _machInst) :
453388Sgblack@eecs.umich.edu                SparcMacroInst(mnem, _machInst, No_OpClass, 8)
463270SN/A            {}
473270SN/A        };
483270SN/A
493270SN/A        class BlockMemImm : public BlockMem
503270SN/A        {
513270SN/A          protected:
523270SN/A
533270SN/A            // Constructor
543388Sgblack@eecs.umich.edu            BlockMemImm(const char *mnem, ExtMachInst _machInst) :
553388Sgblack@eecs.umich.edu                BlockMem(mnem, _machInst)
563270SN/A            {}
573270SN/A        };
583270SN/A
593440Sgblack@eecs.umich.edu        class BlockMemMicro : public SparcMicroInst
603270SN/A        {
613270SN/A          protected:
623270SN/A
633270SN/A            // Constructor
643270SN/A            BlockMemMicro(const char *mnem, ExtMachInst _machInst,
653270SN/A                    OpClass __opClass, int8_t _offset) :
663440Sgblack@eecs.umich.edu                SparcMicroInst(mnem, _machInst, __opClass),
673270SN/A                offset(_offset)
683270SN/A            {}
693270SN/A
703270SN/A            std::string generateDisassembly(Addr pc,
713270SN/A                const SymbolTable *symtab) const;
723270SN/A
733270SN/A            const int8_t offset;
743270SN/A        };
753270SN/A
763270SN/A        class BlockMemImmMicro : public BlockMemMicro
773270SN/A        {
783270SN/A          protected:
793270SN/A
803270SN/A            // Constructor
813270SN/A            BlockMemImmMicro(const char *mnem, ExtMachInst _machInst,
823270SN/A                    OpClass __opClass, int8_t _offset) :
833270SN/A                BlockMemMicro(mnem, _machInst, __opClass, _offset),
843270SN/A                imm(sext<13>(SIMM13))
853270SN/A            {}
863270SN/A
873270SN/A            std::string generateDisassembly(Addr pc,
883270SN/A                const SymbolTable *symtab) const;
893270SN/A
903270SN/A            const int32_t imm;
913270SN/A        };
923270SN/A}};
933270SN/A
943270SN/Aoutput decoder {{
953280SN/A        std::string BlockMemMicro::generateDisassembly(Addr pc,
963270SN/A                const SymbolTable *symtab) const
973270SN/A        {
983270SN/A            std::stringstream response;
993270SN/A            bool load = flags[IsLoad];
1003270SN/A            bool save = flags[IsStore];
1013270SN/A
1023270SN/A            printMnemonic(response, mnemonic);
1037741Sgblack@eecs.umich.edu            if (save) {
1043270SN/A                printReg(response, _srcRegIdx[0]);
1053270SN/A                ccprintf(response, ", ");
1063270SN/A            }
1073270SN/A            ccprintf(response, "[ ");
1083270SN/A            printReg(response, _srcRegIdx[!save ? 0 : 1]);
1093270SN/A            ccprintf(response, " + ");
1103270SN/A            printReg(response, _srcRegIdx[!save ? 1 : 2]);
1113270SN/A            ccprintf(response, " ]");
1127741Sgblack@eecs.umich.edu            if (load) {
1133270SN/A                ccprintf(response, ", ");
1143270SN/A                printReg(response, _destRegIdx[0]);
1153270SN/A            }
1163270SN/A
1173270SN/A            return response.str();
1183270SN/A        }
1193270SN/A
1203280SN/A        std::string BlockMemImmMicro::generateDisassembly(Addr pc,
1213270SN/A                const SymbolTable *symtab) const
1223270SN/A        {
1233270SN/A            std::stringstream response;
1243270SN/A            bool load = flags[IsLoad];
1253270SN/A            bool save = flags[IsStore];
1263270SN/A
1273270SN/A            printMnemonic(response, mnemonic);
1287741Sgblack@eecs.umich.edu            if (save) {
1293379SN/A                printReg(response, _srcRegIdx[1]);
1303270SN/A                ccprintf(response, ", ");
1313270SN/A            }
1323270SN/A            ccprintf(response, "[ ");
1333379SN/A            printReg(response, _srcRegIdx[0]);
1347741Sgblack@eecs.umich.edu            if (imm >= 0)
1353270SN/A                ccprintf(response, " + 0x%x ]", imm);
1363270SN/A            else
1373270SN/A                ccprintf(response, " + -0x%x ]", -imm);
1387741Sgblack@eecs.umich.edu            if (load) {
1393270SN/A                ccprintf(response, ", ");
1403270SN/A                printReg(response, _destRegIdx[0]);
1413270SN/A            }
1423270SN/A
1433270SN/A            return response.str();
1443270SN/A        }
1453270SN/A
1463270SN/A}};
1473270SN/A
1483270SN/Adef template BlockMemDeclare {{
1493270SN/A        /**
1503270SN/A         * Static instruction class for a block memory operation
1513270SN/A         */
1523270SN/A        class %(class_name)s : public %(base_class)s
1533270SN/A        {
1543270SN/A          public:
1557741Sgblack@eecs.umich.edu            // Constructor
1563280SN/A            %(class_name)s(ExtMachInst machInst);
1573270SN/A
1583274SN/A          protected:
1593270SN/A            class %(class_name)s_0 : public %(base_class)sMicro
1603270SN/A            {
1613274SN/A              public:
1627741Sgblack@eecs.umich.edu                // Constructor
1633280SN/A                %(class_name)s_0(ExtMachInst machInst);
1643270SN/A                %(BasicExecDeclare)s
1653391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
1663391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
1673270SN/A            };
1683270SN/A
1693270SN/A            class %(class_name)s_1 : public %(base_class)sMicro
1703270SN/A            {
1713274SN/A              public:
1727741Sgblack@eecs.umich.edu                // Constructor
1733280SN/A                %(class_name)s_1(ExtMachInst machInst);
1743270SN/A                %(BasicExecDeclare)s
1753391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
1763391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
1773270SN/A            };
1783270SN/A
1793270SN/A            class %(class_name)s_2 : public %(base_class)sMicro
1803270SN/A            {
1813274SN/A              public:
1827741Sgblack@eecs.umich.edu                // Constructor
1833280SN/A                %(class_name)s_2(ExtMachInst machInst);
1843270SN/A                %(BasicExecDeclare)s
1853391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
1863391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
1873270SN/A            };
1883270SN/A
1893270SN/A            class %(class_name)s_3 : public %(base_class)sMicro
1903270SN/A            {
1913274SN/A              public:
1927741Sgblack@eecs.umich.edu                // Constructor
1933280SN/A                %(class_name)s_3(ExtMachInst machInst);
1943270SN/A                %(BasicExecDeclare)s
1953391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
1963391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
1973270SN/A            };
1983270SN/A
1993270SN/A            class %(class_name)s_4 : public %(base_class)sMicro
2003270SN/A            {
2013274SN/A              public:
2027741Sgblack@eecs.umich.edu                // Constructor
2033280SN/A                %(class_name)s_4(ExtMachInst machInst);
2043270SN/A                %(BasicExecDeclare)s
2053391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2063391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2073270SN/A            };
2083270SN/A
2093270SN/A            class %(class_name)s_5 : public %(base_class)sMicro
2103270SN/A            {
2113274SN/A              public:
2127741Sgblack@eecs.umich.edu                // Constructor
2133280SN/A                %(class_name)s_5(ExtMachInst machInst);
2143270SN/A                %(BasicExecDeclare)s
2153391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2163391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2173270SN/A            };
2183270SN/A
2193270SN/A            class %(class_name)s_6 : public %(base_class)sMicro
2203270SN/A            {
2213274SN/A              public:
2227741Sgblack@eecs.umich.edu                // Constructor
2233280SN/A                %(class_name)s_6(ExtMachInst machInst);
2243270SN/A                %(BasicExecDeclare)s
2253391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2263391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2273270SN/A            };
2283270SN/A
2293270SN/A            class %(class_name)s_7 : public %(base_class)sMicro
2303270SN/A            {
2313274SN/A              public:
2327741Sgblack@eecs.umich.edu                // Constructor
2333280SN/A                %(class_name)s_7(ExtMachInst machInst);
2343270SN/A                %(BasicExecDeclare)s
2353391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2363391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2373270SN/A            };
2383270SN/A        };
2393270SN/A}};
2403270SN/A
2413270SN/A// Basic instruction class constructor template.
2423270SN/Adef template BlockMemConstructor {{
2433280SN/A        inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2443388Sgblack@eecs.umich.edu            : %(base_class)s("%(mnemonic)s", machInst)
2453270SN/A        {
2463270SN/A            %(constructor)s;
2474539Sgblack@eecs.umich.edu            microops[0] = new %(class_name)s_0(machInst);
2484539Sgblack@eecs.umich.edu            microops[1] = new %(class_name)s_1(machInst);
2494539Sgblack@eecs.umich.edu            microops[2] = new %(class_name)s_2(machInst);
2504539Sgblack@eecs.umich.edu            microops[3] = new %(class_name)s_3(machInst);
2514539Sgblack@eecs.umich.edu            microops[4] = new %(class_name)s_4(machInst);
2524539Sgblack@eecs.umich.edu            microops[5] = new %(class_name)s_5(machInst);
2534539Sgblack@eecs.umich.edu            microops[6] = new %(class_name)s_6(machInst);
2544539Sgblack@eecs.umich.edu            microops[7] = new %(class_name)s_7(machInst);
2553270SN/A        }
2563270SN/A}};
2573270SN/A
2583280SN/Adef template BlockMemMicroConstructor {{
2593280SN/A        inline %(class_name)s::
2603280SN/A            %(class_name)s_%(micro_pc)s::
2613280SN/A            %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
2623280SN/A                %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
2633280SN/A                        machInst, %(op_class)s, %(micro_pc)s * 8)
2643280SN/A    {
2653280SN/A        %(constructor)s;
2663280SN/A        %(set_flags)s;
2673280SN/A    }
2683280SN/A}};
2693280SN/A
2703270SN/Alet {{
2713270SN/A
2725096Sgblack@eecs.umich.edu    def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
2733270SN/A        # XXX Need to take care of pstate.hpriv as well. The lower ASIs
2743270SN/A        # are split into ones that are available in priv and hpriv, and
2753270SN/A        # those that are only available in hpriv
2763379SN/A        addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
2773379SN/A        addrCalcImm = 'EA = Rs1 + imm + offset;'
2783274SN/A        iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
2793274SN/A        iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
2803270SN/A        header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
2813270SN/A        decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
2823270SN/A        decode_block = ROrImmDecode.subst(iop)
2833274SN/A        matcher = re.compile(r'Frd_N')
2843274SN/A        exec_output = ''
2853391Sgblack@eecs.umich.edu        for microPc in range(8):
2863280SN/A            flag_code = ''
2873391Sgblack@eecs.umich.edu            if (microPc == 7):
2884539Sgblack@eecs.umich.edu                flag_code = "flags[IsLastMicroop] = true;"
2893901Ssaidi@eecs.umich.edu            elif (microPc == 0):
2904539Sgblack@eecs.umich.edu                flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;"
2913440Sgblack@eecs.umich.edu            else:
2923440Sgblack@eecs.umich.edu                flag_code = "flags[IsDelayedCommit] = true;"
2933391Sgblack@eecs.umich.edu            pcedCode = matcher.sub("Frd_%d" % microPc, code)
2943792Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name, 'BlockMem',
2953792Sgblack@eecs.umich.edu                    {"code": pcedCode, "ea_code": addrCalcReg,
2963391Sgblack@eecs.umich.edu                    "fault_check": faultCode, "micro_pc": microPc,
2974648Sgblack@eecs.umich.edu                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
2984648Sgblack@eecs.umich.edu                    opt_flags)
2993792Sgblack@eecs.umich.edu            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
3003792Sgblack@eecs.umich.edu                    {"code": pcedCode, "ea_code": addrCalcImm,
3013391Sgblack@eecs.umich.edu                    "fault_check": faultCode, "micro_pc": microPc,
3024648Sgblack@eecs.umich.edu                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
3034648Sgblack@eecs.umich.edu                    opt_flags)
3043280SN/A            decoder_output += BlockMemMicroConstructor.subst(iop)
3053280SN/A            decoder_output += BlockMemMicroConstructor.subst(iop_imm)
3063439Sgblack@eecs.umich.edu            exec_output += doDualSplitExecute(
3074040Ssaidi@eecs.umich.edu                    pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode,
3083391Sgblack@eecs.umich.edu                    makeMicroName(name, microPc),
3093391Sgblack@eecs.umich.edu                    makeMicroName(name + "Imm", microPc),
3103391Sgblack@eecs.umich.edu                    makeMicroName(Name, microPc),
3113391Sgblack@eecs.umich.edu                    makeMicroName(Name + "Imm", microPc),
3125096Sgblack@eecs.umich.edu                    "EXT_ASI", opt_flags);
3133391Sgblack@eecs.umich.edu            faultCode = ''
3143270SN/A        return (header_output, decoder_output, exec_output, decode_block)
3153270SN/A}};
3163270SN/A
3175096Sgblack@eecs.umich.edudef format BlockLoad(code, *opt_flags) {{
3184362Sgblack@eecs.umich.edu        code = filterDoubles(code)
3193391Sgblack@eecs.umich.edu        # We need to make sure to check the highest priority fault last.
3203391Sgblack@eecs.umich.edu        # That way, if other faults have been detected, they'll be overwritten
3213391Sgblack@eecs.umich.edu        # rather than the other way around.
3223391Sgblack@eecs.umich.edu        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
3233270SN/A        (header_output,
3243270SN/A         decoder_output,
3253270SN/A         exec_output,
3263391Sgblack@eecs.umich.edu         decode_block) = doBlockMemFormat(code, faultCode,
3275096Sgblack@eecs.umich.edu             LoadFuncs, name, Name, opt_flags)
3283270SN/A}};
3293270SN/A
3305096Sgblack@eecs.umich.edudef format BlockStore(code, *opt_flags) {{
3314362Sgblack@eecs.umich.edu        code = filterDoubles(code)
3323391Sgblack@eecs.umich.edu        # We need to make sure to check the highest priority fault last.
3333391Sgblack@eecs.umich.edu        # That way, if other faults have been detected, they'll be overwritten
3343391Sgblack@eecs.umich.edu        # rather than the other way around.
3353391Sgblack@eecs.umich.edu        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
3363270SN/A        (header_output,
3373270SN/A         decoder_output,
3383270SN/A         exec_output,
3393391Sgblack@eecs.umich.edu         decode_block) = doBlockMemFormat(code, faultCode,
3405096Sgblack@eecs.umich.edu             StoreFuncs, name, Name, opt_flags)
3413270SN/A}};
342