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