1 // Copyright (c) 2007 The Hewlett-Packard Development Company
2 // All rights reserved.
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:
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.
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
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.
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.
54 // Authors: Gabe Black
56 //////////////////////////////////////////////////////////////////////////
58 // LdStOp Microop templates
60 //////////////////////////////////////////////////////////////////////////
64 def template MicroLeaExecute {{
65 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
66 Trace::InstRecord *traceData) const
68 Fault fault = NoFault;
74 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
86 def template MicroLeaDeclare {{
87 class %(class_name)s : public %(base_class)s
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,
99 uint8_t _dataSize, uint8_t _addressSize);
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,
106 uint8_t _dataSize, uint8_t _addressSize);
114 def template MicroLoadExecute {{
115 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
116 Trace::InstRecord *traceData) const
118 Fault fault = NoFault;
124 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
126 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
140 def template MicroLoadInitiateAcc {{
141 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
142 Trace::InstRecord * traceData) const
144 Fault fault = NoFault;
150 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
152 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
158 def template MicroLoadCompleteAcc {{
159 Fault %(class_name)s::completeAcc(PacketPtr pkt,
160 %(CPU_exec_context)s * xc,
161 Trace::InstRecord * traceData) const
163 Fault fault = NoFault;
168 Mem = pkt->get<typeof(Mem)>();
182 def template MicroStoreExecute {{
183 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
184 Trace::InstRecord *traceData) const
186 Fault fault = NoFault;
192 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
198 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
210 def template MicroStoreInitiateAcc {{
211 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
212 Trace::InstRecord * traceData) const
214 Fault fault = NoFault;
220 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
226 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
237 def template MicroStoreCompleteAcc {{
238 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
239 Trace::InstRecord * traceData) const
247 //This delcares the initiateAcc function in memory operations
248 def template InitiateAccDeclare {{
249 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
252 //This declares the completeAcc function in memory operations
253 def template CompleteAccDeclare {{
254 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
257 def template MicroLdStOpDeclare {{
258 class %(class_name)s : public %(base_class)s
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,
270 uint8_t _dataSize, uint8_t _addressSize);
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,
277 uint8_t _dataSize, uint8_t _addressSize);
281 %(InitiateAccDeclare)s
283 %(CompleteAccDeclare)s
287 def template MicroLdStOpConstructor {{
289 inline void %(class_name)s::buildMe()
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,
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)
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,
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)
327 class LdStOp(X86Microop):
328 def __init__(self, data, segment, addr, disp):
330 [self.scale, self.index, self.base] = addr
332 self.segment = segment
333 self.dataSize = "env.dataSize"
334 self.addressSize = "env.addressSize"
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,
346 "segment" : self.segment, "data" : self.data,
347 "dataSize" : self.dataSize, "addressSize" : self.addressSize}
353 # Make these empty strings so that concatenating onto
354 # them will always work.
359 calculateEA = "EA = scale * Index + Base + disp;"
361 def defineMicroLoadOp(mnemonic, code):
363 global decoder_output
365 global microopClasses
367 name = mnemonic.lower()
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)
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
384 microopClasses[name] = LoadOp
386 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
388 def defineMicroStoreOp(mnemonic, code):
390 global decoder_output
392 global microopClasses
394 name = mnemonic.lower()
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)
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
411 microopClasses[name] = StoreOp
413 defineMicroLoadOp('St', 'Mem = Data;')
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)
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"
427 microopClasses["lea"] = LeaOp