macromem.isa revision 13544
110259SAndrew.Bardsley@arm.com// -*- mode:c++ -*-
210259SAndrew.Bardsley@arm.com
310259SAndrew.Bardsley@arm.com// Copyright (c) 2010-2014 ARM Limited
410259SAndrew.Bardsley@arm.com// All rights reserved
510259SAndrew.Bardsley@arm.com//
610259SAndrew.Bardsley@arm.com// The license below extends only to copyright in the software and shall
710259SAndrew.Bardsley@arm.com// not be construed as granting a license to any other intellectual
810259SAndrew.Bardsley@arm.com// property including but not limited to intellectual property relating
910259SAndrew.Bardsley@arm.com// to a hardware implementation of the functionality of the software
1010259SAndrew.Bardsley@arm.com// licensed hereunder.  You may use the software subject to the license
1110259SAndrew.Bardsley@arm.com// terms below provided that you ensure that this notice is replicated
1210259SAndrew.Bardsley@arm.com// unmodified and in its entirety in all distributions of the software,
1310259SAndrew.Bardsley@arm.com// modified or unmodified, in source code or in binary form.
1410259SAndrew.Bardsley@arm.com//
1510259SAndrew.Bardsley@arm.com// Copyright (c) 2007-2008 The Florida State University
1610259SAndrew.Bardsley@arm.com// All rights reserved.
1710259SAndrew.Bardsley@arm.com//
1810259SAndrew.Bardsley@arm.com// Redistribution and use in source and binary forms, with or without
1910259SAndrew.Bardsley@arm.com// modification, are permitted provided that the following conditions are
2010259SAndrew.Bardsley@arm.com// met: redistributions of source code must retain the above copyright
2110259SAndrew.Bardsley@arm.com// notice, this list of conditions and the following disclaimer;
2210259SAndrew.Bardsley@arm.com// redistributions in binary form must reproduce the above copyright
2310259SAndrew.Bardsley@arm.com// notice, this list of conditions and the following disclaimer in the
2410259SAndrew.Bardsley@arm.com// documentation and/or other materials provided with the distribution;
2510259SAndrew.Bardsley@arm.com// neither the name of the copyright holders nor the names of its
2610259SAndrew.Bardsley@arm.com// contributors may be used to endorse or promote products derived from
2710259SAndrew.Bardsley@arm.com// this software without specific prior written permission.
2810259SAndrew.Bardsley@arm.com//
2910259SAndrew.Bardsley@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3010259SAndrew.Bardsley@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3110259SAndrew.Bardsley@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3210259SAndrew.Bardsley@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3310259SAndrew.Bardsley@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3410259SAndrew.Bardsley@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3510259SAndrew.Bardsley@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3610259SAndrew.Bardsley@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3710259SAndrew.Bardsley@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3810259SAndrew.Bardsley@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3910259SAndrew.Bardsley@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4010259SAndrew.Bardsley@arm.com//
4110259SAndrew.Bardsley@arm.com// Authors: Stephen Hines
4210259SAndrew.Bardsley@arm.com//          Gabe Black
4310259SAndrew.Bardsley@arm.com
4410259SAndrew.Bardsley@arm.com////////////////////////////////////////////////////////////////////
4510259SAndrew.Bardsley@arm.com//
4610259SAndrew.Bardsley@arm.com// Load/store microops
4710259SAndrew.Bardsley@arm.com//
4810259SAndrew.Bardsley@arm.com
4910259SAndrew.Bardsley@arm.comlet {{
5010259SAndrew.Bardsley@arm.com    microLdrUopCode = "IWRa = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
5110259SAndrew.Bardsley@arm.com    microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
5210259SAndrew.Bardsley@arm.com                                   'MicroMemOp',
5310259SAndrew.Bardsley@arm.com                                   {'memacc_code': microLdrUopCode,
5410259SAndrew.Bardsley@arm.com                                    'ea_code': 'EA = URb + (up ? imm : -imm);',
5510259SAndrew.Bardsley@arm.com                                    'predicate_test': predicateTest},
5610259SAndrew.Bardsley@arm.com                                   ['IsMicroop'])
5710259SAndrew.Bardsley@arm.com
5810259SAndrew.Bardsley@arm.com    microLdr2UopCode = '''
5910259SAndrew.Bardsley@arm.com                        uint64_t data = Mem_ud;
6010259SAndrew.Bardsley@arm.com                        Dest = cSwap((uint32_t) data, ((CPSR)Cpsr).e);
6110259SAndrew.Bardsley@arm.com                        IWDest2 = cSwap((uint32_t) (data >> 32),
6210259SAndrew.Bardsley@arm.com                                        ((CPSR)Cpsr).e);
6310259SAndrew.Bardsley@arm.com                        '''
6410259SAndrew.Bardsley@arm.com    microLdr2UopIop = InstObjParams('ldr2_uop', 'MicroLdr2Uop',
6510259SAndrew.Bardsley@arm.com                                   'MicroMemPairOp',
6610259SAndrew.Bardsley@arm.com                                   {'memacc_code': microLdr2UopCode,
6710259SAndrew.Bardsley@arm.com                                    'ea_code': 'EA = URb + (up ? imm : -imm);',
6810259SAndrew.Bardsley@arm.com                                    'predicate_test': predicateTest},
6910259SAndrew.Bardsley@arm.com                                   ['IsMicroop'])
7010259SAndrew.Bardsley@arm.com
7110259SAndrew.Bardsley@arm.com    microLdrFpUopCode = "Fa_uw = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
7210259SAndrew.Bardsley@arm.com    microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
7310259SAndrew.Bardsley@arm.com                                      'MicroMemOp',
7410259SAndrew.Bardsley@arm.com                                      {'memacc_code': microLdrFpUopCode,
7510259SAndrew.Bardsley@arm.com                                       'ea_code': vfpEnabledCheckCode +
7610259SAndrew.Bardsley@arm.com                                           'EA = URb + (up ? imm : -imm);',
7710259SAndrew.Bardsley@arm.com                                       'predicate_test': predicateTest},
7810259SAndrew.Bardsley@arm.com                                      ['IsMicroop'])
7910259SAndrew.Bardsley@arm.com
8010259SAndrew.Bardsley@arm.com    microLdrDBFpUopCode = "Fa_uw = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
8110259SAndrew.Bardsley@arm.com    microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop',
8210259SAndrew.Bardsley@arm.com                                      'MicroMemOp',
8310259SAndrew.Bardsley@arm.com                                      {'memacc_code': microLdrFpUopCode,
8410259SAndrew.Bardsley@arm.com                                       'ea_code': vfpEnabledCheckCode + '''
8510259SAndrew.Bardsley@arm.com                                        EA = URb + (up ? imm : -imm) +
8610259SAndrew.Bardsley@arm.com                                             (((CPSR)Cpsr).e ? 4 : 0);
8710259SAndrew.Bardsley@arm.com                                        ''',
8810259SAndrew.Bardsley@arm.com                                       'predicate_test': predicateTest},
8910259SAndrew.Bardsley@arm.com                                      ['IsMicroop'])
9010259SAndrew.Bardsley@arm.com
9110259SAndrew.Bardsley@arm.com    microLdrDTFpUopCode = "Fa_uw = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
9210259SAndrew.Bardsley@arm.com    microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop',
9310259SAndrew.Bardsley@arm.com                                      'MicroMemOp',
9410259SAndrew.Bardsley@arm.com                                      {'memacc_code': microLdrFpUopCode,
9510259SAndrew.Bardsley@arm.com                                       'ea_code': vfpEnabledCheckCode + '''
9610259SAndrew.Bardsley@arm.com                                        EA = URb + (up ? imm : -imm) -
9710259SAndrew.Bardsley@arm.com                                             (((CPSR)Cpsr).e ? 4 : 0);
9810259SAndrew.Bardsley@arm.com                                        ''',
9910259SAndrew.Bardsley@arm.com                                       'predicate_test': predicateTest},
10010259SAndrew.Bardsley@arm.com                                      ['IsMicroop'])
10110259SAndrew.Bardsley@arm.com
10210259SAndrew.Bardsley@arm.com    microRetUopCode = '''
10310259SAndrew.Bardsley@arm.com        CPSR old_cpsr = Cpsr;
10410259SAndrew.Bardsley@arm.com        SCTLR sctlr = Sctlr;
10510259SAndrew.Bardsley@arm.com
10610259SAndrew.Bardsley@arm.com        CPSR new_cpsr =
10710259SAndrew.Bardsley@arm.com            cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF, true,
10810259SAndrew.Bardsley@arm.com                             sctlr.nmfi, xc->tcBase());
10910259SAndrew.Bardsley@arm.com        Cpsr = ~CondCodesMask & new_cpsr;
11010259SAndrew.Bardsley@arm.com        CondCodesNZ = new_cpsr.nz;
11110259SAndrew.Bardsley@arm.com        CondCodesC = new_cpsr.c;
11210259SAndrew.Bardsley@arm.com        CondCodesV = new_cpsr.v;
11310259SAndrew.Bardsley@arm.com        CondCodesGE = new_cpsr.ge;
11410259SAndrew.Bardsley@arm.com        IWNPC = cSwap(%s, old_cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
11510259SAndrew.Bardsley@arm.com        NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
11610259SAndrew.Bardsley@arm.com                | (((CPSR)Spsr).it1 & 0x3);
11710259SAndrew.Bardsley@arm.com        SevMailbox = 1;
11810259SAndrew.Bardsley@arm.com    '''
11910259SAndrew.Bardsley@arm.com
12010259SAndrew.Bardsley@arm.com    microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
12110259SAndrew.Bardsley@arm.com                                      'MicroMemOp',
12210259SAndrew.Bardsley@arm.com                                      {'memacc_code':
12310259SAndrew.Bardsley@arm.com                                          microRetUopCode % 'Mem_uw',
12410259SAndrew.Bardsley@arm.com                                       'ea_code':
12510259SAndrew.Bardsley@arm.com                                          'EA = URb + (up ? imm : -imm);',
12610259SAndrew.Bardsley@arm.com                                       'predicate_test': condPredicateTest},
12710259SAndrew.Bardsley@arm.com                                      ['IsMicroop','IsNonSpeculative',
12810259SAndrew.Bardsley@arm.com                                       'IsSerializeAfter', 'IsSquashAfter'])
12910259SAndrew.Bardsley@arm.com
13010259SAndrew.Bardsley@arm.com    microStrUopCode = "Mem = cSwap(URa_uw, ((CPSR)Cpsr).e);"
13110259SAndrew.Bardsley@arm.com    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
13210259SAndrew.Bardsley@arm.com                                   'MicroMemOp',
13310259SAndrew.Bardsley@arm.com                                   {'memacc_code': microStrUopCode,
13410259SAndrew.Bardsley@arm.com                                    'postacc_code': "",
13510259SAndrew.Bardsley@arm.com                                    'ea_code': 'EA = URb + (up ? imm : -imm);',
13610259SAndrew.Bardsley@arm.com                                    'predicate_test': predicateTest},
13710259SAndrew.Bardsley@arm.com                                   ['IsMicroop'])
13810259SAndrew.Bardsley@arm.com
13910259SAndrew.Bardsley@arm.com    microStrFpUopCode = "Mem = cSwap(Fa_uw, ((CPSR)Cpsr).e);"
14010259SAndrew.Bardsley@arm.com    microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop',
14110259SAndrew.Bardsley@arm.com                                     'MicroMemOp',
14210259SAndrew.Bardsley@arm.com                                     {'memacc_code': microStrFpUopCode,
14310259SAndrew.Bardsley@arm.com                                      'postacc_code': "",
14410259SAndrew.Bardsley@arm.com                                      'ea_code': vfpEnabledCheckCode +
14510259SAndrew.Bardsley@arm.com                                           'EA = URb + (up ? imm : -imm);',
14610259SAndrew.Bardsley@arm.com                                      'predicate_test': predicateTest},
14710259SAndrew.Bardsley@arm.com                                     ['IsMicroop'])
14810259SAndrew.Bardsley@arm.com
14910259SAndrew.Bardsley@arm.com    microStrDBFpUopCode = "Mem = cSwap(Fa_uw, ((CPSR)Cpsr).e);"
15010259SAndrew.Bardsley@arm.com    microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop',
15110259SAndrew.Bardsley@arm.com                                       'MicroMemOp',
15210259SAndrew.Bardsley@arm.com                                       {'memacc_code': microStrFpUopCode,
15310259SAndrew.Bardsley@arm.com                                        'postacc_code': "",
15410259SAndrew.Bardsley@arm.com                                        'ea_code': vfpEnabledCheckCode + '''
15510259SAndrew.Bardsley@arm.com                                         EA = URb + (up ? imm : -imm) +
15610259SAndrew.Bardsley@arm.com                                              (((CPSR)Cpsr).e ? 4 : 0);
15710259SAndrew.Bardsley@arm.com                                         ''',
15810259SAndrew.Bardsley@arm.com                                        'predicate_test': predicateTest},
15910259SAndrew.Bardsley@arm.com                                       ['IsMicroop'])
16010259SAndrew.Bardsley@arm.com
16110259SAndrew.Bardsley@arm.com    microStrDTFpUopCode = "Mem = cSwap(Fa_uw, ((CPSR)Cpsr).e);"
16210259SAndrew.Bardsley@arm.com    microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop',
16310259SAndrew.Bardsley@arm.com                                       'MicroMemOp',
16410259SAndrew.Bardsley@arm.com                                       {'memacc_code': microStrFpUopCode,
16510259SAndrew.Bardsley@arm.com                                        'postacc_code': "",
16610259SAndrew.Bardsley@arm.com                                        'ea_code': vfpEnabledCheckCode + '''
16710259SAndrew.Bardsley@arm.com                                         EA = URb + (up ? imm : -imm) -
16810259SAndrew.Bardsley@arm.com                                              (((CPSR)Cpsr).e ? 4 : 0);
16910259SAndrew.Bardsley@arm.com                                         ''',
17010259SAndrew.Bardsley@arm.com                                        'predicate_test': predicateTest},
17110259SAndrew.Bardsley@arm.com                                       ['IsMicroop'])
17210259SAndrew.Bardsley@arm.com
17310259SAndrew.Bardsley@arm.com    header_output = decoder_output = exec_output = ''
17410259SAndrew.Bardsley@arm.com
17510259SAndrew.Bardsley@arm.com    loadIops = (microLdrUopIop, microLdrRetUopIop,
17610259SAndrew.Bardsley@arm.com                microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop)
17710259SAndrew.Bardsley@arm.com    storeIops = (microStrUopIop, microStrFpUopIop,
17810259SAndrew.Bardsley@arm.com                 microStrDBFpUopIop, microStrDTFpUopIop)
17910259SAndrew.Bardsley@arm.com    for iop in loadIops + storeIops:
18010259SAndrew.Bardsley@arm.com        header_output += MicroMemDeclare.subst(iop)
18110259SAndrew.Bardsley@arm.com        decoder_output += MicroMemConstructor.subst(iop)
18210259SAndrew.Bardsley@arm.com    for iop in loadIops:
18310259SAndrew.Bardsley@arm.com        exec_output += LoadExecute.subst(iop) + \
18410259SAndrew.Bardsley@arm.com                       LoadInitiateAcc.subst(iop) + \
18510259SAndrew.Bardsley@arm.com                       LoadCompleteAcc.subst(iop)
18610259SAndrew.Bardsley@arm.com    for iop in storeIops:
18710259SAndrew.Bardsley@arm.com        exec_output += StoreExecute.subst(iop) + \
18810259SAndrew.Bardsley@arm.com                       StoreInitiateAcc.subst(iop) + \
18910259SAndrew.Bardsley@arm.com                       StoreCompleteAcc.subst(iop)
19010259SAndrew.Bardsley@arm.com
19110259SAndrew.Bardsley@arm.com    header_output += MicroMemPairDeclare.subst(microLdr2UopIop)
19210259SAndrew.Bardsley@arm.com    decoder_output += MicroMemPairConstructor.subst(microLdr2UopIop)
19310259SAndrew.Bardsley@arm.com    exec_output += LoadExecute.subst(microLdr2UopIop) + \
19410259SAndrew.Bardsley@arm.com                   LoadInitiateAcc.subst(microLdr2UopIop) + \
19510259SAndrew.Bardsley@arm.com                   LoadCompleteAcc.subst(microLdr2UopIop)
19610259SAndrew.Bardsley@arm.com}};
19710259SAndrew.Bardsley@arm.com
19810259SAndrew.Bardsley@arm.comlet {{
19910259SAndrew.Bardsley@arm.com    exec_output = header_output = ''
20010259SAndrew.Bardsley@arm.com
20110259SAndrew.Bardsley@arm.com    eaCode = 'EA = XURa + imm;'
20210259SAndrew.Bardsley@arm.com
20310259SAndrew.Bardsley@arm.com    for size in (1, 2, 3, 4, 6, 8, 12, 16):
20410259SAndrew.Bardsley@arm.com        # Set up the memory access.
20513954Sgiacomo.gabrielli@arm.com        regs = (size + 3) // 4
20613954Sgiacomo.gabrielli@arm.com        subst = { "size" : size, "regs" : regs }
20713954Sgiacomo.gabrielli@arm.com        memDecl = '''
20813954Sgiacomo.gabrielli@arm.com        union MemUnion {
20913954Sgiacomo.gabrielli@arm.com            uint8_t bytes[%(size)d];
21013954Sgiacomo.gabrielli@arm.com            Element elements[%(size)d / sizeof(Element)];
21113954Sgiacomo.gabrielli@arm.com            uint32_t floatRegBits[%(regs)d];
21210259SAndrew.Bardsley@arm.com        };
21310259SAndrew.Bardsley@arm.com        ''' % subst
21410259SAndrew.Bardsley@arm.com
21510259SAndrew.Bardsley@arm.com        # Do endian conversion for all the elements.
21610259SAndrew.Bardsley@arm.com        convCode = '''
21710259SAndrew.Bardsley@arm.com            const unsigned eCount = sizeof(memUnion.elements) /
21810259SAndrew.Bardsley@arm.com                                    sizeof(memUnion.elements[0]);
21910259SAndrew.Bardsley@arm.com            if (((CPSR)Cpsr).e) {
22010259SAndrew.Bardsley@arm.com                for (unsigned i = 0; i < eCount; i++) {
22110259SAndrew.Bardsley@arm.com                    memUnion.elements[i] = gtobe(memUnion.elements[i]);
22210259SAndrew.Bardsley@arm.com                }
22310259SAndrew.Bardsley@arm.com            } else {
22410259SAndrew.Bardsley@arm.com                for (unsigned i = 0; i < eCount; i++) {
22510259SAndrew.Bardsley@arm.com                    memUnion.elements[i] = gtole(memUnion.elements[i]);
22610259SAndrew.Bardsley@arm.com                }
22710259SAndrew.Bardsley@arm.com            }
22810259SAndrew.Bardsley@arm.com        '''
22912104Snathanael.premillieu@arm.com
23010259SAndrew.Bardsley@arm.com        # Offload everything into registers
23110259SAndrew.Bardsley@arm.com        regSetCode = ''
23210259SAndrew.Bardsley@arm.com        for reg in range(regs):
23310259SAndrew.Bardsley@arm.com            mask = ''
23410259SAndrew.Bardsley@arm.com            if reg == regs - 1:
23510259SAndrew.Bardsley@arm.com                mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size))
23610259SAndrew.Bardsley@arm.com            regSetCode += '''
23713954Sgiacomo.gabrielli@arm.com            FpDestP%(reg)d_uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s;
23810259SAndrew.Bardsley@arm.com            ''' % { "reg" : reg, "mask" : mask }
23912420Sgabeblack@google.com
24010259SAndrew.Bardsley@arm.com        # Pull everything in from registers
24110259SAndrew.Bardsley@arm.com        regGetCode = ''
24210259SAndrew.Bardsley@arm.com        for reg in range(regs):
24310259SAndrew.Bardsley@arm.com            regGetCode += '''
24410259SAndrew.Bardsley@arm.com            memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d_uw);
24510259SAndrew.Bardsley@arm.com            ''' % { "reg" : reg }
24610259SAndrew.Bardsley@arm.com
24710259SAndrew.Bardsley@arm.com        loadMemAccCode = convCode + regSetCode
24810259SAndrew.Bardsley@arm.com        storeMemAccCode = regGetCode + convCode
24910259SAndrew.Bardsley@arm.com
25010259SAndrew.Bardsley@arm.com        loadIop = InstObjParams('ldrneon%(size)d_uop' % subst,
25110259SAndrew.Bardsley@arm.com                                'MicroLdrNeon%(size)dUop' % subst,
25210259SAndrew.Bardsley@arm.com                                'MicroNeonMemOp',
25310259SAndrew.Bardsley@arm.com                                { 'mem_decl' : memDecl,
25410259SAndrew.Bardsley@arm.com                                  'size' : size,
25510259SAndrew.Bardsley@arm.com                                  'memacc_code' : loadMemAccCode,
25610259SAndrew.Bardsley@arm.com                                  'ea_code' : simdEnabledCheckCode + eaCode,
25710259SAndrew.Bardsley@arm.com                                  'predicate_test' : predicateTest },
25810259SAndrew.Bardsley@arm.com                                [ 'IsMicroop', 'IsMemRef', 'IsLoad' ])
25910259SAndrew.Bardsley@arm.com        storeIop = InstObjParams('strneon%(size)d_uop' % subst,
26010259SAndrew.Bardsley@arm.com                                 'MicroStrNeon%(size)dUop' % subst,
26110259SAndrew.Bardsley@arm.com                                 'MicroNeonMemOp',
26210259SAndrew.Bardsley@arm.com                                 { 'mem_decl' : memDecl,
26310259SAndrew.Bardsley@arm.com                                   'size' : size,
26410259SAndrew.Bardsley@arm.com                                   'memacc_code' : storeMemAccCode,
26510259SAndrew.Bardsley@arm.com                                   'ea_code' : simdEnabledCheckCode + eaCode,
26610259SAndrew.Bardsley@arm.com                                   'predicate_test' : predicateTest },
26710259SAndrew.Bardsley@arm.com                                 [ 'IsMicroop', 'IsMemRef', 'IsStore' ])
26810259SAndrew.Bardsley@arm.com
26910259SAndrew.Bardsley@arm.com        exec_output += NeonLoadExecute.subst(loadIop) + \
27010259SAndrew.Bardsley@arm.com                       NeonLoadInitiateAcc.subst(loadIop) + \
27110259SAndrew.Bardsley@arm.com                       NeonLoadCompleteAcc.subst(loadIop) + \
27210259SAndrew.Bardsley@arm.com                       NeonStoreExecute.subst(storeIop) + \
27310259SAndrew.Bardsley@arm.com                       NeonStoreInitiateAcc.subst(storeIop) + \
27410259SAndrew.Bardsley@arm.com                       NeonStoreCompleteAcc.subst(storeIop)
27510259SAndrew.Bardsley@arm.com        header_output += MicroNeonMemDeclare.subst(loadIop) + \
27613954Sgiacomo.gabrielli@arm.com                         MicroNeonMemDeclare.subst(storeIop)
27713954Sgiacomo.gabrielli@arm.com}};
27813954Sgiacomo.gabrielli@arm.com
27913954Sgiacomo.gabrielli@arm.comlet {{
28013954Sgiacomo.gabrielli@arm.com    exec_output = ''
28113954Sgiacomo.gabrielli@arm.com    for eSize, type in (1, 'uint8_t'), \
28213954Sgiacomo.gabrielli@arm.com                       (2, 'uint16_t'), \
28313954Sgiacomo.gabrielli@arm.com                       (4, 'uint32_t'), \
28410259SAndrew.Bardsley@arm.com                       (8, 'uint64_t'):
28510259SAndrew.Bardsley@arm.com        size = eSize
28610259SAndrew.Bardsley@arm.com        # An instruction handles no more than 16 bytes and no more than
28710259SAndrew.Bardsley@arm.com        # 4 elements, or the number of elements needed to fill 8 or 16 bytes.
28810259SAndrew.Bardsley@arm.com        sizes = set((16, 8))
28910259SAndrew.Bardsley@arm.com        for count in 1, 2, 3, 4:
29010259SAndrew.Bardsley@arm.com            size = count * eSize
29110259SAndrew.Bardsley@arm.com            if size <= 16:
29210259SAndrew.Bardsley@arm.com                sizes.add(size)
293        for size in sizes:
294            substDict = {
295                "class_name" : "MicroLdrNeon%dUop" % size,
296                "targs" : type
297            }
298            exec_output += MicroNeonMemExecDeclare.subst(substDict)
299            substDict["class_name"] = "MicroStrNeon%dUop" % size
300            exec_output += MicroNeonMemExecDeclare.subst(substDict)
301            size += eSize
302}};
303
304////////////////////////////////////////////////////////////////////
305//
306// Neon (de)interlacing microops
307//
308
309let {{
310    header_output = exec_output = ''
311    for dRegs in (2, 3, 4):
312        loadConv = ''
313        unloadConv = ''
314        for dReg in range(dRegs):
315            loadConv += '''
316                conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d_uw);
317                conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d_uw);
318            ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
319            unloadConv += '''
320                FpDestS%(dReg)dP0_uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]);
321                FpDestS%(dReg)dP1_uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]);
322            ''' % { "dReg" : dReg }
323        microDeintNeonCode = '''
324            const unsigned dRegs = %(dRegs)d;
325            const unsigned regs = 2 * dRegs;
326            const unsigned perDReg =
327                (2 * sizeof(uint32_t)) / sizeof(Element);
328            union convStruct {
329                uint32_t cRegs[regs];
330                Element elements[dRegs * perDReg];
331            } conv1, conv2;
332
333            %(loadConv)s
334
335            unsigned srcElem = 0;
336            for (unsigned destOffset = 0;
337                    destOffset < perDReg; destOffset++) {
338                for (unsigned dReg = 0; dReg < dRegs; dReg++) {
339                    conv2.elements[dReg * perDReg + destOffset] =
340                        conv1.elements[srcElem++];
341                }
342            }
343
344            %(unloadConv)s
345        ''' % { "dRegs" : dRegs,
346                "loadConv" : loadConv,
347                "unloadConv" : unloadConv }
348        microDeintNeonIop = \
349            InstObjParams('deintneon%duop' % (dRegs * 2),
350                          'MicroDeintNeon%dUop' % (dRegs * 2),
351                          'MicroNeonMixOp',
352                          { 'predicate_test': predicateTest,
353                            'code' : microDeintNeonCode },
354                            ['IsMicroop'])
355        header_output += MicroNeonMixDeclare.subst(microDeintNeonIop)
356        exec_output += MicroNeonMixExecute.subst(microDeintNeonIop)
357
358        loadConv = ''
359        unloadConv = ''
360        for dReg in range(dRegs):
361            loadConv += '''
362                conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0_uw);
363                conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1_uw);
364            ''' % { "dReg" : dReg }
365            unloadConv += '''
366                FpDestP%(sReg0)d_uw = gtoh(conv2.cRegs[%(sReg0)d]);
367                FpDestP%(sReg1)d_uw = gtoh(conv2.cRegs[%(sReg1)d]);
368            ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
369        microInterNeonCode = '''
370            const unsigned dRegs = %(dRegs)d;
371            const unsigned regs = 2 * dRegs;
372            const unsigned perDReg =
373                (2 * sizeof(uint32_t)) / sizeof(Element);
374            union convStruct {
375                uint32_t cRegs[regs];
376                Element elements[dRegs * perDReg];
377            } conv1, conv2;
378
379            %(loadConv)s
380
381            unsigned destElem = 0;
382            for (unsigned srcOffset = 0;
383                    srcOffset < perDReg; srcOffset++) {
384                for (unsigned dReg = 0; dReg < dRegs; dReg++) {
385                    conv2.elements[destElem++] =
386                        conv1.elements[dReg * perDReg + srcOffset];
387                }
388            }
389
390            %(unloadConv)s
391        ''' % { "dRegs" : dRegs,
392                "loadConv" : loadConv,
393                "unloadConv" : unloadConv }
394        microInterNeonIop = \
395            InstObjParams('interneon%duop' % (dRegs * 2),
396                          'MicroInterNeon%dUop' % (dRegs * 2),
397                          'MicroNeonMixOp',
398                          { 'predicate_test': predicateTest,
399                            'code' : microInterNeonCode },
400                            ['IsMicroop'])
401        header_output += MicroNeonMixDeclare.subst(microInterNeonIop)
402        exec_output += MicroNeonMixExecute.subst(microInterNeonIop)
403}};
404
405let {{
406    exec_output = ''
407    for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
408        for dRegs in (2, 3, 4):
409            Name = "MicroDeintNeon%dUop" % (dRegs * 2)
410            substDict = { "class_name" : Name, "targs" : type }
411            exec_output += MicroNeonExecDeclare.subst(substDict)
412            Name = "MicroInterNeon%dUop" % (dRegs * 2)
413            substDict = { "class_name" : Name, "targs" : type }
414            exec_output += MicroNeonExecDeclare.subst(substDict)
415}};
416
417////////////////////////////////////////////////////////////////////
418//
419// Neon microops to pack/unpack a single lane
420//
421
422let {{
423    header_output = exec_output = ''
424    for sRegs in 1, 2:
425        baseLoadRegs = ''
426        for reg in range(sRegs):
427            baseLoadRegs += '''
428                sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d_uw);
429                sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d_uw);
430            ''' % { "reg0" : (2 * reg + 0),
431                    "reg1" : (2 * reg + 1) }
432        for dRegs in range(sRegs, 5):
433            unloadRegs = ''
434            loadRegs = baseLoadRegs
435            for reg in range(dRegs):
436                loadRegs += '''
437                    destRegs[%(reg)d].fRegs[0] = htog(FpDestS%(reg)dP0_uw);
438                    destRegs[%(reg)d].fRegs[1] = htog(FpDestS%(reg)dP1_uw);
439                ''' % { "reg" : reg }
440                unloadRegs += '''
441                    FpDestS%(reg)dP0_uw = gtoh(destRegs[%(reg)d].fRegs[0]);
442                    FpDestS%(reg)dP1_uw = gtoh(destRegs[%(reg)d].fRegs[1]);
443                ''' % { "reg" : reg }
444            microUnpackNeonCode = '''
445            const unsigned perDReg = (2 * sizeof(uint32_t)) / sizeof(Element);
446
447            union SourceRegs {
448                uint32_t fRegs[2 * %(sRegs)d];
449                Element elements[%(sRegs)d * perDReg];
450            } sourceRegs;
451
452            union DestReg {
453                uint32_t fRegs[2];
454                Element elements[perDReg];
455            } destRegs[%(dRegs)d];
456
457            %(loadRegs)s
458
459            for (unsigned i = 0; i < %(dRegs)d; i++) {
460                destRegs[i].elements[lane] = sourceRegs.elements[i];
461            }
462
463            %(unloadRegs)s
464            ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
465                    "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
466
467            microUnpackNeonIop = \
468                InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2),
469                              'MicroUnpackNeon%dto%dUop' %
470                                    (sRegs * 2, dRegs * 2),
471                              'MicroNeonMixLaneOp',
472                              { 'predicate_test': predicateTest,
473                                'code' : microUnpackNeonCode },
474                                ['IsMicroop'])
475            header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop)
476            exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop)
477
478    for sRegs in 1, 2:
479        loadRegs = ''
480        for reg in range(sRegs):
481            loadRegs += '''
482                sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d_uw);
483                sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d_uw);
484            ''' % { "reg0" : (2 * reg + 0),
485                    "reg1" : (2 * reg + 1) }
486        for dRegs in range(sRegs, 5):
487            unloadRegs = ''
488            for reg in range(dRegs):
489                unloadRegs += '''
490                    FpDestS%(reg)dP0_uw = gtoh(destRegs[%(reg)d].fRegs[0]);
491                    FpDestS%(reg)dP1_uw = gtoh(destRegs[%(reg)d].fRegs[1]);
492                ''' % { "reg" : reg }
493            microUnpackAllNeonCode = '''
494            const unsigned perDReg = (2 * sizeof(uint32_t)) / sizeof(Element);
495
496            union SourceRegs {
497                uint32_t fRegs[2 * %(sRegs)d];
498                Element elements[%(sRegs)d * perDReg];
499            } sourceRegs;
500
501            union DestReg {
502                uint32_t fRegs[2];
503                Element elements[perDReg];
504            } destRegs[%(dRegs)d];
505
506            %(loadRegs)s
507
508            for (unsigned i = 0; i < %(dRegs)d; i++) {
509                for (unsigned j = 0; j < perDReg; j++)
510                    destRegs[i].elements[j] = sourceRegs.elements[i];
511            }
512
513            %(unloadRegs)s
514            ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
515                    "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
516
517            microUnpackAllNeonIop = \
518                InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2),
519                              'MicroUnpackAllNeon%dto%dUop' %
520                                    (sRegs * 2, dRegs * 2),
521                              'MicroNeonMixOp',
522                              { 'predicate_test': predicateTest,
523                                'code' : microUnpackAllNeonCode },
524                                ['IsMicroop'])
525            header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop)
526            exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop)
527
528    for dRegs in 1, 2:
529        unloadRegs = ''
530        for reg in range(dRegs):
531            unloadRegs += '''
532                FpDestP%(reg0)d_uw = gtoh(destRegs.fRegs[%(reg0)d]);
533                FpDestP%(reg1)d_uw = gtoh(destRegs.fRegs[%(reg1)d]);
534            ''' % { "reg0" : (2 * reg + 0),
535                    "reg1" : (2 * reg + 1) }
536        for sRegs in range(dRegs, 5):
537            loadRegs = ''
538            for reg in range(sRegs):
539                loadRegs += '''
540                    sourceRegs[%(reg)d].fRegs[0] = htog(FpOp1S%(reg)dP0_uw);
541                    sourceRegs[%(reg)d].fRegs[1] = htog(FpOp1S%(reg)dP1_uw);
542                ''' % { "reg" : reg }
543            microPackNeonCode = '''
544            const unsigned perDReg =
545                (2 * sizeof(uint32_t)) / sizeof(Element);
546
547            union SourceReg {
548                uint32_t fRegs[2];
549                Element elements[perDReg];
550            } sourceRegs[%(sRegs)d];
551
552            union DestRegs {
553                uint32_t fRegs[2 * %(dRegs)d];
554                Element elements[%(dRegs)d * perDReg];
555            } destRegs;
556
557            %(loadRegs)s
558
559            for (unsigned i = 0; i < %(sRegs)d; i++) {
560                destRegs.elements[i] = sourceRegs[i].elements[lane];
561            }
562            for (unsigned i = %(sRegs)d; i < %(dRegs)d * perDReg; ++i) {
563                destRegs.elements[i] = 0;
564            }
565
566            %(unloadRegs)s
567            ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
568                    "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
569
570            microPackNeonIop = \
571                InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2),
572                              'MicroPackNeon%dto%dUop' %
573                                    (sRegs * 2, dRegs * 2),
574                              'MicroNeonMixLaneOp',
575                              { 'predicate_test': predicateTest,
576                                'code' : microPackNeonCode },
577                                ['IsMicroop'])
578            header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop)
579            exec_output += MicroNeonMixExecute.subst(microPackNeonIop)
580}};
581
582let {{
583    exec_output = ''
584    for typeSize in (8, 16, 32):
585        for sRegs in 1, 2:
586            for dRegs in range(sRegs, min(sRegs * 64 / typeSize + 1, 5)):
587                for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop",
588                               "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop",
589                               "MicroPackNeon%(dRegs)dto%(sRegs)dUop"):
590                    Name = format % { "sRegs" : sRegs * 2,
591                                      "dRegs" : dRegs * 2 }
592                    substDict = { "class_name" : Name,
593                                  "targs" : "uint%d_t" % typeSize }
594                    exec_output += MicroNeonExecDeclare.subst(substDict)
595}};
596
597////////////////////////////////////////////////////////////////////
598//
599// Integer = Integer op Immediate microops
600//
601
602let {{
603    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
604                                    'MicroIntImmOp',
605                                    {'code': 'URa = URb + imm;',
606                                     'predicate_test': predicateTest},
607                                    ['IsMicroop'])
608
609    microAddUopCode = '''
610        URa = URb + shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC);
611    '''
612
613    microAddXiUopIop = InstObjParams('addxi_uop', 'MicroAddXiUop',
614                                     'MicroIntImmXOp',
615                                     'XURa = XURb + imm;',
616                                     ['IsMicroop'])
617
618    microAddXiSpAlignUopIop = InstObjParams('addxi_uop', 'MicroAddXiSpAlignUop',
619                                            'MicroIntImmXOp', '''
620        if (isSP((IntRegIndex) urb) && bits(XURb, 3, 0) &&
621            SPAlignmentCheckEnabled(xc->tcBase())) {
622            return std::make_shared<SPAlignmentFault>();
623        }
624        XURa = XURb + imm;
625    ''', ['IsMicroop'])
626
627    microAddXERegUopIop = InstObjParams('addxr_uop', 'MicroAddXERegUop',
628                                        'MicroIntRegXOp',
629                                        'XURa = XURb + ' + \
630                                            'extendReg64(XURc, type, shiftAmt, 64);',
631                                        ['IsMicroop'])
632
633    microAddUopIop = InstObjParams('add_uop', 'MicroAddUop',
634                                   'MicroIntRegOp',
635                                   {'code': microAddUopCode,
636                                    'predicate_test': pickPredicate(microAddUopCode)},
637                                   ['IsMicroop'])
638
639    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
640                                    'MicroIntImmOp',
641                                    {'code': 'URa = URb - imm;',
642                                     'predicate_test': predicateTest},
643                                    ['IsMicroop'])
644
645    microSubXiUopIop = InstObjParams('subxi_uop', 'MicroSubXiUop',
646                                     'MicroIntImmXOp',
647                                     'XURa = XURb - imm;',
648                                     ['IsMicroop'])
649
650    microSubUopCode = '''
651        URa = URb - shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC);
652    '''
653    microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop',
654                                   'MicroIntRegOp',
655                                   {'code': microSubUopCode,
656                                    'predicate_test': pickPredicate(microSubUopCode)},
657                                   ['IsMicroop'])
658
659    microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov',
660                                   'MicroIntMov',
661                                   {'code': 'IWRa = URb;',
662                                    'predicate_test': predicateTest},
663                                   ['IsMicroop'])
664
665    microUopRegMovRetIop = InstObjParams('movret_uop', 'MicroUopRegMovRet',
666                                      'MicroIntMov',
667                                     {'code': microRetUopCode % 'URb',
668                                      'predicate_test': predicateTest},
669                                     ['IsMicroop', 'IsNonSpeculative',
670                                      'IsSerializeAfter', 'IsSquashAfter'])
671
672    setPCCPSRDecl = '''
673                    CPSR cpsrOrCondCodes = URc;
674                    SCTLR sctlr = Sctlr;
675                    pNPC = URa;
676                    CPSR new_cpsr =
677                    cpsrWriteByInstr(cpsrOrCondCodes, URb, Scr, Nsacr,
678                                     0xF, true, sctlr.nmfi, xc->tcBase());
679                    Cpsr = ~CondCodesMask & new_cpsr;
680                    NextThumb = new_cpsr.t;
681                    NextJazelle = new_cpsr.j;
682                    NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
683                                    | (((CPSR)URb).it1 & 0x3);
684                    CondCodesNZ = new_cpsr.nz;
685                    CondCodesC = new_cpsr.c;
686                    CondCodesV = new_cpsr.v;
687                    CondCodesGE = new_cpsr.ge;
688                    '''
689
690    microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',
691                                         'MicroSetPCCPSR',
692                                         {'code': setPCCPSRDecl,
693                                          'predicate_test': predicateTest},
694                                         ['IsMicroop'])
695
696    header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \
697                    MicroIntImmDeclare.subst(microAddXiUopIop) + \
698                    MicroIntImmDeclare.subst(microAddXiSpAlignUopIop) + \
699                    MicroIntImmDeclare.subst(microSubiUopIop) + \
700                    MicroIntImmDeclare.subst(microSubXiUopIop) + \
701                    MicroIntRegDeclare.subst(microAddUopIop) + \
702                    MicroIntRegDeclare.subst(microSubUopIop) + \
703                    MicroIntXERegDeclare.subst(microAddXERegUopIop) + \
704                    MicroIntMovDeclare.subst(microUopRegMovIop) + \
705                    MicroIntMovDeclare.subst(microUopRegMovRetIop) + \
706                    MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop)
707
708    decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \
709                     MicroIntImmXConstructor.subst(microAddXiUopIop) + \
710                     MicroIntImmXConstructor.subst(microAddXiSpAlignUopIop) + \
711                     MicroIntImmConstructor.subst(microSubiUopIop) + \
712                     MicroIntImmXConstructor.subst(microSubXiUopIop) + \
713                     MicroIntRegConstructor.subst(microAddUopIop) + \
714                     MicroIntRegConstructor.subst(microSubUopIop) + \
715                     MicroIntXERegConstructor.subst(microAddXERegUopIop) + \
716                     MicroIntMovConstructor.subst(microUopRegMovIop) + \
717                     MicroIntMovConstructor.subst(microUopRegMovRetIop) + \
718                     MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop)
719
720    exec_output = PredOpExecute.subst(microAddiUopIop) + \
721                  BasicExecute.subst(microAddXiUopIop) + \
722                  BasicExecute.subst(microAddXiSpAlignUopIop) + \
723                  PredOpExecute.subst(microSubiUopIop) + \
724                  BasicExecute.subst(microSubXiUopIop) + \
725                  PredOpExecute.subst(microAddUopIop) + \
726                  PredOpExecute.subst(microSubUopIop) + \
727                  BasicExecute.subst(microAddXERegUopIop) + \
728                  PredOpExecute.subst(microUopRegMovIop) + \
729                  PredOpExecute.subst(microUopRegMovRetIop) + \
730                  PredOpExecute.subst(microUopSetPCCPSRIop)
731
732}};
733
734let {{
735    iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", [])
736    header_output = MacroMemDeclare.subst(iop)
737    decoder_output = MacroMemConstructor.subst(iop)
738
739    iop = InstObjParams("ldpstp", "LdpStp", 'PairMemOp', "", [])
740    header_output += PairMemDeclare.subst(iop)
741    decoder_output += PairMemConstructor.subst(iop)
742
743    iopImm = InstObjParams("bigfpmemimm", "BigFpMemImm", "BigFpMemImmOp", "")
744    iopPre = InstObjParams("bigfpmempre", "BigFpMemPre", "BigFpMemPreOp", "")
745    iopPost = InstObjParams("bigfpmempost", "BigFpMemPost", "BigFpMemPostOp", "")
746    for iop in (iopImm, iopPre, iopPost):
747        header_output += BigFpMemImmDeclare.subst(iop)
748        decoder_output += BigFpMemImmConstructor.subst(iop)
749
750    iop = InstObjParams("bigfpmemreg", "BigFpMemReg", "BigFpMemRegOp", "")
751    header_output += BigFpMemRegDeclare.subst(iop)
752    decoder_output += BigFpMemRegConstructor.subst(iop)
753
754    iop = InstObjParams("bigfpmemlit", "BigFpMemLit", "BigFpMemLitOp", "")
755    header_output += BigFpMemLitDeclare.subst(iop)
756    decoder_output += BigFpMemLitConstructor.subst(iop)
757
758    iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", [])
759    header_output += VMemMultDeclare.subst(iop)
760    decoder_output += VMemMultConstructor.subst(iop)
761
762    iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", [])
763    header_output += VMemSingleDeclare.subst(iop)
764    decoder_output += VMemSingleConstructor.subst(iop)
765
766    iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", [])
767    header_output += VMemMultDeclare.subst(iop)
768    decoder_output += VMemMultConstructor.subst(iop)
769
770    iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", [])
771    header_output += VMemSingleDeclare.subst(iop)
772    decoder_output += VMemSingleConstructor.subst(iop)
773
774    vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", [])
775    header_output += MacroVFPMemDeclare.subst(vfpIop)
776    decoder_output += MacroVFPMemConstructor.subst(vfpIop)
777}};
778