macromem.isa revision 7858
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 ForcedItState = ((((CPSR)Spsr).it2 << 2) & 0xFC) 98 | (((CPSR)Spsr).it1 & 0x3); 99 ''' 100 microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', 101 'MicroMemOp', 102 {'memacc_code': microLdrRetUopCode, 103 'ea_code': 104 'EA = Rb + (up ? imm : -imm);', 105 'predicate_test': condPredicateTest}, 106 ['IsMicroop','IsNonSpeculative','IsSerializeAfter']) 107 108 microStrUopCode = "Mem = cSwap(Ra.uw, ((CPSR)Cpsr).e);" 109 microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 110 'MicroMemOp', 111 {'memacc_code': microStrUopCode, 112 'postacc_code': "", 113 'ea_code': 'EA = Rb + (up ? imm : -imm);', 114 'predicate_test': predicateTest}, 115 ['IsMicroop']) 116 117 microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 118 microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop', 119 'MicroMemOp', 120 {'memacc_code': microStrFpUopCode, 121 'postacc_code': "", 122 'ea_code': vfpEnabledCheckCode + 123 'EA = Rb + (up ? imm : -imm);', 124 'predicate_test': predicateTest}, 125 ['IsMicroop']) 126 127 microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 128 microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop', 129 'MicroMemOp', 130 {'memacc_code': microStrFpUopCode, 131 'postacc_code': "", 132 'ea_code': vfpEnabledCheckCode + ''' 133 EA = Rb + (up ? imm : -imm) + 134 (((CPSR)Cpsr).e ? 4 : 0); 135 ''', 136 'predicate_test': predicateTest}, 137 ['IsMicroop']) 138 139 microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 140 microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop', 141 'MicroMemOp', 142 {'memacc_code': microStrFpUopCode, 143 'postacc_code': "", 144 'ea_code': vfpEnabledCheckCode + ''' 145 EA = Rb + (up ? imm : -imm) - 146 (((CPSR)Cpsr).e ? 4 : 0); 147 ''', 148 'predicate_test': predicateTest}, 149 ['IsMicroop']) 150 151 header_output = decoder_output = exec_output = '' 152 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) 160 for iop in loadIops: 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) 168}}; 169 170let {{ 171 exec_output = header_output = '' 172 173 eaCode = 'EA = Ra + imm;' 174 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 } 179 memDecl = ''' 180 union MemUnion { 181 uint8_t bytes[%(size)d]; 182 Element elements[%(size)d / sizeof(Element)]; 183 uint32_t floatRegBits[%(regs)d]; 184 }; 185 ''' % subst 186 187 # Do endian conversion for all the elements. 188 convCode = ''' 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]); 194 } 195 } else { 196 for (unsigned i = 0; i < eCount; i++) { 197 memUnion.elements[i] = gtole(memUnion.elements[i]); 198 } 199 } 200 ''' 201 202 # Offload everything into registers 203 regSetCode = '' 204 for reg in range(regs): 205 mask = '' 206 if reg == regs - 1: 207 mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size)) 208 regSetCode += ''' 209 FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s; 210 ''' % { "reg" : reg, "mask" : mask } 211 212 # Pull everything in from registers 213 regGetCode = '' 214 for reg in range(regs): 215 regGetCode += ''' 216 memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw); 217 ''' % { "reg" : reg } 218 219 loadMemAccCode = convCode + regSetCode 220 storeMemAccCode = regGetCode + convCode 221 222 loadIop = InstObjParams('ldrneon%(size)d_uop' % subst, 223 'MicroLdrNeon%(size)dUop' % subst, 224 'MicroNeonMemOp', 225 { 'mem_decl' : memDecl, 226 'size' : size, 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, 233 'MicroNeonMemOp', 234 { 'mem_decl' : memDecl, 235 'size' : size, 236 'memacc_code' : storeMemAccCode, 237 'ea_code' : simdEnabledCheckCode + eaCode, 238 'predicate_test' : predicateTest }, 239 [ 'IsMicroop', 'IsMemRef', 'IsStore' ]) 240 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) 249}}; 250 251let {{ 252 exec_output = '' 253 for eSize, type in (1, 'uint8_t'), \ 254 (2, 'uint16_t'), \ 255 (4, 'uint32_t'), \ 256 (8, 'uint64_t'): 257 size = eSize 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. 260 sizes = set((16, 8)) 261 for count in 1, 2, 3, 4: 262 size = count * eSize 263 if size <= 16: 264 sizes.add(size) 265 for size in sizes: 266 substDict = { 267 "class_name" : "MicroLdrNeon%dUop" % size, 268 "targs" : type 269 } 270 exec_output += MicroNeonMemExecDeclare.subst(substDict) 271 substDict["class_name"] = "MicroStrNeon%dUop" % size 272 exec_output += MicroNeonMemExecDeclare.subst(substDict) 273 size += eSize 274}}; 275 276//////////////////////////////////////////////////////////////////// 277// 278// Neon (de)interlacing microops 279// 280 281let {{ 282 header_output = exec_output = '' 283 for dRegs in (2, 3, 4): 284 loadConv = '' 285 unloadConv = '' 286 for dReg in range(dRegs): 287 loadConv += ''' 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) } 291 unloadConv += ''' 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)) / 299 sizeof(Element); 300 union convStruct { 301 FloatRegBits cRegs[regs]; 302 Element elements[dRegs * perDReg]; 303 } conv1, conv2; 304 305 %(loadConv)s 306 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++]; 313 } 314 } 315 316 %(unloadConv)s 317 ''' % { "dRegs" : dRegs, 318 "loadConv" : loadConv, 319 "unloadConv" : unloadConv } 320 microDeintNeonIop = \ 321 InstObjParams('deintneon%duop' % (dRegs * 2), 322 'MicroDeintNeon%dUop' % (dRegs * 2), 323 'MicroNeonMixOp', 324 { 'predicate_test': predicateTest, 325 'code' : microDeintNeonCode }, 326 ['IsMicroop']) 327 header_output += MicroNeonMixDeclare.subst(microDeintNeonIop) 328 exec_output += MicroNeonMixExecute.subst(microDeintNeonIop) 329 330 loadConv = '' 331 unloadConv = '' 332 for dReg in range(dRegs): 333 loadConv += ''' 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 } 337 unloadConv += ''' 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)) / 345 sizeof(Element); 346 union convStruct { 347 FloatRegBits cRegs[regs]; 348 Element elements[dRegs * perDReg]; 349 } conv1, conv2; 350 351 %(loadConv)s 352 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]; 359 } 360 } 361 362 %(unloadConv)s 363 ''' % { "dRegs" : dRegs, 364 "loadConv" : loadConv, 365 "unloadConv" : unloadConv } 366 microInterNeonIop = \ 367 InstObjParams('interneon%duop' % (dRegs * 2), 368 'MicroInterNeon%dUop' % (dRegs * 2), 369 'MicroNeonMixOp', 370 { 'predicate_test': predicateTest, 371 'code' : microInterNeonCode }, 372 ['IsMicroop']) 373 header_output += MicroNeonMixDeclare.subst(microInterNeonIop) 374 exec_output += MicroNeonMixExecute.subst(microInterNeonIop) 375}}; 376 377let {{ 378 exec_output = '' 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) 387}}; 388 389//////////////////////////////////////////////////////////////////// 390// 391// Neon microops to pack/unpack a single lane 392// 393 394let {{ 395 header_output = exec_output = '' 396 for sRegs in 1, 2: 397 baseLoadRegs = '' 398 for reg in range(sRegs): 399 baseLoadRegs += ''' 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): 405 unloadRegs = '' 406 loadRegs = baseLoadRegs 407 for reg in range(dRegs): 408 loadRegs += ''' 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 } 412 unloadRegs += ''' 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)) / 418 sizeof(Element); 419 420 union SourceRegs { 421 FloatRegBits fRegs[2 * %(sRegs)d]; 422 Element elements[%(sRegs)d * perDReg]; 423 } sourceRegs; 424 425 union DestReg { 426 FloatRegBits fRegs[2]; 427 Element elements[perDReg]; 428 } destRegs[%(dRegs)d]; 429 430 %(loadRegs)s 431 432 for (unsigned i = 0; i < %(dRegs)d; i++) { 433 destRegs[i].elements[lane] = sourceRegs.elements[i]; 434 } 435 436 %(unloadRegs)s 437 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 438 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 439 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 }, 447 ['IsMicroop']) 448 header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop) 449 exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop) 450 451 for sRegs in 1, 2: 452 loadRegs = '' 453 for reg in range(sRegs): 454 loadRegs += ''' 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): 460 unloadRegs = '' 461 for reg in range(dRegs): 462 unloadRegs += ''' 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)) / 468 sizeof(Element); 469 470 union SourceRegs { 471 FloatRegBits fRegs[2 * %(sRegs)d]; 472 Element elements[%(sRegs)d * perDReg]; 473 } sourceRegs; 474 475 union DestReg { 476 FloatRegBits fRegs[2]; 477 Element elements[perDReg]; 478 } destRegs[%(dRegs)d]; 479 480 %(loadRegs)s 481 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]; 485 } 486 487 %(unloadRegs)s 488 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 489 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 490 491 microUnpackAllNeonIop = \ 492 InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2), 493 'MicroUnpackAllNeon%dto%dUop' % 494 (sRegs * 2, dRegs * 2), 495 'MicroNeonMixOp', 496 { 'predicate_test': predicateTest, 497 'code' : microUnpackAllNeonCode }, 498 ['IsMicroop']) 499 header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop) 500 exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop) 501 502 for dRegs in 1, 2: 503 unloadRegs = '' 504 for reg in range(dRegs): 505 unloadRegs += ''' 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): 511 loadRegs = '' 512 for reg in range(sRegs): 513 loadRegs += ''' 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)) / 519 sizeof(Element); 520 521 union SourceReg { 522 FloatRegBits fRegs[2]; 523 Element elements[perDReg]; 524 } sourceRegs[%(sRegs)d]; 525 526 union DestRegs { 527 FloatRegBits fRegs[2 * %(dRegs)d]; 528 Element elements[%(dRegs)d * perDReg]; 529 } destRegs; 530 531 %(loadRegs)s 532 533 for (unsigned i = 0; i < %(sRegs)d; i++) { 534 destRegs.elements[i] = sourceRegs[i].elements[lane]; 535 } 536 537 %(unloadRegs)s 538 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 539 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 540 541 microPackNeonIop = \ 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 }, 548 ['IsMicroop']) 549 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop) 550 exec_output += MicroNeonMixExecute.subst(microPackNeonIop) 551}}; 552 553let {{ 554 exec_output = '' 555 for type in ('uint8_t', 'uint16_t', 'uint32_t'): 556 for sRegs in 1, 2: 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) 565}}; 566 567//////////////////////////////////////////////////////////////////// 568// 569// Integer = Integer op Immediate microops 570// 571 572let {{ 573 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop', 574 'MicroIntImmOp', 575 {'code': 'Ra = Rb + imm;', 576 'predicate_test': predicateTest}, 577 ['IsMicroop']) 578 579 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop', 580 'MicroIntRegOp', 581 {'code': 582 '''Ra = Rb + shift_rm_imm(Rc, shiftAmt, 583 shiftType, 584 CondCodes<29:>); 585 ''', 586 'predicate_test': predicateTest}, 587 ['IsMicroop']) 588 589 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop', 590 'MicroIntImmOp', 591 {'code': 'Ra = Rb - imm;', 592 'predicate_test': predicateTest}, 593 ['IsMicroop']) 594 595 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop', 596 'MicroIntRegOp', 597 {'code': 598 '''Ra = Rb - shift_rm_imm(Rc, shiftAmt, 599 shiftType, 600 CondCodes<29:>); 601 ''', 602 'predicate_test': predicateTest}, 603 ['IsMicroop']) 604 605 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov', 606 'MicroIntMov', 607 {'code': 'IWRa = Rb;', 608 'predicate_test': predicateTest}, 609 ['IsMicroop']) 610 611 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \ 612 MicroIntImmDeclare.subst(microSubiUopIop) + \ 613 MicroIntRegDeclare.subst(microAddUopIop) + \ 614 MicroIntRegDeclare.subst(microSubUopIop) + \ 615 MicroIntMovDeclare.subst(microUopRegMovIop) 616 617 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \ 618 MicroIntImmConstructor.subst(microSubiUopIop) + \ 619 MicroIntRegConstructor.subst(microAddUopIop) + \ 620 MicroIntRegConstructor.subst(microSubUopIop) + \ 621 MicroIntMovConstructor.subst(microUopRegMovIop) 622 623 exec_output = PredOpExecute.subst(microAddiUopIop) + \ 624 PredOpExecute.subst(microSubiUopIop) + \ 625 PredOpExecute.subst(microAddUopIop) + \ 626 PredOpExecute.subst(microSubUopIop) + \ 627 PredOpExecute.subst(microUopRegMovIop) 628}}; 629 630let {{ 631 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", []) 632 header_output = MacroMemDeclare.subst(iop) 633 decoder_output = MacroMemConstructor.subst(iop) 634 635 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", []) 636 header_output += VMemMultDeclare.subst(iop) 637 decoder_output += VMemMultConstructor.subst(iop) 638 639 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", []) 640 header_output += VMemSingleDeclare.subst(iop) 641 decoder_output += VMemSingleConstructor.subst(iop) 642 643 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", []) 644 header_output += VMemMultDeclare.subst(iop) 645 decoder_output += VMemMultConstructor.subst(iop) 646 647 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", []) 648 header_output += VMemSingleDeclare.subst(iop) 649 decoder_output += VMemSingleConstructor.subst(iop) 650 651 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", []) 652 header_output += MacroVFPMemDeclare.subst(vfpIop) 653 decoder_output += MacroVFPMemConstructor.subst(vfpIop) 654}}; 655