3 // Copyright (c) 2010 ARM Limited
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.
15 // Copyright (c) 2007-2008 The Florida State University
16 // All rights reserved.
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.
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.
41 // Authors: Stephen Hines
44 ////////////////////////////////////////////////////////////////////
46 // Load/store microops
50 microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
51 microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
53 {'memacc_code': microLdrUopCode,
54 'ea_code': 'EA = URb + (up ? imm : -imm);',
55 'predicate_test': predicateTest},
58 microLdrFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
59 microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
61 {'memacc_code': microLdrFpUopCode,
62 'ea_code': vfpEnabledCheckCode +
63 'EA = URb + (up ? imm : -imm);',
64 'predicate_test': predicateTest},
67 microLdrDBFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
68 microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop',
70 {'memacc_code': microLdrFpUopCode,
71 'ea_code': vfpEnabledCheckCode + '''
72 EA = URb + (up ? imm : -imm) +
73 (((CPSR)Cpsr).e ? 4 : 0);
75 'predicate_test': predicateTest},
78 microLdrDTFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);"
79 microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop',
81 {'memacc_code': microLdrFpUopCode,
82 'ea_code': vfpEnabledCheckCode + '''
83 EA = URb + (up ? imm : -imm) -
84 (((CPSR)Cpsr).e ? 4 : 0);
86 'predicate_test': predicateTest},
89 microLdrRetUopCode = '''
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 ForcedItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
98 | (((CPSR)Spsr).it1 & 0x3);
100 microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
102 {'memacc_code': microLdrRetUopCode,
104 'EA = URb + (up ? imm : -imm);',
105 'predicate_test': condPredicateTest},
106 ['IsMicroop','IsNonSpeculative','IsSerializeAfter'])
108 microStrUopCode = "Mem = cSwap(URa.uw, ((CPSR)Cpsr).e);"
109 microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
111 {'memacc_code': microStrUopCode,
113 'ea_code': 'EA = URb + (up ? imm : -imm);',
114 'predicate_test': predicateTest},
117 microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);"
118 microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop',
120 {'memacc_code': microStrFpUopCode,
122 'ea_code': vfpEnabledCheckCode +
123 'EA = URb + (up ? imm : -imm);',
124 'predicate_test': predicateTest},
127 microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);"
128 microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop',
130 {'memacc_code': microStrFpUopCode,
132 'ea_code': vfpEnabledCheckCode + '''
133 EA = URb + (up ? imm : -imm) +
134 (((CPSR)Cpsr).e ? 4 : 0);
136 'predicate_test': predicateTest},
139 microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);"
140 microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop',
142 {'memacc_code': microStrFpUopCode,
144 'ea_code': vfpEnabledCheckCode + '''
145 EA = URb + (up ? imm : -imm) -
146 (((CPSR)Cpsr).e ? 4 : 0);
148 'predicate_test': predicateTest},
151 header_output = decoder_output = exec_output = ''
153 loadIops = (microLdrUopIop, microLdrRetUopIop,
154 microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop)
155 storeIops = (microStrUopIop, microStrFpUopIop,
156 microStrDBFpUopIop, microStrDTFpUopIop)
157 for iop in loadIops + storeIops:
158 header_output += MicroMemDeclare.subst(iop)
159 decoder_output += MicroMemConstructor.subst(iop)
161 exec_output += LoadExecute.subst(iop) + \
162 LoadInitiateAcc.subst(iop) + \
163 LoadCompleteAcc.subst(iop)
164 for iop in storeIops:
165 exec_output += StoreExecute.subst(iop) + \
166 StoreInitiateAcc.subst(iop) + \
167 StoreCompleteAcc.subst(iop)
171 exec_output = header_output = ''
173 eaCode = 'EA = URa + imm;'
175 for size in (1, 2, 3, 4, 6, 8, 12, 16):
176 # Set up the memory access.
177 regs = (size + 3) // 4
178 subst = { "size" : size, "regs" : regs }
181 uint8_t bytes[%(size)d];
182 Element elements[%(size)d / sizeof(Element)];
183 uint32_t floatRegBits[%(regs)d];
187 # Do endian conversion for all the elements.
189 const unsigned eCount = sizeof(memUnion.elements) /
190 sizeof(memUnion.elements[0]);
191 if (((CPSR)Cpsr).e) {
192 for (unsigned i = 0; i < eCount; i++) {
193 memUnion.elements[i] = gtobe(memUnion.elements[i]);
196 for (unsigned i = 0; i < eCount; i++) {
197 memUnion.elements[i] = gtole(memUnion.elements[i]);
202 # Offload everything into registers
204 for reg in range(regs):
207 mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size))
209 FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s;
210 ''' % { "reg" : reg, "mask" : mask }
212 # Pull everything in from registers
214 for reg in range(regs):
216 memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw);
217 ''' % { "reg" : reg }
219 loadMemAccCode = convCode + regSetCode
220 storeMemAccCode = regGetCode + convCode
222 loadIop = InstObjParams('ldrneon%(size)d_uop' % subst,
223 'MicroLdrNeon%(size)dUop' % subst,
225 { 'mem_decl' : memDecl,
227 'memacc_code' : loadMemAccCode,
228 'ea_code' : simdEnabledCheckCode + eaCode,
229 'predicate_test' : predicateTest },
230 [ 'IsMicroop', 'IsMemRef', 'IsLoad' ])
231 storeIop = InstObjParams('strneon%(size)d_uop' % subst,
232 'MicroStrNeon%(size)dUop' % subst,
234 { 'mem_decl' : memDecl,
236 'memacc_code' : storeMemAccCode,
237 'ea_code' : simdEnabledCheckCode + eaCode,
238 'predicate_test' : predicateTest },
239 [ 'IsMicroop', 'IsMemRef', 'IsStore' ])
241 exec_output += NeonLoadExecute.subst(loadIop) + \
242 NeonLoadInitiateAcc.subst(loadIop) + \
243 NeonLoadCompleteAcc.subst(loadIop) + \
244 NeonStoreExecute.subst(storeIop) + \
245 NeonStoreInitiateAcc.subst(storeIop) + \
246 NeonStoreCompleteAcc.subst(storeIop)
247 header_output += MicroNeonMemDeclare.subst(loadIop) + \
248 MicroNeonMemDeclare.subst(storeIop)
253 for eSize, type in (1, 'uint8_t'), \
258 # An instruction handles no more than 16 bytes and no more than
259 # 4 elements, or the number of elements needed to fill 8 or 16 bytes.
261 for count in 1, 2, 3, 4:
267 "class_name" : "MicroLdrNeon%dUop" % size,
270 exec_output += MicroNeonMemExecDeclare.subst(substDict)
271 substDict["class_name"] = "MicroStrNeon%dUop" % size
272 exec_output += MicroNeonMemExecDeclare.subst(substDict)
276 ////////////////////////////////////////////////////////////////////
278 // Neon (de)interlacing microops
282 header_output = exec_output = ''
283 for dRegs in (2, 3, 4):
286 for dReg in range(dRegs):
288 conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d.uw);
289 conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d.uw);
290 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
292 FpDestS%(dReg)dP0.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]);
293 FpDestS%(dReg)dP1.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]);
294 ''' % { "dReg" : dReg }
295 microDeintNeonCode = '''
296 const unsigned dRegs = %(dRegs)d;
297 const unsigned regs = 2 * dRegs;
298 const unsigned perDReg = (2 * sizeof(FloatRegBits)) /
301 FloatRegBits cRegs[regs];
302 Element elements[dRegs * perDReg];
307 unsigned srcElem = 0;
308 for (unsigned destOffset = 0;
309 destOffset < perDReg; destOffset++) {
310 for (unsigned dReg = 0; dReg < dRegs; dReg++) {
311 conv2.elements[dReg * perDReg + destOffset] =
312 conv1.elements[srcElem++];
317 ''' % { "dRegs" : dRegs,
318 "loadConv" : loadConv,
319 "unloadConv" : unloadConv }
320 microDeintNeonIop = \
321 InstObjParams('deintneon%duop' % (dRegs * 2),
322 'MicroDeintNeon%dUop' % (dRegs * 2),
324 { 'predicate_test': predicateTest,
325 'code' : microDeintNeonCode },
327 header_output += MicroNeonMixDeclare.subst(microDeintNeonIop)
328 exec_output += MicroNeonMixExecute.subst(microDeintNeonIop)
332 for dReg in range(dRegs):
334 conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0.uw);
335 conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1.uw);
336 ''' % { "dReg" : dReg }
338 FpDestP%(sReg0)d.uw = gtoh(conv2.cRegs[%(sReg0)d]);
339 FpDestP%(sReg1)d.uw = gtoh(conv2.cRegs[%(sReg1)d]);
340 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
341 microInterNeonCode = '''
342 const unsigned dRegs = %(dRegs)d;
343 const unsigned regs = 2 * dRegs;
344 const unsigned perDReg = (2 * sizeof(FloatRegBits)) /
347 FloatRegBits cRegs[regs];
348 Element elements[dRegs * perDReg];
353 unsigned destElem = 0;
354 for (unsigned srcOffset = 0;
355 srcOffset < perDReg; srcOffset++) {
356 for (unsigned dReg = 0; dReg < dRegs; dReg++) {
357 conv2.elements[destElem++] =
358 conv1.elements[dReg * perDReg + srcOffset];
363 ''' % { "dRegs" : dRegs,
364 "loadConv" : loadConv,
365 "unloadConv" : unloadConv }
366 microInterNeonIop = \
367 InstObjParams('interneon%duop' % (dRegs * 2),
368 'MicroInterNeon%dUop' % (dRegs * 2),
370 { 'predicate_test': predicateTest,
371 'code' : microInterNeonCode },
373 header_output += MicroNeonMixDeclare.subst(microInterNeonIop)
374 exec_output += MicroNeonMixExecute.subst(microInterNeonIop)
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)
389 ////////////////////////////////////////////////////////////////////
391 // Neon microops to pack/unpack a single lane
395 header_output = exec_output = ''
398 for reg in range(sRegs):
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):
406 loadRegs = baseLoadRegs
407 for reg in range(dRegs):
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 }
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)) /
421 FloatRegBits fRegs[2 * %(sRegs)d];
422 Element elements[%(sRegs)d * perDReg];
426 FloatRegBits fRegs[2];
427 Element elements[perDReg];
428 } destRegs[%(dRegs)d];
432 for (unsigned i = 0; i < %(dRegs)d; i++) {
433 destRegs[i].elements[lane] = sourceRegs.elements[i];
437 ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
438 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
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 },
448 header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop)
449 exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop)
453 for reg in range(sRegs):
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):
461 for reg in range(dRegs):
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)) /
471 FloatRegBits fRegs[2 * %(sRegs)d];
472 Element elements[%(sRegs)d * perDReg];
476 FloatRegBits fRegs[2];
477 Element elements[perDReg];
478 } destRegs[%(dRegs)d];
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];
488 ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
489 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
491 microUnpackAllNeonIop = \
492 InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2),
493 'MicroUnpackAllNeon%dto%dUop' %
494 (sRegs * 2, dRegs * 2),
496 { 'predicate_test': predicateTest,
497 'code' : microUnpackAllNeonCode },
499 header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop)
500 exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop)
504 for reg in range(dRegs):
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):
512 for reg in range(sRegs):
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)) /
522 FloatRegBits fRegs[2];
523 Element elements[perDReg];
524 } sourceRegs[%(sRegs)d];
527 FloatRegBits fRegs[2 * %(dRegs)d];
528 Element elements[%(dRegs)d * perDReg];
533 for (unsigned i = 0; i < %(sRegs)d; i++) {
534 destRegs.elements[i] = sourceRegs[i].elements[lane];
538 ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
539 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
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 },
549 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop)
550 exec_output += MicroNeonMixExecute.subst(microPackNeonIop)
555 for type in ('uint8_t', 'uint16_t', 'uint32_t'):
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)
567 ////////////////////////////////////////////////////////////////////
569 // Integer = Integer op Immediate microops
573 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
575 {'code': 'URa = URb + imm;',
576 'predicate_test': predicateTest},
579 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop',
582 '''URa = URb + shift_rm_imm(URc, shiftAmt,
586 'predicate_test': predicateTest},
589 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
591 {'code': 'URa = URb - imm;',
592 'predicate_test': predicateTest},
595 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop',
598 '''URa = URb - shift_rm_imm(URc, shiftAmt,
602 'predicate_test': predicateTest},
605 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov',
607 {'code': 'IWRa = URb;',
608 'predicate_test': predicateTest},
612 CPSR cpsrOrCondCodes = URc;
616 cpsrWriteByInstr(cpsrOrCondCodes, URb,
617 0xF, true, sctlr.nmfi);
618 Cpsr = ~CondCodesMask & newCpsr;
619 NextThumb = ((CPSR)newCpsr).t;
620 NextJazelle = ((CPSR)newCpsr).j;
621 ForcedItState = ((((CPSR)URb).it2 << 2) & 0xFC)
622 | (((CPSR)URb).it1 & 0x3);
623 CondCodes = CondCodesMask & newCpsr;
626 microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',
628 {'code': setPCCPSRDecl,
629 'predicate_test': predicateTest},
632 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \
633 MicroIntImmDeclare.subst(microSubiUopIop) + \
634 MicroIntRegDeclare.subst(microAddUopIop) + \
635 MicroIntRegDeclare.subst(microSubUopIop) + \
636 MicroIntMovDeclare.subst(microUopRegMovIop) + \
637 MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop)
639 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \
640 MicroIntImmConstructor.subst(microSubiUopIop) + \
641 MicroIntRegConstructor.subst(microAddUopIop) + \
642 MicroIntRegConstructor.subst(microSubUopIop) + \
643 MicroIntMovConstructor.subst(microUopRegMovIop) + \
644 MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop)
646 exec_output = PredOpExecute.subst(microAddiUopIop) + \
647 PredOpExecute.subst(microSubiUopIop) + \
648 PredOpExecute.subst(microAddUopIop) + \
649 PredOpExecute.subst(microSubUopIop) + \
650 PredOpExecute.subst(microUopRegMovIop) + \
651 PredOpExecute.subst(microUopSetPCCPSRIop)
656 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", [])
657 header_output = MacroMemDeclare.subst(iop)
658 decoder_output = MacroMemConstructor.subst(iop)
660 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", [])
661 header_output += VMemMultDeclare.subst(iop)
662 decoder_output += VMemMultConstructor.subst(iop)
664 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", [])
665 header_output += VMemSingleDeclare.subst(iop)
666 decoder_output += VMemSingleConstructor.subst(iop)
668 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", [])
669 header_output += VMemMultDeclare.subst(iop)
670 decoder_output += VMemMultConstructor.subst(iop)
672 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", [])
673 header_output += VMemSingleDeclare.subst(iop)
674 decoder_output += VMemSingleConstructor.subst(iop)
676 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", [])
677 header_output += MacroVFPMemDeclare.subst(vfpIop)
678 decoder_output += MacroVFPMemConstructor.subst(vfpIop)