ldstop.isa revision 10184:bbfa3152bdea
16691Stjones1@inf.ed.ac.uk// Copyright (c) 2007-2008 The Hewlett-Packard Development Company 26691Stjones1@inf.ed.ac.uk// All rights reserved. 36691Stjones1@inf.ed.ac.uk// 46691Stjones1@inf.ed.ac.uk// The license below extends only to copyright in the software and shall 56691Stjones1@inf.ed.ac.uk// not be construed as granting a license to any other intellectual 66691Stjones1@inf.ed.ac.uk// property including but not limited to intellectual property relating 76691Stjones1@inf.ed.ac.uk// to a hardware implementation of the functionality of the software 86691Stjones1@inf.ed.ac.uk// licensed hereunder. You may use the software subject to the license 96691Stjones1@inf.ed.ac.uk// terms below provided that you ensure that this notice is replicated 106691Stjones1@inf.ed.ac.uk// unmodified and in its entirety in all distributions of the software, 116691Stjones1@inf.ed.ac.uk// modified or unmodified, in source code or in binary form. 126691Stjones1@inf.ed.ac.uk// 136691Stjones1@inf.ed.ac.uk// Copyright (c) 2008 The Regents of The University of Michigan 146691Stjones1@inf.ed.ac.uk// All rights reserved. 156691Stjones1@inf.ed.ac.uk// 166691Stjones1@inf.ed.ac.uk// Redistribution and use in source and binary forms, with or without 176691Stjones1@inf.ed.ac.uk// modification, are permitted provided that the following conditions are 186691Stjones1@inf.ed.ac.uk// met: redistributions of source code must retain the above copyright 196691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer; 206691Stjones1@inf.ed.ac.uk// redistributions in binary form must reproduce the above copyright 216691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer in the 226691Stjones1@inf.ed.ac.uk// documentation and/or other materials provided with the distribution; 236691Stjones1@inf.ed.ac.uk// neither the name of the copyright holders nor the names of its 246691Stjones1@inf.ed.ac.uk// contributors may be used to endorse or promote products derived from 256691Stjones1@inf.ed.ac.uk// this software without specific prior written permission. 266691Stjones1@inf.ed.ac.uk// 276691Stjones1@inf.ed.ac.uk// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 286691Stjones1@inf.ed.ac.uk// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 296691Stjones1@inf.ed.ac.uk// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 306691Stjones1@inf.ed.ac.uk// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 316691Stjones1@inf.ed.ac.uk// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 326691Stjones1@inf.ed.ac.uk// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 336691Stjones1@inf.ed.ac.uk// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 346691Stjones1@inf.ed.ac.uk// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 356691Stjones1@inf.ed.ac.uk// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 366691Stjones1@inf.ed.ac.uk// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 376691Stjones1@inf.ed.ac.uk// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 386691Stjones1@inf.ed.ac.uk// 396691Stjones1@inf.ed.ac.uk// Authors: Gabe Black 406691Stjones1@inf.ed.ac.uk 416691Stjones1@inf.ed.ac.uk////////////////////////////////////////////////////////////////////////// 426691Stjones1@inf.ed.ac.uk// 436691Stjones1@inf.ed.ac.uk// LdStOp Microop templates 446691Stjones1@inf.ed.ac.uk// 456691Stjones1@inf.ed.ac.uk////////////////////////////////////////////////////////////////////////// 466691Stjones1@inf.ed.ac.uk 476691Stjones1@inf.ed.ac.uk// LEA template 486691Stjones1@inf.ed.ac.uk 496691Stjones1@inf.ed.ac.ukdef template MicroLeaExecute {{ 506691Stjones1@inf.ed.ac.uk Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 516691Stjones1@inf.ed.ac.uk Trace::InstRecord *traceData) const 526691Stjones1@inf.ed.ac.uk { 536691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 546691Stjones1@inf.ed.ac.uk Addr EA; 556691Stjones1@inf.ed.ac.uk 566691Stjones1@inf.ed.ac.uk %(op_decl)s; 576691Stjones1@inf.ed.ac.uk %(op_rd)s; 586691Stjones1@inf.ed.ac.uk %(ea_code)s; 596691Stjones1@inf.ed.ac.uk DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 606691Stjones1@inf.ed.ac.uk 616691Stjones1@inf.ed.ac.uk %(code)s; 626691Stjones1@inf.ed.ac.uk if(fault == NoFault) 636691Stjones1@inf.ed.ac.uk { 646691Stjones1@inf.ed.ac.uk %(op_wb)s; 656691Stjones1@inf.ed.ac.uk } 666691Stjones1@inf.ed.ac.uk 676691Stjones1@inf.ed.ac.uk return fault; 686691Stjones1@inf.ed.ac.uk } 696691Stjones1@inf.ed.ac.uk}}; 706691Stjones1@inf.ed.ac.uk 716691Stjones1@inf.ed.ac.ukdef template MicroLeaDeclare {{ 726691Stjones1@inf.ed.ac.uk class %(class_name)s : public %(base_class)s 736691Stjones1@inf.ed.ac.uk { 746691Stjones1@inf.ed.ac.uk public: 756691Stjones1@inf.ed.ac.uk %(class_name)s(ExtMachInst _machInst, 766691Stjones1@inf.ed.ac.uk const char * instMnem, uint64_t setFlags, 776691Stjones1@inf.ed.ac.uk uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 786691Stjones1@inf.ed.ac.uk uint64_t _disp, InstRegIndex _segment, 796691Stjones1@inf.ed.ac.uk InstRegIndex _data, 806691Stjones1@inf.ed.ac.uk uint8_t _dataSize, uint8_t _addressSize, 816691Stjones1@inf.ed.ac.uk Request::FlagsType _memFlags); 826691Stjones1@inf.ed.ac.uk 836691Stjones1@inf.ed.ac.uk %(BasicExecDeclare)s 846691Stjones1@inf.ed.ac.uk }; 856691Stjones1@inf.ed.ac.uk}}; 866691Stjones1@inf.ed.ac.uk 876691Stjones1@inf.ed.ac.uk// Load templates 886691Stjones1@inf.ed.ac.uk 896691Stjones1@inf.ed.ac.ukdef template MicroLoadExecute {{ 906691Stjones1@inf.ed.ac.uk Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 916691Stjones1@inf.ed.ac.uk Trace::InstRecord *traceData) const 926691Stjones1@inf.ed.ac.uk { 936691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 946691Stjones1@inf.ed.ac.uk Addr EA; 956691Stjones1@inf.ed.ac.uk 966691Stjones1@inf.ed.ac.uk %(op_decl)s; 976691Stjones1@inf.ed.ac.uk %(op_rd)s; 986691Stjones1@inf.ed.ac.uk %(ea_code)s; 996691Stjones1@inf.ed.ac.uk DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 1006691Stjones1@inf.ed.ac.uk 1016691Stjones1@inf.ed.ac.uk fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags); 1026691Stjones1@inf.ed.ac.uk 1036691Stjones1@inf.ed.ac.uk if (fault == NoFault) { 1046691Stjones1@inf.ed.ac.uk %(code)s; 1056691Stjones1@inf.ed.ac.uk } else if (memFlags & Request::PREFETCH) { 1066691Stjones1@inf.ed.ac.uk // For prefetches, ignore any faults/exceptions. 1076691Stjones1@inf.ed.ac.uk return NoFault; 1086691Stjones1@inf.ed.ac.uk } 1096691Stjones1@inf.ed.ac.uk if(fault == NoFault) 1106691Stjones1@inf.ed.ac.uk { 1116691Stjones1@inf.ed.ac.uk %(op_wb)s; 1126691Stjones1@inf.ed.ac.uk } 1136691Stjones1@inf.ed.ac.uk 1146691Stjones1@inf.ed.ac.uk return fault; 1156691Stjones1@inf.ed.ac.uk } 1166691Stjones1@inf.ed.ac.uk}}; 1176691Stjones1@inf.ed.ac.uk 1186691Stjones1@inf.ed.ac.ukdef template MicroLoadInitiateAcc {{ 1196691Stjones1@inf.ed.ac.uk Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 1206691Stjones1@inf.ed.ac.uk Trace::InstRecord * traceData) const 1216691Stjones1@inf.ed.ac.uk { 1226691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 1236691Stjones1@inf.ed.ac.uk Addr EA; 1246691Stjones1@inf.ed.ac.uk 1256691Stjones1@inf.ed.ac.uk %(op_decl)s; 1266691Stjones1@inf.ed.ac.uk %(op_rd)s; 1276691Stjones1@inf.ed.ac.uk %(ea_code)s; 1286691Stjones1@inf.ed.ac.uk DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 1296691Stjones1@inf.ed.ac.uk 1306691Stjones1@inf.ed.ac.uk fault = readMemTiming(xc, traceData, EA, Mem, dataSize, memFlags); 1316691Stjones1@inf.ed.ac.uk 1326691Stjones1@inf.ed.ac.uk return fault; 1336691Stjones1@inf.ed.ac.uk } 1346691Stjones1@inf.ed.ac.uk}}; 1356691Stjones1@inf.ed.ac.uk 1366691Stjones1@inf.ed.ac.ukdef template MicroLoadCompleteAcc {{ 1376691Stjones1@inf.ed.ac.uk Fault %(class_name)s::completeAcc(PacketPtr pkt, 1386691Stjones1@inf.ed.ac.uk %(CPU_exec_context)s * xc, 1396691Stjones1@inf.ed.ac.uk Trace::InstRecord * traceData) const 1406691Stjones1@inf.ed.ac.uk { 1416691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 1426691Stjones1@inf.ed.ac.uk 1436691Stjones1@inf.ed.ac.uk %(op_decl)s; 1446691Stjones1@inf.ed.ac.uk %(op_rd)s; 1456691Stjones1@inf.ed.ac.uk 1466691Stjones1@inf.ed.ac.uk Mem = getMem(pkt, dataSize, traceData); 1476691Stjones1@inf.ed.ac.uk 1486691Stjones1@inf.ed.ac.uk %(code)s; 1496691Stjones1@inf.ed.ac.uk 1506691Stjones1@inf.ed.ac.uk if(fault == NoFault) 1516691Stjones1@inf.ed.ac.uk { 1526691Stjones1@inf.ed.ac.uk %(op_wb)s; 1536691Stjones1@inf.ed.ac.uk } 1546691Stjones1@inf.ed.ac.uk 1556691Stjones1@inf.ed.ac.uk return fault; 1566691Stjones1@inf.ed.ac.uk } 1576691Stjones1@inf.ed.ac.uk}}; 1586691Stjones1@inf.ed.ac.uk 1596691Stjones1@inf.ed.ac.uk// Store templates 1606691Stjones1@inf.ed.ac.uk 1616691Stjones1@inf.ed.ac.ukdef template MicroStoreExecute {{ 1626691Stjones1@inf.ed.ac.uk Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 1636691Stjones1@inf.ed.ac.uk Trace::InstRecord *traceData) const 1646691Stjones1@inf.ed.ac.uk { 1656691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 1666691Stjones1@inf.ed.ac.uk 1676691Stjones1@inf.ed.ac.uk Addr EA; 1686691Stjones1@inf.ed.ac.uk %(op_decl)s; 1696691Stjones1@inf.ed.ac.uk %(op_rd)s; 1706691Stjones1@inf.ed.ac.uk %(ea_code)s; 1716691Stjones1@inf.ed.ac.uk DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 1726691Stjones1@inf.ed.ac.uk 1736691Stjones1@inf.ed.ac.uk %(code)s; 1746691Stjones1@inf.ed.ac.uk 1756691Stjones1@inf.ed.ac.uk if(fault == NoFault) 1766691Stjones1@inf.ed.ac.uk { 1776691Stjones1@inf.ed.ac.uk fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA, 1786691Stjones1@inf.ed.ac.uk memFlags, NULL); 1796691Stjones1@inf.ed.ac.uk if(fault == NoFault) 1806691Stjones1@inf.ed.ac.uk { 1816691Stjones1@inf.ed.ac.uk %(op_wb)s; 1826691Stjones1@inf.ed.ac.uk } 1836691Stjones1@inf.ed.ac.uk } 1846691Stjones1@inf.ed.ac.uk 1856691Stjones1@inf.ed.ac.uk return fault; 1866691Stjones1@inf.ed.ac.uk } 1876691Stjones1@inf.ed.ac.uk}}; 1886691Stjones1@inf.ed.ac.uk 1896691Stjones1@inf.ed.ac.ukdef template MicroStoreInitiateAcc {{ 1906691Stjones1@inf.ed.ac.uk Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 1916691Stjones1@inf.ed.ac.uk Trace::InstRecord * traceData) const 1926691Stjones1@inf.ed.ac.uk { 1936691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 1946691Stjones1@inf.ed.ac.uk 1956691Stjones1@inf.ed.ac.uk Addr EA; 1966691Stjones1@inf.ed.ac.uk %(op_decl)s; 1976691Stjones1@inf.ed.ac.uk %(op_rd)s; 1986691Stjones1@inf.ed.ac.uk %(ea_code)s; 1996691Stjones1@inf.ed.ac.uk DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 2006691Stjones1@inf.ed.ac.uk 2016691Stjones1@inf.ed.ac.uk %(code)s; 2026691Stjones1@inf.ed.ac.uk 2036691Stjones1@inf.ed.ac.uk if(fault == NoFault) 2046691Stjones1@inf.ed.ac.uk { 2056691Stjones1@inf.ed.ac.uk fault = writeMemTiming(xc, traceData, Mem, dataSize, EA, 2066691Stjones1@inf.ed.ac.uk memFlags, NULL); 2076691Stjones1@inf.ed.ac.uk } 2086691Stjones1@inf.ed.ac.uk return fault; 2096691Stjones1@inf.ed.ac.uk } 2106691Stjones1@inf.ed.ac.uk}}; 2116691Stjones1@inf.ed.ac.uk 2126691Stjones1@inf.ed.ac.ukdef template MicroStoreCompleteAcc {{ 2136691Stjones1@inf.ed.ac.uk Fault %(class_name)s::completeAcc(PacketPtr pkt, 2146691Stjones1@inf.ed.ac.uk %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const 2156691Stjones1@inf.ed.ac.uk { 2166691Stjones1@inf.ed.ac.uk %(op_decl)s; 2176691Stjones1@inf.ed.ac.uk %(op_rd)s; 2186691Stjones1@inf.ed.ac.uk %(complete_code)s; 2196691Stjones1@inf.ed.ac.uk %(op_wb)s; 2206691Stjones1@inf.ed.ac.uk return NoFault; 2216691Stjones1@inf.ed.ac.uk } 2226691Stjones1@inf.ed.ac.uk}}; 2236691Stjones1@inf.ed.ac.uk 2246691Stjones1@inf.ed.ac.uk// Common templates 2256691Stjones1@inf.ed.ac.uk 2266691Stjones1@inf.ed.ac.uk//This delcares the initiateAcc function in memory operations 2276691Stjones1@inf.ed.ac.ukdef template InitiateAccDeclare {{ 2286691Stjones1@inf.ed.ac.uk Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 2296691Stjones1@inf.ed.ac.uk}}; 2306691Stjones1@inf.ed.ac.uk 2316691Stjones1@inf.ed.ac.uk//This declares the completeAcc function in memory operations 2326691Stjones1@inf.ed.ac.ukdef template CompleteAccDeclare {{ 2336691Stjones1@inf.ed.ac.uk Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 2346691Stjones1@inf.ed.ac.uk}}; 2356691Stjones1@inf.ed.ac.uk 2366691Stjones1@inf.ed.ac.ukdef template MicroLdStOpDeclare {{ 2376691Stjones1@inf.ed.ac.uk class %(class_name)s : public %(base_class)s 2386691Stjones1@inf.ed.ac.uk { 2396691Stjones1@inf.ed.ac.uk public: 2406691Stjones1@inf.ed.ac.uk %(class_name)s(ExtMachInst _machInst, 2416691Stjones1@inf.ed.ac.uk const char * instMnem, uint64_t setFlags, 2426691Stjones1@inf.ed.ac.uk uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 2436691Stjones1@inf.ed.ac.uk uint64_t _disp, InstRegIndex _segment, 2446691Stjones1@inf.ed.ac.uk InstRegIndex _data, 2456691Stjones1@inf.ed.ac.uk uint8_t _dataSize, uint8_t _addressSize, 2466691Stjones1@inf.ed.ac.uk Request::FlagsType _memFlags); 2476691Stjones1@inf.ed.ac.uk 2486691Stjones1@inf.ed.ac.uk %(BasicExecDeclare)s 2496691Stjones1@inf.ed.ac.uk 2506691Stjones1@inf.ed.ac.uk %(InitiateAccDeclare)s 2516691Stjones1@inf.ed.ac.uk 2526691Stjones1@inf.ed.ac.uk %(CompleteAccDeclare)s 2536691Stjones1@inf.ed.ac.uk }; 2546691Stjones1@inf.ed.ac.uk}}; 2556691Stjones1@inf.ed.ac.uk 2566691Stjones1@inf.ed.ac.ukdef template MicroLdStOpConstructor {{ 2576691Stjones1@inf.ed.ac.uk %(class_name)s::%(class_name)s( 2586691Stjones1@inf.ed.ac.uk ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 2596691Stjones1@inf.ed.ac.uk uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 2606691Stjones1@inf.ed.ac.uk uint64_t _disp, InstRegIndex _segment, 2616691Stjones1@inf.ed.ac.uk InstRegIndex _data, 2626691Stjones1@inf.ed.ac.uk uint8_t _dataSize, uint8_t _addressSize, 2636691Stjones1@inf.ed.ac.uk Request::FlagsType _memFlags) : 2646691Stjones1@inf.ed.ac.uk %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 2656691Stjones1@inf.ed.ac.uk _scale, _index, _base, 2666691Stjones1@inf.ed.ac.uk _disp, _segment, _data, 2676691Stjones1@inf.ed.ac.uk _dataSize, _addressSize, _memFlags, %(op_class)s) 2686691Stjones1@inf.ed.ac.uk { 2696701Sgblack@eecs.umich.edu %(constructor)s; 2706691Stjones1@inf.ed.ac.uk } 2716691Stjones1@inf.ed.ac.uk}}; 2726701Sgblack@eecs.umich.edu 2736691Stjones1@inf.ed.ac.uklet {{ 2746691Stjones1@inf.ed.ac.uk class LdStOp(X86Microop): 2756691Stjones1@inf.ed.ac.uk def __init__(self, data, segment, addr, disp, 2766691Stjones1@inf.ed.ac.uk dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 2776691Stjones1@inf.ed.ac.uk self.data = data 2786691Stjones1@inf.ed.ac.uk [self.scale, self.index, self.base] = addr 2796691Stjones1@inf.ed.ac.uk self.disp = disp 2806691Stjones1@inf.ed.ac.uk self.segment = segment 2816691Stjones1@inf.ed.ac.uk self.dataSize = dataSize 2826691Stjones1@inf.ed.ac.uk self.addressSize = addressSize 2836691Stjones1@inf.ed.ac.uk self.memFlags = baseFlags 2846691Stjones1@inf.ed.ac.uk if atCPL0: 2856691Stjones1@inf.ed.ac.uk self.memFlags += " | (CPL0FlagBit << FlagShift)" 2866691Stjones1@inf.ed.ac.uk self.instFlags = "" 2876691Stjones1@inf.ed.ac.uk if prefetch: 2886691Stjones1@inf.ed.ac.uk self.memFlags += " | Request::PREFETCH" 289 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 290 if nonSpec: 291 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 292 self.memFlags += " | (machInst.legacy.addr ? " + \ 293 "(AddrSizeFlagBit << FlagShift) : 0)" 294 295 def getAllocator(self, microFlags): 296 allocator = '''new %(class_name)s(machInst, macrocodeBlock, 297 %(flags)s, %(scale)s, %(index)s, %(base)s, 298 %(disp)s, %(segment)s, %(data)s, 299 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { 300 "class_name" : self.className, 301 "flags" : self.microFlagsText(microFlags) + self.instFlags, 302 "scale" : self.scale, "index" : self.index, 303 "base" : self.base, 304 "disp" : self.disp, 305 "segment" : self.segment, "data" : self.data, 306 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 307 "memFlags" : self.memFlags} 308 return allocator 309 310 class BigLdStOp(X86Microop): 311 def __init__(self, data, segment, addr, disp, 312 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 313 self.data = data 314 [self.scale, self.index, self.base] = addr 315 self.disp = disp 316 self.segment = segment 317 self.dataSize = dataSize 318 self.addressSize = addressSize 319 self.memFlags = baseFlags 320 if atCPL0: 321 self.memFlags += " | (CPL0FlagBit << FlagShift)" 322 self.instFlags = "" 323 if prefetch: 324 self.memFlags += " | Request::PREFETCH" 325 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 326 if nonSpec: 327 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 328 self.memFlags += " | (machInst.legacy.addr ? " + \ 329 "(AddrSizeFlagBit << FlagShift) : 0)" 330 331 def getAllocator(self, microFlags): 332 allocString = ''' 333 (%(dataSize)s >= 4) ? 334 (StaticInstPtr)(new %(class_name)sBig(machInst, 335 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 336 %(base)s, %(disp)s, %(segment)s, %(data)s, 337 %(dataSize)s, %(addressSize)s, %(memFlags)s)) : 338 (StaticInstPtr)(new %(class_name)s(machInst, 339 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 340 %(base)s, %(disp)s, %(segment)s, %(data)s, 341 %(dataSize)s, %(addressSize)s, %(memFlags)s)) 342 ''' 343 allocator = allocString % { 344 "class_name" : self.className, 345 "flags" : self.microFlagsText(microFlags) + self.instFlags, 346 "scale" : self.scale, "index" : self.index, 347 "base" : self.base, 348 "disp" : self.disp, 349 "segment" : self.segment, "data" : self.data, 350 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 351 "memFlags" : self.memFlags} 352 return allocator 353}}; 354 355let {{ 356 357 # Make these empty strings so that concatenating onto 358 # them will always work. 359 header_output = "" 360 decoder_output = "" 361 exec_output = "" 362 363 calculateEA = ''' 364 EA = SegBase + bits(scale * Index + Base + disp, addressSize * 8 - 1, 0); 365 ''' 366 367 def defineMicroLoadOp(mnemonic, code, bigCode='', 368 mem_flags="0", big=True): 369 global header_output 370 global decoder_output 371 global exec_output 372 global microopClasses 373 Name = mnemonic 374 name = mnemonic.lower() 375 376 # Build up the all register version of this micro op 377 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp', 378 {"code": code, "ea_code": calculateEA})] 379 if big: 380 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp', 381 {"code": bigCode, "ea_code": calculateEA})] 382 for iop in iops: 383 header_output += MicroLdStOpDeclare.subst(iop) 384 decoder_output += MicroLdStOpConstructor.subst(iop) 385 exec_output += MicroLoadExecute.subst(iop) 386 exec_output += MicroLoadInitiateAcc.subst(iop) 387 exec_output += MicroLoadCompleteAcc.subst(iop) 388 389 base = LdStOp 390 if big: 391 base = BigLdStOp 392 class LoadOp(base): 393 def __init__(self, data, segment, addr, disp = 0, 394 dataSize="env.dataSize", 395 addressSize="env.addressSize", 396 atCPL0=False, prefetch=False, nonSpec=False): 397 super(LoadOp, self).__init__(data, segment, addr, 398 disp, dataSize, addressSize, mem_flags, 399 atCPL0, prefetch, nonSpec) 400 self.className = Name 401 self.mnemonic = name 402 403 microopClasses[name] = LoadOp 404 405 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);', 406 'Data = Mem & mask(dataSize * 8);') 407 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 408 'Data = Mem & mask(dataSize * 8);', 409 '(StoreCheck << FlagShift)') 410 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);', 411 'Data = Mem & mask(dataSize * 8);', 412 '(StoreCheck << FlagShift) | Request::LOCKED') 413 414 defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False) 415 416 defineMicroLoadOp('Ldfp87', code=''' 417 switch (dataSize) 418 { 419 case 4: 420 FpData_df = *(float *)&Mem; 421 break; 422 case 8: 423 FpData_df = *(double *)&Mem; 424 break; 425 default: 426 panic("Unhandled data size in LdFp87.\\n"); 427 } 428 ''', big = False) 429 430 def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"): 431 global header_output 432 global decoder_output 433 global exec_output 434 global microopClasses 435 Name = mnemonic 436 name = mnemonic.lower() 437 438 # Build up the all register version of this micro op 439 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 440 {"code": code, 441 "complete_code": completeCode, 442 "ea_code": calculateEA}) 443 header_output += MicroLdStOpDeclare.subst(iop) 444 decoder_output += MicroLdStOpConstructor.subst(iop) 445 exec_output += MicroStoreExecute.subst(iop) 446 exec_output += MicroStoreInitiateAcc.subst(iop) 447 exec_output += MicroStoreCompleteAcc.subst(iop) 448 449 class StoreOp(LdStOp): 450 def __init__(self, data, segment, addr, disp = 0, 451 dataSize="env.dataSize", 452 addressSize="env.addressSize", 453 atCPL0=False, nonSpec=False): 454 super(StoreOp, self).__init__(data, segment, addr, disp, 455 dataSize, addressSize, mem_flags, atCPL0, False, 456 nonSpec) 457 self.className = Name 458 self.mnemonic = name 459 460 microopClasses[name] = StoreOp 461 462 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') 463 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);', 464 mem_flags="Request::LOCKED") 465 466 defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;') 467 468 defineMicroStoreOp('Stfp87', code=''' 469 switch (dataSize) 470 { 471 case 4: { 472 float single(FpData_df); 473 Mem = *(uint32_t *)&single; 474 } break; 475 case 8: 476 Mem = *(uint64_t *)&FpData_df; 477 break; 478 default: 479 panic("Unhandled data size in StFp87.\\n"); 480 } 481 ''') 482 483 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 484 485 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 486 {"code": "Data = merge(Data, EA, dataSize);", 487 "ea_code": ''' 488 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0); 489 '''}) 490 header_output += MicroLeaDeclare.subst(iop) 491 decoder_output += MicroLdStOpConstructor.subst(iop) 492 exec_output += MicroLeaExecute.subst(iop) 493 494 class LeaOp(LdStOp): 495 def __init__(self, data, segment, addr, disp = 0, 496 dataSize="env.dataSize", addressSize="env.addressSize"): 497 super(LeaOp, self).__init__(data, segment, addr, disp, 498 dataSize, addressSize, "0", False, False, False) 499 self.className = "Lea" 500 self.mnemonic = "lea" 501 502 microopClasses["lea"] = LeaOp 503 504 505 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', 506 {"code": "xc->demapPage(EA, 0);", 507 "ea_code": calculateEA}) 508 header_output += MicroLeaDeclare.subst(iop) 509 decoder_output += MicroLdStOpConstructor.subst(iop) 510 exec_output += MicroLeaExecute.subst(iop) 511 512 class TiaOp(LdStOp): 513 def __init__(self, segment, addr, disp = 0, 514 dataSize="env.dataSize", 515 addressSize="env.addressSize"): 516 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 517 addr, disp, dataSize, addressSize, "0", False, False, 518 False) 519 self.className = "Tia" 520 self.mnemonic = "tia" 521 522 microopClasses["tia"] = TiaOp 523 524 class CdaOp(LdStOp): 525 def __init__(self, segment, addr, disp = 0, 526 dataSize="env.dataSize", 527 addressSize="env.addressSize", atCPL0=False): 528 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 529 addr, disp, dataSize, addressSize, "Request::NO_ACCESS", 530 atCPL0, False, False) 531 self.className = "Cda" 532 self.mnemonic = "cda" 533 534 microopClasses["cda"] = CdaOp 535}}; 536 537