blockmem.isa revision 3391
13388Sgblack@eecs.umich.edu// Copyright (c) 2006 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
593270SN/A        class BlockMemMicro : public SparcDelayedMicroInst
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) :
663270SN/A                SparcDelayedMicroInst(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);
1033270SN/A            if(save)
1043270SN/A            {
1053270SN/A                printReg(response, _srcRegIdx[0]);
1063270SN/A                ccprintf(response, ", ");
1073270SN/A            }
1083270SN/A            ccprintf(response, "[ ");
1093270SN/A            printReg(response, _srcRegIdx[!save ? 0 : 1]);
1103270SN/A            ccprintf(response, " + ");
1113270SN/A            printReg(response, _srcRegIdx[!save ? 1 : 2]);
1123270SN/A            ccprintf(response, " ]");
1133270SN/A            if(load)
1143270SN/A            {
1153270SN/A                ccprintf(response, ", ");
1163270SN/A                printReg(response, _destRegIdx[0]);
1173270SN/A            }
1183270SN/A
1193270SN/A            return response.str();
1203270SN/A        }
1213270SN/A
1223280SN/A        std::string BlockMemImmMicro::generateDisassembly(Addr pc,
1233270SN/A                const SymbolTable *symtab) const
1243270SN/A        {
1253270SN/A            std::stringstream response;
1263270SN/A            bool load = flags[IsLoad];
1273270SN/A            bool save = flags[IsStore];
1283270SN/A
1293270SN/A            printMnemonic(response, mnemonic);
1303270SN/A            if(save)
1313270SN/A            {
1323379SN/A                printReg(response, _srcRegIdx[1]);
1333270SN/A                ccprintf(response, ", ");
1343270SN/A            }
1353270SN/A            ccprintf(response, "[ ");
1363379SN/A            printReg(response, _srcRegIdx[0]);
1373270SN/A            if(imm >= 0)
1383270SN/A                ccprintf(response, " + 0x%x ]", imm);
1393270SN/A            else
1403270SN/A                ccprintf(response, " + -0x%x ]", -imm);
1413270SN/A            if(load)
1423270SN/A            {
1433270SN/A                ccprintf(response, ", ");
1443270SN/A                printReg(response, _destRegIdx[0]);
1453270SN/A            }
1463270SN/A
1473270SN/A            return response.str();
1483270SN/A        }
1493270SN/A
1503270SN/A}};
1513270SN/A
1523270SN/Adef template BlockMemDeclare {{
1533270SN/A        /**
1543270SN/A         * Static instruction class for a block memory operation
1553270SN/A         */
1563270SN/A        class %(class_name)s : public %(base_class)s
1573270SN/A        {
1583270SN/A          public:
1593270SN/A            //Constructor
1603280SN/A            %(class_name)s(ExtMachInst machInst);
1613270SN/A
1623274SN/A          protected:
1633270SN/A            class %(class_name)s_0 : public %(base_class)sMicro
1643270SN/A            {
1653274SN/A              public:
1663270SN/A                //Constructor
1673280SN/A                %(class_name)s_0(ExtMachInst machInst);
1683270SN/A                %(BasicExecDeclare)s
1693391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
1703391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
1713270SN/A            };
1723270SN/A
1733270SN/A            class %(class_name)s_1 : public %(base_class)sMicro
1743270SN/A            {
1753274SN/A              public:
1763270SN/A                //Constructor
1773280SN/A                %(class_name)s_1(ExtMachInst machInst);
1783270SN/A                %(BasicExecDeclare)s
1793391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
1803391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
1813270SN/A            };
1823270SN/A
1833270SN/A            class %(class_name)s_2 : public %(base_class)sMicro
1843270SN/A            {
1853274SN/A              public:
1863270SN/A                //Constructor
1873280SN/A                %(class_name)s_2(ExtMachInst machInst);
1883270SN/A                %(BasicExecDeclare)s
1893391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
1903391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
1913270SN/A            };
1923270SN/A
1933270SN/A            class %(class_name)s_3 : public %(base_class)sMicro
1943270SN/A            {
1953274SN/A              public:
1963270SN/A                //Constructor
1973280SN/A                %(class_name)s_3(ExtMachInst machInst);
1983270SN/A                %(BasicExecDeclare)s
1993391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2003391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2013270SN/A            };
2023270SN/A
2033270SN/A            class %(class_name)s_4 : public %(base_class)sMicro
2043270SN/A            {
2053274SN/A              public:
2063270SN/A                //Constructor
2073280SN/A                %(class_name)s_4(ExtMachInst machInst);
2083270SN/A                %(BasicExecDeclare)s
2093391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2103391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2113270SN/A            };
2123270SN/A
2133270SN/A            class %(class_name)s_5 : public %(base_class)sMicro
2143270SN/A            {
2153274SN/A              public:
2163270SN/A                //Constructor
2173280SN/A                %(class_name)s_5(ExtMachInst machInst);
2183270SN/A                %(BasicExecDeclare)s
2193391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2203391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2213270SN/A            };
2223270SN/A
2233270SN/A            class %(class_name)s_6 : public %(base_class)sMicro
2243270SN/A            {
2253274SN/A              public:
2263270SN/A                //Constructor
2273280SN/A                %(class_name)s_6(ExtMachInst machInst);
2283270SN/A                %(BasicExecDeclare)s
2293391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2303391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2313270SN/A            };
2323270SN/A
2333270SN/A            class %(class_name)s_7 : public %(base_class)sMicro
2343270SN/A            {
2353274SN/A              public:
2363270SN/A                //Constructor
2373280SN/A                %(class_name)s_7(ExtMachInst machInst);
2383270SN/A                %(BasicExecDeclare)s
2393391Sgblack@eecs.umich.edu                %(InitiateAccDeclare)s
2403391Sgblack@eecs.umich.edu                %(CompleteAccDeclare)s
2413270SN/A            };
2423270SN/A        };
2433270SN/A}};
2443270SN/A
2453270SN/A// Basic instruction class constructor template.
2463270SN/Adef template BlockMemConstructor {{
2473280SN/A        inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2483388Sgblack@eecs.umich.edu            : %(base_class)s("%(mnemonic)s", machInst)
2493270SN/A        {
2503270SN/A            %(constructor)s;
2513274SN/A            microOps[0] = new %(class_name)s_0(machInst);
2523274SN/A            microOps[1] = new %(class_name)s_1(machInst);
2533274SN/A            microOps[2] = new %(class_name)s_2(machInst);
2543274SN/A            microOps[3] = new %(class_name)s_3(machInst);
2553274SN/A            microOps[4] = new %(class_name)s_4(machInst);
2563274SN/A            microOps[5] = new %(class_name)s_5(machInst);
2573274SN/A            microOps[6] = new %(class_name)s_6(machInst);
2583274SN/A            microOps[7] = new %(class_name)s_7(machInst);
2593270SN/A        }
2603270SN/A}};
2613270SN/A
2623280SN/Adef template BlockMemMicroConstructor {{
2633280SN/A        inline %(class_name)s::
2643280SN/A            %(class_name)s_%(micro_pc)s::
2653280SN/A            %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
2663280SN/A                %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
2673280SN/A                        machInst, %(op_class)s, %(micro_pc)s * 8)
2683280SN/A    {
2693280SN/A        %(constructor)s;
2703280SN/A        %(set_flags)s;
2713280SN/A    }
2723280SN/A}};
2733280SN/A
2743270SN/Alet {{
2753270SN/A
2763391Sgblack@eecs.umich.edu    def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
2773270SN/A        # XXX Need to take care of pstate.hpriv as well. The lower ASIs
2783270SN/A        # are split into ones that are available in priv and hpriv, and
2793270SN/A        # those that are only available in hpriv
2803379SN/A        addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
2813379SN/A        addrCalcImm = 'EA = Rs1 + imm + offset;'
2823274SN/A        iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
2833274SN/A        iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
2843270SN/A        header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
2853270SN/A        decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
2863270SN/A        decode_block = ROrImmDecode.subst(iop)
2873274SN/A        matcher = re.compile(r'Frd_N')
2883274SN/A        exec_output = ''
2893391Sgblack@eecs.umich.edu        for microPc in range(8):
2903280SN/A            flag_code = ''
2913391Sgblack@eecs.umich.edu            if (microPc == 7):
2923388Sgblack@eecs.umich.edu                flag_code = "flags[IsLastMicroOp] = true;"
2933391Sgblack@eecs.umich.edu            pcedCode = matcher.sub("Frd_%d" % microPc, code)
2943274SN/A            iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
2953274SN/A                    opt_flags, {"ea_code": addrCalcReg,
2963391Sgblack@eecs.umich.edu                    "fault_check": faultCode, "micro_pc": microPc,
2973280SN/A                    "set_flags": flag_code})
2983274SN/A            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
2993274SN/A                    opt_flags, {"ea_code": addrCalcImm,
3003391Sgblack@eecs.umich.edu                    "fault_check": faultCode, "micro_pc": microPc,
3013280SN/A                    "set_flags": flag_code})
3023280SN/A            decoder_output += BlockMemMicroConstructor.subst(iop)
3033280SN/A            decoder_output += BlockMemMicroConstructor.subst(iop_imm)
3043391Sgblack@eecs.umich.edu            exec_output += doSplitExecute(
3053391Sgblack@eecs.umich.edu                    pcedCode, addrCalcReg, addrCalcImm, execute, faultCode,
3063391Sgblack@eecs.umich.edu                    makeMicroName(name, microPc),
3073391Sgblack@eecs.umich.edu                    makeMicroName(name + "Imm", microPc),
3083391Sgblack@eecs.umich.edu                    makeMicroName(Name, microPc),
3093391Sgblack@eecs.umich.edu                    makeMicroName(Name + "Imm", microPc),
3103391Sgblack@eecs.umich.edu                    opt_flags);
3113391Sgblack@eecs.umich.edu            faultCode = ''
3123270SN/A        return (header_output, decoder_output, exec_output, decode_block)
3133270SN/A}};
3143270SN/A
3153270SN/Adef format BlockLoad(code, *opt_flags) {{
3163391Sgblack@eecs.umich.edu        # We need to make sure to check the highest priority fault last.
3173391Sgblack@eecs.umich.edu        # That way, if other faults have been detected, they'll be overwritten
3183391Sgblack@eecs.umich.edu        # rather than the other way around.
3193391Sgblack@eecs.umich.edu        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
3203270SN/A        (header_output,
3213270SN/A         decoder_output,
3223270SN/A         exec_output,
3233391Sgblack@eecs.umich.edu         decode_block) = doBlockMemFormat(code, faultCode,
3243391Sgblack@eecs.umich.edu             LoadExecute, name, Name, opt_flags)
3253270SN/A}};
3263270SN/A
3273270SN/Adef format BlockStore(code, *opt_flags) {{
3283391Sgblack@eecs.umich.edu        # We need to make sure to check the highest priority fault last.
3293391Sgblack@eecs.umich.edu        # That way, if other faults have been detected, they'll be overwritten
3303391Sgblack@eecs.umich.edu        # rather than the other way around.
3313391Sgblack@eecs.umich.edu        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
3323270SN/A        (header_output,
3333270SN/A         decoder_output,
3343270SN/A         exec_output,
3353391Sgblack@eecs.umich.edu         decode_block) = doBlockMemFormat(code, faultCode,
3363391Sgblack@eecs.umich.edu             StoreExecute, name, Name, opt_flags)
3373270SN/A}};
338