macromem.isa revision 8139:2b2efc67f6df
110447Snilay@cs.wisc.edu// -*- mode:c++ -*- 210447Snilay@cs.wisc.edu 310447Snilay@cs.wisc.edu// Copyright (c) 2010 ARM Limited 410447Snilay@cs.wisc.edu// All rights reserved 510447Snilay@cs.wisc.edu// 610447Snilay@cs.wisc.edu// The license below extends only to copyright in the software and shall 710447Snilay@cs.wisc.edu// not be construed as granting a license to any other intellectual 810447Snilay@cs.wisc.edu// property including but not limited to intellectual property relating 910447Snilay@cs.wisc.edu// to a hardware implementation of the functionality of the software 1010447Snilay@cs.wisc.edu// licensed hereunder. You may use the software subject to the license 1110447Snilay@cs.wisc.edu// terms below provided that you ensure that this notice is replicated 1210447Snilay@cs.wisc.edu// unmodified and in its entirety in all distributions of the software, 1310447Snilay@cs.wisc.edu// modified or unmodified, in source code or in binary form. 1410447Snilay@cs.wisc.edu// 1510447Snilay@cs.wisc.edu// Copyright (c) 2007-2008 The Florida State University 1610447Snilay@cs.wisc.edu// All rights reserved. 1710447Snilay@cs.wisc.edu// 1810447Snilay@cs.wisc.edu// Redistribution and use in source and binary forms, with or without 1910447Snilay@cs.wisc.edu// modification, are permitted provided that the following conditions are 2010447Snilay@cs.wisc.edu// met: redistributions of source code must retain the above copyright 2110447Snilay@cs.wisc.edu// notice, this list of conditions and the following disclaimer; 2210447Snilay@cs.wisc.edu// redistributions in binary form must reproduce the above copyright 2310447Snilay@cs.wisc.edu// notice, this list of conditions and the following disclaimer in the 2410447Snilay@cs.wisc.edu// documentation and/or other materials provided with the distribution; 2510447Snilay@cs.wisc.edu// neither the name of the copyright holders nor the names of its 2610447Snilay@cs.wisc.edu// contributors may be used to endorse or promote products derived from 2710447Snilay@cs.wisc.edu// this software without specific prior written permission. 2810447Snilay@cs.wisc.edu// 2910447Snilay@cs.wisc.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3010447Snilay@cs.wisc.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3110447Snilay@cs.wisc.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3210447Snilay@cs.wisc.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3310447Snilay@cs.wisc.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3410447Snilay@cs.wisc.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3510447Snilay@cs.wisc.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3610447Snilay@cs.wisc.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3710447Snilay@cs.wisc.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3810447Snilay@cs.wisc.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3910447Snilay@cs.wisc.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4010447Snilay@cs.wisc.edu// 4110447Snilay@cs.wisc.edu// Authors: Stephen Hines 4210447Snilay@cs.wisc.edu// Gabe Black 4310447Snilay@cs.wisc.edu 4410447Snilay@cs.wisc.edu//////////////////////////////////////////////////////////////////// 4510447Snilay@cs.wisc.edu// 4610447Snilay@cs.wisc.edu// Load/store microops 4710447Snilay@cs.wisc.edu// 4810447Snilay@cs.wisc.edu 4910447Snilay@cs.wisc.edulet {{ 5010447Snilay@cs.wisc.edu microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 5110447Snilay@cs.wisc.edu microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop', 5210447Snilay@cs.wisc.edu 'MicroMemOp', 5310447Snilay@cs.wisc.edu {'memacc_code': microLdrUopCode, 5410447Snilay@cs.wisc.edu 'ea_code': 'EA = URb + (up ? imm : -imm);', 5510447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 5610447Snilay@cs.wisc.edu ['IsMicroop']) 5710447Snilay@cs.wisc.edu 5810447Snilay@cs.wisc.edu microLdrFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 5910447Snilay@cs.wisc.edu microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop', 6010447Snilay@cs.wisc.edu 'MicroMemOp', 6110447Snilay@cs.wisc.edu {'memacc_code': microLdrFpUopCode, 6210447Snilay@cs.wisc.edu 'ea_code': vfpEnabledCheckCode + 6310447Snilay@cs.wisc.edu 'EA = URb + (up ? imm : -imm);', 6410447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 6510447Snilay@cs.wisc.edu ['IsMicroop']) 6610447Snilay@cs.wisc.edu 6710447Snilay@cs.wisc.edu microLdrDBFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 6810447Snilay@cs.wisc.edu microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop', 6910447Snilay@cs.wisc.edu 'MicroMemOp', 7010447Snilay@cs.wisc.edu {'memacc_code': microLdrFpUopCode, 7110447Snilay@cs.wisc.edu 'ea_code': vfpEnabledCheckCode + ''' 7210447Snilay@cs.wisc.edu EA = URb + (up ? imm : -imm) + 7310447Snilay@cs.wisc.edu (((CPSR)Cpsr).e ? 4 : 0); 7410447Snilay@cs.wisc.edu ''', 7510447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 7610447Snilay@cs.wisc.edu ['IsMicroop']) 7710447Snilay@cs.wisc.edu 7810447Snilay@cs.wisc.edu microLdrDTFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 7910447Snilay@cs.wisc.edu microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop', 8010447Snilay@cs.wisc.edu 'MicroMemOp', 8110447Snilay@cs.wisc.edu {'memacc_code': microLdrFpUopCode, 8210447Snilay@cs.wisc.edu 'ea_code': vfpEnabledCheckCode + ''' 8310447Snilay@cs.wisc.edu EA = URb + (up ? imm : -imm) - 8410447Snilay@cs.wisc.edu (((CPSR)Cpsr).e ? 4 : 0); 8510447Snilay@cs.wisc.edu ''', 8610447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 8710447Snilay@cs.wisc.edu ['IsMicroop']) 8810447Snilay@cs.wisc.edu 8910447Snilay@cs.wisc.edu microLdrRetUopCode = ''' 9010447Snilay@cs.wisc.edu CPSR cpsr = Cpsr; 9110447Snilay@cs.wisc.edu SCTLR sctlr = Sctlr; 9210447Snilay@cs.wisc.edu uint32_t newCpsr = 9310447Snilay@cs.wisc.edu cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi); 9410447Snilay@cs.wisc.edu Cpsr = ~CondCodesMask & newCpsr; 9510447Snilay@cs.wisc.edu CondCodes = CondCodesMask & newCpsr; 9610447Snilay@cs.wisc.edu IWNPC = cSwap(Mem.uw, cpsr.e) | ((Spsr & 0x20) ? 1 : 0); 9710447Snilay@cs.wisc.edu ForcedItState = ((((CPSR)Spsr).it2 << 2) & 0xFC) 9810447Snilay@cs.wisc.edu | (((CPSR)Spsr).it1 & 0x3); 9910447Snilay@cs.wisc.edu ''' 10010447Snilay@cs.wisc.edu microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', 10110447Snilay@cs.wisc.edu 'MicroMemOp', 10210447Snilay@cs.wisc.edu {'memacc_code': microLdrRetUopCode, 10310447Snilay@cs.wisc.edu 'ea_code': 10410447Snilay@cs.wisc.edu 'EA = URb + (up ? imm : -imm);', 10510447Snilay@cs.wisc.edu 'predicate_test': condPredicateTest}, 10610447Snilay@cs.wisc.edu ['IsMicroop','IsNonSpeculative','IsSerializeAfter']) 10710447Snilay@cs.wisc.edu 10810447Snilay@cs.wisc.edu microStrUopCode = "Mem = cSwap(URa.uw, ((CPSR)Cpsr).e);" 10910447Snilay@cs.wisc.edu microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 11010447Snilay@cs.wisc.edu 'MicroMemOp', 11110447Snilay@cs.wisc.edu {'memacc_code': microStrUopCode, 11210447Snilay@cs.wisc.edu 'postacc_code': "", 11310447Snilay@cs.wisc.edu 'ea_code': 'EA = URb + (up ? imm : -imm);', 11410447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 11510447Snilay@cs.wisc.edu ['IsMicroop']) 11610447Snilay@cs.wisc.edu 11710447Snilay@cs.wisc.edu microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 11810447Snilay@cs.wisc.edu microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop', 11910447Snilay@cs.wisc.edu 'MicroMemOp', 12010447Snilay@cs.wisc.edu {'memacc_code': microStrFpUopCode, 12110447Snilay@cs.wisc.edu 'postacc_code': "", 12210447Snilay@cs.wisc.edu 'ea_code': vfpEnabledCheckCode + 12310447Snilay@cs.wisc.edu 'EA = URb + (up ? imm : -imm);', 12410447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 12510447Snilay@cs.wisc.edu ['IsMicroop']) 12610447Snilay@cs.wisc.edu 12710447Snilay@cs.wisc.edu microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 12810447Snilay@cs.wisc.edu microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop', 12910447Snilay@cs.wisc.edu 'MicroMemOp', 13010447Snilay@cs.wisc.edu {'memacc_code': microStrFpUopCode, 13110447Snilay@cs.wisc.edu 'postacc_code': "", 13210447Snilay@cs.wisc.edu 'ea_code': vfpEnabledCheckCode + ''' 13310447Snilay@cs.wisc.edu EA = URb + (up ? imm : -imm) + 13410447Snilay@cs.wisc.edu (((CPSR)Cpsr).e ? 4 : 0); 13510447Snilay@cs.wisc.edu ''', 13610447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 13710447Snilay@cs.wisc.edu ['IsMicroop']) 13810447Snilay@cs.wisc.edu 13910447Snilay@cs.wisc.edu microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 14010447Snilay@cs.wisc.edu microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop', 14110447Snilay@cs.wisc.edu 'MicroMemOp', 14210447Snilay@cs.wisc.edu {'memacc_code': microStrFpUopCode, 14310447Snilay@cs.wisc.edu 'postacc_code': "", 14410447Snilay@cs.wisc.edu 'ea_code': vfpEnabledCheckCode + ''' 14510447Snilay@cs.wisc.edu EA = URb + (up ? imm : -imm) - 14610447Snilay@cs.wisc.edu (((CPSR)Cpsr).e ? 4 : 0); 14710447Snilay@cs.wisc.edu ''', 14810447Snilay@cs.wisc.edu 'predicate_test': predicateTest}, 14910447Snilay@cs.wisc.edu ['IsMicroop']) 15010447Snilay@cs.wisc.edu 15110447Snilay@cs.wisc.edu header_output = decoder_output = exec_output = '' 15210447Snilay@cs.wisc.edu 15310447Snilay@cs.wisc.edu loadIops = (microLdrUopIop, microLdrRetUopIop, 15410447Snilay@cs.wisc.edu microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop) 15510447Snilay@cs.wisc.edu storeIops = (microStrUopIop, microStrFpUopIop, 15610447Snilay@cs.wisc.edu microStrDBFpUopIop, microStrDTFpUopIop) 15710447Snilay@cs.wisc.edu for iop in loadIops + storeIops: 15810447Snilay@cs.wisc.edu header_output += MicroMemDeclare.subst(iop) 15910447Snilay@cs.wisc.edu decoder_output += MicroMemConstructor.subst(iop) 16010447Snilay@cs.wisc.edu for iop in loadIops: 16110447Snilay@cs.wisc.edu exec_output += LoadExecute.subst(iop) + \ 16210447Snilay@cs.wisc.edu LoadInitiateAcc.subst(iop) + \ 16310447Snilay@cs.wisc.edu LoadCompleteAcc.subst(iop) 16410447Snilay@cs.wisc.edu for iop in storeIops: 16510447Snilay@cs.wisc.edu exec_output += StoreExecute.subst(iop) + \ 16610447Snilay@cs.wisc.edu StoreInitiateAcc.subst(iop) + \ 16710447Snilay@cs.wisc.edu StoreCompleteAcc.subst(iop) 16810447Snilay@cs.wisc.edu}}; 16910447Snilay@cs.wisc.edu 17010447Snilay@cs.wisc.edulet {{ 17110447Snilay@cs.wisc.edu exec_output = header_output = '' 17210447Snilay@cs.wisc.edu 17310447Snilay@cs.wisc.edu eaCode = 'EA = URa + imm;' 17410447Snilay@cs.wisc.edu 17510447Snilay@cs.wisc.edu for size in (1, 2, 3, 4, 6, 8, 12, 16): 17610447Snilay@cs.wisc.edu # Set up the memory access. 17710447Snilay@cs.wisc.edu regs = (size + 3) // 4 17810447Snilay@cs.wisc.edu subst = { "size" : size, "regs" : regs } 17910447Snilay@cs.wisc.edu memDecl = ''' 18010447Snilay@cs.wisc.edu union MemUnion { 18110447Snilay@cs.wisc.edu uint8_t bytes[%(size)d]; 18210447Snilay@cs.wisc.edu Element elements[%(size)d / sizeof(Element)]; 18310447Snilay@cs.wisc.edu uint32_t floatRegBits[%(regs)d]; 18410447Snilay@cs.wisc.edu }; 18510447Snilay@cs.wisc.edu ''' % subst 18610447Snilay@cs.wisc.edu 18710447Snilay@cs.wisc.edu # Do endian conversion for all the elements. 18810447Snilay@cs.wisc.edu convCode = ''' 18910447Snilay@cs.wisc.edu const unsigned eCount = sizeof(memUnion.elements) / 19010447Snilay@cs.wisc.edu sizeof(memUnion.elements[0]); 19110447Snilay@cs.wisc.edu if (((CPSR)Cpsr).e) { 19210447Snilay@cs.wisc.edu for (unsigned i = 0; i < eCount; i++) { 19310447Snilay@cs.wisc.edu memUnion.elements[i] = gtobe(memUnion.elements[i]); 19410447Snilay@cs.wisc.edu } 19510447Snilay@cs.wisc.edu } else { 19610447Snilay@cs.wisc.edu for (unsigned i = 0; i < eCount; i++) { 19710447Snilay@cs.wisc.edu memUnion.elements[i] = gtole(memUnion.elements[i]); 19810447Snilay@cs.wisc.edu } 19910447Snilay@cs.wisc.edu } 20010447Snilay@cs.wisc.edu ''' 20110447Snilay@cs.wisc.edu 20210447Snilay@cs.wisc.edu # Offload everything into registers 20310447Snilay@cs.wisc.edu regSetCode = '' 20410447Snilay@cs.wisc.edu for reg in range(regs): 20510447Snilay@cs.wisc.edu mask = '' 20610447Snilay@cs.wisc.edu if reg == regs - 1: 20710447Snilay@cs.wisc.edu mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size)) 20810447Snilay@cs.wisc.edu regSetCode += ''' 20910447Snilay@cs.wisc.edu FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s; 21010447Snilay@cs.wisc.edu ''' % { "reg" : reg, "mask" : mask } 21110447Snilay@cs.wisc.edu 21210447Snilay@cs.wisc.edu # Pull everything in from registers 21310447Snilay@cs.wisc.edu regGetCode = '' 21410447Snilay@cs.wisc.edu for reg in range(regs): 21510447Snilay@cs.wisc.edu regGetCode += ''' 21610447Snilay@cs.wisc.edu memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw); 21710447Snilay@cs.wisc.edu ''' % { "reg" : reg } 21810447Snilay@cs.wisc.edu 21910447Snilay@cs.wisc.edu loadMemAccCode = convCode + regSetCode 22010447Snilay@cs.wisc.edu storeMemAccCode = regGetCode + convCode 22110447Snilay@cs.wisc.edu 22210447Snilay@cs.wisc.edu loadIop = InstObjParams('ldrneon%(size)d_uop' % subst, 22310447Snilay@cs.wisc.edu 'MicroLdrNeon%(size)dUop' % subst, 22410447Snilay@cs.wisc.edu 'MicroNeonMemOp', 22510447Snilay@cs.wisc.edu { 'mem_decl' : memDecl, 22610447Snilay@cs.wisc.edu 'size' : size, 22710447Snilay@cs.wisc.edu 'memacc_code' : loadMemAccCode, 22810447Snilay@cs.wisc.edu 'ea_code' : simdEnabledCheckCode + eaCode, 22910447Snilay@cs.wisc.edu 'predicate_test' : predicateTest }, 23010447Snilay@cs.wisc.edu [ 'IsMicroop', 'IsMemRef', 'IsLoad' ]) 23110447Snilay@cs.wisc.edu storeIop = InstObjParams('strneon%(size)d_uop' % subst, 23210447Snilay@cs.wisc.edu 'MicroStrNeon%(size)dUop' % subst, 23310447Snilay@cs.wisc.edu 'MicroNeonMemOp', 23410447Snilay@cs.wisc.edu { 'mem_decl' : memDecl, 23510447Snilay@cs.wisc.edu 'size' : size, 23610447Snilay@cs.wisc.edu 'memacc_code' : storeMemAccCode, 23710447Snilay@cs.wisc.edu 'ea_code' : simdEnabledCheckCode + eaCode, 23810447Snilay@cs.wisc.edu 'predicate_test' : predicateTest }, 23910447Snilay@cs.wisc.edu [ 'IsMicroop', 'IsMemRef', 'IsStore' ]) 24010447Snilay@cs.wisc.edu 24110447Snilay@cs.wisc.edu exec_output += NeonLoadExecute.subst(loadIop) + \ 24210447Snilay@cs.wisc.edu NeonLoadInitiateAcc.subst(loadIop) + \ 24310447Snilay@cs.wisc.edu NeonLoadCompleteAcc.subst(loadIop) + \ 24410447Snilay@cs.wisc.edu NeonStoreExecute.subst(storeIop) + \ 24510447Snilay@cs.wisc.edu NeonStoreInitiateAcc.subst(storeIop) + \ 24610447Snilay@cs.wisc.edu NeonStoreCompleteAcc.subst(storeIop) 24710447Snilay@cs.wisc.edu header_output += MicroNeonMemDeclare.subst(loadIop) + \ 24810447Snilay@cs.wisc.edu MicroNeonMemDeclare.subst(storeIop) 24910447Snilay@cs.wisc.edu}}; 25010447Snilay@cs.wisc.edu 25110447Snilay@cs.wisc.edulet {{ 25210447Snilay@cs.wisc.edu exec_output = '' 25310447Snilay@cs.wisc.edu for eSize, type in (1, 'uint8_t'), \ 25410447Snilay@cs.wisc.edu (2, 'uint16_t'), \ 25510447Snilay@cs.wisc.edu (4, 'uint32_t'), \ 25610447Snilay@cs.wisc.edu (8, 'uint64_t'): 25710447Snilay@cs.wisc.edu size = eSize 25810447Snilay@cs.wisc.edu # An instruction handles no more than 16 bytes and no more than 25910447Snilay@cs.wisc.edu # 4 elements, or the number of elements needed to fill 8 or 16 bytes. 26010447Snilay@cs.wisc.edu sizes = set((16, 8)) 26110447Snilay@cs.wisc.edu for count in 1, 2, 3, 4: 26210447Snilay@cs.wisc.edu size = count * eSize 26310447Snilay@cs.wisc.edu if size <= 16: 26410447Snilay@cs.wisc.edu sizes.add(size) 26510447Snilay@cs.wisc.edu for size in sizes: 26610447Snilay@cs.wisc.edu substDict = { 26710447Snilay@cs.wisc.edu "class_name" : "MicroLdrNeon%dUop" % size, 26810447Snilay@cs.wisc.edu "targs" : type 26910447Snilay@cs.wisc.edu } 27010447Snilay@cs.wisc.edu exec_output += MicroNeonMemExecDeclare.subst(substDict) 27110447Snilay@cs.wisc.edu substDict["class_name"] = "MicroStrNeon%dUop" % size 27210447Snilay@cs.wisc.edu exec_output += MicroNeonMemExecDeclare.subst(substDict) 27310447Snilay@cs.wisc.edu size += eSize 27410447Snilay@cs.wisc.edu}}; 27510447Snilay@cs.wisc.edu 27610447Snilay@cs.wisc.edu//////////////////////////////////////////////////////////////////// 27710447Snilay@cs.wisc.edu// 27810447Snilay@cs.wisc.edu// Neon (de)interlacing microops 27910447Snilay@cs.wisc.edu// 28010447Snilay@cs.wisc.edu 28110447Snilay@cs.wisc.edulet {{ 28210447Snilay@cs.wisc.edu header_output = exec_output = '' 28310447Snilay@cs.wisc.edu for dRegs in (2, 3, 4): 28410447Snilay@cs.wisc.edu loadConv = '' 28510447Snilay@cs.wisc.edu unloadConv = '' 28610447Snilay@cs.wisc.edu for dReg in range(dRegs): 28710447Snilay@cs.wisc.edu loadConv += ''' 28810447Snilay@cs.wisc.edu conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d.uw); 28910447Snilay@cs.wisc.edu conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d.uw); 29010447Snilay@cs.wisc.edu ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 29110447Snilay@cs.wisc.edu unloadConv += ''' 29210447Snilay@cs.wisc.edu FpDestS%(dReg)dP0.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]); 29310447Snilay@cs.wisc.edu FpDestS%(dReg)dP1.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]); 29410447Snilay@cs.wisc.edu ''' % { "dReg" : dReg } 29510447Snilay@cs.wisc.edu microDeintNeonCode = ''' 29610447Snilay@cs.wisc.edu const unsigned dRegs = %(dRegs)d; 29710447Snilay@cs.wisc.edu const unsigned regs = 2 * dRegs; 29810447Snilay@cs.wisc.edu const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 29910447Snilay@cs.wisc.edu sizeof(Element); 30010447Snilay@cs.wisc.edu union convStruct { 30110447Snilay@cs.wisc.edu FloatRegBits cRegs[regs]; 30210447Snilay@cs.wisc.edu Element elements[dRegs * perDReg]; 30310447Snilay@cs.wisc.edu } conv1, conv2; 30410447Snilay@cs.wisc.edu 30510447Snilay@cs.wisc.edu %(loadConv)s 30610447Snilay@cs.wisc.edu 30710447Snilay@cs.wisc.edu unsigned srcElem = 0; 30810447Snilay@cs.wisc.edu for (unsigned destOffset = 0; 30910447Snilay@cs.wisc.edu destOffset < perDReg; destOffset++) { 31010447Snilay@cs.wisc.edu for (unsigned dReg = 0; dReg < dRegs; dReg++) { 31110447Snilay@cs.wisc.edu conv2.elements[dReg * perDReg + destOffset] = 31210447Snilay@cs.wisc.edu conv1.elements[srcElem++]; 31310447Snilay@cs.wisc.edu } 31410447Snilay@cs.wisc.edu } 31510447Snilay@cs.wisc.edu 31610447Snilay@cs.wisc.edu %(unloadConv)s 31710447Snilay@cs.wisc.edu ''' % { "dRegs" : dRegs, 31810447Snilay@cs.wisc.edu "loadConv" : loadConv, 31910447Snilay@cs.wisc.edu "unloadConv" : unloadConv } 32010447Snilay@cs.wisc.edu microDeintNeonIop = \ 32110447Snilay@cs.wisc.edu InstObjParams('deintneon%duop' % (dRegs * 2), 32210447Snilay@cs.wisc.edu 'MicroDeintNeon%dUop' % (dRegs * 2), 32310447Snilay@cs.wisc.edu 'MicroNeonMixOp', 32410447Snilay@cs.wisc.edu { 'predicate_test': predicateTest, 32510447Snilay@cs.wisc.edu 'code' : microDeintNeonCode }, 32610447Snilay@cs.wisc.edu ['IsMicroop']) 32710447Snilay@cs.wisc.edu header_output += MicroNeonMixDeclare.subst(microDeintNeonIop) 32810447Snilay@cs.wisc.edu exec_output += MicroNeonMixExecute.subst(microDeintNeonIop) 32910447Snilay@cs.wisc.edu 33010447Snilay@cs.wisc.edu loadConv = '' 33110447Snilay@cs.wisc.edu unloadConv = '' 33210447Snilay@cs.wisc.edu for dReg in range(dRegs): 33310447Snilay@cs.wisc.edu loadConv += ''' 33410447Snilay@cs.wisc.edu conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0.uw); 33510447Snilay@cs.wisc.edu conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1.uw); 33610447Snilay@cs.wisc.edu ''' % { "dReg" : dReg } 33710447Snilay@cs.wisc.edu unloadConv += ''' 33810447Snilay@cs.wisc.edu FpDestP%(sReg0)d.uw = gtoh(conv2.cRegs[%(sReg0)d]); 33910447Snilay@cs.wisc.edu FpDestP%(sReg1)d.uw = gtoh(conv2.cRegs[%(sReg1)d]); 34010447Snilay@cs.wisc.edu ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 34110447Snilay@cs.wisc.edu microInterNeonCode = ''' 34210447Snilay@cs.wisc.edu const unsigned dRegs = %(dRegs)d; 34310447Snilay@cs.wisc.edu const unsigned regs = 2 * dRegs; 34410447Snilay@cs.wisc.edu const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 34510447Snilay@cs.wisc.edu sizeof(Element); 34610447Snilay@cs.wisc.edu union convStruct { 34710447Snilay@cs.wisc.edu FloatRegBits cRegs[regs]; 34810447Snilay@cs.wisc.edu Element elements[dRegs * perDReg]; 34910447Snilay@cs.wisc.edu } conv1, conv2; 35010447Snilay@cs.wisc.edu 35110447Snilay@cs.wisc.edu %(loadConv)s 35210447Snilay@cs.wisc.edu 35310447Snilay@cs.wisc.edu unsigned destElem = 0; 35410447Snilay@cs.wisc.edu for (unsigned srcOffset = 0; 35510447Snilay@cs.wisc.edu srcOffset < perDReg; srcOffset++) { 35610447Snilay@cs.wisc.edu for (unsigned dReg = 0; dReg < dRegs; dReg++) { 35710447Snilay@cs.wisc.edu conv2.elements[destElem++] = 35810447Snilay@cs.wisc.edu conv1.elements[dReg * perDReg + srcOffset]; 35910447Snilay@cs.wisc.edu } 36010447Snilay@cs.wisc.edu } 36110447Snilay@cs.wisc.edu 36210447Snilay@cs.wisc.edu %(unloadConv)s 36310447Snilay@cs.wisc.edu ''' % { "dRegs" : dRegs, 36410447Snilay@cs.wisc.edu "loadConv" : loadConv, 36510447Snilay@cs.wisc.edu "unloadConv" : unloadConv } 36610447Snilay@cs.wisc.edu microInterNeonIop = \ 36710447Snilay@cs.wisc.edu InstObjParams('interneon%duop' % (dRegs * 2), 36810447Snilay@cs.wisc.edu 'MicroInterNeon%dUop' % (dRegs * 2), 36910447Snilay@cs.wisc.edu 'MicroNeonMixOp', 37010447Snilay@cs.wisc.edu { 'predicate_test': predicateTest, 37110447Snilay@cs.wisc.edu 'code' : microInterNeonCode }, 37210447Snilay@cs.wisc.edu ['IsMicroop']) 37310447Snilay@cs.wisc.edu header_output += MicroNeonMixDeclare.subst(microInterNeonIop) 37410447Snilay@cs.wisc.edu exec_output += MicroNeonMixExecute.subst(microInterNeonIop) 375}}; 376 377let {{ 378 exec_output = '' 379 for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'): 380 for dRegs in (2, 3, 4): 381 Name = "MicroDeintNeon%dUop" % (dRegs * 2) 382 substDict = { "class_name" : Name, "targs" : type } 383 exec_output += MicroNeonExecDeclare.subst(substDict) 384 Name = "MicroInterNeon%dUop" % (dRegs * 2) 385 substDict = { "class_name" : Name, "targs" : type } 386 exec_output += MicroNeonExecDeclare.subst(substDict) 387}}; 388 389//////////////////////////////////////////////////////////////////// 390// 391// Neon microops to pack/unpack a single lane 392// 393 394let {{ 395 header_output = exec_output = '' 396 for sRegs in 1, 2: 397 baseLoadRegs = '' 398 for reg in range(sRegs): 399 baseLoadRegs += ''' 400 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 401 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 402 ''' % { "reg0" : (2 * reg + 0), 403 "reg1" : (2 * reg + 1) } 404 for dRegs in range(sRegs, 5): 405 unloadRegs = '' 406 loadRegs = baseLoadRegs 407 for reg in range(dRegs): 408 loadRegs += ''' 409 destRegs[%(reg)d].fRegs[0] = htog(FpDestS%(reg)dP0.uw); 410 destRegs[%(reg)d].fRegs[1] = htog(FpDestS%(reg)dP1.uw); 411 ''' % { "reg" : reg } 412 unloadRegs += ''' 413 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 414 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 415 ''' % { "reg" : reg } 416 microUnpackNeonCode = ''' 417 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 418 sizeof(Element); 419 420 union SourceRegs { 421 FloatRegBits fRegs[2 * %(sRegs)d]; 422 Element elements[%(sRegs)d * perDReg]; 423 } sourceRegs; 424 425 union DestReg { 426 FloatRegBits fRegs[2]; 427 Element elements[perDReg]; 428 } destRegs[%(dRegs)d]; 429 430 %(loadRegs)s 431 432 for (unsigned i = 0; i < %(dRegs)d; i++) { 433 destRegs[i].elements[lane] = sourceRegs.elements[i]; 434 } 435 436 %(unloadRegs)s 437 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 438 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 439 440 microUnpackNeonIop = \ 441 InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2), 442 'MicroUnpackNeon%dto%dUop' % 443 (sRegs * 2, dRegs * 2), 444 'MicroNeonMixLaneOp', 445 { 'predicate_test': predicateTest, 446 'code' : microUnpackNeonCode }, 447 ['IsMicroop']) 448 header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop) 449 exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop) 450 451 for sRegs in 1, 2: 452 loadRegs = '' 453 for reg in range(sRegs): 454 loadRegs += ''' 455 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 456 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 457 ''' % { "reg0" : (2 * reg + 0), 458 "reg1" : (2 * reg + 1) } 459 for dRegs in range(sRegs, 5): 460 unloadRegs = '' 461 for reg in range(dRegs): 462 unloadRegs += ''' 463 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 464 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 465 ''' % { "reg" : reg } 466 microUnpackAllNeonCode = ''' 467 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 468 sizeof(Element); 469 470 union SourceRegs { 471 FloatRegBits fRegs[2 * %(sRegs)d]; 472 Element elements[%(sRegs)d * perDReg]; 473 } sourceRegs; 474 475 union DestReg { 476 FloatRegBits fRegs[2]; 477 Element elements[perDReg]; 478 } destRegs[%(dRegs)d]; 479 480 %(loadRegs)s 481 482 for (unsigned i = 0; i < %(dRegs)d; i++) { 483 for (unsigned j = 0; j < perDReg; j++) 484 destRegs[i].elements[j] = sourceRegs.elements[i]; 485 } 486 487 %(unloadRegs)s 488 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 489 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 490 491 microUnpackAllNeonIop = \ 492 InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2), 493 'MicroUnpackAllNeon%dto%dUop' % 494 (sRegs * 2, dRegs * 2), 495 'MicroNeonMixOp', 496 { 'predicate_test': predicateTest, 497 'code' : microUnpackAllNeonCode }, 498 ['IsMicroop']) 499 header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop) 500 exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop) 501 502 for dRegs in 1, 2: 503 unloadRegs = '' 504 for reg in range(dRegs): 505 unloadRegs += ''' 506 FpDestP%(reg0)d.uw = gtoh(destRegs.fRegs[%(reg0)d]); 507 FpDestP%(reg1)d.uw = gtoh(destRegs.fRegs[%(reg1)d]); 508 ''' % { "reg0" : (2 * reg + 0), 509 "reg1" : (2 * reg + 1) } 510 for sRegs in range(dRegs, 5): 511 loadRegs = '' 512 for reg in range(sRegs): 513 loadRegs += ''' 514 sourceRegs[%(reg)d].fRegs[0] = htog(FpOp1S%(reg)dP0.uw); 515 sourceRegs[%(reg)d].fRegs[1] = htog(FpOp1S%(reg)dP1.uw); 516 ''' % { "reg" : reg } 517 microPackNeonCode = ''' 518 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 519 sizeof(Element); 520 521 union SourceReg { 522 FloatRegBits fRegs[2]; 523 Element elements[perDReg]; 524 } sourceRegs[%(sRegs)d]; 525 526 union DestRegs { 527 FloatRegBits fRegs[2 * %(dRegs)d]; 528 Element elements[%(dRegs)d * perDReg]; 529 } destRegs; 530 531 %(loadRegs)s 532 533 for (unsigned i = 0; i < %(sRegs)d; i++) { 534 destRegs.elements[i] = sourceRegs[i].elements[lane]; 535 } 536 537 %(unloadRegs)s 538 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 539 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 540 541 microPackNeonIop = \ 542 InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2), 543 'MicroPackNeon%dto%dUop' % 544 (sRegs * 2, dRegs * 2), 545 'MicroNeonMixLaneOp', 546 { 'predicate_test': predicateTest, 547 'code' : microPackNeonCode }, 548 ['IsMicroop']) 549 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop) 550 exec_output += MicroNeonMixExecute.subst(microPackNeonIop) 551}}; 552 553let {{ 554 exec_output = '' 555 for type in ('uint8_t', 'uint16_t', 'uint32_t'): 556 for sRegs in 1, 2: 557 for dRegs in range(sRegs, 5): 558 for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop", 559 "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop", 560 "MicroPackNeon%(dRegs)dto%(sRegs)dUop"): 561 Name = format % { "sRegs" : sRegs * 2, 562 "dRegs" : dRegs * 2 } 563 substDict = { "class_name" : Name, "targs" : type } 564 exec_output += MicroNeonExecDeclare.subst(substDict) 565}}; 566 567//////////////////////////////////////////////////////////////////// 568// 569// Integer = Integer op Immediate microops 570// 571 572let {{ 573 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop', 574 'MicroIntImmOp', 575 {'code': 'URa = URb + imm;', 576 'predicate_test': predicateTest}, 577 ['IsMicroop']) 578 579 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop', 580 'MicroIntRegOp', 581 {'code': 582 '''URa = URb + shift_rm_imm(URc, shiftAmt, 583 shiftType, 584 CondCodes<29:>); 585 ''', 586 'predicate_test': predicateTest}, 587 ['IsMicroop']) 588 589 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop', 590 'MicroIntImmOp', 591 {'code': 'URa = URb - imm;', 592 'predicate_test': predicateTest}, 593 ['IsMicroop']) 594 595 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop', 596 'MicroIntRegOp', 597 {'code': 598 '''URa = URb - shift_rm_imm(URc, shiftAmt, 599 shiftType, 600 CondCodes<29:>); 601 ''', 602 'predicate_test': predicateTest}, 603 ['IsMicroop']) 604 605 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov', 606 'MicroIntMov', 607 {'code': 'IWRa = URb;', 608 'predicate_test': predicateTest}, 609 ['IsMicroop']) 610 611 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \ 612 MicroIntImmDeclare.subst(microSubiUopIop) + \ 613 MicroIntRegDeclare.subst(microAddUopIop) + \ 614 MicroIntRegDeclare.subst(microSubUopIop) + \ 615 MicroIntMovDeclare.subst(microUopRegMovIop) 616 617 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \ 618 MicroIntImmConstructor.subst(microSubiUopIop) + \ 619 MicroIntRegConstructor.subst(microAddUopIop) + \ 620 MicroIntRegConstructor.subst(microSubUopIop) + \ 621 MicroIntMovConstructor.subst(microUopRegMovIop) 622 623 exec_output = PredOpExecute.subst(microAddiUopIop) + \ 624 PredOpExecute.subst(microSubiUopIop) + \ 625 PredOpExecute.subst(microAddUopIop) + \ 626 PredOpExecute.subst(microSubUopIop) + \ 627 PredOpExecute.subst(microUopRegMovIop) 628}}; 629 630let {{ 631 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", []) 632 header_output = MacroMemDeclare.subst(iop) 633 decoder_output = MacroMemConstructor.subst(iop) 634 635 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", []) 636 header_output += VMemMultDeclare.subst(iop) 637 decoder_output += VMemMultConstructor.subst(iop) 638 639 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", []) 640 header_output += VMemSingleDeclare.subst(iop) 641 decoder_output += VMemSingleConstructor.subst(iop) 642 643 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", []) 644 header_output += VMemMultDeclare.subst(iop) 645 decoder_output += VMemMultConstructor.subst(iop) 646 647 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", []) 648 header_output += VMemSingleDeclare.subst(iop) 649 decoder_output += VMemSingleConstructor.subst(iop) 650 651 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", []) 652 header_output += MacroVFPMemDeclare.subst(vfpIop) 653 decoder_output += MacroVFPMemConstructor.subst(vfpIop) 654}}; 655