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