mem.isa revision 12327:38a7e269ae2a
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2016 The University of Virginia
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met: redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer;
11// redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution;
14// neither the name of the copyright holders nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Authors: Alec Roelke
31
32////////////////////////////////////////////////////////////////////
33//
34// Memory operation instructions
35//
36def template LoadStoreDeclare {{
37    /**
38     * Static instruction class for "%(mnemonic)s".
39     */
40    class %(class_name)s : public %(base_class)s
41    {
42      public:
43        /// Constructor.
44        %(class_name)s(ExtMachInst machInst);
45
46        Fault execute(ExecContext *, Trace::InstRecord *) const;
47        Fault eaComp(ExecContext *, Trace::InstRecord *) const;
48        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
49        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
50    };
51}};
52
53
54def template LoadStoreConstructor {{
55    %(class_name)s::%(class_name)s(ExtMachInst machInst):
56        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
57    {
58        %(constructor)s;
59        %(offset_code)s;
60    }
61}};
62
63def template EACompExecute {{
64    Fault
65    %(class_name)s::eaComp(ExecContext *xc, Trace::InstRecord *traceData) const
66    {
67        Addr EA;
68        Fault fault = NoFault;
69
70        %(op_decl)s;
71        %(op_rd)s;
72        %(ea_code)s;
73
74        if (fault == NoFault) {
75            %(op_wb)s;
76            xc->setEA(EA);
77        }
78
79        return fault;
80    }
81}};
82
83let {{
84def LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
85        inst_flags, base_class, postacc_code='', decode_template=BasicDecode,
86        exec_template_base=''):
87    # Make sure flags are in lists (convert to lists if not).
88    mem_flags = makeList(mem_flags)
89    inst_flags = makeList(inst_flags)
90
91    iop = InstObjParams(name, Name, base_class,
92        {'offset_code': offset_code, 'ea_code': ea_code,
93         'memacc_code': memacc_code, 'postacc_code': postacc_code },
94        inst_flags)
95
96    if mem_flags:
97        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
98        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
99        iop.constructor += s
100
101    # select templates
102
103    fullExecTemplate = eval(exec_template_base + 'Execute')
104    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
105    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
106
107    # (header_output, decoder_output, decode_block, exec_output)
108    return (LoadStoreDeclare.subst(iop),
109        LoadStoreConstructor.subst(iop),
110        decode_template.subst(iop),
111        fullExecTemplate.subst(iop) +
112        EACompExecute.subst(iop) +
113        initiateAccTemplate.subst(iop) +
114        completeAccTemplate.subst(iop))
115}};
116
117def template LoadExecute {{
118    Fault
119    %(class_name)s::execute(
120        ExecContext *xc, Trace::InstRecord *traceData) const
121    {
122        Addr EA;
123        Fault fault = NoFault;
124
125        %(op_decl)s;
126        %(op_rd)s;
127        %(ea_code)s;
128
129        if (fault == NoFault) {
130            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
131            %(memacc_code)s;
132        }
133
134        if (fault == NoFault) {
135            %(op_wb)s;
136        }
137
138        return fault;
139    }
140}};
141
142def template LoadInitiateAcc {{
143    Fault
144    %(class_name)s::initiateAcc(ExecContext *xc,
145        Trace::InstRecord *traceData) const
146    {
147        Addr EA;
148        Fault fault = NoFault;
149
150        %(op_src_decl)s;
151        %(op_rd)s;
152        %(ea_code)s;
153
154        if (fault == NoFault) {
155            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
156        }
157
158        return fault;
159    }
160}};
161
162def template LoadCompleteAcc {{
163    Fault
164    %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
165        Trace::InstRecord *traceData) const
166    {
167        Fault fault = NoFault;
168
169        %(op_decl)s;
170        %(op_rd)s;
171
172        getMem(pkt, Mem, traceData);
173
174        if (fault == NoFault) {
175            %(memacc_code)s;
176        }
177
178        if (fault == NoFault) {
179            %(op_wb)s;
180        }
181
182        return fault;
183    }
184}};
185
186def template StoreExecute {{
187    Fault
188    %(class_name)s::execute(ExecContext *xc,
189        Trace::InstRecord *traceData) const
190    {
191        Addr EA;
192        Fault fault = NoFault;
193
194        %(op_decl)s;
195        %(op_rd)s;
196        %(ea_code)s;
197
198        if (fault == NoFault) {
199            %(memacc_code)s;
200        }
201
202        if (fault == NoFault) {
203            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
204                nullptr);
205        }
206
207        if (fault == NoFault) {
208            %(postacc_code)s;
209        }
210
211        if (fault == NoFault) {
212            %(op_wb)s;
213        }
214
215        return fault;
216    }
217}};
218
219def template StoreInitiateAcc {{
220    Fault
221    %(class_name)s::initiateAcc(ExecContext *xc,
222        Trace::InstRecord *traceData) const
223    {
224        Addr EA;
225        Fault fault = NoFault;
226
227        %(op_decl)s;
228        %(op_rd)s;
229        %(ea_code)s;
230
231        if (fault == NoFault) {
232            %(memacc_code)s;
233        }
234
235        if (fault == NoFault) {
236            fault = writeMemTiming(xc, traceData, Mem, EA,
237                memAccessFlags, nullptr);
238        }
239
240        if (fault == NoFault) {
241            %(op_wb)s;
242        }
243
244        return fault;
245    }
246}};
247
248def template StoreCompleteAcc {{
249    Fault
250    %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
251        Trace::InstRecord *traceData) const
252    {
253        return NoFault;
254    }
255}};
256
257def format Load(memacc_code, ea_code={{EA = Rs1 + offset;}}, mem_flags=[],
258        inst_flags=[]) {{
259    offset_code = """
260                    offset = IMM12;
261                    if (IMMSIGN > 0)
262                        offset |= ~((uint64_t)0xFFF);
263                  """
264    (header_output, decoder_output, decode_block, exec_output) = \
265        LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
266        inst_flags, 'Load', exec_template_base='Load')
267}};
268
269def format Store(memacc_code, ea_code={{EA = Rs1 + offset;}}, mem_flags=[],
270        inst_flags=[]) {{
271    offset_code = """
272                    offset = IMM5 | (IMM7 << 5);
273                    if (IMMSIGN > 0)
274                        offset |= ~((uint64_t)0xFFF);
275                  """
276    (header_output, decoder_output, decode_block, exec_output) = \
277        LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
278        inst_flags, 'Store', exec_template_base='Store')
279}};
280