macromem.isa revision 8285:c38905a6fa32
15643Sgblack@eecs.umich.edu// -*- mode:c++ -*- 25643Sgblack@eecs.umich.edu 35643Sgblack@eecs.umich.edu// Copyright (c) 2010 ARM Limited 45643Sgblack@eecs.umich.edu// All rights reserved 55643Sgblack@eecs.umich.edu// 65643Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall 75643Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual 85643Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating 95643Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software 105643Sgblack@eecs.umich.edu// licensed hereunder. You may use the software subject to the license 115643Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated 125643Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software, 135643Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form. 145643Sgblack@eecs.umich.edu// 155643Sgblack@eecs.umich.edu// Copyright (c) 2007-2008 The Florida State University 165643Sgblack@eecs.umich.edu// All rights reserved. 175643Sgblack@eecs.umich.edu// 185643Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 195643Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 205643Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 215643Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 225643Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 235643Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 245643Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 255643Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 265643Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 275643Sgblack@eecs.umich.edu// this software without specific prior written permission. 285643Sgblack@eecs.umich.edu// 295643Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 305643Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316138Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 325651Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 338746Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 348232Snate@binkert.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 355643Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 365657Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 375643Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 385643Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 395643Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 405643Sgblack@eecs.umich.edu// 419805Sstever@gmail.com// Authors: Stephen Hines 429808Sstever@gmail.com// Gabe Black 439805Sstever@gmail.com 445643Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 457913SBrad.Beckmann@amd.com// 467913SBrad.Beckmann@amd.com// Load/store microops 477913SBrad.Beckmann@amd.com// 487913SBrad.Beckmann@amd.com 497913SBrad.Beckmann@amd.comlet {{ 506136Sgblack@eecs.umich.edu microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 515643Sgblack@eecs.umich.edu microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop', 525643Sgblack@eecs.umich.edu 'MicroMemOp', 535653Sgblack@eecs.umich.edu {'memacc_code': microLdrUopCode, 545653Sgblack@eecs.umich.edu 'ea_code': 'EA = URb + (up ? imm : -imm);', 555653Sgblack@eecs.umich.edu 'predicate_test': predicateTest}, 565653Sgblack@eecs.umich.edu ['IsMicroop']) 575827Sgblack@eecs.umich.edu 585653Sgblack@eecs.umich.edu microLdrFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 595643Sgblack@eecs.umich.edu microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop', 605643Sgblack@eecs.umich.edu 'MicroMemOp', 617913SBrad.Beckmann@amd.com {'memacc_code': microLdrFpUopCode, 627913SBrad.Beckmann@amd.com 'ea_code': vfpEnabledCheckCode + 637913SBrad.Beckmann@amd.com 'EA = URb + (up ? imm : -imm);', 647913SBrad.Beckmann@amd.com 'predicate_test': predicateTest}, 657913SBrad.Beckmann@amd.com ['IsMicroop']) 669807Sstever@gmail.com 677913SBrad.Beckmann@amd.com microLdrDBFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 689805Sstever@gmail.com microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop', 699807Sstever@gmail.com 'MicroMemOp', 707913SBrad.Beckmann@amd.com {'memacc_code': microLdrFpUopCode, 717913SBrad.Beckmann@amd.com 'ea_code': vfpEnabledCheckCode + ''' 729805Sstever@gmail.com EA = URb + (up ? imm : -imm) + 739805Sstever@gmail.com (((CPSR)Cpsr).e ? 4 : 0); 749805Sstever@gmail.com ''', 759805Sstever@gmail.com 'predicate_test': predicateTest}, 769805Sstever@gmail.com ['IsMicroop']) 779805Sstever@gmail.com 789805Sstever@gmail.com microLdrDTFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 799805Sstever@gmail.com microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop', 809805Sstever@gmail.com 'MicroMemOp', 819805Sstever@gmail.com {'memacc_code': microLdrFpUopCode, 829805Sstever@gmail.com 'ea_code': vfpEnabledCheckCode + ''' 839805Sstever@gmail.com EA = URb + (up ? imm : -imm) - 849805Sstever@gmail.com (((CPSR)Cpsr).e ? 4 : 0); 859805Sstever@gmail.com ''', 869805Sstever@gmail.com 'predicate_test': predicateTest}, 879805Sstever@gmail.com ['IsMicroop']) 889805Sstever@gmail.com 899805Sstever@gmail.com microRetUopCode = ''' 905643Sgblack@eecs.umich.edu CPSR cpsr = Cpsr; 9111144Sjthestness@gmail.com SCTLR sctlr = Sctlr; 9211144Sjthestness@gmail.com uint32_t newCpsr = 9311144Sjthestness@gmail.com cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi); 9411144Sjthestness@gmail.com Cpsr = ~CondCodesMask & newCpsr; 9511144Sjthestness@gmail.com CondCodes = CondCodesMask & newCpsr; 9611144Sjthestness@gmail.com IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0); 9711144Sjthestness@gmail.com NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC) 9811144Sjthestness@gmail.com | (((CPSR)Spsr).it1 & 0x3); 9911144Sjthestness@gmail.com SevMailbox = 1; 1005643Sgblack@eecs.umich.edu ''' 1015643Sgblack@eecs.umich.edu 1025643Sgblack@eecs.umich.edu microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', 1035643Sgblack@eecs.umich.edu 'MicroMemOp', 1045643Sgblack@eecs.umich.edu {'memacc_code': 1055643Sgblack@eecs.umich.edu microRetUopCode % 'Mem.uw', 1065643Sgblack@eecs.umich.edu 'ea_code': 1075643Sgblack@eecs.umich.edu 'EA = URb + (up ? imm : -imm);', 1085643Sgblack@eecs.umich.edu 'predicate_test': condPredicateTest}, 1095643Sgblack@eecs.umich.edu ['IsMicroop','IsNonSpeculative', 1105643Sgblack@eecs.umich.edu 'IsSerializeAfter']) 1115643Sgblack@eecs.umich.edu 1125643Sgblack@eecs.umich.edu microStrUopCode = "Mem = cSwap(URa.uw, ((CPSR)Cpsr).e);" 1135643Sgblack@eecs.umich.edu microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 1145898Sgblack@eecs.umich.edu 'MicroMemOp', 1159805Sstever@gmail.com {'memacc_code': microStrUopCode, 1165643Sgblack@eecs.umich.edu 'postacc_code': "", 1175643Sgblack@eecs.umich.edu 'ea_code': 'EA = URb + (up ? imm : -imm);', 1185643Sgblack@eecs.umich.edu 'predicate_test': predicateTest}, 1195643Sgblack@eecs.umich.edu ['IsMicroop']) 1205643Sgblack@eecs.umich.edu 1215643Sgblack@eecs.umich.edu microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1225643Sgblack@eecs.umich.edu microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop', 1235643Sgblack@eecs.umich.edu 'MicroMemOp', 1245643Sgblack@eecs.umich.edu {'memacc_code': microStrFpUopCode, 1255643Sgblack@eecs.umich.edu 'postacc_code': "", 1265643Sgblack@eecs.umich.edu 'ea_code': vfpEnabledCheckCode + 1275643Sgblack@eecs.umich.edu 'EA = URb + (up ? imm : -imm);', 1285643Sgblack@eecs.umich.edu 'predicate_test': predicateTest}, 1295643Sgblack@eecs.umich.edu ['IsMicroop']) 1305643Sgblack@eecs.umich.edu 1315643Sgblack@eecs.umich.edu microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1325643Sgblack@eecs.umich.edu microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop', 1335898Sgblack@eecs.umich.edu 'MicroMemOp', 1349805Sstever@gmail.com {'memacc_code': microStrFpUopCode, 1355643Sgblack@eecs.umich.edu 'postacc_code': "", 1365643Sgblack@eecs.umich.edu 'ea_code': vfpEnabledCheckCode + ''' 1375643Sgblack@eecs.umich.edu EA = URb + (up ? imm : -imm) + 1385643Sgblack@eecs.umich.edu (((CPSR)Cpsr).e ? 4 : 0); 1395643Sgblack@eecs.umich.edu ''', 1405643Sgblack@eecs.umich.edu 'predicate_test': predicateTest}, 1417913SBrad.Beckmann@amd.com ['IsMicroop']) 1425643Sgblack@eecs.umich.edu 1435643Sgblack@eecs.umich.edu microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1445643Sgblack@eecs.umich.edu microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop', 1457913SBrad.Beckmann@amd.com 'MicroMemOp', 1465643Sgblack@eecs.umich.edu {'memacc_code': microStrFpUopCode, 1475643Sgblack@eecs.umich.edu 'postacc_code': "", 1485643Sgblack@eecs.umich.edu 'ea_code': vfpEnabledCheckCode + ''' 1495643Sgblack@eecs.umich.edu EA = URb + (up ? imm : -imm) - 1505643Sgblack@eecs.umich.edu (((CPSR)Cpsr).e ? 4 : 0); 1515643Sgblack@eecs.umich.edu ''', 1525643Sgblack@eecs.umich.edu 'predicate_test': predicateTest}, 1535643Sgblack@eecs.umich.edu ['IsMicroop']) 1545643Sgblack@eecs.umich.edu 1555643Sgblack@eecs.umich.edu header_output = decoder_output = exec_output = '' 1565643Sgblack@eecs.umich.edu 1575643Sgblack@eecs.umich.edu loadIops = (microLdrUopIop, microLdrRetUopIop, 1585643Sgblack@eecs.umich.edu microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop) 1595643Sgblack@eecs.umich.edu storeIops = (microStrUopIop, microStrFpUopIop, 1605643Sgblack@eecs.umich.edu microStrDBFpUopIop, microStrDTFpUopIop) 1615643Sgblack@eecs.umich.edu for iop in loadIops + storeIops: 1625643Sgblack@eecs.umich.edu header_output += MicroMemDeclare.subst(iop) 1635643Sgblack@eecs.umich.edu decoder_output += MicroMemConstructor.subst(iop) 1645643Sgblack@eecs.umich.edu for iop in loadIops: 1655643Sgblack@eecs.umich.edu exec_output += LoadExecute.subst(iop) + \ 1665643Sgblack@eecs.umich.edu LoadInitiateAcc.subst(iop) + \ 1675643Sgblack@eecs.umich.edu LoadCompleteAcc.subst(iop) 1685643Sgblack@eecs.umich.edu for iop in storeIops: 1695643Sgblack@eecs.umich.edu exec_output += StoreExecute.subst(iop) + \ 1705643Sgblack@eecs.umich.edu StoreInitiateAcc.subst(iop) + \ 1715643Sgblack@eecs.umich.edu StoreCompleteAcc.subst(iop) 1725643Sgblack@eecs.umich.edu}}; 1735643Sgblack@eecs.umich.edu 1745643Sgblack@eecs.umich.edulet {{ 1755643Sgblack@eecs.umich.edu exec_output = header_output = '' 1765643Sgblack@eecs.umich.edu 1775643Sgblack@eecs.umich.edu eaCode = 'EA = URa + imm;' 1785643Sgblack@eecs.umich.edu 1795643Sgblack@eecs.umich.edu for size in (1, 2, 3, 4, 6, 8, 12, 16): 1805643Sgblack@eecs.umich.edu # Set up the memory access. 1815643Sgblack@eecs.umich.edu regs = (size + 3) // 4 1825643Sgblack@eecs.umich.edu subst = { "size" : size, "regs" : regs } 1835643Sgblack@eecs.umich.edu memDecl = ''' 1845643Sgblack@eecs.umich.edu union MemUnion { 1855643Sgblack@eecs.umich.edu uint8_t bytes[%(size)d]; 1865643Sgblack@eecs.umich.edu Element elements[%(size)d / sizeof(Element)]; 1875643Sgblack@eecs.umich.edu uint32_t floatRegBits[%(regs)d]; 1885643Sgblack@eecs.umich.edu }; 1895643Sgblack@eecs.umich.edu ''' % subst 1905643Sgblack@eecs.umich.edu 1915643Sgblack@eecs.umich.edu # Do endian conversion for all the elements. 1925643Sgblack@eecs.umich.edu convCode = ''' 1935643Sgblack@eecs.umich.edu const unsigned eCount = sizeof(memUnion.elements) / 1945643Sgblack@eecs.umich.edu sizeof(memUnion.elements[0]); 1955643Sgblack@eecs.umich.edu if (((CPSR)Cpsr).e) { 1965643Sgblack@eecs.umich.edu for (unsigned i = 0; i < eCount; i++) { 1976712Snate@binkert.org memUnion.elements[i] = gtobe(memUnion.elements[i]); 1985651Sgblack@eecs.umich.edu } 1995657Sgblack@eecs.umich.edu } else { 2005657Sgblack@eecs.umich.edu for (unsigned i = 0; i < eCount; i++) { 2015657Sgblack@eecs.umich.edu memUnion.elements[i] = gtole(memUnion.elements[i]); 2025657Sgblack@eecs.umich.edu } 2035657Sgblack@eecs.umich.edu } 2045657Sgblack@eecs.umich.edu ''' 2055651Sgblack@eecs.umich.edu 2065651Sgblack@eecs.umich.edu # Offload everything into registers 2075654Sgblack@eecs.umich.edu regSetCode = '' 2085654Sgblack@eecs.umich.edu for reg in range(regs): 2096138Sgblack@eecs.umich.edu mask = '' 2106138Sgblack@eecs.umich.edu if reg == regs - 1: 2116138Sgblack@eecs.umich.edu mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size)) 2126138Sgblack@eecs.umich.edu regSetCode += ''' 2136138Sgblack@eecs.umich.edu FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s; 2146138Sgblack@eecs.umich.edu ''' % { "reg" : reg, "mask" : mask } 2156138Sgblack@eecs.umich.edu 2166138Sgblack@eecs.umich.edu # Pull everything in from registers 2176138Sgblack@eecs.umich.edu regGetCode = '' 2186138Sgblack@eecs.umich.edu for reg in range(regs): 2196138Sgblack@eecs.umich.edu regGetCode += ''' 2206138Sgblack@eecs.umich.edu memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw); 2216138Sgblack@eecs.umich.edu ''' % { "reg" : reg } 2226138Sgblack@eecs.umich.edu 2236138Sgblack@eecs.umich.edu loadMemAccCode = convCode + regSetCode 2246138Sgblack@eecs.umich.edu storeMemAccCode = regGetCode + convCode 2256138Sgblack@eecs.umich.edu 2268746Sgblack@eecs.umich.edu loadIop = InstObjParams('ldrneon%(size)d_uop' % subst, 22711150Smitch.hayenga@arm.com 'MicroLdrNeon%(size)dUop' % subst, 2286138Sgblack@eecs.umich.edu 'MicroNeonMemOp', 2296138Sgblack@eecs.umich.edu { 'mem_decl' : memDecl, 2308746Sgblack@eecs.umich.edu 'size' : size, 2316138Sgblack@eecs.umich.edu 'memacc_code' : loadMemAccCode, 2326138Sgblack@eecs.umich.edu 'ea_code' : simdEnabledCheckCode + eaCode, 2336139Sgblack@eecs.umich.edu 'predicate_test' : predicateTest }, 2346139Sgblack@eecs.umich.edu [ 'IsMicroop', 'IsMemRef', 'IsLoad' ]) 2356139Sgblack@eecs.umich.edu storeIop = InstObjParams('strneon%(size)d_uop' % subst, 2366139Sgblack@eecs.umich.edu 'MicroStrNeon%(size)dUop' % subst, 2376139Sgblack@eecs.umich.edu 'MicroNeonMemOp', 2386139Sgblack@eecs.umich.edu { 'mem_decl' : memDecl, 2396139Sgblack@eecs.umich.edu 'size' : size, 2406139Sgblack@eecs.umich.edu 'memacc_code' : storeMemAccCode, 2416139Sgblack@eecs.umich.edu 'ea_code' : simdEnabledCheckCode + eaCode, 2426139Sgblack@eecs.umich.edu 'predicate_test' : predicateTest }, 2436139Sgblack@eecs.umich.edu [ 'IsMicroop', 'IsMemRef', 'IsStore' ]) 2446139Sgblack@eecs.umich.edu 2456139Sgblack@eecs.umich.edu exec_output += NeonLoadExecute.subst(loadIop) + \ 2466139Sgblack@eecs.umich.edu NeonLoadInitiateAcc.subst(loadIop) + \ 2476139Sgblack@eecs.umich.edu NeonLoadCompleteAcc.subst(loadIop) + \ 2486139Sgblack@eecs.umich.edu NeonStoreExecute.subst(storeIop) + \ 2496138Sgblack@eecs.umich.edu NeonStoreInitiateAcc.subst(storeIop) + \ 2506138Sgblack@eecs.umich.edu NeonStoreCompleteAcc.subst(storeIop) 2519524SAndreas.Sandberg@ARM.com header_output += MicroNeonMemDeclare.subst(loadIop) + \ 2525643Sgblack@eecs.umich.edu MicroNeonMemDeclare.subst(storeIop) 2535643Sgblack@eecs.umich.edu}}; 2545643Sgblack@eecs.umich.edu 2555827Sgblack@eecs.umich.edulet {{ 2565827Sgblack@eecs.umich.edu exec_output = '' 2575827Sgblack@eecs.umich.edu for eSize, type in (1, 'uint8_t'), \ 2585827Sgblack@eecs.umich.edu (2, 'uint16_t'), \ 2595827Sgblack@eecs.umich.edu (4, 'uint32_t'), \ 2605827Sgblack@eecs.umich.edu (8, 'uint64_t'): 2615827Sgblack@eecs.umich.edu size = eSize 2625827Sgblack@eecs.umich.edu # An instruction handles no more than 16 bytes and no more than 2635827Sgblack@eecs.umich.edu # 4 elements, or the number of elements needed to fill 8 or 16 bytes. 2645827Sgblack@eecs.umich.edu sizes = set((16, 8)) 2655827Sgblack@eecs.umich.edu for count in 1, 2, 3, 4: 2665827Sgblack@eecs.umich.edu size = count * eSize 2675827Sgblack@eecs.umich.edu if size <= 16: 2685827Sgblack@eecs.umich.edu sizes.add(size) 2695827Sgblack@eecs.umich.edu for size in sizes: 2705827Sgblack@eecs.umich.edu substDict = { 2716137Sgblack@eecs.umich.edu "class_name" : "MicroLdrNeon%dUop" % size, 27210905Sandreas.sandberg@arm.com "targs" : type 2737903Shestness@cs.utexas.edu } 2747903Shestness@cs.utexas.edu exec_output += MicroNeonMemExecDeclare.subst(substDict) 2757903Shestness@cs.utexas.edu substDict["class_name"] = "MicroStrNeon%dUop" % size 2767903Shestness@cs.utexas.edu exec_output += MicroNeonMemExecDeclare.subst(substDict) 2777903Shestness@cs.utexas.edu size += eSize 2787903Shestness@cs.utexas.edu}}; 2797903Shestness@cs.utexas.edu 2807903Shestness@cs.utexas.edu//////////////////////////////////////////////////////////////////// 2817903Shestness@cs.utexas.edu// 2827903Shestness@cs.utexas.edu// Neon (de)interlacing microops 2837903Shestness@cs.utexas.edu// 2847903Shestness@cs.utexas.edu 28510905Sandreas.sandberg@arm.comlet {{ 2867903Shestness@cs.utexas.edu header_output = exec_output = '' 2877903Shestness@cs.utexas.edu for dRegs in (2, 3, 4): 2887903Shestness@cs.utexas.edu loadConv = '' 2897903Shestness@cs.utexas.edu unloadConv = '' 2907903Shestness@cs.utexas.edu for dReg in range(dRegs): 2917903Shestness@cs.utexas.edu loadConv += ''' 2927903Shestness@cs.utexas.edu conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d.uw); 2937903Shestness@cs.utexas.edu conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d.uw); 2947903Shestness@cs.utexas.edu ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 2957903Shestness@cs.utexas.edu unloadConv += ''' 2967903Shestness@cs.utexas.edu FpDestS%(dReg)dP0.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]); 2977903Shestness@cs.utexas.edu FpDestS%(dReg)dP1.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]); 2987903Shestness@cs.utexas.edu ''' % { "dReg" : dReg } 2997903Shestness@cs.utexas.edu microDeintNeonCode = ''' 3005643Sgblack@eecs.umich.edu const unsigned dRegs = %(dRegs)d; 3015643Sgblack@eecs.umich.edu const unsigned regs = 2 * dRegs; 3025643Sgblack@eecs.umich.edu const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 3035643Sgblack@eecs.umich.edu sizeof(Element); 3045643Sgblack@eecs.umich.edu union convStruct { 305 FloatRegBits cRegs[regs]; 306 Element elements[dRegs * perDReg]; 307 } conv1, conv2; 308 309 %(loadConv)s 310 311 unsigned srcElem = 0; 312 for (unsigned destOffset = 0; 313 destOffset < perDReg; destOffset++) { 314 for (unsigned dReg = 0; dReg < dRegs; dReg++) { 315 conv2.elements[dReg * perDReg + destOffset] = 316 conv1.elements[srcElem++]; 317 } 318 } 319 320 %(unloadConv)s 321 ''' % { "dRegs" : dRegs, 322 "loadConv" : loadConv, 323 "unloadConv" : unloadConv } 324 microDeintNeonIop = \ 325 InstObjParams('deintneon%duop' % (dRegs * 2), 326 'MicroDeintNeon%dUop' % (dRegs * 2), 327 'MicroNeonMixOp', 328 { 'predicate_test': predicateTest, 329 'code' : microDeintNeonCode }, 330 ['IsMicroop']) 331 header_output += MicroNeonMixDeclare.subst(microDeintNeonIop) 332 exec_output += MicroNeonMixExecute.subst(microDeintNeonIop) 333 334 loadConv = '' 335 unloadConv = '' 336 for dReg in range(dRegs): 337 loadConv += ''' 338 conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0.uw); 339 conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1.uw); 340 ''' % { "dReg" : dReg } 341 unloadConv += ''' 342 FpDestP%(sReg0)d.uw = gtoh(conv2.cRegs[%(sReg0)d]); 343 FpDestP%(sReg1)d.uw = gtoh(conv2.cRegs[%(sReg1)d]); 344 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 345 microInterNeonCode = ''' 346 const unsigned dRegs = %(dRegs)d; 347 const unsigned regs = 2 * dRegs; 348 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 349 sizeof(Element); 350 union convStruct { 351 FloatRegBits cRegs[regs]; 352 Element elements[dRegs * perDReg]; 353 } conv1, conv2; 354 355 %(loadConv)s 356 357 unsigned destElem = 0; 358 for (unsigned srcOffset = 0; 359 srcOffset < perDReg; srcOffset++) { 360 for (unsigned dReg = 0; dReg < dRegs; dReg++) { 361 conv2.elements[destElem++] = 362 conv1.elements[dReg * perDReg + srcOffset]; 363 } 364 } 365 366 %(unloadConv)s 367 ''' % { "dRegs" : dRegs, 368 "loadConv" : loadConv, 369 "unloadConv" : unloadConv } 370 microInterNeonIop = \ 371 InstObjParams('interneon%duop' % (dRegs * 2), 372 'MicroInterNeon%dUop' % (dRegs * 2), 373 'MicroNeonMixOp', 374 { 'predicate_test': predicateTest, 375 'code' : microInterNeonCode }, 376 ['IsMicroop']) 377 header_output += MicroNeonMixDeclare.subst(microInterNeonIop) 378 exec_output += MicroNeonMixExecute.subst(microInterNeonIop) 379}}; 380 381let {{ 382 exec_output = '' 383 for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'): 384 for dRegs in (2, 3, 4): 385 Name = "MicroDeintNeon%dUop" % (dRegs * 2) 386 substDict = { "class_name" : Name, "targs" : type } 387 exec_output += MicroNeonExecDeclare.subst(substDict) 388 Name = "MicroInterNeon%dUop" % (dRegs * 2) 389 substDict = { "class_name" : Name, "targs" : type } 390 exec_output += MicroNeonExecDeclare.subst(substDict) 391}}; 392 393//////////////////////////////////////////////////////////////////// 394// 395// Neon microops to pack/unpack a single lane 396// 397 398let {{ 399 header_output = exec_output = '' 400 for sRegs in 1, 2: 401 baseLoadRegs = '' 402 for reg in range(sRegs): 403 baseLoadRegs += ''' 404 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 405 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 406 ''' % { "reg0" : (2 * reg + 0), 407 "reg1" : (2 * reg + 1) } 408 for dRegs in range(sRegs, 5): 409 unloadRegs = '' 410 loadRegs = baseLoadRegs 411 for reg in range(dRegs): 412 loadRegs += ''' 413 destRegs[%(reg)d].fRegs[0] = htog(FpDestS%(reg)dP0.uw); 414 destRegs[%(reg)d].fRegs[1] = htog(FpDestS%(reg)dP1.uw); 415 ''' % { "reg" : reg } 416 unloadRegs += ''' 417 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 418 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 419 ''' % { "reg" : reg } 420 microUnpackNeonCode = ''' 421 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 422 sizeof(Element); 423 424 union SourceRegs { 425 FloatRegBits fRegs[2 * %(sRegs)d]; 426 Element elements[%(sRegs)d * perDReg]; 427 } sourceRegs; 428 429 union DestReg { 430 FloatRegBits fRegs[2]; 431 Element elements[perDReg]; 432 } destRegs[%(dRegs)d]; 433 434 %(loadRegs)s 435 436 for (unsigned i = 0; i < %(dRegs)d; i++) { 437 destRegs[i].elements[lane] = sourceRegs.elements[i]; 438 } 439 440 %(unloadRegs)s 441 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 442 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 443 444 microUnpackNeonIop = \ 445 InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2), 446 'MicroUnpackNeon%dto%dUop' % 447 (sRegs * 2, dRegs * 2), 448 'MicroNeonMixLaneOp', 449 { 'predicate_test': predicateTest, 450 'code' : microUnpackNeonCode }, 451 ['IsMicroop']) 452 header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop) 453 exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop) 454 455 for sRegs in 1, 2: 456 loadRegs = '' 457 for reg in range(sRegs): 458 loadRegs += ''' 459 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 460 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 461 ''' % { "reg0" : (2 * reg + 0), 462 "reg1" : (2 * reg + 1) } 463 for dRegs in range(sRegs, 5): 464 unloadRegs = '' 465 for reg in range(dRegs): 466 unloadRegs += ''' 467 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 468 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 469 ''' % { "reg" : reg } 470 microUnpackAllNeonCode = ''' 471 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 472 sizeof(Element); 473 474 union SourceRegs { 475 FloatRegBits fRegs[2 * %(sRegs)d]; 476 Element elements[%(sRegs)d * perDReg]; 477 } sourceRegs; 478 479 union DestReg { 480 FloatRegBits fRegs[2]; 481 Element elements[perDReg]; 482 } destRegs[%(dRegs)d]; 483 484 %(loadRegs)s 485 486 for (unsigned i = 0; i < %(dRegs)d; i++) { 487 for (unsigned j = 0; j < perDReg; j++) 488 destRegs[i].elements[j] = sourceRegs.elements[i]; 489 } 490 491 %(unloadRegs)s 492 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 493 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 494 495 microUnpackAllNeonIop = \ 496 InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2), 497 'MicroUnpackAllNeon%dto%dUop' % 498 (sRegs * 2, dRegs * 2), 499 'MicroNeonMixOp', 500 { 'predicate_test': predicateTest, 501 'code' : microUnpackAllNeonCode }, 502 ['IsMicroop']) 503 header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop) 504 exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop) 505 506 for dRegs in 1, 2: 507 unloadRegs = '' 508 for reg in range(dRegs): 509 unloadRegs += ''' 510 FpDestP%(reg0)d.uw = gtoh(destRegs.fRegs[%(reg0)d]); 511 FpDestP%(reg1)d.uw = gtoh(destRegs.fRegs[%(reg1)d]); 512 ''' % { "reg0" : (2 * reg + 0), 513 "reg1" : (2 * reg + 1) } 514 for sRegs in range(dRegs, 5): 515 loadRegs = '' 516 for reg in range(sRegs): 517 loadRegs += ''' 518 sourceRegs[%(reg)d].fRegs[0] = htog(FpOp1S%(reg)dP0.uw); 519 sourceRegs[%(reg)d].fRegs[1] = htog(FpOp1S%(reg)dP1.uw); 520 ''' % { "reg" : reg } 521 microPackNeonCode = ''' 522 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 523 sizeof(Element); 524 525 union SourceReg { 526 FloatRegBits fRegs[2]; 527 Element elements[perDReg]; 528 } sourceRegs[%(sRegs)d]; 529 530 union DestRegs { 531 FloatRegBits fRegs[2 * %(dRegs)d]; 532 Element elements[%(dRegs)d * perDReg]; 533 } destRegs; 534 535 %(loadRegs)s 536 537 for (unsigned i = 0; i < %(sRegs)d; i++) { 538 destRegs.elements[i] = sourceRegs[i].elements[lane]; 539 } 540 541 %(unloadRegs)s 542 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 543 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 544 545 microPackNeonIop = \ 546 InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2), 547 'MicroPackNeon%dto%dUop' % 548 (sRegs * 2, dRegs * 2), 549 'MicroNeonMixLaneOp', 550 { 'predicate_test': predicateTest, 551 'code' : microPackNeonCode }, 552 ['IsMicroop']) 553 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop) 554 exec_output += MicroNeonMixExecute.subst(microPackNeonIop) 555}}; 556 557let {{ 558 exec_output = '' 559 for type in ('uint8_t', 'uint16_t', 'uint32_t'): 560 for sRegs in 1, 2: 561 for dRegs in range(sRegs, 5): 562 for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop", 563 "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop", 564 "MicroPackNeon%(dRegs)dto%(sRegs)dUop"): 565 Name = format % { "sRegs" : sRegs * 2, 566 "dRegs" : dRegs * 2 } 567 substDict = { "class_name" : Name, "targs" : type } 568 exec_output += MicroNeonExecDeclare.subst(substDict) 569}}; 570 571//////////////////////////////////////////////////////////////////// 572// 573// Integer = Integer op Immediate microops 574// 575 576let {{ 577 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop', 578 'MicroIntImmOp', 579 {'code': 'URa = URb + imm;', 580 'predicate_test': predicateTest}, 581 ['IsMicroop']) 582 583 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop', 584 'MicroIntRegOp', 585 {'code': 586 '''URa = URb + shift_rm_imm(URc, shiftAmt, 587 shiftType, 588 CondCodes<29:>); 589 ''', 590 'predicate_test': predicateTest}, 591 ['IsMicroop']) 592 593 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop', 594 'MicroIntImmOp', 595 {'code': 'URa = URb - imm;', 596 'predicate_test': predicateTest}, 597 ['IsMicroop']) 598 599 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop', 600 'MicroIntRegOp', 601 {'code': 602 '''URa = URb - shift_rm_imm(URc, shiftAmt, 603 shiftType, 604 CondCodes<29:>); 605 ''', 606 'predicate_test': predicateTest}, 607 ['IsMicroop']) 608 609 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov', 610 'MicroIntMov', 611 {'code': 'IWRa = URb;', 612 'predicate_test': predicateTest}, 613 ['IsMicroop']) 614 615 microUopRegMovRetIop = InstObjParams('movret_uop', 'MicroUopRegMovRet', 616 'MicroIntMov', 617 {'code': microRetUopCode % 'URb', 618 'predicate_test': predicateTest}, 619 ['IsMicroop', 'IsNonSpeculative', 620 'IsSerializeAfter']) 621 622 setPCCPSRDecl = ''' 623 CPSR cpsrOrCondCodes = URc; 624 SCTLR sctlr = Sctlr; 625 pNPC = URa; 626 uint32_t newCpsr = 627 cpsrWriteByInstr(cpsrOrCondCodes, URb, 628 0xF, true, sctlr.nmfi); 629 Cpsr = ~CondCodesMask & newCpsr; 630 NextThumb = ((CPSR)newCpsr).t; 631 NextJazelle = ((CPSR)newCpsr).j; 632 NextItState = ((((CPSR)URb).it2 << 2) & 0xFC) 633 | (((CPSR)URb).it1 & 0x3); 634 CondCodes = CondCodesMask & newCpsr; 635 ''' 636 637 microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR', 638 'MicroSetPCCPSR', 639 {'code': setPCCPSRDecl, 640 'predicate_test': predicateTest}, 641 ['IsMicroop']) 642 643 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \ 644 MicroIntImmDeclare.subst(microSubiUopIop) + \ 645 MicroIntRegDeclare.subst(microAddUopIop) + \ 646 MicroIntRegDeclare.subst(microSubUopIop) + \ 647 MicroIntMovDeclare.subst(microUopRegMovIop) + \ 648 MicroIntMovDeclare.subst(microUopRegMovRetIop) + \ 649 MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop) 650 651 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \ 652 MicroIntImmConstructor.subst(microSubiUopIop) + \ 653 MicroIntRegConstructor.subst(microAddUopIop) + \ 654 MicroIntRegConstructor.subst(microSubUopIop) + \ 655 MicroIntMovConstructor.subst(microUopRegMovIop) + \ 656 MicroIntMovConstructor.subst(microUopRegMovRetIop) + \ 657 MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop) 658 659 exec_output = PredOpExecute.subst(microAddiUopIop) + \ 660 PredOpExecute.subst(microSubiUopIop) + \ 661 PredOpExecute.subst(microAddUopIop) + \ 662 PredOpExecute.subst(microSubUopIop) + \ 663 PredOpExecute.subst(microUopRegMovIop) + \ 664 PredOpExecute.subst(microUopRegMovRetIop) + \ 665 PredOpExecute.subst(microUopSetPCCPSRIop) 666 667}}; 668 669let {{ 670 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", []) 671 header_output = MacroMemDeclare.subst(iop) 672 decoder_output = MacroMemConstructor.subst(iop) 673 674 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", []) 675 header_output += VMemMultDeclare.subst(iop) 676 decoder_output += VMemMultConstructor.subst(iop) 677 678 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", []) 679 header_output += VMemSingleDeclare.subst(iop) 680 decoder_output += VMemSingleConstructor.subst(iop) 681 682 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", []) 683 header_output += VMemMultDeclare.subst(iop) 684 decoder_output += VMemMultConstructor.subst(iop) 685 686 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", []) 687 header_output += VMemSingleDeclare.subst(iop) 688 decoder_output += VMemSingleConstructor.subst(iop) 689 690 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", []) 691 header_output += MacroVFPMemDeclare.subst(vfpIop) 692 decoder_output += MacroVFPMemConstructor.subst(vfpIop) 693}}; 694