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