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