macromem.isa revision 8303:5a95f1d2494e
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 = URb + (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 = URb + (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 = URb + (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 = URb + (up ? imm : -imm) - 84 (((CPSR)Cpsr).e ? 4 : 0); 85 ''', 86 'predicate_test': predicateTest}, 87 ['IsMicroop']) 88 89 microRetUopCode = ''' 90 CPSR old_cpsr = Cpsr; 91 SCTLR sctlr = Sctlr; 92 old_cpsr.nz = CondCodesNZ; 93 old_cpsr.c = CondCodesC; 94 old_cpsr.v = CondCodesV; 95 old_cpsr.ge = CondCodesGE; 96 97 CPSR new_cpsr = 98 cpsrWriteByInstr(old_cpsr, Spsr, 0xF, true, sctlr.nmfi); 99 Cpsr = ~CondCodesMask & new_cpsr; 100 CondCodesNZ = new_cpsr.nz; 101 CondCodesC = new_cpsr.c; 102 CondCodesV = new_cpsr.v; 103 CondCodesGE = new_cpsr.ge; 104 IWNPC = cSwap(%s, old_cpsr.e) | ((Spsr & 0x20) ? 1 : 0); 105 NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC) 106 | (((CPSR)Spsr).it1 & 0x3); 107 SevMailbox = 1; 108 ''' 109 110 microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', 111 'MicroMemOp', 112 {'memacc_code': 113 microRetUopCode % 'Mem.uw', 114 'ea_code': 115 'EA = URb + (up ? imm : -imm);', 116 'predicate_test': condPredicateTest}, 117 ['IsMicroop','IsNonSpeculative', 118 'IsSerializeAfter']) 119 120 microStrUopCode = "Mem = cSwap(URa.uw, ((CPSR)Cpsr).e);" 121 microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 122 'MicroMemOp', 123 {'memacc_code': microStrUopCode, 124 'postacc_code': "", 125 'ea_code': 'EA = URb + (up ? imm : -imm);', 126 'predicate_test': predicateTest}, 127 ['IsMicroop']) 128 129 microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 130 microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop', 131 'MicroMemOp', 132 {'memacc_code': microStrFpUopCode, 133 'postacc_code': "", 134 'ea_code': vfpEnabledCheckCode + 135 'EA = URb + (up ? imm : -imm);', 136 'predicate_test': predicateTest}, 137 ['IsMicroop']) 138 139 microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 140 microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop', 141 'MicroMemOp', 142 {'memacc_code': microStrFpUopCode, 143 'postacc_code': "", 144 'ea_code': vfpEnabledCheckCode + ''' 145 EA = URb + (up ? imm : -imm) + 146 (((CPSR)Cpsr).e ? 4 : 0); 147 ''', 148 'predicate_test': predicateTest}, 149 ['IsMicroop']) 150 151 microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 152 microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop', 153 'MicroMemOp', 154 {'memacc_code': microStrFpUopCode, 155 'postacc_code': "", 156 'ea_code': vfpEnabledCheckCode + ''' 157 EA = URb + (up ? imm : -imm) - 158 (((CPSR)Cpsr).e ? 4 : 0); 159 ''', 160 'predicate_test': predicateTest}, 161 ['IsMicroop']) 162 163 header_output = decoder_output = exec_output = '' 164 165 loadIops = (microLdrUopIop, microLdrRetUopIop, 166 microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop) 167 storeIops = (microStrUopIop, microStrFpUopIop, 168 microStrDBFpUopIop, microStrDTFpUopIop) 169 for iop in loadIops + storeIops: 170 header_output += MicroMemDeclare.subst(iop) 171 decoder_output += MicroMemConstructor.subst(iop) 172 for iop in loadIops: 173 exec_output += LoadExecute.subst(iop) + \ 174 LoadInitiateAcc.subst(iop) + \ 175 LoadCompleteAcc.subst(iop) 176 for iop in storeIops: 177 exec_output += StoreExecute.subst(iop) + \ 178 StoreInitiateAcc.subst(iop) + \ 179 StoreCompleteAcc.subst(iop) 180}}; 181 182let {{ 183 exec_output = header_output = '' 184 185 eaCode = 'EA = URa + imm;' 186 187 for size in (1, 2, 3, 4, 6, 8, 12, 16): 188 # Set up the memory access. 189 regs = (size + 3) // 4 190 subst = { "size" : size, "regs" : regs } 191 memDecl = ''' 192 union MemUnion { 193 uint8_t bytes[%(size)d]; 194 Element elements[%(size)d / sizeof(Element)]; 195 uint32_t floatRegBits[%(regs)d]; 196 }; 197 ''' % subst 198 199 # Do endian conversion for all the elements. 200 convCode = ''' 201 const unsigned eCount = sizeof(memUnion.elements) / 202 sizeof(memUnion.elements[0]); 203 if (((CPSR)Cpsr).e) { 204 for (unsigned i = 0; i < eCount; i++) { 205 memUnion.elements[i] = gtobe(memUnion.elements[i]); 206 } 207 } else { 208 for (unsigned i = 0; i < eCount; i++) { 209 memUnion.elements[i] = gtole(memUnion.elements[i]); 210 } 211 } 212 ''' 213 214 # Offload everything into registers 215 regSetCode = '' 216 for reg in range(regs): 217 mask = '' 218 if reg == regs - 1: 219 mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size)) 220 regSetCode += ''' 221 FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s; 222 ''' % { "reg" : reg, "mask" : mask } 223 224 # Pull everything in from registers 225 regGetCode = '' 226 for reg in range(regs): 227 regGetCode += ''' 228 memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw); 229 ''' % { "reg" : reg } 230 231 loadMemAccCode = convCode + regSetCode 232 storeMemAccCode = regGetCode + convCode 233 234 loadIop = InstObjParams('ldrneon%(size)d_uop' % subst, 235 'MicroLdrNeon%(size)dUop' % subst, 236 'MicroNeonMemOp', 237 { 'mem_decl' : memDecl, 238 'size' : size, 239 'memacc_code' : loadMemAccCode, 240 'ea_code' : simdEnabledCheckCode + eaCode, 241 'predicate_test' : predicateTest }, 242 [ 'IsMicroop', 'IsMemRef', 'IsLoad' ]) 243 storeIop = InstObjParams('strneon%(size)d_uop' % subst, 244 'MicroStrNeon%(size)dUop' % subst, 245 'MicroNeonMemOp', 246 { 'mem_decl' : memDecl, 247 'size' : size, 248 'memacc_code' : storeMemAccCode, 249 'ea_code' : simdEnabledCheckCode + eaCode, 250 'predicate_test' : predicateTest }, 251 [ 'IsMicroop', 'IsMemRef', 'IsStore' ]) 252 253 exec_output += NeonLoadExecute.subst(loadIop) + \ 254 NeonLoadInitiateAcc.subst(loadIop) + \ 255 NeonLoadCompleteAcc.subst(loadIop) + \ 256 NeonStoreExecute.subst(storeIop) + \ 257 NeonStoreInitiateAcc.subst(storeIop) + \ 258 NeonStoreCompleteAcc.subst(storeIop) 259 header_output += MicroNeonMemDeclare.subst(loadIop) + \ 260 MicroNeonMemDeclare.subst(storeIop) 261}}; 262 263let {{ 264 exec_output = '' 265 for eSize, type in (1, 'uint8_t'), \ 266 (2, 'uint16_t'), \ 267 (4, 'uint32_t'), \ 268 (8, 'uint64_t'): 269 size = eSize 270 # An instruction handles no more than 16 bytes and no more than 271 # 4 elements, or the number of elements needed to fill 8 or 16 bytes. 272 sizes = set((16, 8)) 273 for count in 1, 2, 3, 4: 274 size = count * eSize 275 if size <= 16: 276 sizes.add(size) 277 for size in sizes: 278 substDict = { 279 "class_name" : "MicroLdrNeon%dUop" % size, 280 "targs" : type 281 } 282 exec_output += MicroNeonMemExecDeclare.subst(substDict) 283 substDict["class_name"] = "MicroStrNeon%dUop" % size 284 exec_output += MicroNeonMemExecDeclare.subst(substDict) 285 size += eSize 286}}; 287 288//////////////////////////////////////////////////////////////////// 289// 290// Neon (de)interlacing microops 291// 292 293let {{ 294 header_output = exec_output = '' 295 for dRegs in (2, 3, 4): 296 loadConv = '' 297 unloadConv = '' 298 for dReg in range(dRegs): 299 loadConv += ''' 300 conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d.uw); 301 conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d.uw); 302 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 303 unloadConv += ''' 304 FpDestS%(dReg)dP0.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]); 305 FpDestS%(dReg)dP1.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]); 306 ''' % { "dReg" : dReg } 307 microDeintNeonCode = ''' 308 const unsigned dRegs = %(dRegs)d; 309 const unsigned regs = 2 * dRegs; 310 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 311 sizeof(Element); 312 union convStruct { 313 FloatRegBits cRegs[regs]; 314 Element elements[dRegs * perDReg]; 315 } conv1, conv2; 316 317 %(loadConv)s 318 319 unsigned srcElem = 0; 320 for (unsigned destOffset = 0; 321 destOffset < perDReg; destOffset++) { 322 for (unsigned dReg = 0; dReg < dRegs; dReg++) { 323 conv2.elements[dReg * perDReg + destOffset] = 324 conv1.elements[srcElem++]; 325 } 326 } 327 328 %(unloadConv)s 329 ''' % { "dRegs" : dRegs, 330 "loadConv" : loadConv, 331 "unloadConv" : unloadConv } 332 microDeintNeonIop = \ 333 InstObjParams('deintneon%duop' % (dRegs * 2), 334 'MicroDeintNeon%dUop' % (dRegs * 2), 335 'MicroNeonMixOp', 336 { 'predicate_test': predicateTest, 337 'code' : microDeintNeonCode }, 338 ['IsMicroop']) 339 header_output += MicroNeonMixDeclare.subst(microDeintNeonIop) 340 exec_output += MicroNeonMixExecute.subst(microDeintNeonIop) 341 342 loadConv = '' 343 unloadConv = '' 344 for dReg in range(dRegs): 345 loadConv += ''' 346 conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0.uw); 347 conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1.uw); 348 ''' % { "dReg" : dReg } 349 unloadConv += ''' 350 FpDestP%(sReg0)d.uw = gtoh(conv2.cRegs[%(sReg0)d]); 351 FpDestP%(sReg1)d.uw = gtoh(conv2.cRegs[%(sReg1)d]); 352 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 353 microInterNeonCode = ''' 354 const unsigned dRegs = %(dRegs)d; 355 const unsigned regs = 2 * dRegs; 356 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 357 sizeof(Element); 358 union convStruct { 359 FloatRegBits cRegs[regs]; 360 Element elements[dRegs * perDReg]; 361 } conv1, conv2; 362 363 %(loadConv)s 364 365 unsigned destElem = 0; 366 for (unsigned srcOffset = 0; 367 srcOffset < perDReg; srcOffset++) { 368 for (unsigned dReg = 0; dReg < dRegs; dReg++) { 369 conv2.elements[destElem++] = 370 conv1.elements[dReg * perDReg + srcOffset]; 371 } 372 } 373 374 %(unloadConv)s 375 ''' % { "dRegs" : dRegs, 376 "loadConv" : loadConv, 377 "unloadConv" : unloadConv } 378 microInterNeonIop = \ 379 InstObjParams('interneon%duop' % (dRegs * 2), 380 'MicroInterNeon%dUop' % (dRegs * 2), 381 'MicroNeonMixOp', 382 { 'predicate_test': predicateTest, 383 'code' : microInterNeonCode }, 384 ['IsMicroop']) 385 header_output += MicroNeonMixDeclare.subst(microInterNeonIop) 386 exec_output += MicroNeonMixExecute.subst(microInterNeonIop) 387}}; 388 389let {{ 390 exec_output = '' 391 for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'): 392 for dRegs in (2, 3, 4): 393 Name = "MicroDeintNeon%dUop" % (dRegs * 2) 394 substDict = { "class_name" : Name, "targs" : type } 395 exec_output += MicroNeonExecDeclare.subst(substDict) 396 Name = "MicroInterNeon%dUop" % (dRegs * 2) 397 substDict = { "class_name" : Name, "targs" : type } 398 exec_output += MicroNeonExecDeclare.subst(substDict) 399}}; 400 401//////////////////////////////////////////////////////////////////// 402// 403// Neon microops to pack/unpack a single lane 404// 405 406let {{ 407 header_output = exec_output = '' 408 for sRegs in 1, 2: 409 baseLoadRegs = '' 410 for reg in range(sRegs): 411 baseLoadRegs += ''' 412 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 413 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 414 ''' % { "reg0" : (2 * reg + 0), 415 "reg1" : (2 * reg + 1) } 416 for dRegs in range(sRegs, 5): 417 unloadRegs = '' 418 loadRegs = baseLoadRegs 419 for reg in range(dRegs): 420 loadRegs += ''' 421 destRegs[%(reg)d].fRegs[0] = htog(FpDestS%(reg)dP0.uw); 422 destRegs[%(reg)d].fRegs[1] = htog(FpDestS%(reg)dP1.uw); 423 ''' % { "reg" : reg } 424 unloadRegs += ''' 425 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 426 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 427 ''' % { "reg" : reg } 428 microUnpackNeonCode = ''' 429 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 430 sizeof(Element); 431 432 union SourceRegs { 433 FloatRegBits fRegs[2 * %(sRegs)d]; 434 Element elements[%(sRegs)d * perDReg]; 435 } sourceRegs; 436 437 union DestReg { 438 FloatRegBits fRegs[2]; 439 Element elements[perDReg]; 440 } destRegs[%(dRegs)d]; 441 442 %(loadRegs)s 443 444 for (unsigned i = 0; i < %(dRegs)d; i++) { 445 destRegs[i].elements[lane] = sourceRegs.elements[i]; 446 } 447 448 %(unloadRegs)s 449 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 450 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 451 452 microUnpackNeonIop = \ 453 InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2), 454 'MicroUnpackNeon%dto%dUop' % 455 (sRegs * 2, dRegs * 2), 456 'MicroNeonMixLaneOp', 457 { 'predicate_test': predicateTest, 458 'code' : microUnpackNeonCode }, 459 ['IsMicroop']) 460 header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop) 461 exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop) 462 463 for sRegs in 1, 2: 464 loadRegs = '' 465 for reg in range(sRegs): 466 loadRegs += ''' 467 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 468 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 469 ''' % { "reg0" : (2 * reg + 0), 470 "reg1" : (2 * reg + 1) } 471 for dRegs in range(sRegs, 5): 472 unloadRegs = '' 473 for reg in range(dRegs): 474 unloadRegs += ''' 475 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 476 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 477 ''' % { "reg" : reg } 478 microUnpackAllNeonCode = ''' 479 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 480 sizeof(Element); 481 482 union SourceRegs { 483 FloatRegBits fRegs[2 * %(sRegs)d]; 484 Element elements[%(sRegs)d * perDReg]; 485 } sourceRegs; 486 487 union DestReg { 488 FloatRegBits fRegs[2]; 489 Element elements[perDReg]; 490 } destRegs[%(dRegs)d]; 491 492 %(loadRegs)s 493 494 for (unsigned i = 0; i < %(dRegs)d; i++) { 495 for (unsigned j = 0; j < perDReg; j++) 496 destRegs[i].elements[j] = sourceRegs.elements[i]; 497 } 498 499 %(unloadRegs)s 500 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 501 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 502 503 microUnpackAllNeonIop = \ 504 InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2), 505 'MicroUnpackAllNeon%dto%dUop' % 506 (sRegs * 2, dRegs * 2), 507 'MicroNeonMixOp', 508 { 'predicate_test': predicateTest, 509 'code' : microUnpackAllNeonCode }, 510 ['IsMicroop']) 511 header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop) 512 exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop) 513 514 for dRegs in 1, 2: 515 unloadRegs = '' 516 for reg in range(dRegs): 517 unloadRegs += ''' 518 FpDestP%(reg0)d.uw = gtoh(destRegs.fRegs[%(reg0)d]); 519 FpDestP%(reg1)d.uw = gtoh(destRegs.fRegs[%(reg1)d]); 520 ''' % { "reg0" : (2 * reg + 0), 521 "reg1" : (2 * reg + 1) } 522 for sRegs in range(dRegs, 5): 523 loadRegs = '' 524 for reg in range(sRegs): 525 loadRegs += ''' 526 sourceRegs[%(reg)d].fRegs[0] = htog(FpOp1S%(reg)dP0.uw); 527 sourceRegs[%(reg)d].fRegs[1] = htog(FpOp1S%(reg)dP1.uw); 528 ''' % { "reg" : reg } 529 microPackNeonCode = ''' 530 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 531 sizeof(Element); 532 533 union SourceReg { 534 FloatRegBits fRegs[2]; 535 Element elements[perDReg]; 536 } sourceRegs[%(sRegs)d]; 537 538 union DestRegs { 539 FloatRegBits fRegs[2 * %(dRegs)d]; 540 Element elements[%(dRegs)d * perDReg]; 541 } destRegs; 542 543 %(loadRegs)s 544 545 for (unsigned i = 0; i < %(sRegs)d; i++) { 546 destRegs.elements[i] = sourceRegs[i].elements[lane]; 547 } 548 549 %(unloadRegs)s 550 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 551 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 552 553 microPackNeonIop = \ 554 InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2), 555 'MicroPackNeon%dto%dUop' % 556 (sRegs * 2, dRegs * 2), 557 'MicroNeonMixLaneOp', 558 { 'predicate_test': predicateTest, 559 'code' : microPackNeonCode }, 560 ['IsMicroop']) 561 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop) 562 exec_output += MicroNeonMixExecute.subst(microPackNeonIop) 563}}; 564 565let {{ 566 exec_output = '' 567 for type in ('uint8_t', 'uint16_t', 'uint32_t'): 568 for sRegs in 1, 2: 569 for dRegs in range(sRegs, 5): 570 for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop", 571 "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop", 572 "MicroPackNeon%(dRegs)dto%(sRegs)dUop"): 573 Name = format % { "sRegs" : sRegs * 2, 574 "dRegs" : dRegs * 2 } 575 substDict = { "class_name" : Name, "targs" : type } 576 exec_output += MicroNeonExecDeclare.subst(substDict) 577}}; 578 579//////////////////////////////////////////////////////////////////// 580// 581// Integer = Integer op Immediate microops 582// 583 584let {{ 585 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop', 586 'MicroIntImmOp', 587 {'code': 'URa = URb + imm;', 588 'predicate_test': predicateTest}, 589 ['IsMicroop']) 590 591 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop', 592 'MicroIntRegOp', 593 {'code': 594 '''URa = URb + shift_rm_imm(URc, shiftAmt, 595 shiftType, 596 CondCodesC); 597 ''', 598 'predicate_test': predicateTest}, 599 ['IsMicroop']) 600 601 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop', 602 'MicroIntImmOp', 603 {'code': 'URa = URb - imm;', 604 'predicate_test': predicateTest}, 605 ['IsMicroop']) 606 607 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop', 608 'MicroIntRegOp', 609 {'code': 610 '''URa = URb - shift_rm_imm(URc, shiftAmt, 611 shiftType, 612 CondCodesC); 613 ''', 614 'predicate_test': predicateTest}, 615 ['IsMicroop']) 616 617 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov', 618 'MicroIntMov', 619 {'code': 'IWRa = URb;', 620 'predicate_test': predicateTest}, 621 ['IsMicroop']) 622 623 microUopRegMovRetIop = InstObjParams('movret_uop', 'MicroUopRegMovRet', 624 'MicroIntMov', 625 {'code': microRetUopCode % 'URb', 626 'predicate_test': predicateTest}, 627 ['IsMicroop', 'IsNonSpeculative', 628 'IsSerializeAfter']) 629 630 setPCCPSRDecl = ''' 631 CPSR cpsrOrCondCodes = URc; 632 SCTLR sctlr = Sctlr; 633 pNPC = URa; 634 CPSR new_cpsr = 635 cpsrWriteByInstr(cpsrOrCondCodes, URb, 636 0xF, true, sctlr.nmfi); 637 Cpsr = ~CondCodesMask & new_cpsr; 638 NextThumb = new_cpsr.t; 639 NextJazelle = new_cpsr.j; 640 NextItState = ((((CPSR)URb).it2 << 2) & 0xFC) 641 | (((CPSR)URb).it1 & 0x3); 642 CondCodesNZ = new_cpsr.nz; 643 CondCodesC = new_cpsr.c; 644 CondCodesV = new_cpsr.v; 645 CondCodesGE = new_cpsr.ge; 646 ''' 647 648 microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR', 649 'MicroSetPCCPSR', 650 {'code': setPCCPSRDecl, 651 'predicate_test': predicateTest}, 652 ['IsMicroop']) 653 654 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \ 655 MicroIntImmDeclare.subst(microSubiUopIop) + \ 656 MicroIntRegDeclare.subst(microAddUopIop) + \ 657 MicroIntRegDeclare.subst(microSubUopIop) + \ 658 MicroIntMovDeclare.subst(microUopRegMovIop) + \ 659 MicroIntMovDeclare.subst(microUopRegMovRetIop) + \ 660 MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop) 661 662 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \ 663 MicroIntImmConstructor.subst(microSubiUopIop) + \ 664 MicroIntRegConstructor.subst(microAddUopIop) + \ 665 MicroIntRegConstructor.subst(microSubUopIop) + \ 666 MicroIntMovConstructor.subst(microUopRegMovIop) + \ 667 MicroIntMovConstructor.subst(microUopRegMovRetIop) + \ 668 MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop) 669 670 exec_output = PredOpExecute.subst(microAddiUopIop) + \ 671 PredOpExecute.subst(microSubiUopIop) + \ 672 PredOpExecute.subst(microAddUopIop) + \ 673 PredOpExecute.subst(microSubUopIop) + \ 674 PredOpExecute.subst(microUopRegMovIop) + \ 675 PredOpExecute.subst(microUopRegMovRetIop) + \ 676 PredOpExecute.subst(microUopSetPCCPSRIop) 677 678}}; 679 680let {{ 681 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", []) 682 header_output = MacroMemDeclare.subst(iop) 683 decoder_output = MacroMemConstructor.subst(iop) 684 685 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", []) 686 header_output += VMemMultDeclare.subst(iop) 687 decoder_output += VMemMultConstructor.subst(iop) 688 689 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", []) 690 header_output += VMemSingleDeclare.subst(iop) 691 decoder_output += VMemSingleConstructor.subst(iop) 692 693 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", []) 694 header_output += VMemMultDeclare.subst(iop) 695 decoder_output += VMemMultConstructor.subst(iop) 696 697 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", []) 698 header_output += VMemSingleDeclare.subst(iop) 699 decoder_output += VMemSingleConstructor.subst(iop) 700 701 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", []) 702 header_output += MacroVFPMemDeclare.subst(vfpIop) 703 decoder_output += MacroVFPMemConstructor.subst(vfpIop) 704}}; 705