ldstop.isa revision 11829
12SN/A// Copyright (c) 2007-2008 The Hewlett-Packard Development Company 214027Stiago.muck@arm.com// Copyright (c) 2015 Advanced Micro Devices, Inc. 310688Sandreas.hansson@arm.com// All rights reserved. 410688Sandreas.hansson@arm.com// 510688Sandreas.hansson@arm.com// The license below extends only to copyright in the software and shall 610688Sandreas.hansson@arm.com// not be construed as granting a license to any other intellectual 710688Sandreas.hansson@arm.com// property including but not limited to intellectual property relating 810688Sandreas.hansson@arm.com// to a hardware implementation of the functionality of the software 910688Sandreas.hansson@arm.com// licensed hereunder. You may use the software subject to the license 1010688Sandreas.hansson@arm.com// terms below provided that you ensure that this notice is replicated 1110688Sandreas.hansson@arm.com// unmodified and in its entirety in all distributions of the software, 1210688Sandreas.hansson@arm.com// modified or unmodified, in source code or in binary form. 1310688Sandreas.hansson@arm.com// 141762SN/A// Copyright (c) 2008 The Regents of The University of Michigan 152SN/A// All rights reserved. 162SN/A// 172SN/A// Redistribution and use in source and binary forms, with or without 182SN/A// modification, are permitted provided that the following conditions are 192SN/A// met: redistributions of source code must retain the above copyright 202SN/A// notice, this list of conditions and the following disclaimer; 212SN/A// redistributions in binary form must reproduce the above copyright 222SN/A// notice, this list of conditions and the following disclaimer in the 232SN/A// documentation and/or other materials provided with the distribution; 242SN/A// neither the name of the copyright holders nor the names of its 252SN/A// contributors may be used to endorse or promote products derived from 262SN/A// this software without specific prior written permission. 272SN/A// 282SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665SN/A// 402665SN/A// Authors: Gabe Black 412665SN/A 4210688Sandreas.hansson@arm.com////////////////////////////////////////////////////////////////////////// 432SN/A// 442SN/A// LdStOp Microop templates 4511793Sbrandon.potter@amd.com// 4611793Sbrandon.potter@amd.com////////////////////////////////////////////////////////////////////////// 4710348Sandreas.hansson@arm.com 48146SN/A// LEA template 4911800Sbrandon.potter@amd.com 508232Snate@binkert.orgdef template MicroLeaExecute {{ 5110688Sandreas.hansson@arm.com Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 52695SN/A Trace::InstRecord *traceData) const 538832SAli.Saidi@ARM.com { 542SN/A Fault fault = NoFault; 552SN/A Addr EA; 562SN/A 5710688Sandreas.hansson@arm.com %(op_decl)s; 581298SN/A %(op_rd)s; 593187SN/A %(ea_code)s; 608975Sandreas.hansson@arm.com DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 613187SN/A 6210688Sandreas.hansson@arm.com %(code)s; 633187SN/A if(fault == NoFault) 643187SN/A { 653187SN/A %(op_wb)s; 663187SN/A } 6710713Sandreas.hansson@arm.com 683187SN/A return fault; 6910688Sandreas.hansson@arm.com } 703187SN/A}}; 713187SN/A 7210688Sandreas.hansson@arm.comdef template MicroLeaDeclare {{ 733349SN/A class %(class_name)s : public %(base_class)s 743262SN/A { 7510688Sandreas.hansson@arm.com public: 763262SN/A %(class_name)s(ExtMachInst _machInst, 777544SN/A const char * instMnem, uint64_t setFlags, 7810688Sandreas.hansson@arm.com uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 7910688Sandreas.hansson@arm.com uint64_t _disp, InstRegIndex _segment, 8010688Sandreas.hansson@arm.com InstRegIndex _data, 817544SN/A uint8_t _dataSize, uint8_t _addressSize, 823262SN/A Request::FlagsType _memFlags); 8310688Sandreas.hansson@arm.com 843262SN/A %(BasicExecDeclare)s 853262SN/A }; 865034SN/A}}; 8713892Sgabeblack@google.com 8812085Sspwilson2@wisc.edu// Load templates 8912085Sspwilson2@wisc.edu 9012085Sspwilson2@wisc.edudef template MicroLoadExecute {{ 9110688Sandreas.hansson@arm.com Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 9210688Sandreas.hansson@arm.com Trace::InstRecord *traceData) const 9310688Sandreas.hansson@arm.com { 9410688Sandreas.hansson@arm.com Fault fault = NoFault; 955034SN/A Addr EA; 965034SN/A 975034SN/A %(op_decl)s; 9812680Sgiacomo.travaglini@arm.com %(op_rd)s; 9910688Sandreas.hansson@arm.com %(ea_code)s; 10010688Sandreas.hansson@arm.com DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 1015034SN/A 10210688Sandreas.hansson@arm.com fault = readMemAtomic(xc, traceData, EA, Mem, 1035034SN/A %(memDataSize)s, memFlags); 1045034SN/A 10510688Sandreas.hansson@arm.com if (fault == NoFault) { 10610688Sandreas.hansson@arm.com %(code)s; 1072SN/A } else if (memFlags & Request::PREFETCH) { 1087544SN/A // For prefetches, ignore any faults/exceptions. 10910688Sandreas.hansson@arm.com return NoFault; 11010688Sandreas.hansson@arm.com } 1117544SN/A if(fault == NoFault) 1122SN/A { 1132SN/A %(op_wb)s; 1142SN/A } 1152SN/A 1162SN/A return fault; 1172SN/A } 1188436SBrad.Beckmann@amd.com}}; 1191298SN/A 12010688Sandreas.hansson@arm.comdef template MicroLoadInitiateAcc {{ 12110688Sandreas.hansson@arm.com Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc, 12210688Sandreas.hansson@arm.com Trace::InstRecord * traceData) const 1233187SN/A { 1243187SN/A Fault fault = NoFault; 12513784Sgabeblack@google.com Addr EA; 12613784Sgabeblack@google.com 1273187SN/A %(op_decl)s; 12810688Sandreas.hansson@arm.com %(op_rd)s; 12910688Sandreas.hansson@arm.com %(ea_code)s; 1303187SN/A DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 13113892Sgabeblack@google.com 1323187SN/A fault = initiateMemRead(xc, traceData, EA, 1333187SN/A %(memDataSize)s, memFlags); 1343187SN/A 13510688Sandreas.hansson@arm.com return fault; 1362SN/A } 13712749Sgiacomo.travaglini@arm.com}}; 13810688Sandreas.hansson@arm.com 1394628SN/Adef template MicroLoadCompleteAcc {{ 14010688Sandreas.hansson@arm.com Fault %(class_name)s::completeAcc(PacketPtr pkt, 14110688Sandreas.hansson@arm.com CPU_EXEC_CONTEXT * xc, 14210688Sandreas.hansson@arm.com Trace::InstRecord * traceData) const 14310688Sandreas.hansson@arm.com { 1447544SN/A Fault fault = NoFault; 14510688Sandreas.hansson@arm.com 1464628SN/A %(op_decl)s; 14710688Sandreas.hansson@arm.com %(op_rd)s; 1488436SBrad.Beckmann@amd.com 1494628SN/A getMem(pkt, Mem, %(memDataSize)s, traceData); 15010688Sandreas.hansson@arm.com 1511298SN/A %(code)s; 1528436SBrad.Beckmann@amd.com 15310688Sandreas.hansson@arm.com if(fault == NoFault) 15410688Sandreas.hansson@arm.com { 15510688Sandreas.hansson@arm.com %(op_wb)s; 1562SN/A } 1578436SBrad.Beckmann@amd.com 1588436SBrad.Beckmann@amd.com return fault; 15910688Sandreas.hansson@arm.com } 16010688Sandreas.hansson@arm.com}}; 1618436SBrad.Beckmann@amd.com 1628436SBrad.Beckmann@amd.com// Store templates 16310688Sandreas.hansson@arm.com 16410688Sandreas.hansson@arm.comdef template MicroStoreExecute {{ 1658436SBrad.Beckmann@amd.com Fault %(class_name)s::execute(CPU_EXEC_CONTEXT * xc, 1662SN/A Trace::InstRecord *traceData) const 1678436SBrad.Beckmann@amd.com { 1688436SBrad.Beckmann@amd.com Fault fault = NoFault; 1692SN/A 1708436SBrad.Beckmann@amd.com Addr EA; 1718436SBrad.Beckmann@amd.com %(op_decl)s; 1728436SBrad.Beckmann@amd.com %(op_rd)s; 1738436SBrad.Beckmann@amd.com %(ea_code)s; 1748436SBrad.Beckmann@amd.com DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 1758436SBrad.Beckmann@amd.com 1768436SBrad.Beckmann@amd.com %(code)s; 1778436SBrad.Beckmann@amd.com 1788436SBrad.Beckmann@amd.com if(fault == NoFault) 1798436SBrad.Beckmann@amd.com { 18010688Sandreas.hansson@arm.com fault = writeMemAtomic(xc, traceData, Mem, %(memDataSize)s, EA, 18110688Sandreas.hansson@arm.com memFlags, NULL); 18210688Sandreas.hansson@arm.com if(fault == NoFault) 1838436SBrad.Beckmann@amd.com { 1848436SBrad.Beckmann@amd.com %(op_wb)s; 1852SN/A } 1862SN/A } 1872SN/A 18810688Sandreas.hansson@arm.com return fault; 1893187SN/A } 19010688Sandreas.hansson@arm.com}}; 19114027Stiago.muck@arm.com 19214027Stiago.muck@arm.comdef template MicroStoreInitiateAcc {{ 19314027Stiago.muck@arm.com Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc, 19414027Stiago.muck@arm.com Trace::InstRecord * traceData) const 19514027Stiago.muck@arm.com { 19614027Stiago.muck@arm.com Fault fault = NoFault; 1972SN/A 1982SN/A Addr EA; 1992SN/A %(op_decl)s; 2002SN/A %(op_rd)s; 2012SN/A %(ea_code)s; 20213892Sgabeblack@google.com DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 20311523Sdavid.guillen@arm.com 204729SN/A %(code)s; 2052SN/A 206695SN/A if(fault == NoFault) 2072SN/A { 2082SN/A fault = writeMemTiming(xc, traceData, Mem, %(memDataSize)s, EA, 2092SN/A memFlags, NULL); 2102SN/A } 211695SN/A return fault; 2122SN/A } 2132SN/A}}; 2142SN/A 2152SN/Adef template MicroStoreCompleteAcc {{ 2162SN/A Fault %(class_name)s::completeAcc(PacketPtr pkt, 2172SN/A CPU_EXEC_CONTEXT * xc, Trace::InstRecord * traceData) const 2182SN/A { 2192SN/A %(op_decl)s; 22010688Sandreas.hansson@arm.com %(op_rd)s; 22110688Sandreas.hansson@arm.com %(complete_code)s; 2222SN/A %(op_wb)s; 22310688Sandreas.hansson@arm.com return NoFault; 22410348Sandreas.hansson@arm.com } 22510688Sandreas.hansson@arm.com}}; 22610688Sandreas.hansson@arm.com 22710348Sandreas.hansson@arm.com// Common templates 2285736SN/A 2293187SN/A//This delcares the initiateAcc function in memory operations 2302SN/Adef template InitiateAccDeclare {{ 23110688Sandreas.hansson@arm.com Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 23210688Sandreas.hansson@arm.com}}; 23310688Sandreas.hansson@arm.com 2349301Snilay@cs.wisc.edu//This declares the completeAcc function in memory operations 23510688Sandreas.hansson@arm.comdef template CompleteAccDeclare {{ 23610688Sandreas.hansson@arm.com Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 23710688Sandreas.hansson@arm.com}}; 23810688Sandreas.hansson@arm.com 23910688Sandreas.hansson@arm.comdef template MicroLdStOpDeclare {{ 24010688Sandreas.hansson@arm.com class %(class_name)s : public %(base_class)s 24110688Sandreas.hansson@arm.com { 24210688Sandreas.hansson@arm.com public: 24310688Sandreas.hansson@arm.com %(class_name)s(ExtMachInst _machInst, 24410688Sandreas.hansson@arm.com const char * instMnem, uint64_t setFlags, 24510688Sandreas.hansson@arm.com uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 2469301Snilay@cs.wisc.edu uint64_t _disp, InstRegIndex _segment, 24710348Sandreas.hansson@arm.com InstRegIndex _data, 24810348Sandreas.hansson@arm.com uint8_t _dataSize, uint8_t _addressSize, 24912749Sgiacomo.travaglini@arm.com Request::FlagsType _memFlags); 25011435Smitch.hayenga@arm.com 2512SN/A %(BasicExecDeclare)s 25210688Sandreas.hansson@arm.com 25310688Sandreas.hansson@arm.com %(InitiateAccDeclare)s 25410688Sandreas.hansson@arm.com 25510688Sandreas.hansson@arm.com %(CompleteAccDeclare)s 25610688Sandreas.hansson@arm.com }; 25710688Sandreas.hansson@arm.com}}; 25810688Sandreas.hansson@arm.com 25910688Sandreas.hansson@arm.com// LdStSplitOp is a load or store that uses a pair of regs as the 2603187SN/A// source or destination. Used for cmpxchg{8,16}b. 2612SN/Adef template MicroLdStSplitOpDeclare {{ 26210688Sandreas.hansson@arm.com class %(class_name)s : public %(base_class)s 26310688Sandreas.hansson@arm.com { 26410688Sandreas.hansson@arm.com public: 26510688Sandreas.hansson@arm.com %(class_name)s(ExtMachInst _machInst, 26610688Sandreas.hansson@arm.com const char * instMnem, uint64_t setFlags, 26710688Sandreas.hansson@arm.com uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 26810688Sandreas.hansson@arm.com uint64_t _disp, InstRegIndex _segment, 26910688Sandreas.hansson@arm.com InstRegIndex _dataLow, InstRegIndex _dataHi, 27010688Sandreas.hansson@arm.com uint8_t _dataSize, uint8_t _addressSize, 2713187SN/A Request::FlagsType _memFlags); 2724628SN/A 27310688Sandreas.hansson@arm.com %(BasicExecDeclare)s 27410688Sandreas.hansson@arm.com 27510688Sandreas.hansson@arm.com %(InitiateAccDeclare)s 2763187SN/A 27710688Sandreas.hansson@arm.com %(CompleteAccDeclare)s 27810688Sandreas.hansson@arm.com }; 27910688Sandreas.hansson@arm.com}}; 28010688Sandreas.hansson@arm.com 28110688Sandreas.hansson@arm.comdef template MicroLdStOpConstructor {{ 28210688Sandreas.hansson@arm.com %(class_name)s::%(class_name)s( 2833187SN/A ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 28410688Sandreas.hansson@arm.com uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 28510688Sandreas.hansson@arm.com uint64_t _disp, InstRegIndex _segment, 28610688Sandreas.hansson@arm.com InstRegIndex _data, 28710688Sandreas.hansson@arm.com uint8_t _dataSize, uint8_t _addressSize, 28810688Sandreas.hansson@arm.com Request::FlagsType _memFlags) : 28910688Sandreas.hansson@arm.com %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 29010688Sandreas.hansson@arm.com _scale, _index, _base, 29110688Sandreas.hansson@arm.com _disp, _segment, _data, 29210688Sandreas.hansson@arm.com _dataSize, _addressSize, _memFlags, %(op_class)s) 29310688Sandreas.hansson@arm.com { 29410688Sandreas.hansson@arm.com %(constructor)s; 2953187SN/A } 29610688Sandreas.hansson@arm.com}}; 29710688Sandreas.hansson@arm.com 2981298SN/Adef template MicroLdStSplitOpConstructor {{ 29910688Sandreas.hansson@arm.com %(class_name)s::%(class_name)s( 30010688Sandreas.hansson@arm.com ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 30110688Sandreas.hansson@arm.com uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 3024628SN/A uint64_t _disp, InstRegIndex _segment, 30310688Sandreas.hansson@arm.com InstRegIndex _dataLow, InstRegIndex _dataHi, 30410688Sandreas.hansson@arm.com uint8_t _dataSize, uint8_t _addressSize, 30510688Sandreas.hansson@arm.com Request::FlagsType _memFlags) : 30610688Sandreas.hansson@arm.com %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 30710688Sandreas.hansson@arm.com _scale, _index, _base, 3083187SN/A _disp, _segment, _dataLow, _dataHi, 30914027Stiago.muck@arm.com _dataSize, _addressSize, _memFlags, %(op_class)s) 31014027Stiago.muck@arm.com { 31114027Stiago.muck@arm.com %(constructor)s; 31214027Stiago.muck@arm.com } 3132SN/A}}; 3142SN/A 3152SN/Alet {{ 31610688Sandreas.hansson@arm.com class LdStOp(X86Microop): 3172SN/A def __init__(self, data, segment, addr, disp, 31810688Sandreas.hansson@arm.com dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec, 31910688Sandreas.hansson@arm.com implicitStack): 32010688Sandreas.hansson@arm.com self.data = data 32110688Sandreas.hansson@arm.com [self.scale, self.index, self.base] = addr 32210688Sandreas.hansson@arm.com self.disp = disp 32310688Sandreas.hansson@arm.com self.segment = segment 32410688Sandreas.hansson@arm.com self.dataSize = dataSize 32510688Sandreas.hansson@arm.com self.addressSize = addressSize 32610688Sandreas.hansson@arm.com self.memFlags = baseFlags 32710688Sandreas.hansson@arm.com if atCPL0: 32810688Sandreas.hansson@arm.com self.memFlags += " | (CPL0FlagBit << FlagShift)" 32910688Sandreas.hansson@arm.com self.instFlags = "" 33010688Sandreas.hansson@arm.com if prefetch: 33110688Sandreas.hansson@arm.com self.memFlags += " | Request::PREFETCH" 33210688Sandreas.hansson@arm.com self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 33310688Sandreas.hansson@arm.com if nonSpec: 33410688Sandreas.hansson@arm.com self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 33510688Sandreas.hansson@arm.com # For implicit stack operations, we should use *not* use the 33610688Sandreas.hansson@arm.com # alternative addressing mode for loads/stores if the prefix is set 33714027Stiago.muck@arm.com if not implicitStack: 3383187SN/A self.memFlags += " | (machInst.legacy.addr ? " + \ 3392SN/A "(AddrSizeFlagBit << FlagShift) : 0)" 3402SN/A 3415315SN/A def getAllocator(self, microFlags): 3425315SN/A allocator = '''new %(class_name)s(machInst, macrocodeBlock, 3435315SN/A %(flags)s, %(scale)s, %(index)s, %(base)s, 3445315SN/A %(disp)s, %(segment)s, %(data)s, 3455315SN/A %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { 346 "class_name" : self.className, 347 "flags" : self.microFlagsText(microFlags) + self.instFlags, 348 "scale" : self.scale, "index" : self.index, 349 "base" : self.base, 350 "disp" : self.disp, 351 "segment" : self.segment, "data" : self.data, 352 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 353 "memFlags" : self.memFlags} 354 return allocator 355 356 class BigLdStOp(X86Microop): 357 def __init__(self, data, segment, addr, disp, 358 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec, 359 implicitStack): 360 self.data = data 361 [self.scale, self.index, self.base] = addr 362 self.disp = disp 363 self.segment = segment 364 self.dataSize = dataSize 365 self.addressSize = addressSize 366 self.memFlags = baseFlags 367 if atCPL0: 368 self.memFlags += " | (CPL0FlagBit << FlagShift)" 369 self.instFlags = "" 370 if prefetch: 371 self.memFlags += " | Request::PREFETCH" 372 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 373 if nonSpec: 374 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 375 # For implicit stack operations, we should use *not* use the 376 # alternative addressing mode for loads/stores if the prefix is set 377 if not implicitStack: 378 self.memFlags += " | (machInst.legacy.addr ? " + \ 379 "(AddrSizeFlagBit << FlagShift) : 0)" 380 381 def getAllocator(self, microFlags): 382 allocString = ''' 383 (%(dataSize)s >= 4) ? 384 (StaticInstPtr)(new %(class_name)sBig(machInst, 385 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 386 %(base)s, %(disp)s, %(segment)s, %(data)s, 387 %(dataSize)s, %(addressSize)s, %(memFlags)s)) : 388 (StaticInstPtr)(new %(class_name)s(machInst, 389 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 390 %(base)s, %(disp)s, %(segment)s, %(data)s, 391 %(dataSize)s, %(addressSize)s, %(memFlags)s)) 392 ''' 393 allocator = allocString % { 394 "class_name" : self.className, 395 "flags" : self.microFlagsText(microFlags) + self.instFlags, 396 "scale" : self.scale, "index" : self.index, 397 "base" : self.base, 398 "disp" : self.disp, 399 "segment" : self.segment, "data" : self.data, 400 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 401 "memFlags" : self.memFlags} 402 return allocator 403 404 class LdStSplitOp(LdStOp): 405 def __init__(self, data, segment, addr, disp, 406 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec, 407 implicitStack): 408 super(LdStSplitOp, self).__init__(0, segment, addr, disp, 409 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec, 410 implicitStack) 411 (self.dataLow, self.dataHi) = data 412 413 def getAllocator(self, microFlags): 414 allocString = '''(StaticInstPtr)(new %(class_name)s(machInst, 415 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 416 %(base)s, %(disp)s, %(segment)s, 417 %(dataLow)s, %(dataHi)s, 418 %(dataSize)s, %(addressSize)s, %(memFlags)s)) 419 ''' 420 allocator = allocString % { 421 "class_name" : self.className, 422 "flags" : self.microFlagsText(microFlags) + self.instFlags, 423 "scale" : self.scale, "index" : self.index, 424 "base" : self.base, 425 "disp" : self.disp, 426 "segment" : self.segment, 427 "dataLow" : self.dataLow, "dataHi" : self.dataHi, 428 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 429 "memFlags" : self.memFlags} 430 return allocator 431 432}}; 433 434let {{ 435 436 # Make these empty strings so that concatenating onto 437 # them will always work. 438 header_output = "" 439 decoder_output = "" 440 exec_output = "" 441 442 segmentEAExpr = \ 443 'bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);' 444 445 calculateEA = 'EA = SegBase + ' + segmentEAExpr 446 447 def defineMicroLoadOp(mnemonic, code, bigCode='', 448 mem_flags="0", big=True, nonSpec=False, 449 implicitStack=False): 450 global header_output 451 global decoder_output 452 global exec_output 453 global microopClasses 454 Name = mnemonic 455 name = mnemonic.lower() 456 457 # Build up the all register version of this micro op 458 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp', 459 { "code": code, 460 "ea_code": calculateEA, 461 "memDataSize": "dataSize" })] 462 if big: 463 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp', 464 { "code": bigCode, 465 "ea_code": calculateEA, 466 "memDataSize": "dataSize" })] 467 for iop in iops: 468 header_output += MicroLdStOpDeclare.subst(iop) 469 decoder_output += MicroLdStOpConstructor.subst(iop) 470 exec_output += MicroLoadExecute.subst(iop) 471 exec_output += MicroLoadInitiateAcc.subst(iop) 472 exec_output += MicroLoadCompleteAcc.subst(iop) 473 474 if implicitStack: 475 # For instructions that implicitly access the stack, the address 476 # size is the same as the stack segment pointer size, not the 477 # address size if specified by the instruction prefix 478 addressSize = "env.stackSize" 479 else: 480 addressSize = "env.addressSize" 481 482 base = LdStOp 483 if big: 484 base = BigLdStOp 485 class LoadOp(base): 486 def __init__(self, data, segment, addr, disp = 0, 487 dataSize="env.dataSize", 488 addressSize=addressSize, 489 atCPL0=False, prefetch=False, nonSpec=nonSpec, 490 implicitStack=implicitStack): 491 super(LoadOp, self).__init__(data, segment, addr, 492 disp, dataSize, addressSize, mem_flags, 493 atCPL0, prefetch, nonSpec, implicitStack) 494 self.className = Name 495 self.mnemonic = name 496 497 microopClasses[name] = LoadOp 498 499 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);', 500 'Data = Mem & mask(dataSize * 8);') 501 defineMicroLoadOp('Ldis', 'Data = merge(Data, Mem, dataSize);', 502 'Data = Mem & mask(dataSize * 8);', 503 implicitStack=True) 504 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 505 'Data = Mem & mask(dataSize * 8);', 506 '(StoreCheck << FlagShift)') 507 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);', 508 'Data = Mem & mask(dataSize * 8);', 509 '(StoreCheck << FlagShift) | Request::LOCKED_RMW', 510 nonSpec=True) 511 512 defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False) 513 514 defineMicroLoadOp('Ldfp87', code=''' 515 switch (dataSize) 516 { 517 case 4: 518 FpData_df = *(float *)&Mem; 519 break; 520 case 8: 521 FpData_df = *(double *)&Mem; 522 break; 523 default: 524 panic("Unhandled data size in LdFp87.\\n"); 525 } 526 ''', big = False) 527 528 # Load integer from memory into x87 top-of-stack register. 529 # Used to implement fild instruction. 530 defineMicroLoadOp('Ldifp87', code=''' 531 switch (dataSize) 532 { 533 case 2: 534 FpData_df = (int64_t)sext<16>(Mem); 535 break; 536 case 4: 537 FpData_df = (int64_t)sext<32>(Mem); 538 break; 539 case 8: 540 FpData_df = (int64_t)Mem; 541 break; 542 default: 543 panic("Unhandled data size in LdIFp87.\\n"); 544 } 545 ''', big = False) 546 547 def defineMicroLoadSplitOp(mnemonic, code, mem_flags="0", nonSpec=False): 548 global header_output 549 global decoder_output 550 global exec_output 551 global microopClasses 552 Name = mnemonic 553 name = mnemonic.lower() 554 555 iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp', 556 { "code": code, 557 "ea_code": calculateEA, 558 "memDataSize": "2 * dataSize" }) 559 560 header_output += MicroLdStSplitOpDeclare.subst(iop) 561 decoder_output += MicroLdStSplitOpConstructor.subst(iop) 562 exec_output += MicroLoadExecute.subst(iop) 563 exec_output += MicroLoadInitiateAcc.subst(iop) 564 exec_output += MicroLoadCompleteAcc.subst(iop) 565 566 class LoadOp(LdStSplitOp): 567 def __init__(self, data, segment, addr, disp = 0, 568 dataSize="env.dataSize", 569 addressSize="env.addressSize", 570 atCPL0=False, prefetch=False, nonSpec=nonSpec, 571 implicitStack=False): 572 super(LoadOp, self).__init__(data, segment, addr, 573 disp, dataSize, addressSize, mem_flags, 574 atCPL0, prefetch, nonSpec, implicitStack) 575 self.className = Name 576 self.mnemonic = name 577 578 microopClasses[name] = LoadOp 579 580 code = ''' 581 switch (dataSize) { 582 case 4: 583 DataLow = bits(Mem_u2qw[0], 31, 0); 584 DataHi = bits(Mem_u2qw[0], 63, 32); 585 break; 586 case 8: 587 DataLow = Mem_u2qw[0]; 588 DataHi = Mem_u2qw[1]; 589 break; 590 default: 591 panic("Unhandled data size %d in LdSplit.\\n", dataSize); 592 }''' 593 594 defineMicroLoadSplitOp('LdSplit', code, 595 '(StoreCheck << FlagShift)') 596 597 defineMicroLoadSplitOp('LdSplitl', code, 598 '(StoreCheck << FlagShift) | Request::LOCKED_RMW', 599 nonSpec=True) 600 601 def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0", 602 implicitStack=False): 603 global header_output 604 global decoder_output 605 global exec_output 606 global microopClasses 607 Name = mnemonic 608 name = mnemonic.lower() 609 610 # Build up the all register version of this micro op 611 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 612 { "code": code, 613 "complete_code": completeCode, 614 "ea_code": calculateEA, 615 "memDataSize": "dataSize" }) 616 header_output += MicroLdStOpDeclare.subst(iop) 617 decoder_output += MicroLdStOpConstructor.subst(iop) 618 exec_output += MicroStoreExecute.subst(iop) 619 exec_output += MicroStoreInitiateAcc.subst(iop) 620 exec_output += MicroStoreCompleteAcc.subst(iop) 621 622 if implicitStack: 623 # For instructions that implicitly access the stack, the address 624 # size is the same as the stack segment pointer size, not the 625 # address size if specified by the instruction prefix 626 addressSize = "env.stackSize" 627 else: 628 addressSize = "env.addressSize" 629 630 class StoreOp(LdStOp): 631 def __init__(self, data, segment, addr, disp = 0, 632 dataSize="env.dataSize", 633 addressSize=addressSize, 634 atCPL0=False, nonSpec=False, implicitStack=implicitStack): 635 super(StoreOp, self).__init__(data, segment, addr, disp, 636 dataSize, addressSize, mem_flags, atCPL0, False, 637 nonSpec, implicitStack) 638 self.className = Name 639 self.mnemonic = name 640 641 microopClasses[name] = StoreOp 642 643 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') 644 defineMicroStoreOp('Stis', 'Mem = pick(Data, 2, dataSize);', 645 implicitStack=True) 646 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);', 647 mem_flags="Request::LOCKED_RMW") 648 649 defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;') 650 651 defineMicroStoreOp('Stfp87', code=''' 652 switch (dataSize) 653 { 654 case 4: { 655 float single(FpData_df); 656 Mem = *(uint32_t *)&single; 657 } break; 658 case 8: 659 Mem = *(uint64_t *)&FpData_df; 660 break; 661 default: 662 panic("Unhandled data size in StFp87.\\n"); 663 } 664 ''') 665 666 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 667 668 def defineMicroStoreSplitOp(mnemonic, code, 669 completeCode="", mem_flags="0"): 670 global header_output 671 global decoder_output 672 global exec_output 673 global microopClasses 674 Name = mnemonic 675 name = mnemonic.lower() 676 677 iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp', 678 { "code": code, 679 "complete_code": completeCode, 680 "ea_code": calculateEA, 681 "memDataSize": "2 * dataSize" }) 682 683 header_output += MicroLdStSplitOpDeclare.subst(iop) 684 decoder_output += MicroLdStSplitOpConstructor.subst(iop) 685 exec_output += MicroStoreExecute.subst(iop) 686 exec_output += MicroStoreInitiateAcc.subst(iop) 687 exec_output += MicroStoreCompleteAcc.subst(iop) 688 689 class StoreOp(LdStSplitOp): 690 def __init__(self, data, segment, addr, disp = 0, 691 dataSize="env.dataSize", 692 addressSize="env.addressSize", 693 atCPL0=False, nonSpec=False, implicitStack=False): 694 super(StoreOp, self).__init__(data, segment, addr, disp, 695 dataSize, addressSize, mem_flags, atCPL0, False, 696 nonSpec, implicitStack) 697 self.className = Name 698 self.mnemonic = name 699 700 microopClasses[name] = StoreOp 701 702 code = ''' 703 switch (dataSize) { 704 case 4: 705 Mem_u2qw[0] = (DataHi << 32) | DataLow; 706 break; 707 case 8: 708 Mem_u2qw[0] = DataLow; 709 Mem_u2qw[1] = DataHi; 710 break; 711 default: 712 panic("Unhandled data size %d in StSplit.\\n", dataSize); 713 }''' 714 715 defineMicroStoreSplitOp('StSplit', code); 716 717 defineMicroStoreSplitOp('StSplitul', code, 718 mem_flags='Request::LOCKED_RMW') 719 720 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 721 { "code": "Data = merge(Data, EA, dataSize);", 722 "ea_code": "EA = " + segmentEAExpr, 723 "memDataSize": "dataSize" }) 724 header_output += MicroLeaDeclare.subst(iop) 725 decoder_output += MicroLdStOpConstructor.subst(iop) 726 exec_output += MicroLeaExecute.subst(iop) 727 728 class LeaOp(LdStOp): 729 def __init__(self, data, segment, addr, disp = 0, 730 dataSize="env.dataSize", addressSize="env.addressSize"): 731 super(LeaOp, self).__init__(data, segment, addr, disp, 732 dataSize, addressSize, "0", False, False, False, False) 733 self.className = "Lea" 734 self.mnemonic = "lea" 735 736 microopClasses["lea"] = LeaOp 737 738 739 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', 740 { "code": "xc->demapPage(EA, 0);", 741 "ea_code": calculateEA, 742 "memDataSize": "dataSize" }) 743 header_output += MicroLeaDeclare.subst(iop) 744 decoder_output += MicroLdStOpConstructor.subst(iop) 745 exec_output += MicroLeaExecute.subst(iop) 746 747 class TiaOp(LdStOp): 748 def __init__(self, segment, addr, disp = 0, 749 dataSize="env.dataSize", 750 addressSize="env.addressSize"): 751 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 752 addr, disp, dataSize, addressSize, "0", False, False, 753 False, False) 754 self.className = "Tia" 755 self.mnemonic = "tia" 756 757 microopClasses["tia"] = TiaOp 758 759 class CdaOp(LdStOp): 760 def __init__(self, segment, addr, disp = 0, 761 dataSize="env.dataSize", 762 addressSize="env.addressSize", atCPL0=False): 763 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 764 addr, disp, dataSize, addressSize, "Request::NO_ACCESS", 765 atCPL0, False, False, False) 766 self.className = "Cda" 767 self.mnemonic = "cda" 768 769 microopClasses["cda"] = CdaOp 770}}; 771