1// Copyright (c) 2006-2007 The Regents of The University of Michigan
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met: redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer;
8// redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution;
11// neither the name of the copyright holders nor the names of its
12// contributors may be used to endorse or promote products derived from
13// this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26//
27// Authors: Ali Saidi
28//          Gabe Black
29
30////////////////////////////////////////////////////////////////////
31//
32// Block Memory instructions
33//
34
35def template BlockMemDeclare {{
36        /**
37         * Static instruction class for a block memory operation
38         */
39        class %(class_name)s : public %(base_class)s
40        {
41          public:
42            // Constructor
43            %(class_name)s(ExtMachInst machInst);
44
45          protected:
46            class %(class_name)s_0 : public %(base_class)sMicro
47            {
48              public:
49                // Constructor
50                %(class_name)s_0(ExtMachInst machInst);
51                Fault execute(ExecContext *,
52                              Trace::InstRecord *) const override;
53                Fault initiateAcc(ExecContext *,
54                                  Trace::InstRecord *) const override;
55                Fault completeAcc(PacketPtr, ExecContext *,
56                                  Trace::InstRecord *) const override;
57            };
58
59            class %(class_name)s_1 : public %(base_class)sMicro
60            {
61              public:
62                // Constructor
63                %(class_name)s_1(ExtMachInst machInst);
64                Fault execute(ExecContext *,
65                              Trace::InstRecord *) const override;
66                Fault initiateAcc(ExecContext *,
67                                  Trace::InstRecord *) const override;
68                Fault completeAcc(PacketPtr, ExecContext *,
69                                  Trace::InstRecord *) const override;
70            };
71
72            class %(class_name)s_2 : public %(base_class)sMicro
73            {
74              public:
75                // Constructor
76                %(class_name)s_2(ExtMachInst machInst);
77                Fault execute(ExecContext *,
78                              Trace::InstRecord *) const override;
79                Fault initiateAcc(ExecContext *,
80                                  Trace::InstRecord *) const override;
81                Fault completeAcc(PacketPtr, ExecContext *,
82                                  Trace::InstRecord *) const override;
83            };
84
85            class %(class_name)s_3 : public %(base_class)sMicro
86            {
87              public:
88                // Constructor
89                %(class_name)s_3(ExtMachInst machInst);
90                Fault execute(ExecContext *,
91                              Trace::InstRecord *) const override;
92                Fault initiateAcc(ExecContext *,
93                                  Trace::InstRecord *) const override;
94                Fault completeAcc(PacketPtr, ExecContext *,
95                                  Trace::InstRecord *) const override;
96            };
97
98            class %(class_name)s_4 : public %(base_class)sMicro
99            {
100              public:
101                // Constructor
102                %(class_name)s_4(ExtMachInst machInst);
103                Fault execute(ExecContext *,
104                              Trace::InstRecord *) const override;
105                Fault initiateAcc(ExecContext *,
106                                  Trace::InstRecord *) const override;
107                Fault completeAcc(PacketPtr, ExecContext *,
108                                  Trace::InstRecord *) const override;
109            };
110
111            class %(class_name)s_5 : public %(base_class)sMicro
112            {
113              public:
114                // Constructor
115                %(class_name)s_5(ExtMachInst machInst);
116                Fault execute(ExecContext *,
117                              Trace::InstRecord *) const override;
118                Fault initiateAcc(ExecContext *,
119                                  Trace::InstRecord *) const override;
120                Fault completeAcc(PacketPtr, ExecContext *,
121                                  Trace::InstRecord *) const override;
122            };
123
124            class %(class_name)s_6 : public %(base_class)sMicro
125            {
126              public:
127                // Constructor
128                %(class_name)s_6(ExtMachInst machInst);
129                Fault execute(ExecContext *,
130                              Trace::InstRecord *) const override;
131                Fault initiateAcc(ExecContext *,
132                                  Trace::InstRecord *) const override;
133                Fault completeAcc(PacketPtr, ExecContext *,
134                                  Trace::InstRecord *) const override;
135            };
136
137            class %(class_name)s_7 : public %(base_class)sMicro
138            {
139              public:
140                // Constructor
141                %(class_name)s_7(ExtMachInst machInst);
142                Fault execute(ExecContext *,
143                              Trace::InstRecord *) const override;
144                Fault initiateAcc(ExecContext *,
145                                  Trace::InstRecord *) const override;
146                Fault completeAcc(PacketPtr, ExecContext *,
147                                  Trace::InstRecord *) const override;
148            };
149        };
150}};
151
152// Basic instruction class constructor template.
153def template BlockMemConstructor {{
154        %(class_name)s::%(class_name)s(ExtMachInst machInst)
155            : %(base_class)s("%(mnemonic)s", machInst)
156        {
157            %(constructor)s;
158            microops[0] = new %(class_name)s_0(machInst);
159            microops[1] = new %(class_name)s_1(machInst);
160            microops[2] = new %(class_name)s_2(machInst);
161            microops[3] = new %(class_name)s_3(machInst);
162            microops[4] = new %(class_name)s_4(machInst);
163            microops[5] = new %(class_name)s_5(machInst);
164            microops[6] = new %(class_name)s_6(machInst);
165            microops[7] = new %(class_name)s_7(machInst);
166        }
167}};
168
169def template BlockMemMicroConstructor {{
170        %(class_name)s::
171            %(class_name)s_%(micro_pc)s::
172            %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
173                %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
174                        machInst, %(op_class)s, %(micro_pc)s * 8)
175    {
176        %(constructor)s;
177        %(set_flags)s;
178    }
179}};
180
181let {{
182
183    def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
184        # XXX Need to take care of pstate.hpriv as well. The lower ASIs
185        # are split into ones that are available in priv and hpriv, and
186        # those that are only available in hpriv
187        addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
188        addrCalcImm = 'EA = Rs1 + imm + offset;'
189        iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
190        iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
191        header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
192        decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
193        decode_block = ROrImmDecode.subst(iop)
194        matcher = re.compile(r'Frd_N')
195        exec_output = ''
196        for microPc in range(8):
197            flag_code = ''
198            if (microPc == 7):
199                flag_code = "flags[IsLastMicroop] = true;"
200            elif (microPc == 0):
201                flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;"
202            else:
203                flag_code = "flags[IsDelayedCommit] = true;"
204            pcedCode = matcher.sub("Frd_%d" % microPc, code)
205            iop = InstObjParams(name, Name, 'BlockMem',
206                    {"code": pcedCode, "ea_code": addrCalcReg,
207                    "fault_check": faultCode, "micro_pc": microPc,
208                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
209                    opt_flags)
210            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
211                    {"code": pcedCode, "ea_code": addrCalcImm,
212                    "fault_check": faultCode, "micro_pc": microPc,
213                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
214                    opt_flags)
215            decoder_output += BlockMemMicroConstructor.subst(iop)
216            decoder_output += BlockMemMicroConstructor.subst(iop_imm)
217            exec_output += doDualSplitExecute(
218                    pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode,
219                    makeMicroName(name, microPc),
220                    makeMicroName(name + "Imm", microPc),
221                    makeMicroName(Name, microPc),
222                    makeMicroName(Name + "Imm", microPc),
223                    "EXT_ASI", opt_flags);
224            faultCode = ''
225        return (header_output, decoder_output, exec_output, decode_block)
226}};
227
228def format BlockLoad(code, *opt_flags) {{
229        code = filterDoubles(code)
230        # We need to make sure to check the highest priority fault last.
231        # That way, if other faults have been detected, they'll be overwritten
232        # rather than the other way around.
233        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
234        (header_output,
235         decoder_output,
236         exec_output,
237         decode_block) = doBlockMemFormat(code, faultCode,
238             LoadFuncs, name, Name, opt_flags)
239}};
240
241def format BlockStore(code, *opt_flags) {{
242        code = filterDoubles(code)
243        # We need to make sure to check the highest priority fault last.
244        # That way, if other faults have been detected, they'll be overwritten
245        # rather than the other way around.
246        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
247        (header_output,
248         decoder_output,
249         exec_output,
250         decode_block) = doBlockMemFormat(code, faultCode,
251             StoreFuncs, name, Name, opt_flags)
252}};
253