2e98a42bf945df69f9647963190e7b923ee14fc5
[gem5.git] / src / arch / x86 / isa / microops / ldstop.isa
1 // Copyright (c) 2007 The Hewlett-Packard Development Company
2 // All rights reserved.
3 //
4 // Redistribution and use of this software in source and binary forms,
5 // with or without modification, are permitted provided that the
6 // following conditions are met:
7 //
8 // The software must be used only for Non-Commercial Use which means any
9 // use which is NOT directed to receiving any direct monetary
10 // compensation for, or commercial advantage from such use. Illustrative
11 // examples of non-commercial use are academic research, personal study,
12 // teaching, education and corporate research & development.
13 // Illustrative examples of commercial use are distributing products for
14 // commercial advantage and providing services using the software for
15 // commercial advantage.
16 //
17 // If you wish to use this software or functionality therein that may be
18 // covered by patents for commercial use, please contact:
19 // Director of Intellectual Property Licensing
20 // Office of Strategy and Technology
21 // Hewlett-Packard Company
22 // 1501 Page Mill Road
23 // Palo Alto, California 94304
24 //
25 // Redistributions of source code must retain the above copyright notice,
26 // this list of conditions and the following disclaimer. Redistributions
27 // in binary form must reproduce the above copyright notice, this list of
28 // conditions and the following disclaimer in the documentation and/or
29 // other materials provided with the distribution. Neither the name of
30 // the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
31 // contributors may be used to endorse or promote products derived from
32 // this software without specific prior written permission. No right of
33 // sublicense is granted herewith. Derivatives of the software and
34 // output created using the software may be prepared, but only for
35 // Non-Commercial Uses. Derivatives of the software may be shared with
36 // others provided: (i) the others agree to abide by the list of
37 // conditions herein which includes the Non-Commercial Use restrictions;
38 // and (ii) such Derivatives of the software include the above copyright
39 // notice to acknowledge the contribution from this software where
40 // applicable, this list of conditions and the disclaimer below.
41 //
42 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 //
54 // Authors: Gabe Black
55
56 //////////////////////////////////////////////////////////////////////////
57 //
58 // LdStOp Microop templates
59 //
60 //////////////////////////////////////////////////////////////////////////
61
62 // LEA template
63
64 def template MicroLeaExecute {{
65 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
66 Trace::InstRecord *traceData) const
67 {
68 Fault fault = NoFault;
69 Addr EA;
70
71 %(op_decl)s;
72 %(op_rd)s;
73 %(ea_code)s;
74 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
75
76 %(code)s;
77 if(fault == NoFault)
78 {
79 %(op_wb)s;
80 }
81
82 return fault;
83 }
84 }};
85
86 def template MicroLeaDeclare {{
87 class %(class_name)s : public %(base_class)s
88 {
89 protected:
90 void buildMe();
91
92 public:
93 %(class_name)s(ExtMachInst _machInst,
94 const char * instMnem,
95 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
96 uint8_t _scale, RegIndex _index, RegIndex _base,
97 uint64_t _disp, uint8_t _segment,
98 RegIndex _data,
99 uint8_t _dataSize, uint8_t _addressSize);
100
101 %(class_name)s(ExtMachInst _machInst,
102 const char * instMnem,
103 uint8_t _scale, RegIndex _index, RegIndex _base,
104 uint64_t _disp, uint8_t _segment,
105 RegIndex _data,
106 uint8_t _dataSize, uint8_t _addressSize);
107
108 %(BasicExecDeclare)s
109 };
110 }};
111
112 // Load templates
113
114 def template MicroLoadExecute {{
115 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
116 Trace::InstRecord *traceData) const
117 {
118 Fault fault = NoFault;
119 Addr EA;
120
121 %(op_decl)s;
122 %(op_rd)s;
123 %(ea_code)s;
124 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
125
126 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
127 if(fault == NoFault)
128 {
129 %(code)s;
130 }
131 if(fault == NoFault)
132 {
133 %(op_wb)s;
134 }
135
136 return fault;
137 }
138 }};
139
140 def template MicroLoadInitiateAcc {{
141 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
142 Trace::InstRecord * traceData) const
143 {
144 Fault fault = NoFault;
145 Addr EA;
146
147 %(op_decl)s;
148 %(op_rd)s;
149 %(ea_code)s;
150 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
151
152 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
153
154 return fault;
155 }
156 }};
157
158 def template MicroLoadCompleteAcc {{
159 Fault %(class_name)s::completeAcc(PacketPtr pkt,
160 %(CPU_exec_context)s * xc,
161 Trace::InstRecord * traceData) const
162 {
163 Fault fault = NoFault;
164
165 %(op_decl)s;
166 %(op_rd)s;
167
168 Mem = pkt->get<typeof(Mem)>();
169 %(code)s;
170
171 if(fault == NoFault)
172 {
173 %(op_wb)s;
174 }
175
176 return fault;
177 }
178 }};
179
180 // Store templates
181
182 def template MicroStoreExecute {{
183 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
184 Trace::InstRecord *traceData) const
185 {
186 Fault fault = NoFault;
187
188 Addr EA;
189 %(op_decl)s;
190 %(op_rd)s;
191 %(ea_code)s;
192 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
193
194 %(code)s;
195
196 if(fault == NoFault)
197 {
198 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
199 EA, 0, 0);
200 }
201 if(fault == NoFault)
202 {
203 %(op_wb)s;
204 }
205
206 return fault;
207 }
208 }};
209
210 def template MicroStoreInitiateAcc {{
211 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
212 Trace::InstRecord * traceData) const
213 {
214 Fault fault = NoFault;
215
216 Addr EA;
217 %(op_decl)s;
218 %(op_rd)s;
219 %(ea_code)s;
220 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
221
222 %(code)s;
223
224 if(fault == NoFault)
225 {
226 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
227 EA, 0, 0);
228 }
229 if(fault == NoFault)
230 {
231 %(op_wb)s;
232 }
233 return fault;
234 }
235 }};
236
237 def template MicroStoreCompleteAcc {{
238 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
239 Trace::InstRecord * traceData) const
240 {
241 return NoFault;
242 }
243 }};
244
245 // Common templates
246
247 //This delcares the initiateAcc function in memory operations
248 def template InitiateAccDeclare {{
249 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
250 }};
251
252 //This declares the completeAcc function in memory operations
253 def template CompleteAccDeclare {{
254 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
255 }};
256
257 def template MicroLdStOpDeclare {{
258 class %(class_name)s : public %(base_class)s
259 {
260 protected:
261 void buildMe();
262
263 public:
264 %(class_name)s(ExtMachInst _machInst,
265 const char * instMnem,
266 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
267 uint8_t _scale, RegIndex _index, RegIndex _base,
268 uint64_t _disp, uint8_t _segment,
269 RegIndex _data,
270 uint8_t _dataSize, uint8_t _addressSize);
271
272 %(class_name)s(ExtMachInst _machInst,
273 const char * instMnem,
274 uint8_t _scale, RegIndex _index, RegIndex _base,
275 uint64_t _disp, uint8_t _segment,
276 RegIndex _data,
277 uint8_t _dataSize, uint8_t _addressSize);
278
279 %(BasicExecDeclare)s
280
281 %(InitiateAccDeclare)s
282
283 %(CompleteAccDeclare)s
284 };
285 }};
286
287 def template MicroLdStOpConstructor {{
288
289 inline void %(class_name)s::buildMe()
290 {
291 %(constructor)s;
292 }
293
294 inline %(class_name)s::%(class_name)s(
295 ExtMachInst machInst, const char * instMnem,
296 uint8_t _scale, RegIndex _index, RegIndex _base,
297 uint64_t _disp, uint8_t _segment,
298 RegIndex _data,
299 uint8_t _dataSize, uint8_t _addressSize) :
300 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
301 false, false, false, false,
302 _scale, _index, _base,
303 _disp, _segment, _data,
304 _dataSize, _addressSize, %(op_class)s)
305 {
306 buildMe();
307 }
308
309 inline %(class_name)s::%(class_name)s(
310 ExtMachInst machInst, const char * instMnem,
311 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
312 uint8_t _scale, RegIndex _index, RegIndex _base,
313 uint64_t _disp, uint8_t _segment,
314 RegIndex _data,
315 uint8_t _dataSize, uint8_t _addressSize) :
316 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
317 isMicro, isDelayed, isFirst, isLast,
318 _scale, _index, _base,
319 _disp, _segment, _data,
320 _dataSize, _addressSize, %(op_class)s)
321 {
322 buildMe();
323 }
324 }};
325
326 let {{
327 class LdStOp(X86Microop):
328 def __init__(self, data, segment, addr, disp):
329 self.data = data
330 [self.scale, self.index, self.base] = addr
331 self.disp = disp
332 self.segment = segment
333 self.dataSize = "env.dataSize"
334 self.addressSize = "env.addressSize"
335
336 def getAllocator(self, *microFlags):
337 allocator = '''new %(class_name)s(machInst, mnemonic
338 %(flags)s, %(scale)s, %(index)s, %(base)s,
339 %(disp)s, %(segment)s, %(data)s,
340 %(dataSize)s, %(addressSize)s)''' % {
341 "class_name" : self.className,
342 "flags" : self.microFlagsText(microFlags),
343 "scale" : self.scale, "index" : self.index,
344 "base" : self.base,
345 "disp" : self.disp,
346 "segment" : self.segment, "data" : self.data,
347 "dataSize" : self.dataSize, "addressSize" : self.addressSize}
348 return allocator
349 }};
350
351 let {{
352
353 # Make these empty strings so that concatenating onto
354 # them will always work.
355 header_output = ""
356 decoder_output = ""
357 exec_output = ""
358
359 calculateEA = "EA = scale * Index + Base + disp;"
360
361 def defineMicroLoadOp(mnemonic, code):
362 global header_output
363 global decoder_output
364 global exec_output
365 global microopClasses
366 Name = mnemonic
367 name = mnemonic.lower()
368
369 # Build up the all register version of this micro op
370 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
371 {"code": code, "ea_code": calculateEA})
372 header_output += MicroLdStOpDeclare.subst(iop)
373 decoder_output += MicroLdStOpConstructor.subst(iop)
374 exec_output += MicroLoadExecute.subst(iop)
375 exec_output += MicroLoadInitiateAcc.subst(iop)
376 exec_output += MicroLoadCompleteAcc.subst(iop)
377
378 class LoadOp(LdStOp):
379 def __init__(self, data, segment, addr, disp = 0):
380 super(LoadOp, self).__init__(data, segment, addr, disp)
381 self.className = Name
382 self.mnemonic = name
383
384 microopClasses[name] = LoadOp
385
386 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
387
388 def defineMicroStoreOp(mnemonic, code):
389 global header_output
390 global decoder_output
391 global exec_output
392 global microopClasses
393 Name = mnemonic
394 name = mnemonic.lower()
395
396 # Build up the all register version of this micro op
397 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
398 {"code": code, "ea_code": calculateEA})
399 header_output += MicroLdStOpDeclare.subst(iop)
400 decoder_output += MicroLdStOpConstructor.subst(iop)
401 exec_output += MicroStoreExecute.subst(iop)
402 exec_output += MicroStoreInitiateAcc.subst(iop)
403 exec_output += MicroStoreCompleteAcc.subst(iop)
404
405 class StoreOp(LdStOp):
406 def __init__(self, data, segment, addr, disp = 0):
407 super(LoadOp, self).__init__(data, segment, addr, disp)
408 self.className = Name
409 self.mnemonic = name
410
411 microopClasses[name] = StoreOp
412
413 defineMicroLoadOp('St', 'Mem = Data;')
414
415 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
416 {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
417 header_output += MicroLeaDeclare.subst(iop)
418 decoder_output += MicroLdStOpConstructor.subst(iop)
419 exec_output += MicroLeaExecute.subst(iop)
420
421 class LeaOp(LdStOp):
422 def __init__(self, data, segment, addr, disp = 0):
423 super(LeaOp, self).__init__(data, segment, addr, disp)
424 self.className = "Lea"
425 self.mnemonic = "lea"
426
427 microopClasses["lea"] = LeaOp
428 }};
429