Deleted Added
sdiff udiff text old ( 12234:78ece221f9f5 ) new ( 12236:126ac9da6050 )
full compact
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 Fault execute(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 }
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}};