3 // Copyright (c) 2010-2014 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 ////////////////////////////////////////////////////////////////////
43 // Load/store microops
47 microLdrUopCode = "IWRa = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
48 microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
50 {'memacc_code': microLdrUopCode,
51 'ea_code': 'EA = URb + (up ? imm : -imm);',
52 'predicate_test': predicateTest},
55 microLdr2UopCode = '''
56 uint64_t data = Mem_ud;
57 Dest = cSwap((uint32_t) data, ((CPSR)Cpsr).e);
58 IWDest2 = cSwap((uint32_t) (data >> 32),
61 microLdr2UopIop = InstObjParams('ldr2_uop', 'MicroLdr2Uop',
63 {'memacc_code': microLdr2UopCode,
64 'ea_code': 'EA = URb + (up ? imm : -imm);',
65 'predicate_test': predicateTest},
68 microLdrFpUopCode = "Fa_uw = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
69 microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop',
71 {'memacc_code': microLdrFpUopCode,
72 'ea_code': vfpEnabledCheckCode +
73 'EA = URb + (up ? imm : -imm);',
74 'predicate_test': predicateTest},
77 microLdrDBFpUopCode = "Fa_uw = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
78 microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop',
80 {'memacc_code': microLdrFpUopCode,
81 'ea_code': vfpEnabledCheckCode + '''
82 EA = URb + (up ? imm : -imm) +
83 (((CPSR)Cpsr).e ? 4 : 0);
85 'predicate_test': predicateTest},
88 microLdrDTFpUopCode = "Fa_uw = cSwap(Mem_uw, ((CPSR)Cpsr).e);"
89 microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop',
91 {'memacc_code': microLdrFpUopCode,
92 'ea_code': vfpEnabledCheckCode + '''
93 EA = URb + (up ? imm : -imm) -
94 (((CPSR)Cpsr).e ? 4 : 0);
96 'predicate_test': predicateTest},
100 CPSR old_cpsr = Cpsr;
104 cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF, true,
105 sctlr.nmfi, xc->tcBase());
106 Cpsr = ~CondCodesMask & new_cpsr;
107 CondCodesNZ = new_cpsr.nz;
108 CondCodesC = new_cpsr.c;
109 CondCodesV = new_cpsr.v;
110 CondCodesGE = new_cpsr.ge;
111 IWNPC = cSwap(%s, old_cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
112 NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
113 | (((CPSR)Spsr).it1 & 0x3);
117 microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
120 microRetUopCode % 'Mem_uw',
122 'EA = URb + (up ? imm : -imm);',
123 'predicate_test': condPredicateTest},
124 ['IsMicroop','IsNonSpeculative',
125 'IsSerializeAfter', 'IsSquashAfter'])
127 microStrUopCode = "Mem = cSwap(URa_uw, ((CPSR)Cpsr).e);"
128 microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
130 {'memacc_code': microStrUopCode,
132 'ea_code': 'EA = URb + (up ? imm : -imm);',
133 'predicate_test': predicateTest},
136 microStrFpUopCode = "Mem = cSwap(Fa_uw, ((CPSR)Cpsr).e);"
137 microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop',
139 {'memacc_code': microStrFpUopCode,
141 'ea_code': vfpEnabledCheckCode +
142 'EA = URb + (up ? imm : -imm);',
143 'predicate_test': predicateTest},
146 microStrDBFpUopCode = "Mem = cSwap(Fa_uw, ((CPSR)Cpsr).e);"
147 microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop',
149 {'memacc_code': microStrFpUopCode,
151 'ea_code': vfpEnabledCheckCode + '''
152 EA = URb + (up ? imm : -imm) +
153 (((CPSR)Cpsr).e ? 4 : 0);
155 'predicate_test': predicateTest},
158 microStrDTFpUopCode = "Mem = cSwap(Fa_uw, ((CPSR)Cpsr).e);"
159 microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop',
161 {'memacc_code': microStrFpUopCode,
163 'ea_code': vfpEnabledCheckCode + '''
164 EA = URb + (up ? imm : -imm) -
165 (((CPSR)Cpsr).e ? 4 : 0);
167 'predicate_test': predicateTest},
170 header_output = decoder_output = exec_output = ''
172 loadIops = (microLdrUopIop, microLdrRetUopIop,
173 microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop)
174 storeIops = (microStrUopIop, microStrFpUopIop,
175 microStrDBFpUopIop, microStrDTFpUopIop)
176 for iop in loadIops + storeIops:
177 header_output += MicroMemDeclare.subst(iop)
178 decoder_output += MicroMemConstructor.subst(iop)
180 exec_output += LoadExecute.subst(iop) + \
181 LoadInitiateAcc.subst(iop) + \
182 LoadCompleteAcc.subst(iop)
183 for iop in storeIops:
184 exec_output += StoreExecute.subst(iop) + \
185 StoreInitiateAcc.subst(iop) + \
186 StoreCompleteAcc.subst(iop)
188 header_output += MicroMemPairDeclare.subst(microLdr2UopIop)
189 decoder_output += MicroMemPairConstructor.subst(microLdr2UopIop)
190 exec_output += LoadExecute.subst(microLdr2UopIop) + \
191 LoadInitiateAcc.subst(microLdr2UopIop) + \
192 LoadCompleteAcc.subst(microLdr2UopIop)
196 exec_output = header_output = ''
198 eaCode = 'EA = XURa + imm;'
200 for size in (1, 2, 3, 4, 6, 8, 12, 16):
201 # Set up the memory access.
202 regs = (size + 3) // 4
203 subst = { "size" : size, "regs" : regs }
206 uint8_t bytes[%(size)d];
207 Element elements[%(size)d / sizeof(Element)];
208 uint32_t floatRegBits[%(regs)d];
212 # Do endian conversion for all the elements.
214 const unsigned eCount = sizeof(memUnion.elements) /
215 sizeof(memUnion.elements[0]);
216 if (((CPSR)Cpsr).e) {
217 for (unsigned i = 0; i < eCount; i++) {
218 memUnion.elements[i] = letobe(memUnion.elements[i]);
221 for (unsigned i = 0; i < eCount; i++) {
222 memUnion.elements[i] = memUnion.elements[i];
227 # Offload everything into registers
229 for reg in range(regs):
232 mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size))
234 FpDestP%(reg)d_uw = letoh(memUnion.floatRegBits[%(reg)d])%(mask)s;
235 ''' % { "reg" : reg, "mask" : mask }
237 # Pull everything in from registers
239 for reg in range(regs):
241 memUnion.floatRegBits[%(reg)d] = htole(FpDestP%(reg)d_uw);
242 ''' % { "reg" : reg }
244 loadMemAccCode = convCode + regSetCode
245 storeMemAccCode = regGetCode + convCode
247 loadIop = InstObjParams('ldrneon%(size)d_uop' % subst,
248 'MicroLdrNeon%(size)dUop' % subst,
250 { 'mem_decl' : memDecl,
252 'memacc_code' : loadMemAccCode,
253 'ea_code' : simdEnabledCheckCode + eaCode,
254 'predicate_test' : predicateTest },
255 [ 'IsMicroop', 'IsMemRef', 'IsLoad' ])
256 storeIop = InstObjParams('strneon%(size)d_uop' % subst,
257 'MicroStrNeon%(size)dUop' % subst,
259 { 'mem_decl' : memDecl,
261 'memacc_code' : storeMemAccCode,
262 'ea_code' : simdEnabledCheckCode + eaCode,
263 'predicate_test' : predicateTest },
264 [ 'IsMicroop', 'IsMemRef', 'IsStore' ])
266 exec_output += NeonLoadExecute.subst(loadIop) + \
267 NeonLoadInitiateAcc.subst(loadIop) + \
268 NeonLoadCompleteAcc.subst(loadIop) + \
269 NeonStoreExecute.subst(storeIop) + \
270 NeonStoreInitiateAcc.subst(storeIop) + \
271 NeonStoreCompleteAcc.subst(storeIop)
272 header_output += MicroNeonMemDeclare.subst(loadIop) + \
273 MicroNeonMemDeclare.subst(storeIop)
278 for eSize, type in (1, 'uint8_t'), \
283 # An instruction handles no more than 16 bytes and no more than
284 # 4 elements, or the number of elements needed to fill 8 or 16 bytes.
286 for count in 1, 2, 3, 4:
292 "class_name" : "MicroLdrNeon%dUop" % size,
295 exec_output += MicroNeonMemExecDeclare.subst(substDict)
296 substDict["class_name"] = "MicroStrNeon%dUop" % size
297 exec_output += MicroNeonMemExecDeclare.subst(substDict)
301 ////////////////////////////////////////////////////////////////////
303 // Neon (de)interlacing microops
307 header_output = exec_output = ''
308 for dRegs in (2, 3, 4):
311 for dReg in range(dRegs):
313 conv1.cRegs[%(sReg0)d] = htole(FpOp1P%(sReg0)d_uw);
314 conv1.cRegs[%(sReg1)d] = htole(FpOp1P%(sReg1)d_uw);
315 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
317 FpDestS%(dReg)dP0_uw = letoh(conv2.cRegs[2 * %(dReg)d + 0]);
318 FpDestS%(dReg)dP1_uw = letoh(conv2.cRegs[2 * %(dReg)d + 1]);
319 ''' % { "dReg" : dReg }
320 microDeintNeonCode = '''
321 const unsigned dRegs = %(dRegs)d;
322 const unsigned regs = 2 * dRegs;
323 const unsigned perDReg =
324 (2 * sizeof(uint32_t)) / sizeof(Element);
326 uint32_t cRegs[regs];
327 Element elements[dRegs * perDReg];
332 unsigned srcElem = 0;
333 for (unsigned destOffset = 0;
334 destOffset < perDReg; destOffset++) {
335 for (unsigned dReg = 0; dReg < dRegs; dReg++) {
336 conv2.elements[dReg * perDReg + destOffset] =
337 conv1.elements[srcElem++];
342 ''' % { "dRegs" : dRegs,
343 "loadConv" : loadConv,
344 "unloadConv" : unloadConv }
345 microDeintNeonIop = \
346 InstObjParams('deintneon%duop' % (dRegs * 2),
347 'MicroDeintNeon%dUop' % (dRegs * 2),
349 { 'predicate_test': predicateTest,
350 'code' : microDeintNeonCode },
352 header_output += MicroNeonMixDeclare.subst(microDeintNeonIop)
353 exec_output += MicroNeonMixExecute.subst(microDeintNeonIop)
357 for dReg in range(dRegs):
359 conv1.cRegs[2 * %(dReg)d + 0] = htole(FpOp1S%(dReg)dP0_uw);
360 conv1.cRegs[2 * %(dReg)d + 1] = htole(FpOp1S%(dReg)dP1_uw);
361 ''' % { "dReg" : dReg }
363 FpDestP%(sReg0)d_uw = letoh(conv2.cRegs[%(sReg0)d]);
364 FpDestP%(sReg1)d_uw = letoh(conv2.cRegs[%(sReg1)d]);
365 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) }
366 microInterNeonCode = '''
367 const unsigned dRegs = %(dRegs)d;
368 const unsigned regs = 2 * dRegs;
369 const unsigned perDReg =
370 (2 * sizeof(uint32_t)) / sizeof(Element);
372 uint32_t cRegs[regs];
373 Element elements[dRegs * perDReg];
378 unsigned destElem = 0;
379 for (unsigned srcOffset = 0;
380 srcOffset < perDReg; srcOffset++) {
381 for (unsigned dReg = 0; dReg < dRegs; dReg++) {
382 conv2.elements[destElem++] =
383 conv1.elements[dReg * perDReg + srcOffset];
388 ''' % { "dRegs" : dRegs,
389 "loadConv" : loadConv,
390 "unloadConv" : unloadConv }
391 microInterNeonIop = \
392 InstObjParams('interneon%duop' % (dRegs * 2),
393 'MicroInterNeon%dUop' % (dRegs * 2),
395 { 'predicate_test': predicateTest,
396 'code' : microInterNeonCode },
398 header_output += MicroNeonMixDeclare.subst(microInterNeonIop)
399 exec_output += MicroNeonMixExecute.subst(microInterNeonIop)
404 for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'):
405 for dRegs in (2, 3, 4):
406 Name = "MicroDeintNeon%dUop" % (dRegs * 2)
407 substDict = { "class_name" : Name, "targs" : type }
408 exec_output += MicroNeonExecDeclare.subst(substDict)
409 Name = "MicroInterNeon%dUop" % (dRegs * 2)
410 substDict = { "class_name" : Name, "targs" : type }
411 exec_output += MicroNeonExecDeclare.subst(substDict)
414 ////////////////////////////////////////////////////////////////////
416 // Neon microops to pack/unpack a single lane
420 header_output = exec_output = ''
423 for reg in range(sRegs):
425 sourceRegs.fRegs[%(reg0)d] = htole(FpOp1P%(reg0)d_uw);
426 sourceRegs.fRegs[%(reg1)d] = htole(FpOp1P%(reg1)d_uw);
427 ''' % { "reg0" : (2 * reg + 0),
428 "reg1" : (2 * reg + 1) }
429 for dRegs in range(sRegs, 5):
431 loadRegs = baseLoadRegs
432 for reg in range(dRegs):
434 destRegs[%(reg)d].fRegs[0] = htole(FpDestS%(reg)dP0_uw);
435 destRegs[%(reg)d].fRegs[1] = htole(FpDestS%(reg)dP1_uw);
436 ''' % { "reg" : reg }
438 FpDestS%(reg)dP0_uw = letoh(destRegs[%(reg)d].fRegs[0]);
439 FpDestS%(reg)dP1_uw = letoh(destRegs[%(reg)d].fRegs[1]);
440 ''' % { "reg" : reg }
441 microUnpackNeonCode = '''
442 const unsigned perDReg = (2 * sizeof(uint32_t)) / sizeof(Element);
445 uint32_t fRegs[2 * %(sRegs)d];
446 Element elements[%(sRegs)d * perDReg];
451 Element elements[perDReg];
452 } destRegs[%(dRegs)d];
456 for (unsigned i = 0; i < %(dRegs)d; i++) {
457 destRegs[i].elements[lane] = sourceRegs.elements[i];
461 ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
462 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
464 microUnpackNeonIop = \
465 InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2),
466 'MicroUnpackNeon%dto%dUop' %
467 (sRegs * 2, dRegs * 2),
468 'MicroNeonMixLaneOp',
469 { 'predicate_test': predicateTest,
470 'code' : microUnpackNeonCode },
472 header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop)
473 exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop)
477 for reg in range(sRegs):
479 sourceRegs.fRegs[%(reg0)d] = htole(FpOp1P%(reg0)d_uw);
480 sourceRegs.fRegs[%(reg1)d] = htole(FpOp1P%(reg1)d_uw);
481 ''' % { "reg0" : (2 * reg + 0),
482 "reg1" : (2 * reg + 1) }
483 for dRegs in range(sRegs, 5):
485 for reg in range(dRegs):
487 FpDestS%(reg)dP0_uw = letoh(destRegs[%(reg)d].fRegs[0]);
488 FpDestS%(reg)dP1_uw = letoh(destRegs[%(reg)d].fRegs[1]);
489 ''' % { "reg" : reg }
490 microUnpackAllNeonCode = '''
491 const unsigned perDReg = (2 * sizeof(uint32_t)) / sizeof(Element);
494 uint32_t fRegs[2 * %(sRegs)d];
495 Element elements[%(sRegs)d * perDReg];
500 Element elements[perDReg];
501 } destRegs[%(dRegs)d];
505 for (unsigned i = 0; i < %(dRegs)d; i++) {
506 for (unsigned j = 0; j < perDReg; j++)
507 destRegs[i].elements[j] = sourceRegs.elements[i];
511 ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
512 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
514 microUnpackAllNeonIop = \
515 InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2),
516 'MicroUnpackAllNeon%dto%dUop' %
517 (sRegs * 2, dRegs * 2),
519 { 'predicate_test': predicateTest,
520 'code' : microUnpackAllNeonCode },
522 header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop)
523 exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop)
527 for reg in range(dRegs):
529 FpDestP%(reg0)d_uw = letoh(destRegs.fRegs[%(reg0)d]);
530 FpDestP%(reg1)d_uw = letoh(destRegs.fRegs[%(reg1)d]);
531 ''' % { "reg0" : (2 * reg + 0),
532 "reg1" : (2 * reg + 1) }
533 for sRegs in range(dRegs, 5):
535 for reg in range(sRegs):
537 sourceRegs[%(reg)d].fRegs[0] = htole(FpOp1S%(reg)dP0_uw);
538 sourceRegs[%(reg)d].fRegs[1] = htole(FpOp1S%(reg)dP1_uw);
539 ''' % { "reg" : reg }
540 microPackNeonCode = '''
541 const unsigned perDReg =
542 (2 * sizeof(uint32_t)) / sizeof(Element);
546 Element elements[perDReg];
547 } sourceRegs[%(sRegs)d];
550 uint32_t fRegs[2 * %(dRegs)d];
551 Element elements[%(dRegs)d * perDReg];
556 for (unsigned i = 0; i < %(sRegs)d; i++) {
557 destRegs.elements[i] = sourceRegs[i].elements[lane];
559 for (unsigned i = %(sRegs)d; i < %(dRegs)d * perDReg; ++i) {
560 destRegs.elements[i] = 0;
564 ''' % { "sRegs" : sRegs, "dRegs" : dRegs,
565 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs }
568 InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2),
569 'MicroPackNeon%dto%dUop' %
570 (sRegs * 2, dRegs * 2),
571 'MicroNeonMixLaneOp',
572 { 'predicate_test': predicateTest,
573 'code' : microPackNeonCode },
575 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop)
576 exec_output += MicroNeonMixExecute.subst(microPackNeonIop)
581 for typeSize in (8, 16, 32):
583 for dRegs in range(sRegs, min(sRegs * 64 / typeSize + 1, 5)):
584 for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop",
585 "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop",
586 "MicroPackNeon%(dRegs)dto%(sRegs)dUop"):
587 Name = format % { "sRegs" : sRegs * 2,
588 "dRegs" : dRegs * 2 }
589 substDict = { "class_name" : Name,
590 "targs" : "uint%d_t" % typeSize }
591 exec_output += MicroNeonExecDeclare.subst(substDict)
594 ////////////////////////////////////////////////////////////////////
596 // Integer = Integer op Immediate microops
600 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
602 {'code': 'URa = URb + imm;',
603 'predicate_test': predicateTest},
606 microAddUopCode = '''
607 URa = URb + shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC);
610 microAddXiUopIop = InstObjParams('addxi_uop', 'MicroAddXiUop',
612 'XURa = XURb + imm;',
615 microAddXiSpAlignUopIop = InstObjParams('addxi_uop', 'MicroAddXiSpAlignUop',
616 'MicroIntImmXOp', '''
617 if (isSP((IntRegIndex) urb) && bits(XURb, 3, 0) &&
618 SPAlignmentCheckEnabled(xc->tcBase())) {
619 return std::make_shared<SPAlignmentFault>();
624 microAddXERegUopIop = InstObjParams('addxr_uop', 'MicroAddXERegUop',
627 'extendReg64(XURc, type, shiftAmt, 64);',
630 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop',
632 {'code': microAddUopCode,
633 'predicate_test': pickPredicate(microAddUopCode)},
636 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
638 {'code': 'URa = URb - imm;',
639 'predicate_test': predicateTest},
642 microSubXiUopIop = InstObjParams('subxi_uop', 'MicroSubXiUop',
644 'XURa = XURb - imm;',
647 microSubUopCode = '''
648 URa = URb - shift_rm_imm(URc, shiftAmt, shiftType, OptShiftRmCondCodesC);
650 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop',
652 {'code': microSubUopCode,
653 'predicate_test': pickPredicate(microSubUopCode)},
656 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov',
658 {'code': 'IWRa = URb;',
659 'predicate_test': predicateTest},
662 microUopRegMovRetIop = InstObjParams('movret_uop', 'MicroUopRegMovRet',
664 {'code': microRetUopCode % 'URb',
665 'predicate_test': predicateTest},
666 ['IsMicroop', 'IsNonSpeculative',
667 'IsSerializeAfter', 'IsSquashAfter'])
670 CPSR cpsrOrCondCodes = URc;
674 cpsrWriteByInstr(cpsrOrCondCodes, URb, Scr, Nsacr,
675 0xF, true, sctlr.nmfi, xc->tcBase());
676 Cpsr = ~CondCodesMask & new_cpsr;
677 NextThumb = new_cpsr.t;
678 NextJazelle = new_cpsr.j;
679 NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
680 | (((CPSR)URb).it1 & 0x3);
681 CondCodesNZ = new_cpsr.nz;
682 CondCodesC = new_cpsr.c;
683 CondCodesV = new_cpsr.v;
684 CondCodesGE = new_cpsr.ge;
687 microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR',
689 {'code': setPCCPSRDecl,
690 'predicate_test': predicateTest},
691 ['IsMicroop', 'IsSerializeAfter'])
693 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \
694 MicroIntImmDeclare.subst(microAddXiUopIop) + \
695 MicroIntImmDeclare.subst(microAddXiSpAlignUopIop) + \
696 MicroIntImmDeclare.subst(microSubiUopIop) + \
697 MicroIntImmDeclare.subst(microSubXiUopIop) + \
698 MicroIntRegDeclare.subst(microAddUopIop) + \
699 MicroIntRegDeclare.subst(microSubUopIop) + \
700 MicroIntXERegDeclare.subst(microAddXERegUopIop) + \
701 MicroIntMovDeclare.subst(microUopRegMovIop) + \
702 MicroIntMovDeclare.subst(microUopRegMovRetIop) + \
703 MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop)
705 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \
706 MicroIntImmXConstructor.subst(microAddXiUopIop) + \
707 MicroIntImmXConstructor.subst(microAddXiSpAlignUopIop) + \
708 MicroIntImmConstructor.subst(microSubiUopIop) + \
709 MicroIntImmXConstructor.subst(microSubXiUopIop) + \
710 MicroIntRegConstructor.subst(microAddUopIop) + \
711 MicroIntRegConstructor.subst(microSubUopIop) + \
712 MicroIntXERegConstructor.subst(microAddXERegUopIop) + \
713 MicroIntMovConstructor.subst(microUopRegMovIop) + \
714 MicroIntMovConstructor.subst(microUopRegMovRetIop) + \
715 MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop)
717 exec_output = PredOpExecute.subst(microAddiUopIop) + \
718 BasicExecute.subst(microAddXiUopIop) + \
719 BasicExecute.subst(microAddXiSpAlignUopIop) + \
720 PredOpExecute.subst(microSubiUopIop) + \
721 BasicExecute.subst(microSubXiUopIop) + \
722 PredOpExecute.subst(microAddUopIop) + \
723 PredOpExecute.subst(microSubUopIop) + \
724 BasicExecute.subst(microAddXERegUopIop) + \
725 PredOpExecute.subst(microUopRegMovIop) + \
726 PredOpExecute.subst(microUopRegMovRetIop) + \
727 PredOpExecute.subst(microUopSetPCCPSRIop)
732 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", [])
733 header_output = MacroMemDeclare.subst(iop)
734 decoder_output = MacroMemConstructor.subst(iop)
736 iop = InstObjParams("ldpstp", "LdpStp", 'PairMemOp', "", [])
737 header_output += PairMemDeclare.subst(iop)
738 decoder_output += PairMemConstructor.subst(iop)
740 iopImm = InstObjParams("bigfpmemimm", "BigFpMemImm", "BigFpMemImmOp", "")
741 iopPre = InstObjParams("bigfpmempre", "BigFpMemPre", "BigFpMemPreOp", "")
742 iopPost = InstObjParams("bigfpmempost", "BigFpMemPost", "BigFpMemPostOp", "")
743 for iop in (iopImm, iopPre, iopPost):
744 header_output += BigFpMemImmDeclare.subst(iop)
745 decoder_output += BigFpMemImmConstructor.subst(iop)
747 iop = InstObjParams("bigfpmemreg", "BigFpMemReg", "BigFpMemRegOp", "")
748 header_output += BigFpMemRegDeclare.subst(iop)
749 decoder_output += BigFpMemRegConstructor.subst(iop)
751 iop = InstObjParams("bigfpmemlit", "BigFpMemLit", "BigFpMemLitOp", "")
752 header_output += BigFpMemLitDeclare.subst(iop)
753 decoder_output += BigFpMemLitConstructor.subst(iop)
755 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", [])
756 header_output += VMemMultDeclare.subst(iop)
757 decoder_output += VMemMultConstructor.subst(iop)
759 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", [])
760 header_output += VMemSingleDeclare.subst(iop)
761 decoder_output += VMemSingleConstructor.subst(iop)
763 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", [])
764 header_output += VMemMultDeclare.subst(iop)
765 decoder_output += VMemMultConstructor.subst(iop)
767 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", [])
768 header_output += VMemSingleDeclare.subst(iop)
769 decoder_output += VMemSingleConstructor.subst(iop)
771 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", [])
772 header_output += MacroVFPMemDeclare.subst(vfpIop)
773 decoder_output += MacroVFPMemConstructor.subst(vfpIop)