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/Adef template BlockMemDeclare {{
363270SN/A        /**
373270SN/A         * Static instruction class for a block memory operation
383270SN/A         */
393270SN/A        class %(class_name)s : public %(base_class)s
403270SN/A        {
413270SN/A          public:
427741Sgblack@eecs.umich.edu            // Constructor
433280SN/A            %(class_name)s(ExtMachInst machInst);
443270SN/A
453274SN/A          protected:
463270SN/A            class %(class_name)s_0 : public %(base_class)sMicro
473270SN/A            {
483274SN/A              public:
497741Sgblack@eecs.umich.edu                // Constructor
503280SN/A                %(class_name)s_0(ExtMachInst machInst);
5112616Sgabeblack@google.com                Fault execute(ExecContext *,
5212616Sgabeblack@google.com                              Trace::InstRecord *) const override;
5312616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
5412616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
5512236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
5612616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
573270SN/A            };
583270SN/A
593270SN/A            class %(class_name)s_1 : public %(base_class)sMicro
603270SN/A            {
613274SN/A              public:
627741Sgblack@eecs.umich.edu                // Constructor
633280SN/A                %(class_name)s_1(ExtMachInst machInst);
6412616Sgabeblack@google.com                Fault execute(ExecContext *,
6512616Sgabeblack@google.com                              Trace::InstRecord *) const override;
6612616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
6712616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
6812236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
6912616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
703270SN/A            };
713270SN/A
723270SN/A            class %(class_name)s_2 : public %(base_class)sMicro
733270SN/A            {
743274SN/A              public:
757741Sgblack@eecs.umich.edu                // Constructor
763280SN/A                %(class_name)s_2(ExtMachInst machInst);
7712616Sgabeblack@google.com                Fault execute(ExecContext *,
7812616Sgabeblack@google.com                              Trace::InstRecord *) const override;
7912616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
8012616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
8112236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
8212616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
833270SN/A            };
843270SN/A
853270SN/A            class %(class_name)s_3 : public %(base_class)sMicro
863270SN/A            {
873274SN/A              public:
887741Sgblack@eecs.umich.edu                // Constructor
893280SN/A                %(class_name)s_3(ExtMachInst machInst);
9012616Sgabeblack@google.com                Fault execute(ExecContext *,
9112616Sgabeblack@google.com                              Trace::InstRecord *) const override;
9212616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
9312616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
9412236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
9512616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
963270SN/A            };
973270SN/A
983270SN/A            class %(class_name)s_4 : public %(base_class)sMicro
993270SN/A            {
1003274SN/A              public:
1017741Sgblack@eecs.umich.edu                // Constructor
1023280SN/A                %(class_name)s_4(ExtMachInst machInst);
10312616Sgabeblack@google.com                Fault execute(ExecContext *,
10412616Sgabeblack@google.com                              Trace::InstRecord *) const override;
10512616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
10612616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
10712236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
10812616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
1093270SN/A            };
1103270SN/A
1113270SN/A            class %(class_name)s_5 : public %(base_class)sMicro
1123270SN/A            {
1133274SN/A              public:
1147741Sgblack@eecs.umich.edu                // Constructor
1153280SN/A                %(class_name)s_5(ExtMachInst machInst);
11612616Sgabeblack@google.com                Fault execute(ExecContext *,
11712616Sgabeblack@google.com                              Trace::InstRecord *) const override;
11812616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
11912616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
12012236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
12112616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
1223270SN/A            };
1233270SN/A
1243270SN/A            class %(class_name)s_6 : public %(base_class)sMicro
1253270SN/A            {
1263274SN/A              public:
1277741Sgblack@eecs.umich.edu                // Constructor
1283280SN/A                %(class_name)s_6(ExtMachInst machInst);
12912616Sgabeblack@google.com                Fault execute(ExecContext *,
13012616Sgabeblack@google.com                              Trace::InstRecord *) const override;
13112616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
13212616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
13312236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
13412616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
1353270SN/A            };
1363270SN/A
1373270SN/A            class %(class_name)s_7 : public %(base_class)sMicro
1383270SN/A            {
1393274SN/A              public:
1407741Sgblack@eecs.umich.edu                // Constructor
1413280SN/A                %(class_name)s_7(ExtMachInst machInst);
14212616Sgabeblack@google.com                Fault execute(ExecContext *,
14312616Sgabeblack@google.com                              Trace::InstRecord *) const override;
14412616Sgabeblack@google.com                Fault initiateAcc(ExecContext *,
14512616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
14612236Sgabeblack@google.com                Fault completeAcc(PacketPtr, ExecContext *,
14712616Sgabeblack@google.com                                  Trace::InstRecord *) const override;
1483270SN/A            };
1493270SN/A        };
1503270SN/A}};
1513270SN/A
1523270SN/A// Basic instruction class constructor template.
1533270SN/Adef template BlockMemConstructor {{
15410184SCurtis.Dunham@arm.com        %(class_name)s::%(class_name)s(ExtMachInst machInst)
1553388Sgblack@eecs.umich.edu            : %(base_class)s("%(mnemonic)s", machInst)
1563270SN/A        {
1573270SN/A            %(constructor)s;
1584539Sgblack@eecs.umich.edu            microops[0] = new %(class_name)s_0(machInst);
1594539Sgblack@eecs.umich.edu            microops[1] = new %(class_name)s_1(machInst);
1604539Sgblack@eecs.umich.edu            microops[2] = new %(class_name)s_2(machInst);
1614539Sgblack@eecs.umich.edu            microops[3] = new %(class_name)s_3(machInst);
1624539Sgblack@eecs.umich.edu            microops[4] = new %(class_name)s_4(machInst);
1634539Sgblack@eecs.umich.edu            microops[5] = new %(class_name)s_5(machInst);
1644539Sgblack@eecs.umich.edu            microops[6] = new %(class_name)s_6(machInst);
1654539Sgblack@eecs.umich.edu            microops[7] = new %(class_name)s_7(machInst);
1663270SN/A        }
1673270SN/A}};
1683270SN/A
1693280SN/Adef template BlockMemMicroConstructor {{
17010184SCurtis.Dunham@arm.com        %(class_name)s::
1713280SN/A            %(class_name)s_%(micro_pc)s::
1723280SN/A            %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
1733280SN/A                %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
1743280SN/A                        machInst, %(op_class)s, %(micro_pc)s * 8)
1753280SN/A    {
1763280SN/A        %(constructor)s;
1773280SN/A        %(set_flags)s;
1783280SN/A    }
1793280SN/A}};
1803280SN/A
1813270SN/Alet {{
1823270SN/A
1835096Sgblack@eecs.umich.edu    def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
1843270SN/A        # XXX Need to take care of pstate.hpriv as well. The lower ASIs
1853270SN/A        # are split into ones that are available in priv and hpriv, and
1863270SN/A        # those that are only available in hpriv
1873379SN/A        addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
1883379SN/A        addrCalcImm = 'EA = Rs1 + imm + offset;'
1893274SN/A        iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
1903274SN/A        iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
1913270SN/A        header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
1923270SN/A        decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
1933270SN/A        decode_block = ROrImmDecode.subst(iop)
1943274SN/A        matcher = re.compile(r'Frd_N')
1953274SN/A        exec_output = ''
1963391Sgblack@eecs.umich.edu        for microPc in range(8):
1973280SN/A            flag_code = ''
1983391Sgblack@eecs.umich.edu            if (microPc == 7):
1994539Sgblack@eecs.umich.edu                flag_code = "flags[IsLastMicroop] = true;"
2003901Ssaidi@eecs.umich.edu            elif (microPc == 0):
2014539Sgblack@eecs.umich.edu                flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;"
2023440Sgblack@eecs.umich.edu            else:
2033440Sgblack@eecs.umich.edu                flag_code = "flags[IsDelayedCommit] = true;"
2043391Sgblack@eecs.umich.edu            pcedCode = matcher.sub("Frd_%d" % microPc, code)
2053792Sgblack@eecs.umich.edu            iop = InstObjParams(name, Name, 'BlockMem',
2063792Sgblack@eecs.umich.edu                    {"code": pcedCode, "ea_code": addrCalcReg,
2073391Sgblack@eecs.umich.edu                    "fault_check": faultCode, "micro_pc": microPc,
2084648Sgblack@eecs.umich.edu                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
2094648Sgblack@eecs.umich.edu                    opt_flags)
2103792Sgblack@eecs.umich.edu            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
2113792Sgblack@eecs.umich.edu                    {"code": pcedCode, "ea_code": addrCalcImm,
2123391Sgblack@eecs.umich.edu                    "fault_check": faultCode, "micro_pc": microPc,
2134648Sgblack@eecs.umich.edu                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
2144648Sgblack@eecs.umich.edu                    opt_flags)
2153280SN/A            decoder_output += BlockMemMicroConstructor.subst(iop)
2163280SN/A            decoder_output += BlockMemMicroConstructor.subst(iop_imm)
2173439Sgblack@eecs.umich.edu            exec_output += doDualSplitExecute(
2184040Ssaidi@eecs.umich.edu                    pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode,
2193391Sgblack@eecs.umich.edu                    makeMicroName(name, microPc),
2203391Sgblack@eecs.umich.edu                    makeMicroName(name + "Imm", microPc),
2213391Sgblack@eecs.umich.edu                    makeMicroName(Name, microPc),
2223391Sgblack@eecs.umich.edu                    makeMicroName(Name + "Imm", microPc),
2235096Sgblack@eecs.umich.edu                    "EXT_ASI", opt_flags);
2243391Sgblack@eecs.umich.edu            faultCode = ''
2253270SN/A        return (header_output, decoder_output, exec_output, decode_block)
2263270SN/A}};
2273270SN/A
2285096Sgblack@eecs.umich.edudef format BlockLoad(code, *opt_flags) {{
2294362Sgblack@eecs.umich.edu        code = filterDoubles(code)
2303391Sgblack@eecs.umich.edu        # We need to make sure to check the highest priority fault last.
2313391Sgblack@eecs.umich.edu        # That way, if other faults have been detected, they'll be overwritten
2323391Sgblack@eecs.umich.edu        # rather than the other way around.
2333391Sgblack@eecs.umich.edu        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
2343270SN/A        (header_output,
2353270SN/A         decoder_output,
2363270SN/A         exec_output,
2373391Sgblack@eecs.umich.edu         decode_block) = doBlockMemFormat(code, faultCode,
2385096Sgblack@eecs.umich.edu             LoadFuncs, name, Name, opt_flags)
2393270SN/A}};
2403270SN/A
2415096Sgblack@eecs.umich.edudef format BlockStore(code, *opt_flags) {{
2424362Sgblack@eecs.umich.edu        code = filterDoubles(code)
2433391Sgblack@eecs.umich.edu        # We need to make sure to check the highest priority fault last.
2443391Sgblack@eecs.umich.edu        # That way, if other faults have been detected, they'll be overwritten
2453391Sgblack@eecs.umich.edu        # rather than the other way around.
2463391Sgblack@eecs.umich.edu        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
2473270SN/A        (header_output,
2483270SN/A         decoder_output,
2493270SN/A         exec_output,
2503391Sgblack@eecs.umich.edu         decode_block) = doBlockMemFormat(code, faultCode,
2515096Sgblack@eecs.umich.edu             StoreFuncs, name, Name, opt_flags)
2523270SN/A}};
253