macromem.isa revision 8304
12SN/A// -*- mode:c++ -*- 21762SN/A 32SN/A// Copyright (c) 2010 ARM Limited 42SN/A// All rights reserved 52SN/A// 62SN/A// The license below extends only to copyright in the software and shall 72SN/A// not be construed as granting a license to any other intellectual 82SN/A// property including but not limited to intellectual property relating 92SN/A// to a hardware implementation of the functionality of the software 102SN/A// licensed hereunder. You may use the software subject to the license 112SN/A// terms below provided that you ensure that this notice is replicated 122SN/A// unmodified and in its entirety in all distributions of the software, 132SN/A// modified or unmodified, in source code or in binary form. 142SN/A// 152SN/A// Copyright (c) 2007-2008 The Florida State University 162SN/A// All rights reserved. 172SN/A// 182SN/A// Redistribution and use in source and binary forms, with or without 192SN/A// modification, are permitted provided that the following conditions are 202SN/A// met: redistributions of source code must retain the above copyright 212SN/A// notice, this list of conditions and the following disclaimer; 222SN/A// redistributions in binary form must reproduce the above copyright 232SN/A// notice, this list of conditions and the following disclaimer in the 242SN/A// documentation and/or other materials provided with the distribution; 252SN/A// neither the name of the copyright holders nor the names of its 262SN/A// contributors may be used to endorse or promote products derived from 272665Ssaidi@eecs.umich.edu// this software without specific prior written permission. 282665Ssaidi@eecs.umich.edu// 292SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312439SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322984Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33146SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34146SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35146SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36146SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37146SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38146SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 391717SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40146SN/A// 411717SN/A// Authors: Stephen Hines 42146SN/A// Gabe Black 431977SN/A 442623SN/A//////////////////////////////////////////////////////////////////// 452683Sktlim@umich.edu// 461717SN/A// Load/store microops 47146SN/A// 482683Sktlim@umich.edu 493348Sbinkertn@umich.edulet {{ 502683Sktlim@umich.edu microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 512036SN/A microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop', 52146SN/A 'MicroMemOp', 5356SN/A {'memacc_code': microLdrUopCode, 5456SN/A 'ea_code': 'EA = URb + (up ? imm : -imm);', 5556SN/A 'predicate_test': predicateTest}, 56695SN/A ['IsMicroop']) 572901Ssaidi@eecs.umich.edu 582SN/A microLdrFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 591858SN/A microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop', 603565Sgblack@eecs.umich.edu 'MicroMemOp', 613565Sgblack@eecs.umich.edu {'memacc_code': microLdrFpUopCode, 622171SN/A 'ea_code': vfpEnabledCheckCode + 632170SN/A 'EA = URb + (up ? imm : -imm);', 643562Sgblack@eecs.umich.edu 'predicate_test': predicateTest}, 65146SN/A ['IsMicroop']) 662462SN/A 67146SN/A microLdrDBFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 682SN/A microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop', 692SN/A 'MicroMemOp', 702449SN/A {'memacc_code': microLdrFpUopCode, 711355SN/A 'ea_code': vfpEnabledCheckCode + ''' 722623SN/A EA = URb + (up ? imm : -imm) + 734495Sacolyte@umich.edu (((CPSR)Cpsr).e ? 4 : 0); 74224SN/A ''', 751858SN/A 'predicate_test': predicateTest}, 762683Sktlim@umich.edu ['IsMicroop']) 772420SN/A 782683Sktlim@umich.edu microLdrDTFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 793402Sktlim@umich.edu microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop', 802420SN/A 'MicroMemOp', 812SN/A {'memacc_code': microLdrFpUopCode, 824400Srdreslin@umich.edu 'ea_code': vfpEnabledCheckCode + ''' 832672Sktlim@umich.edu EA = URb + (up ? imm : -imm) - 842683Sktlim@umich.edu (((CPSR)Cpsr).e ? 4 : 0); 852SN/A ''', 862SN/A 'predicate_test': predicateTest}, 87334SN/A ['IsMicroop']) 88140SN/A 89334SN/A microRetUopCode = ''' 902SN/A CPSR old_cpsr = Cpsr; 912SN/A SCTLR sctlr = Sctlr; 922SN/A 932680Sktlim@umich.edu CPSR new_cpsr = 944377Sgblack@eecs.umich.edu cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi); 954377Sgblack@eecs.umich.edu Cpsr = ~CondCodesMask & new_cpsr; 964377Sgblack@eecs.umich.edu CondCodesNZ = new_cpsr.nz; 972SN/A CondCodesC = new_cpsr.c; 982SN/A CondCodesV = new_cpsr.v; 992623SN/A CondCodesGE = new_cpsr.ge; 1002SN/A IWNPC = cSwap(%s, old_cpsr.e) | ((Spsr & 0x20) ? 1 : 0); 1012SN/A NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC) 1022SN/A | (((CPSR)Spsr).it1 & 0x3); 103180SN/A SevMailbox = 1; 1042623SN/A ''' 105393SN/A 106393SN/A microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', 107393SN/A 'MicroMemOp', 108393SN/A {'memacc_code': 109384SN/A microRetUopCode % 'Mem.uw', 110384SN/A 'ea_code': 111393SN/A 'EA = URb + (up ? imm : -imm);', 1122623SN/A 'predicate_test': condPredicateTest}, 113393SN/A ['IsMicroop','IsNonSpeculative', 114393SN/A 'IsSerializeAfter']) 115393SN/A 116393SN/A microStrUopCode = "Mem = cSwap(URa.uw, ((CPSR)Cpsr).e);" 117384SN/A microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 118189SN/A 'MicroMemOp', 119189SN/A {'memacc_code': microStrUopCode, 1202623SN/A 'postacc_code': "", 1212SN/A 'ea_code': 'EA = URb + (up ? imm : -imm);', 122729SN/A 'predicate_test': predicateTest}, 123334SN/A ['IsMicroop']) 1242SN/A 1252SN/A microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1262SN/A microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop', 1272SN/A 'MicroMemOp', 1282SN/A {'memacc_code': microStrFpUopCode, 1292SN/A 'postacc_code': "", 1302SN/A 'ea_code': vfpEnabledCheckCode + 1312SN/A 'EA = URb + (up ? imm : -imm);', 1322SN/A 'predicate_test': predicateTest}, 1332SN/A ['IsMicroop']) 1342SN/A 1352SN/A microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1361001SN/A microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop', 1371001SN/A 'MicroMemOp', 1381001SN/A {'memacc_code': microStrFpUopCode, 1391001SN/A 'postacc_code': "", 1401001SN/A 'ea_code': vfpEnabledCheckCode + ''' 1412SN/A EA = URb + (up ? imm : -imm) + 1422SN/A (((CPSR)Cpsr).e ? 4 : 0); 1432SN/A ''', 1442SN/A 'predicate_test': predicateTest}, 1452SN/A ['IsMicroop']) 1462SN/A 1472SN/A microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1482SN/A microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop', 1492SN/A 'MicroMemOp', 1502SN/A {'memacc_code': microStrFpUopCode, 1512SN/A 'postacc_code': "", 1522SN/A 'ea_code': vfpEnabledCheckCode + ''' 1532SN/A EA = URb + (up ? imm : -imm) - 1542SN/A (((CPSR)Cpsr).e ? 4 : 0); 1552SN/A ''', 1562SN/A 'predicate_test': predicateTest}, 1572SN/A ['IsMicroop']) 1582390SN/A 1592390SN/A header_output = decoder_output = exec_output = '' 1602390SN/A 1612390SN/A loadIops = (microLdrUopIop, microLdrRetUopIop, 1622390SN/A microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop) 1632390SN/A storeIops = (microStrUopIop, microStrFpUopIop, 1642390SN/A microStrDBFpUopIop, microStrDTFpUopIop) 1652390SN/A for iop in loadIops + storeIops: 1662390SN/A header_output += MicroMemDeclare.subst(iop) 1672390SN/A decoder_output += MicroMemConstructor.subst(iop) 1682390SN/A for iop in loadIops: 1692390SN/A exec_output += LoadExecute.subst(iop) + \ 170385SN/A LoadInitiateAcc.subst(iop) + \ 1712SN/A LoadCompleteAcc.subst(iop) 1722SN/A for iop in storeIops: 1732SN/A exec_output += StoreExecute.subst(iop) + \ 1742623SN/A StoreInitiateAcc.subst(iop) + \ 175334SN/A StoreCompleteAcc.subst(iop) 1762361SN/A}}; 1772623SN/A 178334SN/Alet {{ 179334SN/A exec_output = header_output = '' 180334SN/A 1812623SN/A eaCode = 'EA = URa + imm;' 1822SN/A 183921SN/A for size in (1, 2, 3, 4, 6, 8, 12, 16): 1842915Sktlim@umich.edu # Set up the memory access. 1852915Sktlim@umich.edu regs = (size + 3) // 4 1862683Sktlim@umich.edu subst = { "size" : size, "regs" : regs } 1872SN/A memDecl = ''' 1882SN/A union MemUnion { 1892SN/A uint8_t bytes[%(size)d]; 1902623SN/A Element elements[%(size)d / sizeof(Element)]; 1912SN/A uint32_t floatRegBits[%(regs)d]; 192921SN/A }; 1932915Sktlim@umich.edu ''' % subst 1942915Sktlim@umich.edu 1952SN/A # Do endian conversion for all the elements. 1962SN/A convCode = ''' 1972SN/A const unsigned eCount = sizeof(memUnion.elements) / 1982SN/A sizeof(memUnion.elements[0]); 1992SN/A if (((CPSR)Cpsr).e) { 2002SN/A for (unsigned i = 0; i < eCount; i++) { 2012SN/A memUnion.elements[i] = gtobe(memUnion.elements[i]); 202595SN/A } 2032623SN/A } else { 204595SN/A for (unsigned i = 0; i < eCount; i++) { 2052390SN/A memUnion.elements[i] = gtole(memUnion.elements[i]); 2061080SN/A } 2071080SN/A } 2081080SN/A ''' 2091080SN/A 2101080SN/A # Offload everything into registers 2111080SN/A regSetCode = '' 2121080SN/A for reg in range(regs): 2131121SN/A mask = '' 2142107SN/A if reg == regs - 1: 2151089SN/A mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size)) 2161089SN/A regSetCode += ''' 2171080SN/A FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s; 2181080SN/A ''' % { "reg" : reg, "mask" : mask } 2191080SN/A 2201080SN/A # Pull everything in from registers 221595SN/A regGetCode = '' 2222623SN/A for reg in range(regs): 2232683Sktlim@umich.edu regGetCode += ''' 224595SN/A memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw); 2252090SN/A ''' % { "reg" : reg } 2262683Sktlim@umich.edu 2272683Sktlim@umich.edu loadMemAccCode = convCode + regSetCode 228595SN/A storeMemAccCode = regGetCode + convCode 2292205SN/A 2302205SN/A loadIop = InstObjParams('ldrneon%(size)d_uop' % subst, 2312683Sktlim@umich.edu 'MicroLdrNeon%(size)dUop' % subst, 2322683Sktlim@umich.edu 'MicroNeonMemOp', 233595SN/A { 'mem_decl' : memDecl, 234595SN/A 'size' : size, 2352390SN/A 'memacc_code' : loadMemAccCode, 2362423SN/A 'ea_code' : simdEnabledCheckCode + eaCode, 2372390SN/A 'predicate_test' : predicateTest }, 238595SN/A [ 'IsMicroop', 'IsMemRef', 'IsLoad' ]) 239595SN/A storeIop = InstObjParams('strneon%(size)d_uop' % subst, 240595SN/A 'MicroStrNeon%(size)dUop' % subst, 2412623SN/A 'MicroNeonMemOp', 242595SN/A { 'mem_decl' : memDecl, 2432390SN/A 'size' : size, 2441080SN/A 'memacc_code' : storeMemAccCode, 245595SN/A 'ea_code' : simdEnabledCheckCode + eaCode, 2461080SN/A 'predicate_test' : predicateTest }, 2471080SN/A [ 'IsMicroop', 'IsMemRef', 'IsStore' ]) 248595SN/A 2492683Sktlim@umich.edu exec_output += NeonLoadExecute.subst(loadIop) + \ 2501080SN/A NeonLoadInitiateAcc.subst(loadIop) + \ 2511080SN/A NeonLoadCompleteAcc.subst(loadIop) + \ 2521080SN/A NeonStoreExecute.subst(storeIop) + \ 2531121SN/A NeonStoreInitiateAcc.subst(storeIop) + \ 2542107SN/A NeonStoreCompleteAcc.subst(storeIop) 2551089SN/A header_output += MicroNeonMemDeclare.subst(loadIop) + \ 2561080SN/A MicroNeonMemDeclare.subst(storeIop) 2571089SN/A}}; 2581080SN/A 2591080SN/Alet {{ 2601080SN/A exec_output = '' 261595SN/A for eSize, type in (1, 'uint8_t'), \ 2622683Sktlim@umich.edu (2, 'uint16_t'), \ 2631080SN/A (4, 'uint32_t'), \ 2642090SN/A (8, 'uint64_t'): 2651080SN/A size = eSize 266595SN/A # An instruction handles no more than 16 bytes and no more than 2672683Sktlim@umich.edu # 4 elements, or the number of elements needed to fill 8 or 16 bytes. 2682683Sktlim@umich.edu sizes = set((16, 8)) 269595SN/A for count in 1, 2, 3, 4: 2702683Sktlim@umich.edu size = count * eSize 2711098SN/A if size <= 16: 2721098SN/A sizes.add(size) 2731098SN/A for size in sizes: 2742683Sktlim@umich.edu substDict = { 2751098SN/A "class_name" : "MicroLdrNeon%dUop" % size, 2761098SN/A "targs" : type 2771098SN/A } 2782012SN/A exec_output += MicroNeonMemExecDeclare.subst(substDict) 2791098SN/A substDict["class_name"] = "MicroStrNeon%dUop" % size 2801098SN/A exec_output += MicroNeonMemExecDeclare.subst(substDict) 281595SN/A size += eSize 2822205SN/A}}; 2832205SN/A 2842205SN/A//////////////////////////////////////////////////////////////////// 285595SN/A// 2862390SN/A// Neon (de)interlacing microops 2872420SN/A// 2882423SN/A 2892390SN/Alet {{ 290595SN/A header_output = exec_output = '' 291595SN/A for dRegs in (2, 3, 4): 2921858SN/A loadConv = '' 2932SN/A unloadConv = '' 2942623SN/A for dReg in range(dRegs): 2952SN/A loadConv += ''' 2962680Sktlim@umich.edu conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d.uw); 2972SN/A conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d.uw); 2982SN/A ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 2992SN/A unloadConv += ''' 3001858SN/A FpDestS%(dReg)dP0.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]); 3012SN/A FpDestS%(dReg)dP1.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]); 3022623SN/A ''' % { "dReg" : dReg } 3032SN/A microDeintNeonCode = ''' 3042SN/A const unsigned dRegs = %(dRegs)d; 3052SN/A const unsigned regs = 2 * dRegs; 3062683Sktlim@umich.edu const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 3074216Ssaidi@eecs.umich.edu sizeof(Element); 3082683Sktlim@umich.edu union convStruct { 3092SN/A FloatRegBits cRegs[regs]; 3102SN/A Element elements[dRegs * perDReg]; 3112SN/A } conv1, conv2; 3122SN/A 3132SN/A %(loadConv)s 3142623SN/A 3152SN/A unsigned srcElem = 0; 3161858SN/A for (unsigned destOffset = 0; 3173923Shsul@eecs.umich.edu destOffset < perDReg; destOffset++) { 3183520Sgblack@eecs.umich.edu for (unsigned dReg = 0; dReg < dRegs; dReg++) { 3192SN/A conv2.elements[dReg * perDReg + destOffset] = 3203520Sgblack@eecs.umich.edu conv1.elements[srcElem++]; 3213633Sktlim@umich.edu } 3223520Sgblack@eecs.umich.edu } 3232SN/A 3242SN/A %(unloadConv)s 3252SN/A ''' % { "dRegs" : dRegs, 3262623SN/A "loadConv" : loadConv, 3272SN/A "unloadConv" : unloadConv } 3282623SN/A microDeintNeonIop = \ 3292623SN/A InstObjParams('deintneon%duop' % (dRegs * 2), 3302662Sstever@eecs.umich.edu 'MicroDeintNeon%dUop' % (dRegs * 2), 3312623SN/A 'MicroNeonMixOp', 3324514Ssaidi@eecs.umich.edu { 'predicate_test': predicateTest, 3334495Sacolyte@umich.edu 'code' : microDeintNeonCode }, 3342623SN/A ['IsMicroop']) 3353093Sksewell@umich.edu header_output += MicroNeonMixDeclare.subst(microDeintNeonIop) 3364495Sacolyte@umich.edu exec_output += MicroNeonMixExecute.subst(microDeintNeonIop) 3373093Sksewell@umich.edu 3383093Sksewell@umich.edu loadConv = '' 3394564Sgblack@eecs.umich.edu unloadConv = '' 3402741Sksewell@umich.edu for dReg in range(dRegs): 3412741Sksewell@umich.edu loadConv += ''' 3422623SN/A conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0.uw); 3434564Sgblack@eecs.umich.edu conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1.uw); 3444564Sgblack@eecs.umich.edu ''' % { "dReg" : dReg } 3452623SN/A unloadConv += ''' 3462683Sktlim@umich.edu FpDestP%(sReg0)d.uw = gtoh(conv2.cRegs[%(sReg0)d]); 3472623SN/A FpDestP%(sReg1)d.uw = gtoh(conv2.cRegs[%(sReg1)d]); 3482623SN/A ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 3492623SN/A microInterNeonCode = ''' 3502623SN/A const unsigned dRegs = %(dRegs)d; 3512623SN/A const unsigned regs = 2 * dRegs; 3522623SN/A const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 3532623SN/A sizeof(Element); 3542623SN/A union convStruct { 3552SN/A FloatRegBits cRegs[regs]; 3562683Sktlim@umich.edu Element elements[dRegs * perDReg]; 3572427SN/A } conv1, conv2; 3582683Sktlim@umich.edu 3592427SN/A %(loadConv)s 3602SN/A 3612623SN/A unsigned destElem = 0; 3622623SN/A for (unsigned srcOffset = 0; 3632623SN/A srcOffset < perDReg; srcOffset++) { 3642SN/A for (unsigned dReg = 0; dReg < dRegs; dReg++) { 3652683Sktlim@umich.edu conv2.elements[destElem++] = 3662SN/A conv1.elements[dReg * perDReg + srcOffset]; 3672623SN/A } 3682623SN/A } 3692SN/A 3702623SN/A %(unloadConv)s 3712623SN/A ''' % { "dRegs" : dRegs, 3724377Sgblack@eecs.umich.edu "loadConv" : loadConv, 3733276Sgblack@eecs.umich.edu "unloadConv" : unloadConv } 3743276Sgblack@eecs.umich.edu microInterNeonIop = \ 3754377Sgblack@eecs.umich.edu InstObjParams('interneon%duop' % (dRegs * 2), 3764181Sgblack@eecs.umich.edu 'MicroInterNeon%dUop' % (dRegs * 2), 3774181Sgblack@eecs.umich.edu 'MicroNeonMixOp', 3784181Sgblack@eecs.umich.edu { 'predicate_test': predicateTest, 3794182Sgblack@eecs.umich.edu 'code' : microInterNeonCode }, 3804182Sgblack@eecs.umich.edu ['IsMicroop']) 3814182Sgblack@eecs.umich.edu header_output += MicroNeonMixDeclare.subst(microInterNeonIop) 3824182Sgblack@eecs.umich.edu exec_output += MicroNeonMixExecute.subst(microInterNeonIop) 3834564Sgblack@eecs.umich.edu}}; 3844564Sgblack@eecs.umich.edu 3854182Sgblack@eecs.umich.edulet {{ 3864182Sgblack@eecs.umich.edu exec_output = '' 3874377Sgblack@eecs.umich.edu for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'): 3884377Sgblack@eecs.umich.edu for dRegs in (2, 3, 4): 3894377Sgblack@eecs.umich.edu Name = "MicroDeintNeon%dUop" % (dRegs * 2) 3904377Sgblack@eecs.umich.edu substDict = { "class_name" : Name, "targs" : type } 3914377Sgblack@eecs.umich.edu exec_output += MicroNeonExecDeclare.subst(substDict) 3924377Sgblack@eecs.umich.edu Name = "MicroInterNeon%dUop" % (dRegs * 2) 3934377Sgblack@eecs.umich.edu substDict = { "class_name" : Name, "targs" : type } 3944377Sgblack@eecs.umich.edu exec_output += MicroNeonExecDeclare.subst(substDict) 3954572Sacolyte@umich.edu}}; 3964572Sacolyte@umich.edu 3974377Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 3984377Sgblack@eecs.umich.edu// 3994377Sgblack@eecs.umich.edu// Neon microops to pack/unpack a single lane 4004377Sgblack@eecs.umich.edu// 4014181Sgblack@eecs.umich.edu 4024181Sgblack@eecs.umich.edulet {{ 4034181Sgblack@eecs.umich.edu header_output = exec_output = '' 4044539Sgblack@eecs.umich.edu for sRegs in 1, 2: 4053276Sgblack@eecs.umich.edu baseLoadRegs = '' 4063442Sgblack@eecs.umich.edu for reg in range(sRegs): 4074539Sgblack@eecs.umich.edu baseLoadRegs += ''' 4083280Sgblack@eecs.umich.edu sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 4093280Sgblack@eecs.umich.edu sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 4103276Sgblack@eecs.umich.edu ''' % { "reg0" : (2 * reg + 0), 4113276Sgblack@eecs.umich.edu "reg1" : (2 * reg + 1) } 4123276Sgblack@eecs.umich.edu for dRegs in range(sRegs, 5): 4133442Sgblack@eecs.umich.edu unloadRegs = '' 4144539Sgblack@eecs.umich.edu loadRegs = baseLoadRegs 4153276Sgblack@eecs.umich.edu for reg in range(dRegs): 4163276Sgblack@eecs.umich.edu loadRegs += ''' 4174181Sgblack@eecs.umich.edu destRegs[%(reg)d].fRegs[0] = htog(FpDestS%(reg)dP0.uw); 4184181Sgblack@eecs.umich.edu destRegs[%(reg)d].fRegs[1] = htog(FpDestS%(reg)dP1.uw); 4194181Sgblack@eecs.umich.edu ''' % { "reg" : reg } 4204522Ssaidi@eecs.umich.edu unloadRegs += ''' 4214181Sgblack@eecs.umich.edu FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 4224181Sgblack@eecs.umich.edu FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 4232470SN/A ''' % { "reg" : reg } 4244181Sgblack@eecs.umich.edu microUnpackNeonCode = ''' 4254181Sgblack@eecs.umich.edu const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 4264522Ssaidi@eecs.umich.edu sizeof(Element); 4272623SN/A 4282623SN/A union SourceRegs { 4294181Sgblack@eecs.umich.edu FloatRegBits fRegs[2 * %(sRegs)d]; 4302623SN/A Element elements[%(sRegs)d * perDReg]; 4314181Sgblack@eecs.umich.edu } sourceRegs; 4322623SN/A 4332623SN/A union DestReg { 4342623SN/A FloatRegBits fRegs[2]; 4352623SN/A Element elements[perDReg]; 4362623SN/A } destRegs[%(dRegs)d]; 4372623SN/A 4382683Sktlim@umich.edu %(loadRegs)s 4393577Sgblack@eecs.umich.edu 4402683Sktlim@umich.edu for (unsigned i = 0; i < %(dRegs)d; i++) { 4414572Sacolyte@umich.edu destRegs[i].elements[lane] = sourceRegs.elements[i]; 4424254Sgblack@eecs.umich.edu } 4432623SN/A 4442683Sktlim@umich.edu %(unloadRegs)s 4452623SN/A ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 4462420SN/A "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 4472SN/A 4482623SN/A microUnpackNeonIop = \ 4492623SN/A InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2), 4502SN/A 'MicroUnpackNeon%dto%dUop' % 4512SN/A (sRegs * 2, dRegs * 2), 4522623SN/A 'MicroNeonMixLaneOp', 4532623SN/A { 'predicate_test': predicateTest, 4542623SN/A 'code' : microUnpackNeonCode }, 4552623SN/A ['IsMicroop']) 4562SN/A header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop) 4572683Sktlim@umich.edu exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop) 4582644Sstever@eecs.umich.edu 4592644Sstever@eecs.umich.edu for sRegs in 1, 2: 4604046Sbinkertn@umich.edu loadRegs = '' 4614046Sbinkertn@umich.edu for reg in range(sRegs): 4624046Sbinkertn@umich.edu loadRegs += ''' 4632644Sstever@eecs.umich.edu sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 4642623SN/A sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 4652SN/A ''' % { "reg0" : (2 * reg + 0), 4662SN/A "reg1" : (2 * reg + 1) } 4672623SN/A for dRegs in range(sRegs, 5): 4682623SN/A unloadRegs = '' 4692623SN/A for reg in range(dRegs): 4704377Sgblack@eecs.umich.edu unloadRegs += ''' 4714377Sgblack@eecs.umich.edu FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 4722090SN/A FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 4733905Ssaidi@eecs.umich.edu ''' % { "reg" : reg } 4742680Sktlim@umich.edu microUnpackAllNeonCode = ''' 4753929Ssaidi@eecs.umich.edu const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 4763929Ssaidi@eecs.umich.edu sizeof(Element); 4774377Sgblack@eecs.umich.edu 4783276Sgblack@eecs.umich.edu union SourceRegs { 4794539Sgblack@eecs.umich.edu FloatRegBits fRegs[2 * %(sRegs)d]; 4803276Sgblack@eecs.umich.edu Element elements[%(sRegs)d * perDReg]; 4813276Sgblack@eecs.umich.edu } sourceRegs; 4823276Sgblack@eecs.umich.edu 4833276Sgblack@eecs.umich.edu union DestReg { 4843280Sgblack@eecs.umich.edu FloatRegBits fRegs[2]; 4853276Sgblack@eecs.umich.edu Element elements[perDReg]; 4863280Sgblack@eecs.umich.edu } destRegs[%(dRegs)d]; 4873276Sgblack@eecs.umich.edu 4883276Sgblack@eecs.umich.edu %(loadRegs)s 4893276Sgblack@eecs.umich.edu 4903276Sgblack@eecs.umich.edu for (unsigned i = 0; i < %(dRegs)d; i++) { 4913280Sgblack@eecs.umich.edu for (unsigned j = 0; j < perDReg; j++) 4923276Sgblack@eecs.umich.edu destRegs[i].elements[j] = sourceRegs.elements[i]; 4933276Sgblack@eecs.umich.edu } 4943280Sgblack@eecs.umich.edu 4953276Sgblack@eecs.umich.edu %(unloadRegs)s 4963276Sgblack@eecs.umich.edu ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 4973276Sgblack@eecs.umich.edu "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 4983276Sgblack@eecs.umich.edu 4993276Sgblack@eecs.umich.edu microUnpackAllNeonIop = \ 5003276Sgblack@eecs.umich.edu InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2), 5013276Sgblack@eecs.umich.edu 'MicroUnpackAllNeon%dto%dUop' % 5022SN/A (sRegs * 2, dRegs * 2), 5032SN/A 'MicroNeonMixOp', 5041858SN/A { 'predicate_test': predicateTest, 5052SN/A 'code' : microUnpackAllNeonCode }, 5062SN/A ['IsMicroop']) 5072683Sktlim@umich.edu header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop) 5082680Sktlim@umich.edu exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop) 5092683Sktlim@umich.edu 5102SN/A for dRegs in 1, 2: 5112SN/A unloadRegs = '' 5122SN/A for reg in range(dRegs): 513 unloadRegs += ''' 514 FpDestP%(reg0)d.uw = gtoh(destRegs.fRegs[%(reg0)d]); 515 FpDestP%(reg1)d.uw = gtoh(destRegs.fRegs[%(reg1)d]); 516 ''' % { "reg0" : (2 * reg + 0), 517 "reg1" : (2 * reg + 1) } 518 for sRegs in range(dRegs, 5): 519 loadRegs = '' 520 for reg in range(sRegs): 521 loadRegs += ''' 522 sourceRegs[%(reg)d].fRegs[0] = htog(FpOp1S%(reg)dP0.uw); 523 sourceRegs[%(reg)d].fRegs[1] = htog(FpOp1S%(reg)dP1.uw); 524 ''' % { "reg" : reg } 525 microPackNeonCode = ''' 526 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 527 sizeof(Element); 528 529 union SourceReg { 530 FloatRegBits fRegs[2]; 531 Element elements[perDReg]; 532 } sourceRegs[%(sRegs)d]; 533 534 union DestRegs { 535 FloatRegBits fRegs[2 * %(dRegs)d]; 536 Element elements[%(dRegs)d * perDReg]; 537 } destRegs; 538 539 %(loadRegs)s 540 541 for (unsigned i = 0; i < %(sRegs)d; i++) { 542 destRegs.elements[i] = sourceRegs[i].elements[lane]; 543 } 544 545 %(unloadRegs)s 546 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 547 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 548 549 microPackNeonIop = \ 550 InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2), 551 'MicroPackNeon%dto%dUop' % 552 (sRegs * 2, dRegs * 2), 553 'MicroNeonMixLaneOp', 554 { 'predicate_test': predicateTest, 555 'code' : microPackNeonCode }, 556 ['IsMicroop']) 557 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop) 558 exec_output += MicroNeonMixExecute.subst(microPackNeonIop) 559}}; 560 561let {{ 562 exec_output = '' 563 for type in ('uint8_t', 'uint16_t', 'uint32_t'): 564 for sRegs in 1, 2: 565 for dRegs in range(sRegs, 5): 566 for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop", 567 "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop", 568 "MicroPackNeon%(dRegs)dto%(sRegs)dUop"): 569 Name = format % { "sRegs" : sRegs * 2, 570 "dRegs" : dRegs * 2 } 571 substDict = { "class_name" : Name, "targs" : type } 572 exec_output += MicroNeonExecDeclare.subst(substDict) 573}}; 574 575//////////////////////////////////////////////////////////////////// 576// 577// Integer = Integer op Immediate microops 578// 579 580let {{ 581 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop', 582 'MicroIntImmOp', 583 {'code': 'URa = URb + imm;', 584 'predicate_test': predicateTest}, 585 ['IsMicroop']) 586 587 microAddUopCode = ''' 588 URa = URb + shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC); 589 ''' 590 591 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop', 592 'MicroIntRegOp', 593 {'code': microAddUopCode, 594 'predicate_test': pickPredicate(microAddUopCode)}, 595 ['IsMicroop']) 596 597 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop', 598 'MicroIntImmOp', 599 {'code': 'URa = URb - imm;', 600 'predicate_test': predicateTest}, 601 ['IsMicroop']) 602 603 microSubUopCode = ''' 604 URa = URb - shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC); 605 ''' 606 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop', 607 'MicroIntRegOp', 608 {'code': microSubUopCode, 609 'predicate_test': pickPredicate(microSubUopCode)}, 610 ['IsMicroop']) 611 612 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov', 613 'MicroIntMov', 614 {'code': 'IWRa = URb;', 615 'predicate_test': predicateTest}, 616 ['IsMicroop']) 617 618 microUopRegMovRetIop = InstObjParams('movret_uop', 'MicroUopRegMovRet', 619 'MicroIntMov', 620 {'code': microRetUopCode % 'URb', 621 'predicate_test': predicateTest}, 622 ['IsMicroop', 'IsNonSpeculative', 623 'IsSerializeAfter']) 624 625 setPCCPSRDecl = ''' 626 CPSR cpsrOrCondCodes = URc; 627 SCTLR sctlr = Sctlr; 628 pNPC = URa; 629 CPSR new_cpsr = 630 cpsrWriteByInstr(cpsrOrCondCodes, URb, 631 0xF, true, sctlr.nmfi); 632 Cpsr = ~CondCodesMask & new_cpsr; 633 NextThumb = new_cpsr.t; 634 NextJazelle = new_cpsr.j; 635 NextItState = ((((CPSR)URb).it2 << 2) & 0xFC) 636 | (((CPSR)URb).it1 & 0x3); 637 CondCodesNZ = new_cpsr.nz; 638 CondCodesC = new_cpsr.c; 639 CondCodesV = new_cpsr.v; 640 CondCodesGE = new_cpsr.ge; 641 ''' 642 643 microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR', 644 'MicroSetPCCPSR', 645 {'code': setPCCPSRDecl, 646 'predicate_test': predicateTest}, 647 ['IsMicroop']) 648 649 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \ 650 MicroIntImmDeclare.subst(microSubiUopIop) + \ 651 MicroIntRegDeclare.subst(microAddUopIop) + \ 652 MicroIntRegDeclare.subst(microSubUopIop) + \ 653 MicroIntMovDeclare.subst(microUopRegMovIop) + \ 654 MicroIntMovDeclare.subst(microUopRegMovRetIop) + \ 655 MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop) 656 657 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \ 658 MicroIntImmConstructor.subst(microSubiUopIop) + \ 659 MicroIntRegConstructor.subst(microAddUopIop) + \ 660 MicroIntRegConstructor.subst(microSubUopIop) + \ 661 MicroIntMovConstructor.subst(microUopRegMovIop) + \ 662 MicroIntMovConstructor.subst(microUopRegMovRetIop) + \ 663 MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop) 664 665 exec_output = PredOpExecute.subst(microAddiUopIop) + \ 666 PredOpExecute.subst(microSubiUopIop) + \ 667 PredOpExecute.subst(microAddUopIop) + \ 668 PredOpExecute.subst(microSubUopIop) + \ 669 PredOpExecute.subst(microUopRegMovIop) + \ 670 PredOpExecute.subst(microUopRegMovRetIop) + \ 671 PredOpExecute.subst(microUopSetPCCPSRIop) 672 673}}; 674 675let {{ 676 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", []) 677 header_output = MacroMemDeclare.subst(iop) 678 decoder_output = MacroMemConstructor.subst(iop) 679 680 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", []) 681 header_output += VMemMultDeclare.subst(iop) 682 decoder_output += VMemMultConstructor.subst(iop) 683 684 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", []) 685 header_output += VMemSingleDeclare.subst(iop) 686 decoder_output += VMemSingleConstructor.subst(iop) 687 688 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", []) 689 header_output += VMemMultDeclare.subst(iop) 690 decoder_output += VMemMultConstructor.subst(iop) 691 692 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", []) 693 header_output += VMemSingleDeclare.subst(iop) 694 decoder_output += VMemSingleConstructor.subst(iop) 695 696 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", []) 697 header_output += MacroVFPMemDeclare.subst(vfpIop) 698 decoder_output += MacroVFPMemConstructor.subst(vfpIop) 699}}; 700