ldr.isa revision 10037
11689SN/A// -*- mode:c++ -*- 21689SN/A 31689SN/A// Copyright (c) 2010-2011 ARM Limited 41689SN/A// All rights reserved 51689SN/A// 61689SN/A// The license below extends only to copyright in the software and shall 71689SN/A// not be construed as granting a license to any other intellectual 81689SN/A// property including but not limited to intellectual property relating 91689SN/A// to a hardware implementation of the functionality of the software 101689SN/A// licensed hereunder. You may use the software subject to the license 111689SN/A// terms below provided that you ensure that this notice is replicated 121689SN/A// unmodified and in its entirety in all distributions of the software, 131689SN/A// modified or unmodified, in source code or in binary form. 141689SN/A// 151689SN/A// Redistribution and use in source and binary forms, with or without 161689SN/A// modification, are permitted provided that the following conditions are 171689SN/A// met: redistributions of source code must retain the above copyright 181689SN/A// notice, this list of conditions and the following disclaimer; 191689SN/A// redistributions in binary form must reproduce the above copyright 201689SN/A// notice, this list of conditions and the following disclaimer in the 211689SN/A// documentation and/or other materials provided with the distribution; 221689SN/A// neither the name of the copyright holders nor the names of its 231689SN/A// contributors may be used to endorse or promote products derived from 241689SN/A// this software without specific prior written permission. 251689SN/A// 261689SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 272665Ssaidi@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 282665Ssaidi@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 292756Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 301689SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 311689SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 322325SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 332325SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 341060SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 351060SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 361060SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 372292SN/A// 382292SN/A// Authors: Gabe Black 391681SN/A 401060SN/Alet {{ 412980Sgblack@eecs.umich.edu import math 421060SN/A 431060SN/A header_output = "" 441858SN/A decoder_output = "" 454598Sbinkertn@umich.edu exec_output = "" 462325SN/A 471717SN/A class LoadInst(LoadStoreInst): 482683Sktlim@umich.edu execBase = 'Load' 491717SN/A 501717SN/A def __init__(self, mnem, post, add, writeback, 512292SN/A size=4, sign=False, user=False, flavor="normal"): 522292SN/A super(LoadInst, self).__init__() 532817Sksewell@umich.edu 541060SN/A self.name = mnem 551060SN/A self.post = post 565529Snate@binkert.org self.add = add 575529Snate@binkert.org self.writeback = writeback 582316SN/A self.size = size 592316SN/A self.sign = sign 602680Sktlim@umich.edu self.user = user 612817Sksewell@umich.edu self.flavor = flavor 622817Sksewell@umich.edu self.rasPop = False 632843Sktlim@umich.edu 642843Sktlim@umich.edu if self.add: 652669Sktlim@umich.edu self.op = " +" 661060SN/A else: 671060SN/A self.op = " -" 685529Snate@binkert.org 695529Snate@binkert.org self.memFlags = ["ArmISA::TLB::MustBeOne"] 702733Sktlim@umich.edu self.codeBlobs = {"postacc_code" : ""} 711060SN/A 721060SN/A def emitHelper(self, base = 'Memory', wbDecl = None, instFlags = [], pcDecl = None): 731060SN/A 745529Snate@binkert.org global header_output, decoder_output, exec_output 752292SN/A 762292SN/A codeBlobs = self.codeBlobs 772632Sstever@eecs.umich.edu codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 782817Sksewell@umich.edu (newHeader, 792817Sksewell@umich.edu newDecoder, 802817Sksewell@umich.edu newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 812817Sksewell@umich.edu self.memFlags, instFlags, base, 822669Sktlim@umich.edu wbDecl, pcDecl, self.rasPop, 831681SN/A self.size, self.sign) 841685SN/A 851681SN/A header_output += newHeader 861060SN/A decoder_output += newDecoder 871060SN/A exec_output += newExec 882348SN/A 892348SN/A class RfeInst(LoadInst): 902348SN/A decConstBase = 'Rfe' 912348SN/A 922348SN/A def __init__(self, mnem, post, add, writeback): 931060SN/A super(RfeInst, self).__init__(mnem, post, add, writeback) 942733Sktlim@umich.edu self.Name = "RFE_" + loadImmClassName(post, add, writeback, 8) 951060SN/A 961060SN/A self.memFlags.append("ArmISA::TLB::AlignWord") 972325SN/A 981060SN/A def emit(self): 991061SN/A offset = 0 1004329Sktlim@umich.edu if self.post != self.add: 1011060SN/A offset += 4 1022292SN/A if not self.add: 1032292SN/A offset -= 8 1042292SN/A self.codeBlobs["ea_code"] = "EA = Base + %d;" % offset 1052292SN/A 1062817Sksewell@umich.edu wbDiff = -8 1072829Sksewell@umich.edu if self.add: 1081060SN/A wbDiff = 8 1091060SN/A accCode = ''' 1101060SN/A CPSR cpsr = Cpsr; 1111060SN/A cpsr.nz = CondCodesNZ; 1121060SN/A cpsr.c = CondCodesC; 1132307SN/A cpsr.v = CondCodesV; 1142307SN/A cpsr.ge = CondCodesGE; 1151060SN/A URc = cpsr; 1161060SN/A URa = cSwap<uint32_t>(Mem_ud, cpsr.e); 1173781Sgblack@eecs.umich.edu URb = cSwap<uint32_t>(Mem_ud >> 32, cpsr.e); 1183781Sgblack@eecs.umich.edu ''' 1193781Sgblack@eecs.umich.edu self.codeBlobs["memacc_code"] = accCode 1202292SN/A 1211060SN/A wbDecl = None 1221060SN/A pcDecl = "MicroUopSetPCCPSR(machInst, INTREG_UREG0, INTREG_UREG1, INTREG_UREG2);" 1232829Sksewell@umich.edu 1242829Sksewell@umich.edu if self.writeback: 1252829Sksewell@umich.edu wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff 1261060SN/A self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", "IsNonSpeculative"], pcDecl) 1271060SN/A 1281060SN/A class LoadImmInst(LoadInst): 1291060SN/A def __init__(self, *args, **kargs): 1302292SN/A super(LoadImmInst, self).__init__(*args, **kargs) 1311755SN/A self.offset = self.op + " imm" 1321060SN/A 1331060SN/A if self.add: 1342292SN/A self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" 1351755SN/A else: 1362292SN/A self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" 1372292SN/A 1381060SN/A if self.add and self.post and self.writeback and not self.sign and \ 1392292SN/A not self.user and self.size == 4: 1405336Shines@cs.fsu.edu self.rasPop = True 1411060SN/A 1421060SN/A class LoadRegInst(LoadInst): 1432292SN/A def __init__(self, *args, **kargs): 1441060SN/A super(LoadRegInst, self).__init__(*args, **kargs) 1451060SN/A self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 1462292SN/A " shiftType, OptShiftRmCondCodesC)" 1471060SN/A if self.add: 1481060SN/A self.wbDecl = ''' 1491060SN/A MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType); 1505100Ssaidi@eecs.umich.edu ''' 1511060SN/A else: 1525100Ssaidi@eecs.umich.edu self.wbDecl = ''' 1531060SN/A MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType); 1541060SN/A ''' 1552292SN/A 1561060SN/A class LoadSingle(LoadInst): 1571060SN/A def __init__(self, *args, **kargs): 1581060SN/A super(LoadSingle, self).__init__(*args, **kargs) 1591060SN/A 1601060SN/A # Build the default class name 1611060SN/A self.Name = self.nameFunc(self.post, self.add, self.writeback, 1622829Sksewell@umich.edu self.size, self.sign, self.user) 1632829Sksewell@umich.edu 1642829Sksewell@umich.edu # Add memory request flags where necessary 1652829Sksewell@umich.edu self.memFlags.append("%d" % int(math.log(self.size, 2))) 1662829Sksewell@umich.edu if self.user: 1672829Sksewell@umich.edu self.memFlags.append("ArmISA::TLB::UserMode") 1682829Sksewell@umich.edu 1692829Sksewell@umich.edu self.instFlags = [] 1702829Sksewell@umich.edu if self.flavor == "dprefetch": 1712829Sksewell@umich.edu self.memFlags.append("Request::PREFETCH") 1722829Sksewell@umich.edu self.instFlags = ['IsDataPrefetch'] 1732829Sksewell@umich.edu elif self.flavor == "iprefetch": 1742829Sksewell@umich.edu self.memFlags.append("Request::PREFETCH") 1752829Sksewell@umich.edu self.instFlags = ['IsInstPrefetch'] 1762829Sksewell@umich.edu elif self.flavor == "exclusive": 1772829Sksewell@umich.edu self.memFlags.append("Request::LLSC") 1782829Sksewell@umich.edu elif self.flavor == "normal": 1792829Sksewell@umich.edu self.memFlags.append("ArmISA::TLB::AllowUnaligned") 1802829Sksewell@umich.edu 1812829Sksewell@umich.edu # Disambiguate the class name for different flavors of loads 1825336Shines@cs.fsu.edu if self.flavor != "normal": 1832829Sksewell@umich.edu self.Name = "%s_%s" % (self.name.upper(), self.Name) 1842829Sksewell@umich.edu 1852829Sksewell@umich.edu def emit(self): 1862829Sksewell@umich.edu # Address compuation code 1872829Sksewell@umich.edu eaCode = "EA = Base" 1882829Sksewell@umich.edu if not self.post: 1892829Sksewell@umich.edu eaCode += self.offset 1904030Sktlim@umich.edu eaCode += ";" 1915100Ssaidi@eecs.umich.edu 1922829Sksewell@umich.edu if self.flavor == "fp": 1934030Sktlim@umich.edu eaCode += vfpEnabledCheckCode 1945100Ssaidi@eecs.umich.edu 1952829Sksewell@umich.edu self.codeBlobs["ea_code"] = eaCode 1962829Sksewell@umich.edu 1972829Sksewell@umich.edu # Code that actually handles the access 1982829Sksewell@umich.edu if self.flavor == "dprefetch" or self.flavor == "iprefetch": 1992829Sksewell@umich.edu accCode = 'uint64_t temp = Mem%s; temp = temp;' 2002829Sksewell@umich.edu elif self.flavor == "fp": 2012829Sksewell@umich.edu accCode = "FpDest_uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n" 2022829Sksewell@umich.edu else: 2032829Sksewell@umich.edu accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" 2042829Sksewell@umich.edu accCode = accCode % buildMemSuffix(self.sign, self.size) 2052829Sksewell@umich.edu 2062829Sksewell@umich.edu self.codeBlobs["memacc_code"] = accCode 2072875Sksewell@umich.edu 2082875Sksewell@umich.edu # Push it out to the output files 2092875Sksewell@umich.edu base = buildMemBase(self.basePrefix, self.post, self.writeback) 2103221Sktlim@umich.edu wbDecl = None 2112875Sksewell@umich.edu if self.writeback: 2122875Sksewell@umich.edu wbDecl = self.wbDecl 2133221Sktlim@umich.edu self.emitHelper(base, wbDecl, self.instFlags) 2143221Sktlim@umich.edu 2153221Sktlim@umich.edu def loadImmClassName(post, add, writeback, size=4, sign=False, user=False): 2162875Sksewell@umich.edu return memClassName("LOAD_IMM", post, add, writeback, size, sign, user) 2172875Sksewell@umich.edu 2182875Sksewell@umich.edu class LoadImm(LoadImmInst, LoadSingle): 2192875Sksewell@umich.edu decConstBase = 'LoadImm' 2202875Sksewell@umich.edu basePrefix = 'MemoryImm' 2212875Sksewell@umich.edu nameFunc = staticmethod(loadImmClassName) 2222875Sksewell@umich.edu 2232875Sksewell@umich.edu def loadRegClassName(post, add, writeback, size=4, sign=False, user=False): 2242875Sksewell@umich.edu return memClassName("LOAD_REG", post, add, writeback, size, sign, user) 2252875Sksewell@umich.edu 2262875Sksewell@umich.edu class LoadReg(LoadRegInst, LoadSingle): 2272875Sksewell@umich.edu decConstBase = 'LoadReg' 2282875Sksewell@umich.edu basePrefix = 'MemoryReg' 2293221Sktlim@umich.edu nameFunc = staticmethod(loadRegClassName) 2303221Sktlim@umich.edu 2313221Sktlim@umich.edu class LoadDouble(LoadInst): 2322875Sksewell@umich.edu def __init__(self, *args, **kargs): 2335336Shines@cs.fsu.edu super(LoadDouble, self).__init__(*args, **kargs) 2342875Sksewell@umich.edu 2352875Sksewell@umich.edu # Build the default class name 2362875Sksewell@umich.edu self.Name = self.nameFunc(self.post, self.add, self.writeback) 2373221Sktlim@umich.edu 2382875Sksewell@umich.edu # Add memory request flags where necessary 2392875Sksewell@umich.edu if self.flavor == "exclusive": 2402875Sksewell@umich.edu self.memFlags.append("Request::LLSC") 2414030Sktlim@umich.edu self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 2425100Ssaidi@eecs.umich.edu else: 2432875Sksewell@umich.edu self.memFlags.append("ArmISA::TLB::AlignWord") 2444030Sktlim@umich.edu 2455100Ssaidi@eecs.umich.edu # Disambiguate the class name for different flavors of loads 2462875Sksewell@umich.edu if self.flavor != "normal": 2472875Sksewell@umich.edu self.Name = "%s_%s" % (self.name.upper(), self.Name) 2482875Sksewell@umich.edu 2492875Sksewell@umich.edu def emit(self): 2502875Sksewell@umich.edu # Address computation code 2512875Sksewell@umich.edu eaCode = "EA = Base" 2522875Sksewell@umich.edu if not self.post: 2532875Sksewell@umich.edu eaCode += self.offset 2542875Sksewell@umich.edu eaCode += ";" 2552875Sksewell@umich.edu 2562875Sksewell@umich.edu if self.flavor == "fp": 2572875Sksewell@umich.edu eaCode += vfpEnabledCheckCode 2581060SN/A 2592292SN/A self.codeBlobs["ea_code"] = eaCode 2605529Snate@binkert.org 2612292SN/A # Code that actually handles the access 2621755SN/A if self.flavor != "fp": 2631060SN/A accCode = ''' 2642292SN/A CPSR cpsr = Cpsr; 2651684SN/A Dest = cSwap<uint32_t>(Mem_ud, cpsr.e); 2661684SN/A Dest2 = cSwap<uint32_t>(Mem_ud >> 32, cpsr.e); 2675358Sgblack@eecs.umich.edu ''' 2685358Sgblack@eecs.umich.edu else: 2695358Sgblack@eecs.umich.edu accCode = ''' 2705358Sgblack@eecs.umich.edu uint64_t swappedMem = cSwap(Mem_ud, ((CPSR)Cpsr).e); 2715358Sgblack@eecs.umich.edu FpDest_uw = (uint32_t)swappedMem; 2725358Sgblack@eecs.umich.edu FpDest2_uw = (uint32_t)(swappedMem >> 32); 2735358Sgblack@eecs.umich.edu ''' 2745358Sgblack@eecs.umich.edu 2755358Sgblack@eecs.umich.edu self.codeBlobs["memacc_code"] = accCode 2765358Sgblack@eecs.umich.edu 2775358Sgblack@eecs.umich.edu # Push it out to the output files 2785358Sgblack@eecs.umich.edu base = buildMemBase(self.basePrefix, self.post, self.writeback) 2795358Sgblack@eecs.umich.edu wbDecl = None 2805358Sgblack@eecs.umich.edu if self.writeback: 2815358Sgblack@eecs.umich.edu wbDecl = self.wbDecl 2825358Sgblack@eecs.umich.edu self.emitHelper(base, wbDecl) 2834988Sgblack@eecs.umich.edu 2844988Sgblack@eecs.umich.edu def loadDoubleImmClassName(post, add, writeback): 2854988Sgblack@eecs.umich.edu return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False) 2864988Sgblack@eecs.umich.edu 2874988Sgblack@eecs.umich.edu class LoadDoubleImm(LoadImmInst, LoadDouble): 2884988Sgblack@eecs.umich.edu decConstBase = 'LoadStoreDImm' 2894988Sgblack@eecs.umich.edu basePrefix = 'MemoryDImm' 2904988Sgblack@eecs.umich.edu nameFunc = staticmethod(loadDoubleImmClassName) 2914988Sgblack@eecs.umich.edu 2924988Sgblack@eecs.umich.edu def loadDoubleRegClassName(post, add, writeback): 2934988Sgblack@eecs.umich.edu return memClassName("LOAD_REGD", post, add, writeback, 4, False, False) 2944988Sgblack@eecs.umich.edu 2954988Sgblack@eecs.umich.edu class LoadDoubleReg(LoadRegInst, LoadDouble): 2964988Sgblack@eecs.umich.edu decConstBase = 'LoadDReg' 2974988Sgblack@eecs.umich.edu basePrefix = 'MemoryDReg' 2984988Sgblack@eecs.umich.edu nameFunc = staticmethod(loadDoubleRegClassName) 2994988Sgblack@eecs.umich.edu 3004988Sgblack@eecs.umich.edu def buildLoads(mnem, size=4, sign=False, user=False): 3012871Sktlim@umich.edu LoadImm(mnem, True, True, True, size, sign, user).emit() 3022871Sktlim@umich.edu LoadReg(mnem, True, True, True, size, sign, user).emit() 3032871Sktlim@umich.edu LoadImm(mnem, True, False, True, size, sign, user).emit() 3042292SN/A LoadReg(mnem, True, False, True, size, sign, user).emit() 3052292SN/A LoadImm(mnem, False, True, True, size, sign, user).emit() 3062292SN/A LoadReg(mnem, False, True, True, size, sign, user).emit() 3071684SN/A LoadImm(mnem, False, False, True, size, sign, user).emit() 3081684SN/A LoadReg(mnem, False, False, True, size, sign, user).emit() 3092292SN/A LoadImm(mnem, False, True, False, size, sign, user).emit() 3101060SN/A LoadReg(mnem, False, True, False, size, sign, user).emit() 3111060SN/A LoadImm(mnem, False, False, False, size, sign, user).emit() 3122834Sksewell@umich.edu LoadReg(mnem, False, False, False, size, sign, user).emit() 3132834Sksewell@umich.edu 3142834Sksewell@umich.edu def buildDoubleLoads(mnem): 3152834Sksewell@umich.edu LoadDoubleImm(mnem, True, True, True).emit() 3162829Sksewell@umich.edu LoadDoubleReg(mnem, True, True, True).emit() 3172875Sksewell@umich.edu LoadDoubleImm(mnem, True, False, True).emit() 3182875Sksewell@umich.edu LoadDoubleReg(mnem, True, False, True).emit() 3192875Sksewell@umich.edu LoadDoubleImm(mnem, False, True, True).emit() 3202875Sksewell@umich.edu LoadDoubleReg(mnem, False, True, True).emit() 3212829Sksewell@umich.edu LoadDoubleImm(mnem, False, False, True).emit() 3222292SN/A LoadDoubleReg(mnem, False, False, True).emit() 3232292SN/A LoadDoubleImm(mnem, False, True, False).emit() 3241060SN/A LoadDoubleReg(mnem, False, True, False).emit() 3252292SN/A LoadDoubleImm(mnem, False, False, False).emit() 3262292SN/A LoadDoubleReg(mnem, False, False, False).emit() 3272292SN/A 3282292SN/A def buildRfeLoads(mnem): 3292292SN/A RfeInst(mnem, True, True, True).emit() 3302292SN/A RfeInst(mnem, True, True, False).emit() 3312292SN/A RfeInst(mnem, True, False, True).emit() 3322292SN/A RfeInst(mnem, True, False, False).emit() 3332292SN/A RfeInst(mnem, False, True, True).emit() 3342292SN/A RfeInst(mnem, False, True, False).emit() 3352292SN/A RfeInst(mnem, False, False, True).emit() 3362292SN/A RfeInst(mnem, False, False, False).emit() 3372292SN/A 3382292SN/A def buildPrefetches(mnem, type): 3392292SN/A LoadReg(mnem, False, False, False, size=1, flavor=type).emit() 3402292SN/A LoadImm(mnem, False, False, False, size=1, flavor=type).emit() 3412292SN/A LoadReg(mnem, False, True, False, size=1, flavor=type).emit() 3422292SN/A LoadImm(mnem, False, True, False, size=1, flavor=type).emit() 3432292SN/A 3442292SN/A buildLoads("ldr") 3452292SN/A buildLoads("ldrt", user=True) 3463221Sktlim@umich.edu buildLoads("ldrb", size=1) 3472292SN/A buildLoads("ldrbt", size=1, user=True) 3483221Sktlim@umich.edu buildLoads("ldrsb", size=1, sign=True) 3492292SN/A buildLoads("ldrsbt", size=1, sign=True, user=True) 3502292SN/A buildLoads("ldrh", size=2) 3512292SN/A buildLoads("ldrht", size=2, user=True) 3522292SN/A buildLoads("hdrsh", size=2, sign=True) 3532292SN/A buildLoads("ldrsht", size=2, sign=True, user=True) 3542292SN/A 3552292SN/A buildDoubleLoads("ldrd") 3562292SN/A 3572292SN/A buildRfeLoads("rfe") 3582292SN/A 3592292SN/A buildPrefetches("pld", "dprefetch") 3602292SN/A buildPrefetches("pldw", "dprefetch") 3612292SN/A buildPrefetches("pli", "iprefetch") 3622292SN/A 3632292SN/A LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit() 3642864Sktlim@umich.edu LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit() 3652864Sktlim@umich.edu LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit() 3662864Sktlim@umich.edu LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit() 3672864Sktlim@umich.edu 3682864Sktlim@umich.edu LoadImm("vldr", False, True, False, size=4, flavor="fp").emit() 3692864Sktlim@umich.edu LoadImm("vldr", False, False, False, size=4, flavor="fp").emit() 3702864Sktlim@umich.edu LoadDoubleImm("vldr", False, True, False, flavor="fp").emit() 3712292SN/A LoadDoubleImm("vldr", False, False, False, flavor="fp").emit() 3722292SN/A}}; 3732292SN/A