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