mem.isa (6691:cd68b6ecd68d) mem.isa (7045:e21fe6a62b1c)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2009 The University of Edinburgh
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Timothy M. Jones
30
31////////////////////////////////////////////////////////////////////
32//
33// Memory-format instructions
34//
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
44 /// Constructor.
45 %(class_name)s(ExtMachInst machInst);
46
47 %(BasicExecDeclare)s
48
49 %(InitiateAccDeclare)s
50
51 %(CompleteAccDeclare)s
52 };
53}};
54
55
56def template InitiateAccDeclare {{
57 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
58}};
59
60
61def template CompleteAccDeclare {{
62 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
63}};
64
65
66def template LoadStoreConstructor {{
67 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
68 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
69 {
70 %(constructor)s;
71 }
72}};
73
74
75def template LoadExecute {{
76 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
77 Trace::InstRecord *traceData) const
78 {
79 Addr EA;
80 Fault fault = NoFault;
81
82 %(op_decl)s;
83 %(op_rd)s;
84 %(ea_code)s;
85
86 if (fault == NoFault) {
87 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
88 %(memacc_code)s;
89 }
90
91 if (fault == NoFault) {
92 %(op_wb)s;
93 }
94
95 return fault;
96 }
97}};
98
99
100def template LoadInitiateAcc {{
101 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
102 Trace::InstRecord *traceData) const
103 {
104 Addr EA;
105 Fault fault = NoFault;
106
107 %(op_src_decl)s;
108 %(op_rd)s;
109 %(ea_code)s;
110
111 if (fault == NoFault) {
112 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
113 xc->setEA(EA);
114 }
115
116 return fault;
117 }
118}};
119
120
121def template LoadCompleteAcc {{
122 Fault %(class_name)s::completeAcc(PacketPtr pkt,
123 %(CPU_exec_context)s *xc,
124 Trace::InstRecord *traceData) const
125 {
126 Addr EA;
127 Fault fault = NoFault;
128 uint%(mem_acc_size)d_t val;
129
130 %(op_decl)s;
131 %(op_rd)s;
132
133 EA = xc->getEA();
134
135 val = pkt->get<uint%(mem_acc_size)d_t>();
136 *((uint%(mem_acc_size)d_t*)&Mem) = val;
137
138 if (fault == NoFault) {
139 %(memacc_code)s;
140 }
141
142 if (fault == NoFault) {
143 %(op_wb)s;
144 }
145
146 return fault;
147 }
148}};
149
150
151def template StoreExecute {{
152 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
153 Trace::InstRecord *traceData) const
154 {
155 Addr EA;
156 Fault fault = NoFault;
157
158 %(op_decl)s;
159 %(op_rd)s;
160 %(ea_code)s;
161
162 if (fault == NoFault) {
163 %(memacc_code)s;
164 }
165
166 if (fault == NoFault) {
167 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
168 memAccessFlags, NULL);
1// -*- mode:c++ -*-
2
3// Copyright (c) 2009 The University of Edinburgh
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Timothy M. Jones
30
31////////////////////////////////////////////////////////////////////
32//
33// Memory-format instructions
34//
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
44 /// Constructor.
45 %(class_name)s(ExtMachInst machInst);
46
47 %(BasicExecDeclare)s
48
49 %(InitiateAccDeclare)s
50
51 %(CompleteAccDeclare)s
52 };
53}};
54
55
56def template InitiateAccDeclare {{
57 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
58}};
59
60
61def template CompleteAccDeclare {{
62 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
63}};
64
65
66def template LoadStoreConstructor {{
67 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
68 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
69 {
70 %(constructor)s;
71 }
72}};
73
74
75def template LoadExecute {{
76 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
77 Trace::InstRecord *traceData) const
78 {
79 Addr EA;
80 Fault fault = NoFault;
81
82 %(op_decl)s;
83 %(op_rd)s;
84 %(ea_code)s;
85
86 if (fault == NoFault) {
87 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
88 %(memacc_code)s;
89 }
90
91 if (fault == NoFault) {
92 %(op_wb)s;
93 }
94
95 return fault;
96 }
97}};
98
99
100def template LoadInitiateAcc {{
101 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
102 Trace::InstRecord *traceData) const
103 {
104 Addr EA;
105 Fault fault = NoFault;
106
107 %(op_src_decl)s;
108 %(op_rd)s;
109 %(ea_code)s;
110
111 if (fault == NoFault) {
112 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
113 xc->setEA(EA);
114 }
115
116 return fault;
117 }
118}};
119
120
121def template LoadCompleteAcc {{
122 Fault %(class_name)s::completeAcc(PacketPtr pkt,
123 %(CPU_exec_context)s *xc,
124 Trace::InstRecord *traceData) const
125 {
126 Addr EA;
127 Fault fault = NoFault;
128 uint%(mem_acc_size)d_t val;
129
130 %(op_decl)s;
131 %(op_rd)s;
132
133 EA = xc->getEA();
134
135 val = pkt->get<uint%(mem_acc_size)d_t>();
136 *((uint%(mem_acc_size)d_t*)&Mem) = val;
137
138 if (fault == NoFault) {
139 %(memacc_code)s;
140 }
141
142 if (fault == NoFault) {
143 %(op_wb)s;
144 }
145
146 return fault;
147 }
148}};
149
150
151def template StoreExecute {{
152 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
153 Trace::InstRecord *traceData) const
154 {
155 Addr EA;
156 Fault fault = NoFault;
157
158 %(op_decl)s;
159 %(op_rd)s;
160 %(ea_code)s;
161
162 if (fault == NoFault) {
163 %(memacc_code)s;
164 }
165
166 if (fault == NoFault) {
167 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
168 memAccessFlags, NULL);
169 if (traceData) { traceData->setData(Mem); }
170 }
171
172 if (fault == NoFault) {
173 %(op_wb)s;
174 }
175
176 return fault;
177 }
178}};
179
180
181def template StoreInitiateAcc {{
182 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
183 Trace::InstRecord *traceData) const
184 {
185 Addr EA;
186 Fault fault = NoFault;
187
188 %(op_decl)s;
189 %(op_rd)s;
190 %(ea_code)s;
191
192 if (fault == NoFault) {
193 %(memacc_code)s;
194 }
195
196 if (fault == NoFault) {
197 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
198 memAccessFlags, NULL);
169 }
170
171 if (fault == NoFault) {
172 %(op_wb)s;
173 }
174
175 return fault;
176 }
177}};
178
179
180def template StoreInitiateAcc {{
181 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
182 Trace::InstRecord *traceData) const
183 {
184 Addr EA;
185 Fault fault = NoFault;
186
187 %(op_decl)s;
188 %(op_rd)s;
189 %(ea_code)s;
190
191 if (fault == NoFault) {
192 %(memacc_code)s;
193 }
194
195 if (fault == NoFault) {
196 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
197 memAccessFlags, NULL);
199 if (traceData) { traceData->setData(Mem); }
200 }
201
202 // Need to write back any potential address register update
203 if (fault == NoFault) {
204 %(op_wb)s;
205 }
206
207 return fault;
208 }
209}};
210
211
212def template StoreCompleteAcc {{
213 Fault %(class_name)s::completeAcc(PacketPtr pkt,
214 %(CPU_exec_context)s *xc,
215 Trace::InstRecord *traceData) const
216 {
217 Fault fault = NoFault;
218
219 %(op_dest_decl)s;
220
221 if (fault == NoFault) {
222 %(op_wb)s;
223 }
224
225 return fault;
226 }
227}};
228
229
230// The generic memory operation generator. This is called when two versions
231// of an instruction are needed - when Ra == 0 and otherwise. This is so
232// that instructions can use the value 0 when Ra == 0 but avoid having a
233// dependence on Ra.
234let {{
235
236def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
237 load_or_store, mem_flags = [], inst_flags = []):
238
239 # First the version where Ra is non-zero
240 (header_output, decoder_output, decode_block, exec_output) = \
241 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
242 base_class = base,
243 decode_template = CheckRaDecode,
244 exec_template_base = load_or_store)
245
246 # Now another version where Ra == 0
247 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
248 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
249 mem_flags, inst_flags,
250 base_class = base,
251 exec_template_base = load_or_store)
252
253 # Finally, add to the other outputs
254 header_output += header_output_ra0
255 decoder_output += decoder_output_ra0
256 exec_output += exec_output_ra0
257 return (header_output, decoder_output, decode_block, exec_output)
258
259}};
260
261
262def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
263 ea_code_ra0 = {{ EA = Rb; }},
264 mem_flags = [], inst_flags = []) {{
265 (header_output, decoder_output, decode_block, exec_output) = \
266 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
267 'MemOp', 'Load', mem_flags, inst_flags)
268}};
269
270
271def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
272 ea_code_ra0 = {{ EA = Rb; }},
273 mem_flags = [], inst_flags = []) {{
274 (header_output, decoder_output, decode_block, exec_output) = \
275 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
276 'MemOp', 'Store', mem_flags, inst_flags)
277}};
278
279
280def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
281 mem_flags = [], inst_flags = []) {{
282
283 # Add in the update code
284 memacc_code += 'Ra = EA;'
285
286 # Generate the class
287 (header_output, decoder_output, decode_block, exec_output) = \
288 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
289 base_class = 'MemOp',
290 exec_template_base = 'Load')
291}};
292
293
294def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
295 mem_flags = [], inst_flags = []) {{
296
297 # Add in the update code
298 memacc_code += 'Ra = EA;'
299
300 # Generate the class
301 (header_output, decoder_output, decode_block, exec_output) = \
302 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
303 base_class = 'MemOp',
304 exec_template_base = 'Store')
305}};
306
307
308def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
309 ea_code_ra0 = {{ EA = disp; }},
310 mem_flags = [], inst_flags = []) {{
311 (header_output, decoder_output, decode_block, exec_output) = \
312 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
313 'MemDispOp', 'Load', mem_flags, inst_flags)
314}};
315
316
317def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
318 ea_code_ra0 = {{ EA = disp; }},
319 mem_flags = [], inst_flags = []) {{
320 (header_output, decoder_output, decode_block, exec_output) = \
321 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
322 'MemDispOp', 'Store', mem_flags, inst_flags)
323}};
324
325
326def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
327 mem_flags = [], inst_flags = []) {{
328
329 # Add in the update code
330 memacc_code += 'Ra = EA;'
331
332 # Generate the class
333 (header_output, decoder_output, decode_block, exec_output) = \
334 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
335 base_class = 'MemDispOp',
336 exec_template_base = 'Load')
337}};
338
339
340def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
341 mem_flags = [], inst_flags = []) {{
342
343 # Add in the update code
344 memacc_code += 'Ra = EA;'
345
346 # Generate the class
347 (header_output, decoder_output, decode_block, exec_output) = \
348 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
349 base_class = 'MemDispOp',
350 exec_template_base = 'Store')
351}};
198 }
199
200 // Need to write back any potential address register update
201 if (fault == NoFault) {
202 %(op_wb)s;
203 }
204
205 return fault;
206 }
207}};
208
209
210def template StoreCompleteAcc {{
211 Fault %(class_name)s::completeAcc(PacketPtr pkt,
212 %(CPU_exec_context)s *xc,
213 Trace::InstRecord *traceData) const
214 {
215 Fault fault = NoFault;
216
217 %(op_dest_decl)s;
218
219 if (fault == NoFault) {
220 %(op_wb)s;
221 }
222
223 return fault;
224 }
225}};
226
227
228// The generic memory operation generator. This is called when two versions
229// of an instruction are needed - when Ra == 0 and otherwise. This is so
230// that instructions can use the value 0 when Ra == 0 but avoid having a
231// dependence on Ra.
232let {{
233
234def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
235 load_or_store, mem_flags = [], inst_flags = []):
236
237 # First the version where Ra is non-zero
238 (header_output, decoder_output, decode_block, exec_output) = \
239 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
240 base_class = base,
241 decode_template = CheckRaDecode,
242 exec_template_base = load_or_store)
243
244 # Now another version where Ra == 0
245 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
246 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
247 mem_flags, inst_flags,
248 base_class = base,
249 exec_template_base = load_or_store)
250
251 # Finally, add to the other outputs
252 header_output += header_output_ra0
253 decoder_output += decoder_output_ra0
254 exec_output += exec_output_ra0
255 return (header_output, decoder_output, decode_block, exec_output)
256
257}};
258
259
260def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
261 ea_code_ra0 = {{ EA = Rb; }},
262 mem_flags = [], inst_flags = []) {{
263 (header_output, decoder_output, decode_block, exec_output) = \
264 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
265 'MemOp', 'Load', mem_flags, inst_flags)
266}};
267
268
269def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
270 ea_code_ra0 = {{ EA = Rb; }},
271 mem_flags = [], inst_flags = []) {{
272 (header_output, decoder_output, decode_block, exec_output) = \
273 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
274 'MemOp', 'Store', mem_flags, inst_flags)
275}};
276
277
278def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
279 mem_flags = [], inst_flags = []) {{
280
281 # Add in the update code
282 memacc_code += 'Ra = EA;'
283
284 # Generate the class
285 (header_output, decoder_output, decode_block, exec_output) = \
286 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
287 base_class = 'MemOp',
288 exec_template_base = 'Load')
289}};
290
291
292def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
293 mem_flags = [], inst_flags = []) {{
294
295 # Add in the update code
296 memacc_code += 'Ra = EA;'
297
298 # Generate the class
299 (header_output, decoder_output, decode_block, exec_output) = \
300 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
301 base_class = 'MemOp',
302 exec_template_base = 'Store')
303}};
304
305
306def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
307 ea_code_ra0 = {{ EA = disp; }},
308 mem_flags = [], inst_flags = []) {{
309 (header_output, decoder_output, decode_block, exec_output) = \
310 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
311 'MemDispOp', 'Load', mem_flags, inst_flags)
312}};
313
314
315def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
316 ea_code_ra0 = {{ EA = disp; }},
317 mem_flags = [], inst_flags = []) {{
318 (header_output, decoder_output, decode_block, exec_output) = \
319 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
320 'MemDispOp', 'Store', mem_flags, inst_flags)
321}};
322
323
324def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
325 mem_flags = [], inst_flags = []) {{
326
327 # Add in the update code
328 memacc_code += 'Ra = EA;'
329
330 # Generate the class
331 (header_output, decoder_output, decode_block, exec_output) = \
332 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
333 base_class = 'MemDispOp',
334 exec_template_base = 'Load')
335}};
336
337
338def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
339 mem_flags = [], inst_flags = []) {{
340
341 # Add in the update code
342 memacc_code += 'Ra = EA;'
343
344 # Generate the class
345 (header_output, decoder_output, decode_block, exec_output) = \
346 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
347 base_class = 'MemDispOp',
348 exec_template_base = 'Store')
349}};