blockmem.isa revision 12294:650a9d8b23cc
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 *, Trace::InstRecord *) const;
52                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
53                Fault completeAcc(PacketPtr, ExecContext *,
54                                  Trace::InstRecord *) const;
55            };
56
57            class %(class_name)s_1 : public %(base_class)sMicro
58            {
59              public:
60                // Constructor
61                %(class_name)s_1(ExtMachInst machInst);
62                Fault execute(ExecContext *, Trace::InstRecord *) const;
63                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
64                Fault completeAcc(PacketPtr, ExecContext *,
65                                  Trace::InstRecord *) const;
66            };
67
68            class %(class_name)s_2 : public %(base_class)sMicro
69            {
70              public:
71                // Constructor
72                %(class_name)s_2(ExtMachInst machInst);
73                Fault execute(ExecContext *, Trace::InstRecord *) const;
74                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
75                Fault completeAcc(PacketPtr, ExecContext *,
76                                  Trace::InstRecord *) const;
77            };
78
79            class %(class_name)s_3 : public %(base_class)sMicro
80            {
81              public:
82                // Constructor
83                %(class_name)s_3(ExtMachInst machInst);
84                Fault execute(ExecContext *, Trace::InstRecord *) const;
85                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
86                Fault completeAcc(PacketPtr, ExecContext *,
87                                  Trace::InstRecord *) const;
88            };
89
90            class %(class_name)s_4 : public %(base_class)sMicro
91            {
92              public:
93                // Constructor
94                %(class_name)s_4(ExtMachInst machInst);
95                Fault execute(ExecContext *, Trace::InstRecord *) const;
96                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
97                Fault completeAcc(PacketPtr, ExecContext *,
98                                  Trace::InstRecord *) const;
99            };
100
101            class %(class_name)s_5 : public %(base_class)sMicro
102            {
103              public:
104                // Constructor
105                %(class_name)s_5(ExtMachInst machInst);
106                Fault execute(ExecContext *, Trace::InstRecord *) const;
107                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
108                Fault completeAcc(PacketPtr, ExecContext *,
109                                  Trace::InstRecord *) const;
110            };
111
112            class %(class_name)s_6 : public %(base_class)sMicro
113            {
114              public:
115                // Constructor
116                %(class_name)s_6(ExtMachInst machInst);
117                Fault execute(ExecContext *, Trace::InstRecord *) const;
118                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
119                Fault completeAcc(PacketPtr, ExecContext *,
120                                  Trace::InstRecord *) const;
121            };
122
123            class %(class_name)s_7 : public %(base_class)sMicro
124            {
125              public:
126                // Constructor
127                %(class_name)s_7(ExtMachInst machInst);
128                Fault execute(ExecContext *, Trace::InstRecord *) const;
129                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
130                Fault completeAcc(PacketPtr, ExecContext *,
131                                  Trace::InstRecord *) const;
132            };
133        };
134}};
135
136// Basic instruction class constructor template.
137def template BlockMemConstructor {{
138        %(class_name)s::%(class_name)s(ExtMachInst machInst)
139            : %(base_class)s("%(mnemonic)s", machInst)
140        {
141            %(constructor)s;
142            microops[0] = new %(class_name)s_0(machInst);
143            microops[1] = new %(class_name)s_1(machInst);
144            microops[2] = new %(class_name)s_2(machInst);
145            microops[3] = new %(class_name)s_3(machInst);
146            microops[4] = new %(class_name)s_4(machInst);
147            microops[5] = new %(class_name)s_5(machInst);
148            microops[6] = new %(class_name)s_6(machInst);
149            microops[7] = new %(class_name)s_7(machInst);
150        }
151}};
152
153def template BlockMemMicroConstructor {{
154        %(class_name)s::
155            %(class_name)s_%(micro_pc)s::
156            %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
157                %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
158                        machInst, %(op_class)s, %(micro_pc)s * 8)
159    {
160        %(constructor)s;
161        %(set_flags)s;
162    }
163}};
164
165let {{
166
167    def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
168        # XXX Need to take care of pstate.hpriv as well. The lower ASIs
169        # are split into ones that are available in priv and hpriv, and
170        # those that are only available in hpriv
171        addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
172        addrCalcImm = 'EA = Rs1 + imm + offset;'
173        iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
174        iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
175        header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
176        decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
177        decode_block = ROrImmDecode.subst(iop)
178        matcher = re.compile(r'Frd_N')
179        exec_output = ''
180        for microPc in range(8):
181            flag_code = ''
182            if (microPc == 7):
183                flag_code = "flags[IsLastMicroop] = true;"
184            elif (microPc == 0):
185                flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;"
186            else:
187                flag_code = "flags[IsDelayedCommit] = true;"
188            pcedCode = matcher.sub("Frd_%d" % microPc, code)
189            iop = InstObjParams(name, Name, 'BlockMem',
190                    {"code": pcedCode, "ea_code": addrCalcReg,
191                    "fault_check": faultCode, "micro_pc": microPc,
192                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
193                    opt_flags)
194            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
195                    {"code": pcedCode, "ea_code": addrCalcImm,
196                    "fault_check": faultCode, "micro_pc": microPc,
197                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
198                    opt_flags)
199            decoder_output += BlockMemMicroConstructor.subst(iop)
200            decoder_output += BlockMemMicroConstructor.subst(iop_imm)
201            exec_output += doDualSplitExecute(
202                    pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode,
203                    makeMicroName(name, microPc),
204                    makeMicroName(name + "Imm", microPc),
205                    makeMicroName(Name, microPc),
206                    makeMicroName(Name + "Imm", microPc),
207                    "EXT_ASI", opt_flags);
208            faultCode = ''
209        return (header_output, decoder_output, exec_output, decode_block)
210}};
211
212def format BlockLoad(code, *opt_flags) {{
213        code = filterDoubles(code)
214        # We need to make sure to check the highest priority fault last.
215        # That way, if other faults have been detected, they'll be overwritten
216        # rather than the other way around.
217        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
218        (header_output,
219         decoder_output,
220         exec_output,
221         decode_block) = doBlockMemFormat(code, faultCode,
222             LoadFuncs, name, Name, opt_flags)
223}};
224
225def format BlockStore(code, *opt_flags) {{
226        code = filterDoubles(code)
227        # We need to make sure to check the highest priority fault last.
228        # That way, if other faults have been detected, they'll be overwritten
229        # rather than the other way around.
230        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
231        (header_output,
232         decoder_output,
233         exec_output,
234         decode_block) = doBlockMemFormat(code, faultCode,
235             StoreFuncs, name, Name, opt_flags)
236}};
237