Deleted Added
sdiff udiff text old ( 4587:2c9a2534a489 ) new ( 4601:38c989d15fef )
full compact
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
62output header {{
63 /**
64 * Base class for load and store ops
65 */
66 class LdStOp : public X86MicroopBase
67 {
68 protected:
69 const uint8_t scale;
70 const RegIndex index;
71 const RegIndex base;
72 const uint64_t disp;
73 const uint8_t segment;
74 const RegIndex data;
75 const uint8_t dataSize;
76 const uint8_t addressSize;
77
78 //Constructor
79 LdStOp(ExtMachInst _machInst,
80 const char * mnem, const char * _instMnem,
81 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
82 uint8_t _scale, RegIndex _index, RegIndex _base,
83 uint64_t _disp, uint8_t _segment,
84 RegIndex _data,
85 uint8_t _dataSize, uint8_t _addressSize,
86 OpClass __opClass) :
87 X86MicroopBase(machInst, mnem, _instMnem,
88 isMicro, isDelayed, isFirst, isLast, __opClass),
89 scale(_scale), index(_index), base(_base),
90 disp(_disp), segment(_segment),
91 data(_data),
92 dataSize(_dataSize), addressSize(_addressSize)
93 {}
94
95 std::string generateDisassembly(Addr pc,
96 const SymbolTable *symtab) const;
97 };
98}};
99
100output decoder {{
101 std::string LdStOp::generateDisassembly(Addr pc,
102 const SymbolTable *symtab) const
103 {
104 std::stringstream response;
105
106 printMnemonic(response, instMnem, mnemonic);
107 printReg(response, data);
108 response << ", ";
109 printSegment(response, segment);
110 ccprintf(response, ":[%d*", scale);
111 printReg(response, index);
112 response << " + ";
113 printReg(response, base);
114 ccprintf(response, " + %#x]", disp);
115 return response.str();
116 }
117}};
118
119// LEA template
120
121def template MicroLeaExecute {{
122 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
123 Trace::InstRecord *traceData) const
124 {
125 Fault fault = NoFault;
126 Addr EA;
127
128 %(op_decl)s;
129 %(op_rd)s;
130 %(ea_code)s;
131 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
132
133 %(code)s;
134 if(fault == NoFault)
135 {
136 %(op_wb)s;
137 }
138
139 return fault;
140 }
141}};
142
143def template MicroLeaDeclare {{
144 class %(class_name)s : public %(base_class)s
145 {
146 protected:
147 void buildMe();
148
149 public:
150 %(class_name)s(ExtMachInst _machInst,
151 const char * instMnem,
152 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
153 uint8_t _scale, RegIndex _index, RegIndex _base,
154 uint64_t _disp, uint8_t _segment,
155 RegIndex _data,
156 uint8_t _dataSize, uint8_t _addressSize);
157
158 %(class_name)s(ExtMachInst _machInst,
159 const char * instMnem,
160 uint8_t _scale, RegIndex _index, RegIndex _base,
161 uint64_t _disp, uint8_t _segment,
162 RegIndex _data,
163 uint8_t _dataSize, uint8_t _addressSize);
164
165 %(BasicExecDeclare)s
166 };
167}};
168
169// Load templates
170
171def template MicroLoadExecute {{
172 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
173 Trace::InstRecord *traceData) const
174 {
175 Fault fault = NoFault;
176 Addr EA;
177
178 %(op_decl)s;
179 %(op_rd)s;
180 %(ea_code)s;
181 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
182
183 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
184 if(fault == NoFault)
185 {
186 %(code)s;
187 }
188 if(fault == NoFault)
189 {
190 %(op_wb)s;
191 }
192
193 return fault;
194 }
195}};
196
197def template MicroLoadInitiateAcc {{
198 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
199 Trace::InstRecord * traceData) const
200 {
201 Fault fault = NoFault;
202 Addr EA;
203
204 %(op_decl)s;
205 %(op_rd)s;
206 %(ea_code)s;
207 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
208
209 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
210
211 return fault;
212 }
213}};
214
215def template MicroLoadCompleteAcc {{
216 Fault %(class_name)s::completeAcc(PacketPtr pkt,
217 %(CPU_exec_context)s * xc,
218 Trace::InstRecord * traceData) const
219 {
220 Fault fault = NoFault;
221
222 %(op_decl)s;
223 %(op_rd)s;
224
225 Mem = pkt->get<typeof(Mem)>();
226 %(code)s;
227
228 if(fault == NoFault)
229 {
230 %(op_wb)s;
231 }
232
233 return fault;
234 }
235}};
236
237// Store templates
238
239def template MicroStoreExecute {{
240 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
241 Trace::InstRecord *traceData) const
242 {
243 Fault fault = NoFault;
244
245 Addr EA;
246 %(op_decl)s;
247 %(op_rd)s;
248 %(ea_code)s;
249 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
250
251 %(code)s;
252
253 if(fault == NoFault)
254 {
255 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
256 EA, 0, 0);
257 }
258 if(fault == NoFault)
259 {
260 %(op_wb)s;
261 }
262
263 return fault;
264 }
265}};
266
267def template MicroStoreInitiateAcc {{
268 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
269 Trace::InstRecord * traceData) const
270 {
271 Fault fault = NoFault;
272
273 Addr EA;
274 %(op_decl)s;
275 %(op_rd)s;
276 %(ea_code)s;
277 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
278
279 %(code)s;
280
281 if(fault == NoFault)
282 {
283 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
284 EA, 0, 0);
285 }
286 if(fault == NoFault)
287 {
288 %(op_wb)s;
289 }
290 return fault;
291 }
292}};
293
294def template MicroStoreCompleteAcc {{
295 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
296 Trace::InstRecord * traceData) const
297 {
298 return NoFault;
299 }
300}};
301
302// Common templates
303
304//This delcares the initiateAcc function in memory operations
305def template InitiateAccDeclare {{
306 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
307}};
308
309//This declares the completeAcc function in memory operations
310def template CompleteAccDeclare {{
311 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
312}};
313
314def template MicroLdStOpDeclare {{
315 class %(class_name)s : public %(base_class)s
316 {
317 protected:
318 void buildMe();
319
320 public:
321 %(class_name)s(ExtMachInst _machInst,
322 const char * instMnem,
323 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
324 uint8_t _scale, RegIndex _index, RegIndex _base,
325 uint64_t _disp, uint8_t _segment,
326 RegIndex _data,
327 uint8_t _dataSize, uint8_t _addressSize);
328
329 %(class_name)s(ExtMachInst _machInst,
330 const char * instMnem,
331 uint8_t _scale, RegIndex _index, RegIndex _base,
332 uint64_t _disp, uint8_t _segment,
333 RegIndex _data,
334 uint8_t _dataSize, uint8_t _addressSize);
335
336 %(BasicExecDeclare)s
337
338 %(InitiateAccDeclare)s
339
340 %(CompleteAccDeclare)s
341 };
342}};
343
344def template MicroLdStOpConstructor {{
345
346 inline void %(class_name)s::buildMe()
347 {
348 %(constructor)s;
349 }
350
351 inline %(class_name)s::%(class_name)s(
352 ExtMachInst machInst, const char * instMnem,
353 uint8_t _scale, RegIndex _index, RegIndex _base,
354 uint64_t _disp, uint8_t _segment,
355 RegIndex _data,
356 uint8_t _dataSize, uint8_t _addressSize) :
357 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
358 false, false, false, false,
359 _scale, _index, _base,
360 _disp, _segment, _data,
361 _dataSize, _addressSize, %(op_class)s)
362 {
363 buildMe();
364 }
365
366 inline %(class_name)s::%(class_name)s(
367 ExtMachInst machInst, const char * instMnem,
368 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
369 uint8_t _scale, RegIndex _index, RegIndex _base,
370 uint64_t _disp, uint8_t _segment,
371 RegIndex _data,
372 uint8_t _dataSize, uint8_t _addressSize) :
373 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
374 isMicro, isDelayed, isFirst, isLast,
375 _scale, _index, _base,
376 _disp, _segment, _data,
377 _dataSize, _addressSize, %(op_class)s)
378 {
379 buildMe();
380 }
381}};
382
383let {{
384 class LdStOp(X86Microop):
385 def __init__(self, data, segment, addr, disp):
386 self.data = data
387 [self.scale, self.index, self.base] = addr
388 self.disp = disp
389 self.segment = segment
390 self.dataSize = "env.dataSize"
391 self.addressSize = "env.addressSize"
392
393 def getAllocator(self, *microFlags):
394 allocator = '''new %(class_name)s(machInst, mnemonic
395 %(flags)s, %(scale)s, %(index)s, %(base)s,
396 %(disp)s, %(segment)s, %(data)s,
397 %(dataSize)s, %(addressSize)s)''' % {
398 "class_name" : self.className,
399 "flags" : self.microFlagsText(microFlags),
400 "scale" : self.scale, "index" : self.index,
401 "base" : self.base,
402 "disp" : self.disp,
403 "segment" : self.segment, "data" : self.data,
404 "dataSize" : self.dataSize, "addressSize" : self.addressSize}
405 return allocator
406}};
407
408let {{
409
410 # Make these empty strings so that concatenating onto
411 # them will always work.
412 header_output = ""
413 decoder_output = ""
414 exec_output = ""
415
416 calculateEA = "EA = scale * Index + Base + disp;"
417
418 def defineMicroLoadOp(mnemonic, code):
419 global header_output
420 global decoder_output
421 global exec_output
422 global microopClasses
423 Name = mnemonic
424 name = mnemonic.lower()
425
426 # Build up the all register version of this micro op
427 iop = InstObjParams(name, Name, 'LdStOp',
428 {"code": code, "ea_code": calculateEA})
429 header_output += MicroLdStOpDeclare.subst(iop)
430 decoder_output += MicroLdStOpConstructor.subst(iop)
431 exec_output += MicroLoadExecute.subst(iop)
432 exec_output += MicroLoadInitiateAcc.subst(iop)
433 exec_output += MicroLoadCompleteAcc.subst(iop)
434
435 class LoadOp(LdStOp):
436 def __init__(self, data, segment, addr, disp = 0):
437 super(LoadOp, self).__init__(data, segment, addr, disp)
438 self.className = Name
439 self.mnemonic = name
440
441 microopClasses[name] = LoadOp
442
443 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
444
445 def defineMicroStoreOp(mnemonic, code):
446 global header_output
447 global decoder_output
448 global exec_output
449 global microopClasses
450 Name = mnemonic
451 name = mnemonic.lower()
452
453 # Build up the all register version of this micro op
454 iop = InstObjParams(name, Name, 'LdStOp',
455 {"code": code, "ea_code": calculateEA})
456 header_output += MicroLdStOpDeclare.subst(iop)
457 decoder_output += MicroLdStOpConstructor.subst(iop)
458 exec_output += MicroStoreExecute.subst(iop)
459 exec_output += MicroStoreInitiateAcc.subst(iop)
460 exec_output += MicroStoreCompleteAcc.subst(iop)
461
462 class StoreOp(LdStOp):
463 def __init__(self, data, segment, addr, disp = 0):
464 super(LoadOp, self).__init__(data, segment, addr, disp)
465 self.className = Name
466 self.mnemonic = name
467
468 microopClasses[name] = StoreOp
469
470 defineMicroLoadOp('St', 'Mem = Data;')
471
472 iop = InstObjParams("lea", "Lea", 'LdStOp',
473 {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
474 header_output += MicroLeaDeclare.subst(iop)
475 decoder_output += MicroLdStOpConstructor.subst(iop)
476 exec_output += MicroLeaExecute.subst(iop)
477
478 class LeaOp(LdStOp):
479 def __init__(self, data, segment, addr, disp = 0):
480 super(LeaOp, self).__init__(data, segment, addr, disp)
481 self.className = "Lea"
482 self.mnemonic = "lea"
483
484 microopClasses["lea"] = LeaOp
485}};
486