macromem.isa revision 7797
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42//          Gabe Black
43
44////////////////////////////////////////////////////////////////////
45//
46// Load/store microops
47//
48
49let {{
50    microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
51    microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
52                                   'MicroMemOp',
53                                   {'memacc_code': microLdrUopCode,
54                                    'ea_code': 'EA = Rb + (up ? imm : -imm);',
55                                    'predicate_test': predicateTest},
56                                   ['IsMicroop'])
57
58    microLdrFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
59    microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
60                                      'MicroMemOp',
61                                      {'memacc_code': microLdrFpUopCode,
62                                       'ea_code': vfpEnabledCheckCode +
63                                           'EA = Rb + (up ? imm : -imm);',
64                                       'predicate_test': predicateTest},
65                                      ['IsMicroop'])
66
67    microLdrDBFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
68    microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop',
69                                      'MicroMemOp',
70                                      {'memacc_code': microLdrFpUopCode,
71                                       'ea_code': vfpEnabledCheckCode + '''
72                                        EA = Rb + (up ? imm : -imm) +
73                                             (((CPSR)Cpsr).e ? 4 : 0);
74                                        ''',
75                                       'predicate_test': predicateTest},
76                                      ['IsMicroop'])
77
78    microLdrDTFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
79    microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop',
80                                      'MicroMemOp',
81                                      {'memacc_code': microLdrFpUopCode,
82                                       'ea_code': vfpEnabledCheckCode + '''
83                                        EA = Rb + (up ? imm : -imm) -
84                                             (((CPSR)Cpsr).e ? 4 : 0);
85                                        ''',
86                                       'predicate_test': predicateTest},
87                                      ['IsMicroop'])
88
89    microLdrRetUopCode = '''
90        CPSR cpsr = Cpsr;
91        SCTLR sctlr = Sctlr;
92        uint32_t newCpsr =
93            cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi);
94        Cpsr = ~CondCodesMask & newCpsr;
95        CondCodes = CondCodesMask & newCpsr;
96        IWNPC = cSwap(Mem.uw, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
97    '''
98    microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
99                                      'MicroMemOp',
100                                      {'memacc_code': microLdrRetUopCode,
101                                       'ea_code':
102                                          'EA = Rb + (up ? imm : -imm);',
103                                       'predicate_test': condPredicateTest},
104                                      ['IsMicroop','IsNonSpeculative','IsSerializeAfter'])
105
106    microStrUopCode = "Mem = cSwap(Ra.uw, ((CPSR)Cpsr).e);"
107    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
108                                   'MicroMemOp',
109                                   {'memacc_code': microStrUopCode,
110                                    'postacc_code': "",
111                                    'ea_code': 'EA = Rb + (up ? imm : -imm);',
112                                    'predicate_test': predicateTest},
113                                   ['IsMicroop'])
114
115    microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);"
116    microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop',
117                                     'MicroMemOp',
118                                     {'memacc_code': microStrFpUopCode,
119                                      'postacc_code': "",
120                                      'ea_code': vfpEnabledCheckCode +
121                                           'EA = Rb + (up ? imm : -imm);',
122                                      'predicate_test': predicateTest},
123                                     ['IsMicroop'])
124
125    microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);"
126    microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop',
127                                       'MicroMemOp',
128                                       {'memacc_code': microStrFpUopCode,
129                                        'postacc_code': "",
130                                        'ea_code': vfpEnabledCheckCode + '''
131                                         EA = Rb + (up ? imm : -imm) +
132                                              (((CPSR)Cpsr).e ? 4 : 0);
133                                         ''',
134                                        'predicate_test': predicateTest},
135                                       ['IsMicroop'])
136
137    microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);"
138    microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop',
139                                       'MicroMemOp',
140                                       {'memacc_code': microStrFpUopCode,
141                                        'postacc_code': "",
142                                        'ea_code': vfpEnabledCheckCode + '''
143                                         EA = Rb + (up ? imm : -imm) -
144                                              (((CPSR)Cpsr).e ? 4 : 0);
145                                         ''',
146                                        'predicate_test': predicateTest},
147                                       ['IsMicroop'])
148
149    header_output = decoder_output = exec_output = ''
150
151    loadIops = (microLdrUopIop, microLdrRetUopIop,
152                microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop)
153    storeIops = (microStrUopIop, microStrFpUopIop,
154                 microStrDBFpUopIop, microStrDTFpUopIop)
155    for iop in loadIops + storeIops:
156        header_output += MicroMemDeclare.subst(iop)
157        decoder_output += MicroMemConstructor.subst(iop)
158    for iop in loadIops:
159        exec_output += LoadExecute.subst(iop) + \
160                       LoadInitiateAcc.subst(iop) + \
161                       LoadCompleteAcc.subst(iop)
162    for iop in storeIops:
163        exec_output += StoreExecute.subst(iop) + \
164                       StoreInitiateAcc.subst(iop) + \
165                       StoreCompleteAcc.subst(iop)
166}};
167
168let {{
169    exec_output = header_output = ''
170
171    eaCode = 'EA = Ra + imm;'
172
173    for size in (1, 2, 3, 4, 6, 8, 12, 16):
174        # Set up the memory access.
175        regs = (size + 3) // 4
176        subst = { "size" : size, "regs" : regs }
177        memDecl = '''
178        union MemUnion {
179            uint8_t bytes[%(size)d];
180            Element elements[%(size)d / sizeof(Element)];
181            uint32_t floatRegBits[%(regs)d];
182        };
183        ''' % subst
184
185        # Do endian conversion for all the elements.
186        convCode = '''
187            const unsigned eCount = sizeof(memUnion.elements) /
188                                    sizeof(memUnion.elements[0]);
189            if (((CPSR)Cpsr).e) {
190                for (unsigned i = 0; i < eCount; i++) {
191                    memUnion.elements[i] = gtobe(memUnion.elements[i]);
192                }
193            } else {
194                for (unsigned i = 0; i < eCount; i++) {
195                    memUnion.elements[i] = gtole(memUnion.elements[i]);
196                }
197            }
198        '''
199
200        # Offload everything into registers
201        regSetCode = ''
202        for reg in range(regs):
203            mask = ''
204            if reg == regs - 1:
205                mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size))
206            regSetCode += '''
207            FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s;
208            ''' % { "reg" : reg, "mask" : mask }
209
210        # Pull everything in from registers
211        regGetCode = ''
212        for reg in range(regs):
213            regGetCode += '''
214            memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw);
215            ''' % { "reg" : reg }
216
217        loadMemAccCode = convCode + regSetCode
218        storeMemAccCode = regGetCode + convCode
219
220        loadIop = InstObjParams('ldrneon%(size)d_uop' % subst,
221                                'MicroLdrNeon%(size)dUop' % subst,
222                                'MicroNeonMemOp',
223                                { 'mem_decl' : memDecl,
224                                  'size' : size,
225                                  'memacc_code' : loadMemAccCode,
226                                  'ea_code' : simdEnabledCheckCode + eaCode,
227                                  'predicate_test' : predicateTest },
228                                [ 'IsMicroop', 'IsMemRef', 'IsLoad' ])
229        storeIop = InstObjParams('strneon%(size)d_uop' % subst,
230                                 'MicroStrNeon%(size)dUop' % subst,
231                                 'MicroNeonMemOp',
232                                 { 'mem_decl' : memDecl,
233                                   'size' : size,
234                                   'memacc_code' : storeMemAccCode,
235                                   'ea_code' : simdEnabledCheckCode + eaCode,
236                                   'predicate_test' : predicateTest },
237                                 [ 'IsMicroop', 'IsMemRef', 'IsStore' ])
238
239        exec_output += NeonLoadExecute.subst(loadIop) + \
240                       NeonLoadInitiateAcc.subst(loadIop) + \
241                       NeonLoadCompleteAcc.subst(loadIop) + \
242                       NeonStoreExecute.subst(storeIop) + \
243                       NeonStoreInitiateAcc.subst(storeIop) + \
244                       NeonStoreCompleteAcc.subst(storeIop)
245        header_output += MicroNeonMemDeclare.subst(loadIop) + \
246                         MicroNeonMemDeclare.subst(storeIop)
247}};
248
249let {{
250    exec_output = ''
251    for eSize, type in (1, 'uint8_t'), \
252                       (2, 'uint16_t'), \
253                       (4, 'uint32_t'), \
254                       (8, 'uint64_t'):
255        size = eSize
256        # An instruction handles no more than 16 bytes and no more than
257        # 4 elements, or the number of elements needed to fill 8 or 16 bytes.
258        sizes = set((16, 8))
259        for count in 1, 2, 3, 4:
260            size = count * eSize
261            if size <= 16:
262                sizes.add(size)
263        for size in sizes:
264            substDict = {
265                "class_name" : "MicroLdrNeon%dUop" % size,
266                "targs" : type
267            }
268            exec_output += MicroNeonMemExecDeclare.subst(substDict)
269            substDict["class_name"] = "MicroStrNeon%dUop" % size
270            exec_output += MicroNeonMemExecDeclare.subst(substDict)
271            size += eSize
272}};
273
274////////////////////////////////////////////////////////////////////
275//
276// Neon (de)interlacing microops
277//
278
279let {{
280    header_output = exec_output = ''
281    for dRegs in (2, 3, 4):
282        loadConv = ''
283        unloadConv = ''
284        for dReg in range(dRegs):
285            loadConv += '''
286                conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d.uw);
287                conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d.uw);
288            ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
289            unloadConv += '''
290                FpDestS%(dReg)dP0.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]);
291                FpDestS%(dReg)dP1.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]);
292            ''' % { "dReg" : dReg }
293        microDeintNeonCode = '''
294            const unsigned dRegs = %(dRegs)d;
295            const unsigned regs = 2 * dRegs;
296            const unsigned perDReg = (2 * sizeof(FloatRegBits)) /
297                                     sizeof(Element);
298            union convStruct {
299                FloatRegBits cRegs[regs];
300                Element elements[dRegs * perDReg];
301            } conv1, conv2;
302
303            %(loadConv)s
304
305            unsigned srcElem = 0;
306            for (unsigned destOffset = 0;
307                    destOffset < perDReg; destOffset++) {
308                for (unsigned dReg = 0; dReg < dRegs; dReg++) {
309                    conv2.elements[dReg * perDReg + destOffset] =
310                        conv1.elements[srcElem++];
311                }
312            }
313
314            %(unloadConv)s
315        ''' % { "dRegs" : dRegs,
316                "loadConv" : loadConv,
317                "unloadConv" : unloadConv }
318        microDeintNeonIop = \
319            InstObjParams('deintneon%duop' % (dRegs * 2),
320                          'MicroDeintNeon%dUop' % (dRegs * 2),
321                          'MicroNeonMixOp',
322                          { 'predicate_test': predicateTest,
323                            'code' : microDeintNeonCode },
324                            ['IsMicroop'])
325        header_output += MicroNeonMixDeclare.subst(microDeintNeonIop)
326        exec_output += MicroNeonMixExecute.subst(microDeintNeonIop)
327
328        loadConv = ''
329        unloadConv = ''
330        for dReg in range(dRegs):
331            loadConv += '''
332                conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0.uw);
333                conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1.uw);
334            ''' % { "dReg" : dReg }
335            unloadConv += '''
336                FpDestP%(sReg0)d.uw = gtoh(conv2.cRegs[%(sReg0)d]);
337                FpDestP%(sReg1)d.uw = gtoh(conv2.cRegs[%(sReg1)d]);
338            ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
339        microInterNeonCode = '''
340            const unsigned dRegs = %(dRegs)d;
341            const unsigned regs = 2 * dRegs;
342            const unsigned perDReg = (2 * sizeof(FloatRegBits)) /
343                                     sizeof(Element);
344            union convStruct {
345                FloatRegBits cRegs[regs];
346                Element elements[dRegs * perDReg];
347            } conv1, conv2;
348
349            %(loadConv)s
350
351            unsigned destElem = 0;
352            for (unsigned srcOffset = 0;
353                    srcOffset < perDReg; srcOffset++) {
354                for (unsigned dReg = 0; dReg < dRegs; dReg++) {
355                    conv2.elements[destElem++] =
356                        conv1.elements[dReg * perDReg + srcOffset];
357                }
358            }
359
360            %(unloadConv)s
361        ''' % { "dRegs" : dRegs,
362                "loadConv" : loadConv,
363                "unloadConv" : unloadConv }
364        microInterNeonIop = \
365            InstObjParams('interneon%duop' % (dRegs * 2),
366                          'MicroInterNeon%dUop' % (dRegs * 2),
367                          'MicroNeonMixOp',
368                          { 'predicate_test': predicateTest,
369                            'code' : microInterNeonCode },
370                            ['IsMicroop'])
371        header_output += MicroNeonMixDeclare.subst(microInterNeonIop)
372        exec_output += MicroNeonMixExecute.subst(microInterNeonIop)
373}};
374
375let {{
376    exec_output = ''
377    for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
378        for dRegs in (2, 3, 4):
379            Name = "MicroDeintNeon%dUop" % (dRegs * 2)
380            substDict = { "class_name" : Name, "targs" : type }
381            exec_output += MicroNeonExecDeclare.subst(substDict)
382            Name = "MicroInterNeon%dUop" % (dRegs * 2)
383            substDict = { "class_name" : Name, "targs" : type }
384            exec_output += MicroNeonExecDeclare.subst(substDict)
385}};
386
387////////////////////////////////////////////////////////////////////
388//
389// Neon microops to pack/unpack a single lane
390//
391
392let {{
393    header_output = exec_output = ''
394    for sRegs in 1, 2:
395        baseLoadRegs = ''
396        for reg in range(sRegs):
397            baseLoadRegs += '''
398                sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw);
399                sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw);
400            ''' % { "reg0" : (2 * reg + 0),
401                    "reg1" : (2 * reg + 1) }
402        for dRegs in range(sRegs, 5):
403            unloadRegs = ''
404            loadRegs = baseLoadRegs
405            for reg in range(dRegs):
406                loadRegs += '''
407                    destRegs[%(reg)d].fRegs[0] = htog(FpDestS%(reg)dP0.uw);
408                    destRegs[%(reg)d].fRegs[1] = htog(FpDestS%(reg)dP1.uw);
409                ''' % { "reg" : reg }
410                unloadRegs += '''
411                    FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]);
412                    FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]);
413                ''' % { "reg" : reg }
414            microUnpackNeonCode = '''
415            const unsigned perDReg = (2 * sizeof(FloatRegBits)) /
416                                     sizeof(Element);
417
418            union SourceRegs {
419                FloatRegBits fRegs[2 * %(sRegs)d];
420                Element elements[%(sRegs)d * perDReg];
421            } sourceRegs;
422
423            union DestReg {
424                FloatRegBits fRegs[2];
425                Element elements[perDReg];
426            } destRegs[%(dRegs)d];
427
428            %(loadRegs)s
429
430            for (unsigned i = 0; i < %(dRegs)d; i++) {
431                destRegs[i].elements[lane] = sourceRegs.elements[i];
432            }
433
434            %(unloadRegs)s
435            ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
436                    "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
437
438            microUnpackNeonIop = \
439                InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2),
440                              'MicroUnpackNeon%dto%dUop' %
441                                    (sRegs * 2, dRegs * 2),
442                              'MicroNeonMixLaneOp',
443                              { 'predicate_test': predicateTest,
444                                'code' : microUnpackNeonCode },
445                                ['IsMicroop'])
446            header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop)
447            exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop)
448
449    for sRegs in 1, 2:
450        loadRegs = ''
451        for reg in range(sRegs):
452            loadRegs += '''
453                sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw);
454                sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw);
455            ''' % { "reg0" : (2 * reg + 0),
456                    "reg1" : (2 * reg + 1) }
457        for dRegs in range(sRegs, 5):
458            unloadRegs = ''
459            for reg in range(dRegs):
460                unloadRegs += '''
461                    FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]);
462                    FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]);
463                ''' % { "reg" : reg }
464            microUnpackAllNeonCode = '''
465            const unsigned perDReg = (2 * sizeof(FloatRegBits)) /
466                                     sizeof(Element);
467
468            union SourceRegs {
469                FloatRegBits fRegs[2 * %(sRegs)d];
470                Element elements[%(sRegs)d * perDReg];
471            } sourceRegs;
472
473            union DestReg {
474                FloatRegBits fRegs[2];
475                Element elements[perDReg];
476            } destRegs[%(dRegs)d];
477
478            %(loadRegs)s
479
480            for (unsigned i = 0; i < %(dRegs)d; i++) {
481                for (unsigned j = 0; j < perDReg; j++)
482                    destRegs[i].elements[j] = sourceRegs.elements[i];
483            }
484
485            %(unloadRegs)s
486            ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
487                    "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
488
489            microUnpackAllNeonIop = \
490                InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2),
491                              'MicroUnpackAllNeon%dto%dUop' %
492                                    (sRegs * 2, dRegs * 2),
493                              'MicroNeonMixOp',
494                              { 'predicate_test': predicateTest,
495                                'code' : microUnpackAllNeonCode },
496                                ['IsMicroop'])
497            header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop)
498            exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop)
499
500    for dRegs in 1, 2:
501        unloadRegs = ''
502        for reg in range(dRegs):
503            unloadRegs += '''
504                FpDestP%(reg0)d.uw = gtoh(destRegs.fRegs[%(reg0)d]);
505                FpDestP%(reg1)d.uw = gtoh(destRegs.fRegs[%(reg1)d]);
506            ''' % { "reg0" : (2 * reg + 0),
507                    "reg1" : (2 * reg + 1) }
508        for sRegs in range(dRegs, 5):
509            loadRegs = ''
510            for reg in range(sRegs):
511                loadRegs += '''
512                    sourceRegs[%(reg)d].fRegs[0] = htog(FpOp1S%(reg)dP0.uw);
513                    sourceRegs[%(reg)d].fRegs[1] = htog(FpOp1S%(reg)dP1.uw);
514                ''' % { "reg" : reg }
515            microPackNeonCode = '''
516            const unsigned perDReg = (2 * sizeof(FloatRegBits)) /
517                                     sizeof(Element);
518
519            union SourceReg {
520                FloatRegBits fRegs[2];
521                Element elements[perDReg];
522            } sourceRegs[%(sRegs)d];
523
524            union DestRegs {
525                FloatRegBits fRegs[2 * %(dRegs)d];
526                Element elements[%(dRegs)d * perDReg];
527            } destRegs;
528
529            %(loadRegs)s
530
531            for (unsigned i = 0; i < %(sRegs)d; i++) {
532                destRegs.elements[i] = sourceRegs[i].elements[lane];
533            }
534
535            %(unloadRegs)s
536            ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
537                    "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
538
539            microPackNeonIop = \
540                InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2),
541                              'MicroPackNeon%dto%dUop' %
542                                    (sRegs * 2, dRegs * 2),
543                              'MicroNeonMixLaneOp',
544                              { 'predicate_test': predicateTest,
545                                'code' : microPackNeonCode },
546                                ['IsMicroop'])
547            header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop)
548            exec_output += MicroNeonMixExecute.subst(microPackNeonIop)
549}};
550
551let {{
552    exec_output = ''
553    for type in ('uint8_t', 'uint16_t', 'uint32_t'):
554        for sRegs in 1, 2:
555            for dRegs in range(sRegs, 5):
556                for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop",
557                               "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop",
558                               "MicroPackNeon%(dRegs)dto%(sRegs)dUop"):
559                    Name = format % { "sRegs" : sRegs * 2,
560                                      "dRegs" : dRegs * 2 }
561                    substDict = { "class_name" : Name, "targs" : type }
562                    exec_output += MicroNeonExecDeclare.subst(substDict)
563}};
564
565////////////////////////////////////////////////////////////////////
566//
567// Integer = Integer op Immediate microops
568//
569
570let {{
571    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
572                                    'MicroIntImmOp',
573                                    {'code': 'Ra = Rb + imm;',
574                                     'predicate_test': predicateTest},
575                                    ['IsMicroop'])
576
577    microAddUopIop = InstObjParams('add_uop', 'MicroAddUop',
578                                   'MicroIntRegOp',
579                                   {'code':
580                                    '''Ra = Rb + shift_rm_imm(Rc, shiftAmt,
581                                                              shiftType,
582                                                              CondCodes<29:>);
583                                    ''',
584                                    'predicate_test': predicateTest},
585                                   ['IsMicroop'])
586
587    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
588                                    'MicroIntImmOp',
589                                    {'code': 'Ra = Rb - imm;',
590                                     'predicate_test': predicateTest},
591                                    ['IsMicroop'])
592
593    microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop',
594                                   'MicroIntRegOp',
595                                   {'code':
596                                    '''Ra = Rb - shift_rm_imm(Rc, shiftAmt,
597                                                              shiftType,
598                                                              CondCodes<29:>);
599                                    ''',
600                                    'predicate_test': predicateTest},
601                                   ['IsMicroop'])
602
603    microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov',
604                                   'MicroIntMov',
605                                   {'code': 'IWRa = Rb;',
606                                    'predicate_test': predicateTest},
607                                   ['IsMicroop'])
608
609    header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \
610                    MicroIntImmDeclare.subst(microSubiUopIop) + \
611                    MicroIntRegDeclare.subst(microAddUopIop) + \
612                    MicroIntRegDeclare.subst(microSubUopIop) + \
613                    MicroIntMovDeclare.subst(microUopRegMovIop)
614
615    decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \
616                     MicroIntImmConstructor.subst(microSubiUopIop) + \
617                     MicroIntRegConstructor.subst(microAddUopIop) + \
618                     MicroIntRegConstructor.subst(microSubUopIop) + \
619                     MicroIntMovConstructor.subst(microUopRegMovIop)
620
621    exec_output = PredOpExecute.subst(microAddiUopIop) + \
622                  PredOpExecute.subst(microSubiUopIop) + \
623                  PredOpExecute.subst(microAddUopIop) + \
624                  PredOpExecute.subst(microSubUopIop) + \
625                  PredOpExecute.subst(microUopRegMovIop)
626}};
627
628let {{
629    iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", [])
630    header_output = MacroMemDeclare.subst(iop)
631    decoder_output = MacroMemConstructor.subst(iop)
632
633    iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", [])
634    header_output += VMemMultDeclare.subst(iop)
635    decoder_output += VMemMultConstructor.subst(iop)
636
637    iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", [])
638    header_output += VMemSingleDeclare.subst(iop)
639    decoder_output += VMemSingleConstructor.subst(iop)
640
641    iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", [])
642    header_output += VMemMultDeclare.subst(iop)
643    decoder_output += VMemMultConstructor.subst(iop)
644
645    iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", [])
646    header_output += VMemSingleDeclare.subst(iop)
647    decoder_output += VMemSingleConstructor.subst(iop)
648
649    vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", [])
650    header_output += MacroVFPMemDeclare.subst(vfpIop)
651    decoder_output += MacroVFPMemConstructor.subst(vfpIop)
652}};
653