mem.isa (12236:126ac9da6050) mem.isa (12322:e5a1d42b876b)
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//
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//
36output header {{
37 class Load : public RiscvStaticInst
38 {
39 public:
40 /// Displacement for EA calculation (signed).
41 int64_t ldisp;
42
43 protected:
44 /// Memory request flags. See mem_req_base.hh.
45 Request::Flags memAccessFlags;
46
47 /// Constructor
48 Load(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
49 : RiscvStaticInst(mnem, _machInst, __opClass), ldisp(0)
50 {}
51
52 std::string
53 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
54 };
55
56 class Store : public RiscvStaticInst
57 {
58 public:
59 /// Displacement for EA calculation (signed).
60 int64_t sdisp;
61
62 protected:
63 /// Memory request flags. See mem_req_base.hh.
64 Request::Flags memAccessFlags;
65
66 /// Constructor
67 Store(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
68 : RiscvStaticInst(mnem, _machInst, __opClass), sdisp(0)
69 {
70 sdisp = IMM5 | (IMM7 << 5);
71 if (IMMSIGN > 0)
72 sdisp |= ~((uint64_t)0xFFF);
73 }
74
75 std::string
76 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
77 };
78
79}};
80
81
82output decoder {{
83 std::string
84 Load::generateDisassembly(Addr pc, const SymbolTable *symtab) const
85 {
86 std::stringstream ss;
87 ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " <<
88 ldisp << '(' << registerName(_srcRegIdx[0]) << ')';
89 return ss.str();
90 }
91
92 std::string
93 Store::generateDisassembly(Addr pc, const SymbolTable *symtab) const
94 {
95 std::stringstream ss;
96 ss << mnemonic << ' ' << registerName(_srcRegIdx[1]) << ", " <<
97 sdisp << '(' << registerName(_srcRegIdx[0]) << ')';
98 return ss.str();
99 }
100}};
101
102def template LoadStoreDeclare {{
103 /**
104 * Static instruction class for "%(mnemonic)s".
105 */
106 class %(class_name)s : public %(base_class)s
107 {
108 public:
109 /// Constructor.
110 %(class_name)s(ExtMachInst machInst);
111
112 Fault execute(ExecContext *, Trace::InstRecord *) const;
113 Fault eaComp(ExecContext *, Trace::InstRecord *) const;
114 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
115 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
116 };
117}};
118
119
120def template LoadStoreConstructor {{
121 %(class_name)s::%(class_name)s(ExtMachInst machInst):
122 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
123 {
124 %(constructor)s;
125 %(offset_code)s;
126 }
127}};
128
129def template EACompExecute {{
130 Fault
131 %(class_name)s::eaComp(ExecContext *xc, Trace::InstRecord *traceData) const
132 {
133 Addr EA;
134 Fault fault = NoFault;
135
136 %(op_decl)s;
137 %(op_rd)s;
138 %(ea_code)s;
139
140 if (fault == NoFault) {
141 %(op_wb)s;
142 xc->setEA(EA);
143 }
144
145 return fault;
146 }
147}};
148
149let {{
150def LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
151 inst_flags, base_class, postacc_code='', decode_template=BasicDecode,
152 exec_template_base=''):
153 # Make sure flags are in lists (convert to lists if not).
154 mem_flags = makeList(mem_flags)
155 inst_flags = makeList(inst_flags)
156
157 iop = InstObjParams(name, Name, base_class,
158 {'offset_code': offset_code, 'ea_code': ea_code,
159 'memacc_code': memacc_code, 'postacc_code': postacc_code },
160 inst_flags)
161
162 if mem_flags:
163 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
164 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
165 iop.constructor += s
166
167 # select templates
168
169 fullExecTemplate = eval(exec_template_base + 'Execute')
170 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
171 completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
172
173 # (header_output, decoder_output, decode_block, exec_output)
174 return (LoadStoreDeclare.subst(iop),
175 LoadStoreConstructor.subst(iop),
176 decode_template.subst(iop),
177 fullExecTemplate.subst(iop) +
178 EACompExecute.subst(iop) +
179 initiateAccTemplate.subst(iop) +
180 completeAccTemplate.subst(iop))
181}};
182
183def template LoadExecute {{
184 Fault
185 %(class_name)s::execute(
186 ExecContext *xc, Trace::InstRecord *traceData) const
187 {
188 Addr EA;
189 Fault fault = NoFault;
190
191 %(op_decl)s;
192 %(op_rd)s;
193 %(ea_code)s;
194
195 if (fault == NoFault) {
196 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
197 %(memacc_code)s;
198 }
199
200 if (fault == NoFault) {
201 %(op_wb)s;
202 }
203
204 return fault;
205 }
206}};
207
208def template LoadInitiateAcc {{
209 Fault
210 %(class_name)s::initiateAcc(ExecContext *xc,
211 Trace::InstRecord *traceData) const
212 {
213 Addr EA;
214 Fault fault = NoFault;
215
216 %(op_src_decl)s;
217 %(op_rd)s;
218 %(ea_code)s;
219
220 if (fault == NoFault) {
221 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
222 }
223
224 return fault;
225 }
226}};
227
228def template LoadCompleteAcc {{
229 Fault
230 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
231 Trace::InstRecord *traceData) const
232 {
233 Fault fault = NoFault;
234
235 %(op_decl)s;
236 %(op_rd)s;
237
238 getMem(pkt, Mem, traceData);
239
240 if (fault == NoFault) {
241 %(memacc_code)s;
242 }
243
244 if (fault == NoFault) {
245 %(op_wb)s;
246 }
247
248 return fault;
249 }
250}};
251
252def template StoreExecute {{
253 Fault
254 %(class_name)s::execute(ExecContext *xc,
255 Trace::InstRecord *traceData) const
256 {
257 Addr EA;
258 Fault fault = NoFault;
259
260 %(op_decl)s;
261 %(op_rd)s;
262 %(ea_code)s;
263
264 if (fault == NoFault) {
265 %(memacc_code)s;
266 }
267
268 if (fault == NoFault) {
269 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
270 nullptr);
271 }
272
273 if (fault == NoFault) {
274 %(postacc_code)s;
275 }
276
277 if (fault == NoFault) {
278 %(op_wb)s;
279 }
280
281 return fault;
282 }
283}};
284
285def template StoreInitiateAcc {{
286 Fault
287 %(class_name)s::initiateAcc(ExecContext *xc,
288 Trace::InstRecord *traceData) const
289 {
290 Addr EA;
291 Fault fault = NoFault;
292
293 %(op_decl)s;
294 %(op_rd)s;
295 %(ea_code)s;
296
297 if (fault == NoFault) {
298 %(memacc_code)s;
299 }
300
301 if (fault == NoFault) {
302 fault = writeMemTiming(xc, traceData, Mem, EA,
303 memAccessFlags, nullptr);
304 }
305
306 if (fault == NoFault) {
307 %(op_wb)s;
308 }
309
310 return fault;
311 }
312}};
313
314def template StoreCompleteAcc {{
315 Fault
316 %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
317 Trace::InstRecord *traceData) const
318 {
319 return NoFault;
320 }
321}};
322
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
323def format Load(memacc_code, ea_code = {{EA = Rs1 + ldisp;}}, mem_flags=[],
257def format Load(memacc_code, ea_code = {{EA = Rs1 + offset;}}, mem_flags=[],
324 inst_flags=[]) {{
325 offset_code = """
258 inst_flags=[]) {{
259 offset_code = """
326 ldisp = IMM12;
260 offset = IMM12;
327 if (IMMSIGN > 0)
261 if (IMMSIGN > 0)
328 ldisp |= ~((uint64_t)0xFFF);
262 offset |= ~((uint64_t)0xFFF);
329 """
330 (header_output, decoder_output, decode_block, exec_output) = \
331 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
332 inst_flags, 'Load', exec_template_base='Load')
333}};
334
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
335def format Store(memacc_code, ea_code={{EA = Rs1 + sdisp;}}, mem_flags=[],
269def format Store(memacc_code, ea_code={{EA = Rs1 + offset;}}, mem_flags=[],
336 inst_flags=[]) {{
337 offset_code = """
270 inst_flags=[]) {{
271 offset_code = """
338 sdisp = IMM5 | (IMM7 << 5);
272 offset = IMM5 | (IMM7 << 5);
339 if (IMMSIGN > 0)
273 if (IMMSIGN > 0)
340 sdisp |= ~((uint64_t)0xFFF);
274 offset |= ~((uint64_t)0xFFF);
341 """
342 (header_output, decoder_output, decode_block, exec_output) = \
343 LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags,
344 inst_flags, 'Store', exec_template_base='Store')
345}};
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}};