mem.isa (8450:40e10746b049) mem.isa (8607:5fb918115c07)
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 = 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(%(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 = readMemTiming(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 %(CPU_exec_context)s *xc,
124 Trace::InstRecord *traceData) const
125 {
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 = 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(%(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 = readMemTiming(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 %(CPU_exec_context)s *xc,
124 Trace::InstRecord *traceData) const
125 {
126 Addr EA;
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(%(CPU_exec_context)s *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(%(CPU_exec_context)s *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,
210 %(CPU_exec_context)s *xc,
211 Trace::InstRecord *traceData) const
212 {
213 return NoFault;
214 }
215}};
216
217
218// The generic memory operation generator. This is called when two versions
219// of an instruction are needed - when Ra == 0 and otherwise. This is so
220// that instructions can use the value 0 when Ra == 0 but avoid having a
221// dependence on Ra.
222let {{
223
224def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
225 load_or_store, mem_flags = [], inst_flags = []):
226
227 # First the version where Ra is non-zero
228 (header_output, decoder_output, decode_block, exec_output) = \
229 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
230 base_class = base,
231 decode_template = CheckRaDecode,
232 exec_template_base = load_or_store)
233
234 # Now another version where Ra == 0
235 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
236 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
237 mem_flags, inst_flags,
238 base_class = base,
239 exec_template_base = load_or_store)
240
241 # Finally, add to the other outputs
242 header_output += header_output_ra0
243 decoder_output += decoder_output_ra0
244 exec_output += exec_output_ra0
245 return (header_output, decoder_output, decode_block, exec_output)
246
247}};
248
249
250def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
251 ea_code_ra0 = {{ EA = Rb; }},
252 mem_flags = [], inst_flags = []) {{
253 (header_output, decoder_output, decode_block, exec_output) = \
254 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
255 'MemOp', 'Load', mem_flags, inst_flags)
256}};
257
258
259def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
260 ea_code_ra0 = {{ EA = Rb; }},
261 mem_flags = [], inst_flags = []) {{
262 (header_output, decoder_output, decode_block, exec_output) = \
263 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
264 'MemOp', 'Store', mem_flags, inst_flags)
265}};
266
267
268def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
269 mem_flags = [], inst_flags = []) {{
270
271 # Add in the update code
272 memacc_code += 'Ra = EA;'
273
274 # Generate the class
275 (header_output, decoder_output, decode_block, exec_output) = \
276 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
277 base_class = 'MemOp',
278 exec_template_base = 'Load')
279}};
280
281
282def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
283 mem_flags = [], inst_flags = []) {{
284
285 # Add in the update code
286 memacc_code += 'Ra = EA;'
287
288 # Generate the class
289 (header_output, decoder_output, decode_block, exec_output) = \
290 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
291 base_class = 'MemOp',
292 exec_template_base = 'Store')
293}};
294
295
296def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
297 ea_code_ra0 = {{ EA = disp; }},
298 mem_flags = [], inst_flags = []) {{
299 (header_output, decoder_output, decode_block, exec_output) = \
300 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
301 'MemDispOp', 'Load', mem_flags, inst_flags)
302}};
303
304
305def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
306 ea_code_ra0 = {{ EA = disp; }},
307 mem_flags = [], inst_flags = []) {{
308 (header_output, decoder_output, decode_block, exec_output) = \
309 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
310 'MemDispOp', 'Store', mem_flags, inst_flags)
311}};
312
313
314def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
315 mem_flags = [], inst_flags = []) {{
316
317 # Add in the update code
318 memacc_code += 'Ra = EA;'
319
320 # Generate the class
321 (header_output, decoder_output, decode_block, exec_output) = \
322 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
323 base_class = 'MemDispOp',
324 exec_template_base = 'Load')
325}};
326
327
328def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
329 mem_flags = [], inst_flags = []) {{
330
331 # Add in the update code
332 memacc_code += 'Ra = EA;'
333
334 # Generate the class
335 (header_output, decoder_output, decode_block, exec_output) = \
336 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
337 base_class = 'MemDispOp',
338 exec_template_base = 'Store')
339}};
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(%(CPU_exec_context)s *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(%(CPU_exec_context)s *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,
210 %(CPU_exec_context)s *xc,
211 Trace::InstRecord *traceData) const
212 {
213 return NoFault;
214 }
215}};
216
217
218// The generic memory operation generator. This is called when two versions
219// of an instruction are needed - when Ra == 0 and otherwise. This is so
220// that instructions can use the value 0 when Ra == 0 but avoid having a
221// dependence on Ra.
222let {{
223
224def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
225 load_or_store, mem_flags = [], inst_flags = []):
226
227 # First the version where Ra is non-zero
228 (header_output, decoder_output, decode_block, exec_output) = \
229 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
230 base_class = base,
231 decode_template = CheckRaDecode,
232 exec_template_base = load_or_store)
233
234 # Now another version where Ra == 0
235 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
236 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
237 mem_flags, inst_flags,
238 base_class = base,
239 exec_template_base = load_or_store)
240
241 # Finally, add to the other outputs
242 header_output += header_output_ra0
243 decoder_output += decoder_output_ra0
244 exec_output += exec_output_ra0
245 return (header_output, decoder_output, decode_block, exec_output)
246
247}};
248
249
250def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
251 ea_code_ra0 = {{ EA = Rb; }},
252 mem_flags = [], inst_flags = []) {{
253 (header_output, decoder_output, decode_block, exec_output) = \
254 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
255 'MemOp', 'Load', mem_flags, inst_flags)
256}};
257
258
259def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
260 ea_code_ra0 = {{ EA = Rb; }},
261 mem_flags = [], inst_flags = []) {{
262 (header_output, decoder_output, decode_block, exec_output) = \
263 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
264 'MemOp', 'Store', mem_flags, inst_flags)
265}};
266
267
268def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
269 mem_flags = [], inst_flags = []) {{
270
271 # Add in the update code
272 memacc_code += 'Ra = EA;'
273
274 # Generate the class
275 (header_output, decoder_output, decode_block, exec_output) = \
276 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
277 base_class = 'MemOp',
278 exec_template_base = 'Load')
279}};
280
281
282def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
283 mem_flags = [], inst_flags = []) {{
284
285 # Add in the update code
286 memacc_code += 'Ra = EA;'
287
288 # Generate the class
289 (header_output, decoder_output, decode_block, exec_output) = \
290 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
291 base_class = 'MemOp',
292 exec_template_base = 'Store')
293}};
294
295
296def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
297 ea_code_ra0 = {{ EA = disp; }},
298 mem_flags = [], inst_flags = []) {{
299 (header_output, decoder_output, decode_block, exec_output) = \
300 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
301 'MemDispOp', 'Load', mem_flags, inst_flags)
302}};
303
304
305def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
306 ea_code_ra0 = {{ EA = disp; }},
307 mem_flags = [], inst_flags = []) {{
308 (header_output, decoder_output, decode_block, exec_output) = \
309 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
310 'MemDispOp', 'Store', mem_flags, inst_flags)
311}};
312
313
314def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
315 mem_flags = [], inst_flags = []) {{
316
317 # Add in the update code
318 memacc_code += 'Ra = EA;'
319
320 # Generate the class
321 (header_output, decoder_output, decode_block, exec_output) = \
322 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
323 base_class = 'MemDispOp',
324 exec_template_base = 'Load')
325}};
326
327
328def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
329 mem_flags = [], inst_flags = []) {{
330
331 # Add in the update code
332 memacc_code += 'Ra = EA;'
333
334 # Generate the class
335 (header_output, decoder_output, decode_block, exec_output) = \
336 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
337 base_class = 'MemDispOp',
338 exec_template_base = 'Store')
339}};