1 // Copyright (c) 2008 The Regents of The University of Michigan
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met: redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer;
8 // redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution;
11 // neither the name of the copyright holders nor the names of its
12 // contributors may be used to endorse or promote products derived from
13 // this software without specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 // Authors: Gabe Black
29 // Copyright (c) 2007-2008 The Hewlett-Packard Development Company
30 // All rights reserved.
32 // Redistribution and use of this software in source and binary forms,
33 // with or without modification, are permitted provided that the
34 // following conditions are met:
36 // The software must be used only for Non-Commercial Use which means any
37 // use which is NOT directed to receiving any direct monetary
38 // compensation for, or commercial advantage from such use. Illustrative
39 // examples of non-commercial use are academic research, personal study,
40 // teaching, education and corporate research & development.
41 // Illustrative examples of commercial use are distributing products for
42 // commercial advantage and providing services using the software for
43 // commercial advantage.
45 // If you wish to use this software or functionality therein that may be
46 // covered by patents for commercial use, please contact:
47 // Director of Intellectual Property Licensing
48 // Office of Strategy and Technology
49 // Hewlett-Packard Company
50 // 1501 Page Mill Road
51 // Palo Alto, California 94304
53 // Redistributions of source code must retain the above copyright notice,
54 // this list of conditions and the following disclaimer. Redistributions
55 // in binary form must reproduce the above copyright notice, this list of
56 // conditions and the following disclaimer in the documentation and/or
57 // other materials provided with the distribution. Neither the name of
58 // the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
59 // contributors may be used to endorse or promote products derived from
60 // this software without specific prior written permission. No right of
61 // sublicense is granted herewith. Derivatives of the software and
62 // output created using the software may be prepared, but only for
63 // Non-Commercial Uses. Derivatives of the software may be shared with
64 // others provided: (i) the others agree to abide by the list of
65 // conditions herein which includes the Non-Commercial Use restrictions;
66 // and (ii) such Derivatives of the software include the above copyright
67 // notice to acknowledge the contribution from this software where
68 // applicable, this list of conditions and the disclaimer below.
70 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
71 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
72 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
73 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
74 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
75 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
76 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
77 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
78 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82 // Authors: Gabe Black
84 //////////////////////////////////////////////////////////////////////////
86 // LdStOp Microop templates
88 //////////////////////////////////////////////////////////////////////////
92 def template MicroLeaExecute {{
93 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
94 Trace::InstRecord *traceData) const
96 Fault fault = NoFault;
102 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
114 def template MicroLeaDeclare {{
115 class %(class_name)s : public %(base_class)s
121 %(class_name)s(ExtMachInst _machInst,
122 const char * instMnem,
123 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
124 uint8_t _scale, RegIndex _index, RegIndex _base,
125 uint64_t _disp, uint8_t _segment,
127 uint8_t _dataSize, uint8_t _addressSize,
128 Request::FlagsType _memFlags);
130 %(class_name)s(ExtMachInst _machInst,
131 const char * instMnem,
132 uint8_t _scale, RegIndex _index, RegIndex _base,
133 uint64_t _disp, uint8_t _segment,
135 uint8_t _dataSize, uint8_t _addressSize,
136 Request::FlagsType _memFlags);
144 def template MicroLoadExecute {{
145 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
146 Trace::InstRecord *traceData) const
148 Fault fault = NoFault;
154 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
156 fault = read(xc, EA, Mem, memFlags);
158 if (fault == NoFault) {
160 } else if (memFlags & Request::PF_EXCLUSIVE) {
161 // For prefetches, ignore any faults/exceptions.
173 def template MicroLoadInitiateAcc {{
174 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
175 Trace::InstRecord * traceData) const
177 Fault fault = NoFault;
183 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
185 fault = read(xc, EA, Mem, memFlags);
191 def template MicroLoadCompleteAcc {{
192 Fault %(class_name)s::completeAcc(PacketPtr pkt,
193 %(CPU_exec_context)s * xc,
194 Trace::InstRecord * traceData) const
196 Fault fault = NoFault;
216 def template MicroStoreExecute {{
217 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
218 Trace::InstRecord *traceData) const
220 Fault fault = NoFault;
226 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
232 fault = write(xc, Mem, EA, memFlags);
244 def template MicroStoreInitiateAcc {{
245 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
246 Trace::InstRecord * traceData) const
248 Fault fault = NoFault;
254 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
260 write(xc, Mem, EA, memFlags);
266 def template MicroStoreCompleteAcc {{
267 Fault %(class_name)s::completeAcc(PacketPtr pkt,
268 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const
280 //This delcares the initiateAcc function in memory operations
281 def template InitiateAccDeclare {{
282 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
285 //This declares the completeAcc function in memory operations
286 def template CompleteAccDeclare {{
287 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
290 def template MicroLdStOpDeclare {{
291 class %(class_name)s : public %(base_class)s
297 %(class_name)s(ExtMachInst _machInst,
298 const char * instMnem,
299 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
300 uint8_t _scale, RegIndex _index, RegIndex _base,
301 uint64_t _disp, uint8_t _segment,
303 uint8_t _dataSize, uint8_t _addressSize,
304 Request::FlagsType _memFlags);
306 %(class_name)s(ExtMachInst _machInst,
307 const char * instMnem,
308 uint8_t _scale, RegIndex _index, RegIndex _base,
309 uint64_t _disp, uint8_t _segment,
311 uint8_t _dataSize, uint8_t _addressSize,
312 Request::FlagsType _memFlags);
316 %(InitiateAccDeclare)s
318 %(CompleteAccDeclare)s
322 def template MicroLdStOpConstructor {{
324 inline void %(class_name)s::buildMe()
329 inline %(class_name)s::%(class_name)s(
330 ExtMachInst machInst, const char * instMnem,
331 uint8_t _scale, RegIndex _index, RegIndex _base,
332 uint64_t _disp, uint8_t _segment,
334 uint8_t _dataSize, uint8_t _addressSize,
335 Request::FlagsType _memFlags) :
336 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
337 false, false, false, false,
338 _scale, _index, _base,
339 _disp, _segment, _data,
340 _dataSize, _addressSize, _memFlags, %(op_class)s)
345 inline %(class_name)s::%(class_name)s(
346 ExtMachInst machInst, const char * instMnem,
347 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
348 uint8_t _scale, RegIndex _index, RegIndex _base,
349 uint64_t _disp, uint8_t _segment,
351 uint8_t _dataSize, uint8_t _addressSize,
352 Request::FlagsType _memFlags) :
353 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
354 isMicro, isDelayed, isFirst, isLast,
355 _scale, _index, _base,
356 _disp, _segment, _data,
357 _dataSize, _addressSize, _memFlags, %(op_class)s)
364 class LdStOp(X86Microop):
365 def __init__(self, data, segment, addr, disp,
366 dataSize, addressSize, baseFlags, atCPL0, prefetch):
368 [self.scale, self.index, self.base] = addr
370 self.segment = segment
371 self.dataSize = dataSize
372 self.addressSize = addressSize
373 self.memFlags = baseFlags
375 self.memFlags += " | (CPL0FlagBit << FlagShift)"
377 self.memFlags += " | Request::PF_EXCLUSIVE"
378 self.memFlags += " | (machInst.legacy.addr ? " + \
379 "(AddrSizeFlagBit << FlagShift) : 0)"
381 def getAllocator(self, *microFlags):
382 allocator = '''new %(class_name)s(machInst, macrocodeBlock
383 %(flags)s, %(scale)s, %(index)s, %(base)s,
384 %(disp)s, %(segment)s, %(data)s,
385 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
386 "class_name" : self.className,
387 "flags" : self.microFlagsText(microFlags),
388 "scale" : self.scale, "index" : self.index,
391 "segment" : self.segment, "data" : self.data,
392 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
393 "memFlags" : self.memFlags}
399 # Make these empty strings so that concatenating onto
400 # them will always work.
406 EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0);
409 def defineMicroLoadOp(mnemonic, code, mem_flags="0"):
411 global decoder_output
413 global microopClasses
415 name = mnemonic.lower()
417 # Build up the all register version of this micro op
418 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
420 "ea_code": calculateEA})
421 header_output += MicroLdStOpDeclare.subst(iop)
422 decoder_output += MicroLdStOpConstructor.subst(iop)
423 exec_output += MicroLoadExecute.subst(iop)
424 exec_output += MicroLoadInitiateAcc.subst(iop)
425 exec_output += MicroLoadCompleteAcc.subst(iop)
427 class LoadOp(LdStOp):
428 def __init__(self, data, segment, addr, disp = 0,
429 dataSize="env.dataSize",
430 addressSize="env.addressSize",
431 atCPL0=False, prefetch=False):
432 super(LoadOp, self).__init__(data, segment, addr,
433 disp, dataSize, addressSize, mem_flags,
435 self.className = Name
438 microopClasses[name] = LoadOp
440 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
441 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
442 'X86ISA::StoreCheck')
443 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
444 'X86ISA::StoreCheck | Request::LOCKED')
445 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;')
447 def defineMicroStoreOp(mnemonic, code, \
448 postCode="", completeCode="", mem_flags="0"):
450 global decoder_output
452 global microopClasses
454 name = mnemonic.lower()
456 # Build up the all register version of this micro op
457 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
459 "post_code": postCode,
460 "complete_code": completeCode,
461 "ea_code": calculateEA})
462 header_output += MicroLdStOpDeclare.subst(iop)
463 decoder_output += MicroLdStOpConstructor.subst(iop)
464 exec_output += MicroStoreExecute.subst(iop)
465 exec_output += MicroStoreInitiateAcc.subst(iop)
466 exec_output += MicroStoreCompleteAcc.subst(iop)
468 class StoreOp(LdStOp):
469 def __init__(self, data, segment, addr, disp = 0,
470 dataSize="env.dataSize",
471 addressSize="env.addressSize",
473 super(StoreOp, self).__init__(data, segment, addr,
474 disp, dataSize, addressSize, mem_flags, atCPL0, False)
475 self.className = Name
478 microopClasses[name] = StoreOp
480 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
481 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;')
482 defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);',
483 'Base = merge(Base, EA - SegBase, addressSize);',
484 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);');
485 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
487 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
488 {"code": "Data = merge(Data, EA, dataSize);",
490 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
492 header_output += MicroLeaDeclare.subst(iop)
493 decoder_output += MicroLdStOpConstructor.subst(iop)
494 exec_output += MicroLeaExecute.subst(iop)
497 def __init__(self, data, segment, addr, disp = 0,
498 dataSize="env.dataSize", addressSize="env.addressSize"):
499 super(LeaOp, self).__init__(data, segment,
500 addr, disp, dataSize, addressSize, "0", False, False)
501 self.className = "Lea"
502 self.mnemonic = "lea"
504 microopClasses["lea"] = LeaOp
507 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
508 {"code": "xc->demapPage(EA, 0);",
509 "ea_code": calculateEA})
510 header_output += MicroLeaDeclare.subst(iop)
511 decoder_output += MicroLdStOpConstructor.subst(iop)
512 exec_output += MicroLeaExecute.subst(iop)
515 def __init__(self, segment, addr, disp = 0,
516 dataSize="env.dataSize",
517 addressSize="env.addressSize"):
518 super(TiaOp, self).__init__("NUM_INTREGS", segment,
519 addr, disp, dataSize, addressSize, "0", False, False)
520 self.className = "Tia"
521 self.mnemonic = "tia"
523 microopClasses["tia"] = TiaOp
526 def __init__(self, segment, addr, disp = 0,
527 dataSize="env.dataSize",
528 addressSize="env.addressSize", atCPL0=False):
529 super(CdaOp, self).__init__("NUM_INTREGS", segment,
530 addr, disp, dataSize, addressSize, "0", atCPL0, False)
531 self.className = "Cda"
532 self.mnemonic = "cda"
534 microopClasses["cda"] = CdaOp