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