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 //////////////////////////////////////////////////////////////////////////
67 * Base class for load and store ops
69 class LdStOp : public X86MicroopBase
76 const uint8_t segment;
78 const uint8_t dataSize;
79 const uint8_t addressSize;
82 LdStOp(ExtMachInst _machInst,
83 const char * mnem, const char * _instMnem,
84 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
85 uint8_t _scale, RegIndex _index, RegIndex _base,
86 uint64_t _disp, uint8_t _segment,
88 uint8_t _dataSize, uint8_t _addressSize,
90 X86MicroopBase(machInst, mnem, _instMnem,
91 isMicro, isDelayed, isFirst, isLast, __opClass),
92 scale(_scale), index(_index), base(_base),
93 disp(_disp), segment(_segment),
95 dataSize(_dataSize), addressSize(_addressSize)
98 std::string generateDisassembly(Addr pc,
99 const SymbolTable *symtab) const;
104 std::string LdStOp::generateDisassembly(Addr pc,
105 const SymbolTable *symtab) const
107 std::stringstream response;
109 printMnemonic(response, instMnem, mnemonic);
110 printReg(response, data);
112 printSegment(response, segment);
113 ccprintf(response, ":[%d*", scale);
114 printReg(response, index);
116 printReg(response, base);
117 ccprintf(response, " + %#x]", disp);
118 return response.str();
122 def template MicroLoadExecute {{
123 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
124 Trace::InstRecord *traceData) const
126 Fault fault = NoFault;
132 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
134 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
148 def template MicroLoadInitiateAcc {{
149 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
150 Trace::InstRecord * traceData) const
152 Fault fault = NoFault;
158 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
160 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
166 def template MicroLoadCompleteAcc {{
167 Fault %(class_name)s::completeAcc(PacketPtr pkt,
168 %(CPU_exec_context)s * xc,
169 Trace::InstRecord * traceData) const
171 Fault fault = NoFault;
176 Mem = pkt->get<typeof(Mem)>();
190 def template MicroStoreExecute {{
191 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
192 Trace::InstRecord *traceData) const
194 Fault fault = NoFault;
200 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
206 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
218 def template MicroStoreInitiateAcc {{
219 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
220 Trace::InstRecord * traceData) const
222 Fault fault = NoFault;
228 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
234 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
245 def template MicroStoreCompleteAcc {{
246 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
247 Trace::InstRecord * traceData) const
255 //This delcares the initiateAcc function in memory operations
256 def template InitiateAccDeclare {{
257 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
260 //This declares the completeAcc function in memory operations
261 def template CompleteAccDeclare {{
262 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
265 def template MicroLdStOpDeclare {{
266 class %(class_name)s : public %(base_class)s
272 %(class_name)s(ExtMachInst _machInst,
273 const char * instMnem,
274 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
275 uint8_t _scale, RegIndex _index, RegIndex _base,
276 uint64_t _disp, uint8_t _segment,
278 uint8_t _dataSize, uint8_t _addressSize);
280 %(class_name)s(ExtMachInst _machInst,
281 const char * instMnem,
282 uint8_t _scale, RegIndex _index, RegIndex _base,
283 uint64_t _disp, uint8_t _segment,
285 uint8_t _dataSize, uint8_t _addressSize);
289 %(InitiateAccDeclare)s
291 %(CompleteAccDeclare)s
295 def template MicroLdStOpConstructor {{
297 inline void %(class_name)s::buildMe()
302 inline %(class_name)s::%(class_name)s(
303 ExtMachInst machInst, const char * instMnem,
304 uint8_t _scale, RegIndex _index, RegIndex _base,
305 uint64_t _disp, uint8_t _segment,
307 uint8_t _dataSize, uint8_t _addressSize) :
308 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
309 false, false, false, false,
310 _scale, _index, _base,
311 _disp, _segment, _data,
312 _dataSize, _addressSize, %(op_class)s)
317 inline %(class_name)s::%(class_name)s(
318 ExtMachInst machInst, const char * instMnem,
319 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
320 uint8_t _scale, RegIndex _index, RegIndex _base,
321 uint64_t _disp, uint8_t _segment,
323 uint8_t _dataSize, uint8_t _addressSize) :
324 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
325 isMicro, isDelayed, isFirst, isLast,
326 _scale, _index, _base,
327 _disp, _segment, _data,
328 _dataSize, _addressSize, %(op_class)s)
335 class LdStOp(X86Microop):
336 def __init__(self, data, segment, addr, disp):
338 [self.scale, self.index, self.base] = addr
340 self.segment = segment
341 self.dataSize = "env.dataSize"
342 self.addressSize = "env.addressSize"
344 def getAllocator(self, *microFlags):
345 allocator = '''new %(class_name)s(machInst, mnemonic
346 %(flags)s, %(scale)s, %(index)s, %(base)s,
347 %(disp)s, %(segment)s, %(data)s,
348 %(dataSize)s, %(addressSize)s)''' % {
349 "class_name" : self.className,
350 "flags" : self.microFlagsText(microFlags),
351 "scale" : self.scale, "index" : self.index,
354 "segment" : self.segment, "data" : self.data,
355 "dataSize" : self.dataSize, "addressSize" : self.addressSize}
361 # Make these empty strings so that concatenating onto
362 # them will always work.
367 calculateEA = "EA = scale * Index + Base + disp;"
369 def defineMicroLoadOp(mnemonic, code):
371 global decoder_output
373 global microopClasses
375 name = mnemonic.lower()
377 # Build up the all register version of this micro op
378 iop = InstObjParams(name, Name, 'LdStOp',
379 {"code": code, "ea_code": calculateEA})
380 header_output += MicroLdStOpDeclare.subst(iop)
381 decoder_output += MicroLdStOpConstructor.subst(iop)
382 exec_output += MicroLoadExecute.subst(iop)
383 exec_output += MicroLoadInitiateAcc.subst(iop)
384 exec_output += MicroLoadCompleteAcc.subst(iop)
386 class LoadOp(LdStOp):
387 def __init__(self, data, segment, addr, disp = 0):
388 super(LoadOp, self).__init__(data, segment, addr, disp)
389 self.className = Name
392 microopClasses[name] = LoadOp
394 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
396 def defineMicroStoreOp(mnemonic, code):
398 global decoder_output
400 global microopClasses
402 name = mnemonic.lower()
404 # Build up the all register version of this micro op
405 iop = InstObjParams(name, Name, 'LdStOp',
406 {"code": code, "ea_code": calculateEA})
407 header_output += MicroLdStOpDeclare.subst(iop)
408 decoder_output += MicroLdStOpConstructor.subst(iop)
409 exec_output += MicroStoreExecute.subst(iop)
410 exec_output += MicroStoreInitiateAcc.subst(iop)
411 exec_output += MicroStoreCompleteAcc.subst(iop)
413 class StoreOp(LdStOp):
414 def __init__(self, data, addr, segment):
415 super(LoadOp, self).__init__(data, addr, segment)
416 self.className = Name
419 microopClasses[name] = StoreOp
421 defineMicroLoadOp('St', 'Mem = Data;')