mem.isa (12234:78ece221f9f5) mem.isa (12236:126ac9da6050)
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
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
47 Fault execute(ExecContext *, Trace::InstRecord *) const;
48 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
49 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
52 };
53}};
54
55
50 };
51}};
52
53
56def template InitiateAccDeclare {{
57 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
58}};
59
60
61def template CompleteAccDeclare {{
62 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
63}};
64
65
66def template LoadStoreConstructor {{
67 %(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(ExecContext *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 = readMemAtomic(xc, traceData, EA, 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(ExecContext *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 = initiateMemRead(xc, traceData, EA, 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 ExecContext *xc,
124 Trace::InstRecord *traceData) const
125 {
126 Addr M5_VAR_USED EA;
127 Fault fault = NoFault;
128
129 %(op_decl)s;
130 %(op_rd)s;
131
132 EA = xc->getEA();
133
134 getMem(pkt, Mem, traceData);
135
136 if (fault == NoFault) {
137 %(memacc_code)s;
138 }
139
140 if (fault == NoFault) {
141 %(op_wb)s;
142 }
143
144 return fault;
145 }
146}};
147
148
149def template StoreExecute {{
150 Fault %(class_name)s::execute(ExecContext *xc,
151 Trace::InstRecord *traceData) const
152 {
153 Addr EA;
154 Fault fault = NoFault;
155
156 %(op_decl)s;
157 %(op_rd)s;
158 %(ea_code)s;
159
160 if (fault == NoFault) {
161 %(memacc_code)s;
162 }
163
164 if (fault == NoFault) {
165 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
166 NULL);
167 }
168
169 if (fault == NoFault) {
170 %(op_wb)s;
171 }
172
173 return fault;
174 }
175}};
176
177
178def template StoreInitiateAcc {{
179 Fault %(class_name)s::initiateAcc(ExecContext *xc,
180 Trace::InstRecord *traceData) const
181 {
182 Addr EA;
183 Fault fault = NoFault;
184
185 %(op_decl)s;
186 %(op_rd)s;
187 %(ea_code)s;
188
189 if (fault == NoFault) {
190 %(memacc_code)s;
191 }
192
193 if (fault == NoFault) {
194 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
195 NULL);
196 }
197
198 // Need to write back any potential address register update
199 if (fault == NoFault) {
200 %(op_wb)s;
201 }
202
203 return fault;
204 }
205}};
206
207
208def template StoreCompleteAcc {{
209 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
210 Trace::InstRecord *traceData) const
211 {
212 return NoFault;
213 }
214}};
215
216
217// The generic memory operation generator. This is called when two versions
218// of an instruction are needed - when Ra == 0 and otherwise. This is so
219// that instructions can use the value 0 when Ra == 0 but avoid having a
220// dependence on Ra.
221let {{
222
223def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
224 load_or_store, mem_flags = [], inst_flags = []):
225
226 # First the version where Ra is non-zero
227 (header_output, decoder_output, decode_block, exec_output) = \
228 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
229 base_class = base,
230 decode_template = CheckRaDecode,
231 exec_template_base = load_or_store)
232
233 # Now another version where Ra == 0
234 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
235 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
236 mem_flags, inst_flags,
237 base_class = base,
238 exec_template_base = load_or_store)
239
240 # Finally, add to the other outputs
241 header_output += header_output_ra0
242 decoder_output += decoder_output_ra0
243 exec_output += exec_output_ra0
244 return (header_output, decoder_output, decode_block, exec_output)
245
246}};
247
248
249def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
250 ea_code_ra0 = {{ EA = Rb; }},
251 mem_flags = [], inst_flags = []) {{
252 (header_output, decoder_output, decode_block, exec_output) = \
253 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
254 'MemOp', 'Load', mem_flags, inst_flags)
255}};
256
257
258def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
259 ea_code_ra0 = {{ EA = Rb; }},
260 mem_flags = [], inst_flags = []) {{
261 (header_output, decoder_output, decode_block, exec_output) = \
262 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
263 'MemOp', 'Store', mem_flags, inst_flags)
264}};
265
266
267def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
268 mem_flags = [], inst_flags = []) {{
269
270 # Add in the update code
271 memacc_code += 'Ra = EA;'
272
273 # Generate the class
274 (header_output, decoder_output, decode_block, exec_output) = \
275 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
276 base_class = 'MemOp',
277 exec_template_base = 'Load')
278}};
279
280
281def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
282 mem_flags = [], inst_flags = []) {{
283
284 # Add in the update code
285 memacc_code += 'Ra = EA;'
286
287 # Generate the class
288 (header_output, decoder_output, decode_block, exec_output) = \
289 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
290 base_class = 'MemOp',
291 exec_template_base = 'Store')
292}};
293
294
295def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
296 ea_code_ra0 = {{ EA = disp; }},
297 mem_flags = [], inst_flags = []) {{
298 (header_output, decoder_output, decode_block, exec_output) = \
299 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
300 'MemDispOp', 'Load', mem_flags, inst_flags)
301}};
302
303
304def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
305 ea_code_ra0 = {{ EA = disp; }},
306 mem_flags = [], inst_flags = []) {{
307 (header_output, decoder_output, decode_block, exec_output) = \
308 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
309 'MemDispOp', 'Store', mem_flags, inst_flags)
310}};
311
312
313def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
314 mem_flags = [], inst_flags = []) {{
315
316 # Add in the update code
317 memacc_code += 'Ra = EA;'
318
319 # Generate the class
320 (header_output, decoder_output, decode_block, exec_output) = \
321 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
322 base_class = 'MemDispOp',
323 exec_template_base = 'Load')
324}};
325
326
327def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
328 mem_flags = [], inst_flags = []) {{
329
330 # Add in the update code
331 memacc_code += 'Ra = EA;'
332
333 # Generate the class
334 (header_output, decoder_output, decode_block, exec_output) = \
335 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
336 base_class = 'MemDispOp',
337 exec_template_base = 'Store')
338}};
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 }
60}};
61
62
63def template LoadExecute {{
64 Fault %(class_name)s::execute(ExecContext *xc,
65 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 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
76 %(memacc_code)s;
77 }
78
79 if (fault == NoFault) {
80 %(op_wb)s;
81 }
82
83 return fault;
84 }
85}};
86
87
88def template LoadInitiateAcc {{
89 Fault %(class_name)s::initiateAcc(ExecContext *xc,
90 Trace::InstRecord *traceData) const
91 {
92 Addr EA;
93 Fault fault = NoFault;
94
95 %(op_src_decl)s;
96 %(op_rd)s;
97 %(ea_code)s;
98
99 if (fault == NoFault) {
100 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
101 xc->setEA(EA);
102 }
103
104 return fault;
105 }
106}};
107
108
109def template LoadCompleteAcc {{
110 Fault %(class_name)s::completeAcc(PacketPtr pkt,
111 ExecContext *xc,
112 Trace::InstRecord *traceData) const
113 {
114 Addr M5_VAR_USED EA;
115 Fault fault = NoFault;
116
117 %(op_decl)s;
118 %(op_rd)s;
119
120 EA = xc->getEA();
121
122 getMem(pkt, Mem, traceData);
123
124 if (fault == NoFault) {
125 %(memacc_code)s;
126 }
127
128 if (fault == NoFault) {
129 %(op_wb)s;
130 }
131
132 return fault;
133 }
134}};
135
136
137def template StoreExecute {{
138 Fault %(class_name)s::execute(ExecContext *xc,
139 Trace::InstRecord *traceData) const
140 {
141 Addr EA;
142 Fault fault = NoFault;
143
144 %(op_decl)s;
145 %(op_rd)s;
146 %(ea_code)s;
147
148 if (fault == NoFault) {
149 %(memacc_code)s;
150 }
151
152 if (fault == NoFault) {
153 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
154 NULL);
155 }
156
157 if (fault == NoFault) {
158 %(op_wb)s;
159 }
160
161 return fault;
162 }
163}};
164
165
166def template StoreInitiateAcc {{
167 Fault %(class_name)s::initiateAcc(ExecContext *xc,
168 Trace::InstRecord *traceData) const
169 {
170 Addr EA;
171 Fault fault = NoFault;
172
173 %(op_decl)s;
174 %(op_rd)s;
175 %(ea_code)s;
176
177 if (fault == NoFault) {
178 %(memacc_code)s;
179 }
180
181 if (fault == NoFault) {
182 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
183 NULL);
184 }
185
186 // Need to write back any potential address register update
187 if (fault == NoFault) {
188 %(op_wb)s;
189 }
190
191 return fault;
192 }
193}};
194
195
196def template StoreCompleteAcc {{
197 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
198 Trace::InstRecord *traceData) const
199 {
200 return NoFault;
201 }
202}};
203
204
205// The generic memory operation generator. This is called when two versions
206// of an instruction are needed - when Ra == 0 and otherwise. This is so
207// that instructions can use the value 0 when Ra == 0 but avoid having a
208// dependence on Ra.
209let {{
210
211def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
212 load_or_store, mem_flags = [], inst_flags = []):
213
214 # First the version where Ra is non-zero
215 (header_output, decoder_output, decode_block, exec_output) = \
216 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
217 base_class = base,
218 decode_template = CheckRaDecode,
219 exec_template_base = load_or_store)
220
221 # Now another version where Ra == 0
222 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
223 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
224 mem_flags, inst_flags,
225 base_class = base,
226 exec_template_base = load_or_store)
227
228 # Finally, add to the other outputs
229 header_output += header_output_ra0
230 decoder_output += decoder_output_ra0
231 exec_output += exec_output_ra0
232 return (header_output, decoder_output, decode_block, exec_output)
233
234}};
235
236
237def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
238 ea_code_ra0 = {{ EA = Rb; }},
239 mem_flags = [], inst_flags = []) {{
240 (header_output, decoder_output, decode_block, exec_output) = \
241 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
242 'MemOp', 'Load', mem_flags, inst_flags)
243}};
244
245
246def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
247 ea_code_ra0 = {{ EA = Rb; }},
248 mem_flags = [], inst_flags = []) {{
249 (header_output, decoder_output, decode_block, exec_output) = \
250 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
251 'MemOp', 'Store', mem_flags, inst_flags)
252}};
253
254
255def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
256 mem_flags = [], inst_flags = []) {{
257
258 # Add in the update code
259 memacc_code += 'Ra = EA;'
260
261 # Generate the class
262 (header_output, decoder_output, decode_block, exec_output) = \
263 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
264 base_class = 'MemOp',
265 exec_template_base = 'Load')
266}};
267
268
269def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
270 mem_flags = [], inst_flags = []) {{
271
272 # Add in the update code
273 memacc_code += 'Ra = EA;'
274
275 # Generate the class
276 (header_output, decoder_output, decode_block, exec_output) = \
277 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
278 base_class = 'MemOp',
279 exec_template_base = 'Store')
280}};
281
282
283def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
284 ea_code_ra0 = {{ EA = disp; }},
285 mem_flags = [], inst_flags = []) {{
286 (header_output, decoder_output, decode_block, exec_output) = \
287 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
288 'MemDispOp', 'Load', mem_flags, inst_flags)
289}};
290
291
292def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
293 ea_code_ra0 = {{ EA = disp; }},
294 mem_flags = [], inst_flags = []) {{
295 (header_output, decoder_output, decode_block, exec_output) = \
296 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
297 'MemDispOp', 'Store', mem_flags, inst_flags)
298}};
299
300
301def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
302 mem_flags = [], inst_flags = []) {{
303
304 # Add in the update code
305 memacc_code += 'Ra = EA;'
306
307 # Generate the class
308 (header_output, decoder_output, decode_block, exec_output) = \
309 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
310 base_class = 'MemDispOp',
311 exec_template_base = 'Load')
312}};
313
314
315def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
316 mem_flags = [], inst_flags = []) {{
317
318 # Add in the update code
319 memacc_code += 'Ra = EA;'
320
321 # Generate the class
322 (header_output, decoder_output, decode_block, exec_output) = \
323 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
324 base_class = 'MemDispOp',
325 exec_template_base = 'Store')
326}};