macromem.isa revision 8285
12810SN/A// -*- mode:c++ -*- 211893Snikos.nikoleris@arm.com 39796Sprakash.ramrakhyani@arm.com// Copyright (c) 2010 ARM Limited 49796Sprakash.ramrakhyani@arm.com// All rights reserved 59796Sprakash.ramrakhyani@arm.com// 69796Sprakash.ramrakhyani@arm.com// The license below extends only to copyright in the software and shall 79796Sprakash.ramrakhyani@arm.com// not be construed as granting a license to any other intellectual 89796Sprakash.ramrakhyani@arm.com// property including but not limited to intellectual property relating 99796Sprakash.ramrakhyani@arm.com// to a hardware implementation of the functionality of the software 109796Sprakash.ramrakhyani@arm.com// licensed hereunder. You may use the software subject to the license 119796Sprakash.ramrakhyani@arm.com// terms below provided that you ensure that this notice is replicated 129796Sprakash.ramrakhyani@arm.com// unmodified and in its entirety in all distributions of the software, 139796Sprakash.ramrakhyani@arm.com// modified or unmodified, in source code or in binary form. 142810SN/A// 152810SN/A// Copyright (c) 2007-2008 The Florida State University 162810SN/A// All rights reserved. 172810SN/A// 182810SN/A// Redistribution and use in source and binary forms, with or without 192810SN/A// modification, are permitted provided that the following conditions are 202810SN/A// met: redistributions of source code must retain the above copyright 212810SN/A// notice, this list of conditions and the following disclaimer; 222810SN/A// redistributions in binary form must reproduce the above copyright 232810SN/A// notice, this list of conditions and the following disclaimer in the 242810SN/A// documentation and/or other materials provided with the distribution; 252810SN/A// neither the name of the copyright holders nor the names of its 262810SN/A// contributors may be used to endorse or promote products derived from 272810SN/A// this software without specific prior written permission. 282810SN/A// 292810SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302810SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312810SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322810SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332810SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342810SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352810SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362810SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372810SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382810SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392810SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402810SN/A// 412810SN/A// Authors: Stephen Hines 422810SN/A// Gabe Black 432810SN/A 442810SN/A//////////////////////////////////////////////////////////////////// 452810SN/A// 462810SN/A// Load/store microops 472810SN/A// 482810SN/A 4911486Snikos.nikoleris@arm.comlet {{ 5011486Snikos.nikoleris@arm.com microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 518229Snate@binkert.org microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop', 525338Sstever@gmail.com 'MicroMemOp', 532810SN/A {'memacc_code': microLdrUopCode, 542810SN/A 'ea_code': 'EA = URb + (up ? imm : -imm);', 552810SN/A 'predicate_test': predicateTest}, 562810SN/A ['IsMicroop']) 579796Sprakash.ramrakhyani@arm.com 5811893Snikos.nikoleris@arm.com microLdrFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 5911893Snikos.nikoleris@arm.com microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop', 6011722Ssophiane.senni@gmail.com 'MicroMemOp', 6111722Ssophiane.senni@gmail.com {'memacc_code': microLdrFpUopCode, 6211722Ssophiane.senni@gmail.com 'ea_code': vfpEnabledCheckCode + 6311722Ssophiane.senni@gmail.com 'EA = URb + (up ? imm : -imm);', 6412513Sodanrc@yahoo.com.br 'predicate_test': predicateTest}, 6512513Sodanrc@yahoo.com.br ['IsMicroop']) 6610360Sandreas.hansson@arm.com 679796Sprakash.ramrakhyani@arm.com microLdrDBFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 689796Sprakash.ramrakhyani@arm.com microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop', 699796Sprakash.ramrakhyani@arm.com 'MicroMemOp', 702810SN/A {'memacc_code': microLdrFpUopCode, 712810SN/A 'ea_code': vfpEnabledCheckCode + ''' 722810SN/A EA = URb + (up ? imm : -imm) + 7310360Sandreas.hansson@arm.com (((CPSR)Cpsr).e ? 4 : 0); 742810SN/A ''', 752810SN/A 'predicate_test': predicateTest}, 762810SN/A ['IsMicroop']) 772810SN/A 789796Sprakash.ramrakhyani@arm.com microLdrDTFpUopCode = "Fa.uw = cSwap(Mem.uw, ((CPSR)Cpsr).e);" 792810SN/A microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop', 8011522Sstephan.diestelhorst@arm.com 'MicroMemOp', 8111522Sstephan.diestelhorst@arm.com {'memacc_code': microLdrFpUopCode, 822810SN/A 'ea_code': vfpEnabledCheckCode + ''' 8311522Sstephan.diestelhorst@arm.com EA = URb + (up ? imm : -imm) - 842810SN/A (((CPSR)Cpsr).e ? 4 : 0); 852810SN/A ''', 869796Sprakash.ramrakhyani@arm.com 'predicate_test': predicateTest}, 872810SN/A ['IsMicroop']) 882810SN/A 892810SN/A microRetUopCode = ''' 902810SN/A CPSR cpsr = Cpsr; 912810SN/A SCTLR sctlr = Sctlr; 929796Sprakash.ramrakhyani@arm.com uint32_t newCpsr = 932810SN/A cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi); 942810SN/A Cpsr = ~CondCodesMask & newCpsr; 952810SN/A CondCodes = CondCodesMask & newCpsr; 962810SN/A IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0); 979796Sprakash.ramrakhyani@arm.com NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC) 982810SN/A | (((CPSR)Spsr).it1 & 0x3); 992810SN/A SevMailbox = 1; 1002810SN/A ''' 1012810SN/A 1029796Sprakash.ramrakhyani@arm.com microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', 1032810SN/A 'MicroMemOp', 1042810SN/A {'memacc_code': 1052810SN/A microRetUopCode % 'Mem.uw', 1062810SN/A 'ea_code': 1079796Sprakash.ramrakhyani@arm.com 'EA = URb + (up ? imm : -imm);', 1082810SN/A 'predicate_test': condPredicateTest}, 1092810SN/A ['IsMicroop','IsNonSpeculative', 1102810SN/A 'IsSerializeAfter']) 1112810SN/A 1122810SN/A microStrUopCode = "Mem = cSwap(URa.uw, ((CPSR)Cpsr).e);" 1132810SN/A microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 1149796Sprakash.ramrakhyani@arm.com 'MicroMemOp', 1152810SN/A {'memacc_code': microStrUopCode, 1162810SN/A 'postacc_code': "", 1172810SN/A 'ea_code': 'EA = URb + (up ? imm : -imm);', 1186978SLisa.Hsu@amd.com 'predicate_test': predicateTest}, 1198833Sdam.sunwoo@arm.com ['IsMicroop']) 1209796Sprakash.ramrakhyani@arm.com 1218833Sdam.sunwoo@arm.com microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1226978SLisa.Hsu@amd.com microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop', 1236978SLisa.Hsu@amd.com 'MicroMemOp', 1248833Sdam.sunwoo@arm.com {'memacc_code': microStrFpUopCode, 1258833Sdam.sunwoo@arm.com 'postacc_code': "", 1268833Sdam.sunwoo@arm.com 'ea_code': vfpEnabledCheckCode + 1276978SLisa.Hsu@amd.com 'EA = URb + (up ? imm : -imm);', 1286978SLisa.Hsu@amd.com 'predicate_test': predicateTest}, 1299796Sprakash.ramrakhyani@arm.com ['IsMicroop']) 1306978SLisa.Hsu@amd.com 1318833Sdam.sunwoo@arm.com microStrDBFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 1326978SLisa.Hsu@amd.com microStrDBFpUopIop = InstObjParams('strfp_uop', 'MicroStrDBFpUop', 1338833Sdam.sunwoo@arm.com 'MicroMemOp', 1348833Sdam.sunwoo@arm.com {'memacc_code': microStrFpUopCode, 1358833Sdam.sunwoo@arm.com 'postacc_code': "", 1366978SLisa.Hsu@amd.com 'ea_code': vfpEnabledCheckCode + ''' 1376978SLisa.Hsu@amd.com EA = URb + (up ? imm : -imm) + 1386978SLisa.Hsu@amd.com (((CPSR)Cpsr).e ? 4 : 0); 13910024Sdam.sunwoo@arm.com ''', 14010024Sdam.sunwoo@arm.com 'predicate_test': predicateTest}, 14110024Sdam.sunwoo@arm.com ['IsMicroop']) 14210024Sdam.sunwoo@arm.com 14310024Sdam.sunwoo@arm.com microStrDTFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" 14410024Sdam.sunwoo@arm.com microStrDTFpUopIop = InstObjParams('strfp_uop', 'MicroStrDTFpUop', 14510024Sdam.sunwoo@arm.com 'MicroMemOp', 14610024Sdam.sunwoo@arm.com {'memacc_code': microStrFpUopCode, 14710024Sdam.sunwoo@arm.com 'postacc_code': "", 14810024Sdam.sunwoo@arm.com 'ea_code': vfpEnabledCheckCode + ''' 14910024Sdam.sunwoo@arm.com EA = URb + (up ? imm : -imm) - 15010024Sdam.sunwoo@arm.com (((CPSR)Cpsr).e ? 4 : 0); 15110024Sdam.sunwoo@arm.com ''', 15210024Sdam.sunwoo@arm.com 'predicate_test': predicateTest}, 15310024Sdam.sunwoo@arm.com ['IsMicroop']) 15410024Sdam.sunwoo@arm.com 15510024Sdam.sunwoo@arm.com header_output = decoder_output = exec_output = '' 15610024Sdam.sunwoo@arm.com 15710024Sdam.sunwoo@arm.com loadIops = (microLdrUopIop, microLdrRetUopIop, 15810024Sdam.sunwoo@arm.com microLdrFpUopIop, microLdrDBFpUopIop, microLdrDTFpUopIop) 15910024Sdam.sunwoo@arm.com storeIops = (microStrUopIop, microStrFpUopIop, 16010024Sdam.sunwoo@arm.com microStrDBFpUopIop, microStrDTFpUopIop) 16110025Stimothy.jones@arm.com for iop in loadIops + storeIops: 16210025Stimothy.jones@arm.com header_output += MicroMemDeclare.subst(iop) 16310025Stimothy.jones@arm.com decoder_output += MicroMemConstructor.subst(iop) 16410025Stimothy.jones@arm.com for iop in loadIops: 16510025Stimothy.jones@arm.com exec_output += LoadExecute.subst(iop) + \ 16610025Stimothy.jones@arm.com LoadInitiateAcc.subst(iop) + \ 16710025Stimothy.jones@arm.com LoadCompleteAcc.subst(iop) 16810025Stimothy.jones@arm.com for iop in storeIops: 16910025Stimothy.jones@arm.com exec_output += StoreExecute.subst(iop) + \ 17010025Stimothy.jones@arm.com StoreInitiateAcc.subst(iop) + \ 17110024Sdam.sunwoo@arm.com StoreCompleteAcc.subst(iop) 1722810SN/A}}; 1732810SN/A 174let {{ 175 exec_output = header_output = '' 176 177 eaCode = 'EA = URa + imm;' 178 179 for size in (1, 2, 3, 4, 6, 8, 12, 16): 180 # Set up the memory access. 181 regs = (size + 3) // 4 182 subst = { "size" : size, "regs" : regs } 183 memDecl = ''' 184 union MemUnion { 185 uint8_t bytes[%(size)d]; 186 Element elements[%(size)d / sizeof(Element)]; 187 uint32_t floatRegBits[%(regs)d]; 188 }; 189 ''' % subst 190 191 # Do endian conversion for all the elements. 192 convCode = ''' 193 const unsigned eCount = sizeof(memUnion.elements) / 194 sizeof(memUnion.elements[0]); 195 if (((CPSR)Cpsr).e) { 196 for (unsigned i = 0; i < eCount; i++) { 197 memUnion.elements[i] = gtobe(memUnion.elements[i]); 198 } 199 } else { 200 for (unsigned i = 0; i < eCount; i++) { 201 memUnion.elements[i] = gtole(memUnion.elements[i]); 202 } 203 } 204 ''' 205 206 # Offload everything into registers 207 regSetCode = '' 208 for reg in range(regs): 209 mask = '' 210 if reg == regs - 1: 211 mask = ' & mask(%d)' % (32 - 8 * (regs * 4 - size)) 212 regSetCode += ''' 213 FpDestP%(reg)d.uw = gtoh(memUnion.floatRegBits[%(reg)d])%(mask)s; 214 ''' % { "reg" : reg, "mask" : mask } 215 216 # Pull everything in from registers 217 regGetCode = '' 218 for reg in range(regs): 219 regGetCode += ''' 220 memUnion.floatRegBits[%(reg)d] = htog(FpDestP%(reg)d.uw); 221 ''' % { "reg" : reg } 222 223 loadMemAccCode = convCode + regSetCode 224 storeMemAccCode = regGetCode + convCode 225 226 loadIop = InstObjParams('ldrneon%(size)d_uop' % subst, 227 'MicroLdrNeon%(size)dUop' % subst, 228 'MicroNeonMemOp', 229 { 'mem_decl' : memDecl, 230 'size' : size, 231 'memacc_code' : loadMemAccCode, 232 'ea_code' : simdEnabledCheckCode + eaCode, 233 'predicate_test' : predicateTest }, 234 [ 'IsMicroop', 'IsMemRef', 'IsLoad' ]) 235 storeIop = InstObjParams('strneon%(size)d_uop' % subst, 236 'MicroStrNeon%(size)dUop' % subst, 237 'MicroNeonMemOp', 238 { 'mem_decl' : memDecl, 239 'size' : size, 240 'memacc_code' : storeMemAccCode, 241 'ea_code' : simdEnabledCheckCode + eaCode, 242 'predicate_test' : predicateTest }, 243 [ 'IsMicroop', 'IsMemRef', 'IsStore' ]) 244 245 exec_output += NeonLoadExecute.subst(loadIop) + \ 246 NeonLoadInitiateAcc.subst(loadIop) + \ 247 NeonLoadCompleteAcc.subst(loadIop) + \ 248 NeonStoreExecute.subst(storeIop) + \ 249 NeonStoreInitiateAcc.subst(storeIop) + \ 250 NeonStoreCompleteAcc.subst(storeIop) 251 header_output += MicroNeonMemDeclare.subst(loadIop) + \ 252 MicroNeonMemDeclare.subst(storeIop) 253}}; 254 255let {{ 256 exec_output = '' 257 for eSize, type in (1, 'uint8_t'), \ 258 (2, 'uint16_t'), \ 259 (4, 'uint32_t'), \ 260 (8, 'uint64_t'): 261 size = eSize 262 # An instruction handles no more than 16 bytes and no more than 263 # 4 elements, or the number of elements needed to fill 8 or 16 bytes. 264 sizes = set((16, 8)) 265 for count in 1, 2, 3, 4: 266 size = count * eSize 267 if size <= 16: 268 sizes.add(size) 269 for size in sizes: 270 substDict = { 271 "class_name" : "MicroLdrNeon%dUop" % size, 272 "targs" : type 273 } 274 exec_output += MicroNeonMemExecDeclare.subst(substDict) 275 substDict["class_name"] = "MicroStrNeon%dUop" % size 276 exec_output += MicroNeonMemExecDeclare.subst(substDict) 277 size += eSize 278}}; 279 280//////////////////////////////////////////////////////////////////// 281// 282// Neon (de)interlacing microops 283// 284 285let {{ 286 header_output = exec_output = '' 287 for dRegs in (2, 3, 4): 288 loadConv = '' 289 unloadConv = '' 290 for dReg in range(dRegs): 291 loadConv += ''' 292 conv1.cRegs[%(sReg0)d] = htog(FpOp1P%(sReg0)d.uw); 293 conv1.cRegs[%(sReg1)d] = htog(FpOp1P%(sReg1)d.uw); 294 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 295 unloadConv += ''' 296 FpDestS%(dReg)dP0.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 0]); 297 FpDestS%(dReg)dP1.uw = gtoh(conv2.cRegs[2 * %(dReg)d + 1]); 298 ''' % { "dReg" : dReg } 299 microDeintNeonCode = ''' 300 const unsigned dRegs = %(dRegs)d; 301 const unsigned regs = 2 * dRegs; 302 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 303 sizeof(Element); 304 union convStruct { 305 FloatRegBits cRegs[regs]; 306 Element elements[dRegs * perDReg]; 307 } conv1, conv2; 308 309 %(loadConv)s 310 311 unsigned srcElem = 0; 312 for (unsigned destOffset = 0; 313 destOffset < perDReg; destOffset++) { 314 for (unsigned dReg = 0; dReg < dRegs; dReg++) { 315 conv2.elements[dReg * perDReg + destOffset] = 316 conv1.elements[srcElem++]; 317 } 318 } 319 320 %(unloadConv)s 321 ''' % { "dRegs" : dRegs, 322 "loadConv" : loadConv, 323 "unloadConv" : unloadConv } 324 microDeintNeonIop = \ 325 InstObjParams('deintneon%duop' % (dRegs * 2), 326 'MicroDeintNeon%dUop' % (dRegs * 2), 327 'MicroNeonMixOp', 328 { 'predicate_test': predicateTest, 329 'code' : microDeintNeonCode }, 330 ['IsMicroop']) 331 header_output += MicroNeonMixDeclare.subst(microDeintNeonIop) 332 exec_output += MicroNeonMixExecute.subst(microDeintNeonIop) 333 334 loadConv = '' 335 unloadConv = '' 336 for dReg in range(dRegs): 337 loadConv += ''' 338 conv1.cRegs[2 * %(dReg)d + 0] = htog(FpOp1S%(dReg)dP0.uw); 339 conv1.cRegs[2 * %(dReg)d + 1] = htog(FpOp1S%(dReg)dP1.uw); 340 ''' % { "dReg" : dReg } 341 unloadConv += ''' 342 FpDestP%(sReg0)d.uw = gtoh(conv2.cRegs[%(sReg0)d]); 343 FpDestP%(sReg1)d.uw = gtoh(conv2.cRegs[%(sReg1)d]); 344 ''' % { "sReg0" : (dReg * 2), "sReg1" : (dReg * 2 + 1) } 345 microInterNeonCode = ''' 346 const unsigned dRegs = %(dRegs)d; 347 const unsigned regs = 2 * dRegs; 348 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 349 sizeof(Element); 350 union convStruct { 351 FloatRegBits cRegs[regs]; 352 Element elements[dRegs * perDReg]; 353 } conv1, conv2; 354 355 %(loadConv)s 356 357 unsigned destElem = 0; 358 for (unsigned srcOffset = 0; 359 srcOffset < perDReg; srcOffset++) { 360 for (unsigned dReg = 0; dReg < dRegs; dReg++) { 361 conv2.elements[destElem++] = 362 conv1.elements[dReg * perDReg + srcOffset]; 363 } 364 } 365 366 %(unloadConv)s 367 ''' % { "dRegs" : dRegs, 368 "loadConv" : loadConv, 369 "unloadConv" : unloadConv } 370 microInterNeonIop = \ 371 InstObjParams('interneon%duop' % (dRegs * 2), 372 'MicroInterNeon%dUop' % (dRegs * 2), 373 'MicroNeonMixOp', 374 { 'predicate_test': predicateTest, 375 'code' : microInterNeonCode }, 376 ['IsMicroop']) 377 header_output += MicroNeonMixDeclare.subst(microInterNeonIop) 378 exec_output += MicroNeonMixExecute.subst(microInterNeonIop) 379}}; 380 381let {{ 382 exec_output = '' 383 for type in ('uint8_t', 'uint16_t', 'uint32_t', 'uint64_t'): 384 for dRegs in (2, 3, 4): 385 Name = "MicroDeintNeon%dUop" % (dRegs * 2) 386 substDict = { "class_name" : Name, "targs" : type } 387 exec_output += MicroNeonExecDeclare.subst(substDict) 388 Name = "MicroInterNeon%dUop" % (dRegs * 2) 389 substDict = { "class_name" : Name, "targs" : type } 390 exec_output += MicroNeonExecDeclare.subst(substDict) 391}}; 392 393//////////////////////////////////////////////////////////////////// 394// 395// Neon microops to pack/unpack a single lane 396// 397 398let {{ 399 header_output = exec_output = '' 400 for sRegs in 1, 2: 401 baseLoadRegs = '' 402 for reg in range(sRegs): 403 baseLoadRegs += ''' 404 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 405 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 406 ''' % { "reg0" : (2 * reg + 0), 407 "reg1" : (2 * reg + 1) } 408 for dRegs in range(sRegs, 5): 409 unloadRegs = '' 410 loadRegs = baseLoadRegs 411 for reg in range(dRegs): 412 loadRegs += ''' 413 destRegs[%(reg)d].fRegs[0] = htog(FpDestS%(reg)dP0.uw); 414 destRegs[%(reg)d].fRegs[1] = htog(FpDestS%(reg)dP1.uw); 415 ''' % { "reg" : reg } 416 unloadRegs += ''' 417 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 418 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 419 ''' % { "reg" : reg } 420 microUnpackNeonCode = ''' 421 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 422 sizeof(Element); 423 424 union SourceRegs { 425 FloatRegBits fRegs[2 * %(sRegs)d]; 426 Element elements[%(sRegs)d * perDReg]; 427 } sourceRegs; 428 429 union DestReg { 430 FloatRegBits fRegs[2]; 431 Element elements[perDReg]; 432 } destRegs[%(dRegs)d]; 433 434 %(loadRegs)s 435 436 for (unsigned i = 0; i < %(dRegs)d; i++) { 437 destRegs[i].elements[lane] = sourceRegs.elements[i]; 438 } 439 440 %(unloadRegs)s 441 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 442 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 443 444 microUnpackNeonIop = \ 445 InstObjParams('unpackneon%dto%duop' % (sRegs * 2, dRegs * 2), 446 'MicroUnpackNeon%dto%dUop' % 447 (sRegs * 2, dRegs * 2), 448 'MicroNeonMixLaneOp', 449 { 'predicate_test': predicateTest, 450 'code' : microUnpackNeonCode }, 451 ['IsMicroop']) 452 header_output += MicroNeonMixLaneDeclare.subst(microUnpackNeonIop) 453 exec_output += MicroNeonMixExecute.subst(microUnpackNeonIop) 454 455 for sRegs in 1, 2: 456 loadRegs = '' 457 for reg in range(sRegs): 458 loadRegs += ''' 459 sourceRegs.fRegs[%(reg0)d] = htog(FpOp1P%(reg0)d.uw); 460 sourceRegs.fRegs[%(reg1)d] = htog(FpOp1P%(reg1)d.uw); 461 ''' % { "reg0" : (2 * reg + 0), 462 "reg1" : (2 * reg + 1) } 463 for dRegs in range(sRegs, 5): 464 unloadRegs = '' 465 for reg in range(dRegs): 466 unloadRegs += ''' 467 FpDestS%(reg)dP0.uw = gtoh(destRegs[%(reg)d].fRegs[0]); 468 FpDestS%(reg)dP1.uw = gtoh(destRegs[%(reg)d].fRegs[1]); 469 ''' % { "reg" : reg } 470 microUnpackAllNeonCode = ''' 471 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 472 sizeof(Element); 473 474 union SourceRegs { 475 FloatRegBits fRegs[2 * %(sRegs)d]; 476 Element elements[%(sRegs)d * perDReg]; 477 } sourceRegs; 478 479 union DestReg { 480 FloatRegBits fRegs[2]; 481 Element elements[perDReg]; 482 } destRegs[%(dRegs)d]; 483 484 %(loadRegs)s 485 486 for (unsigned i = 0; i < %(dRegs)d; i++) { 487 for (unsigned j = 0; j < perDReg; j++) 488 destRegs[i].elements[j] = sourceRegs.elements[i]; 489 } 490 491 %(unloadRegs)s 492 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 493 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 494 495 microUnpackAllNeonIop = \ 496 InstObjParams('unpackallneon%dto%duop' % (sRegs * 2, dRegs * 2), 497 'MicroUnpackAllNeon%dto%dUop' % 498 (sRegs * 2, dRegs * 2), 499 'MicroNeonMixOp', 500 { 'predicate_test': predicateTest, 501 'code' : microUnpackAllNeonCode }, 502 ['IsMicroop']) 503 header_output += MicroNeonMixDeclare.subst(microUnpackAllNeonIop) 504 exec_output += MicroNeonMixExecute.subst(microUnpackAllNeonIop) 505 506 for dRegs in 1, 2: 507 unloadRegs = '' 508 for reg in range(dRegs): 509 unloadRegs += ''' 510 FpDestP%(reg0)d.uw = gtoh(destRegs.fRegs[%(reg0)d]); 511 FpDestP%(reg1)d.uw = gtoh(destRegs.fRegs[%(reg1)d]); 512 ''' % { "reg0" : (2 * reg + 0), 513 "reg1" : (2 * reg + 1) } 514 for sRegs in range(dRegs, 5): 515 loadRegs = '' 516 for reg in range(sRegs): 517 loadRegs += ''' 518 sourceRegs[%(reg)d].fRegs[0] = htog(FpOp1S%(reg)dP0.uw); 519 sourceRegs[%(reg)d].fRegs[1] = htog(FpOp1S%(reg)dP1.uw); 520 ''' % { "reg" : reg } 521 microPackNeonCode = ''' 522 const unsigned perDReg = (2 * sizeof(FloatRegBits)) / 523 sizeof(Element); 524 525 union SourceReg { 526 FloatRegBits fRegs[2]; 527 Element elements[perDReg]; 528 } sourceRegs[%(sRegs)d]; 529 530 union DestRegs { 531 FloatRegBits fRegs[2 * %(dRegs)d]; 532 Element elements[%(dRegs)d * perDReg]; 533 } destRegs; 534 535 %(loadRegs)s 536 537 for (unsigned i = 0; i < %(sRegs)d; i++) { 538 destRegs.elements[i] = sourceRegs[i].elements[lane]; 539 } 540 541 %(unloadRegs)s 542 ''' % { "sRegs" : sRegs, "dRegs" : dRegs, 543 "loadRegs" : loadRegs, "unloadRegs" : unloadRegs } 544 545 microPackNeonIop = \ 546 InstObjParams('packneon%dto%duop' % (sRegs * 2, dRegs * 2), 547 'MicroPackNeon%dto%dUop' % 548 (sRegs * 2, dRegs * 2), 549 'MicroNeonMixLaneOp', 550 { 'predicate_test': predicateTest, 551 'code' : microPackNeonCode }, 552 ['IsMicroop']) 553 header_output += MicroNeonMixLaneDeclare.subst(microPackNeonIop) 554 exec_output += MicroNeonMixExecute.subst(microPackNeonIop) 555}}; 556 557let {{ 558 exec_output = '' 559 for type in ('uint8_t', 'uint16_t', 'uint32_t'): 560 for sRegs in 1, 2: 561 for dRegs in range(sRegs, 5): 562 for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop", 563 "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop", 564 "MicroPackNeon%(dRegs)dto%(sRegs)dUop"): 565 Name = format % { "sRegs" : sRegs * 2, 566 "dRegs" : dRegs * 2 } 567 substDict = { "class_name" : Name, "targs" : type } 568 exec_output += MicroNeonExecDeclare.subst(substDict) 569}}; 570 571//////////////////////////////////////////////////////////////////// 572// 573// Integer = Integer op Immediate microops 574// 575 576let {{ 577 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop', 578 'MicroIntImmOp', 579 {'code': 'URa = URb + imm;', 580 'predicate_test': predicateTest}, 581 ['IsMicroop']) 582 583 microAddUopIop = InstObjParams('add_uop', 'MicroAddUop', 584 'MicroIntRegOp', 585 {'code': 586 '''URa = URb + shift_rm_imm(URc, shiftAmt, 587 shiftType, 588 CondCodes<29:>); 589 ''', 590 'predicate_test': predicateTest}, 591 ['IsMicroop']) 592 593 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop', 594 'MicroIntImmOp', 595 {'code': 'URa = URb - imm;', 596 'predicate_test': predicateTest}, 597 ['IsMicroop']) 598 599 microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop', 600 'MicroIntRegOp', 601 {'code': 602 '''URa = URb - shift_rm_imm(URc, shiftAmt, 603 shiftType, 604 CondCodes<29:>); 605 ''', 606 'predicate_test': predicateTest}, 607 ['IsMicroop']) 608 609 microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov', 610 'MicroIntMov', 611 {'code': 'IWRa = URb;', 612 'predicate_test': predicateTest}, 613 ['IsMicroop']) 614 615 microUopRegMovRetIop = InstObjParams('movret_uop', 'MicroUopRegMovRet', 616 'MicroIntMov', 617 {'code': microRetUopCode % 'URb', 618 'predicate_test': predicateTest}, 619 ['IsMicroop', 'IsNonSpeculative', 620 'IsSerializeAfter']) 621 622 setPCCPSRDecl = ''' 623 CPSR cpsrOrCondCodes = URc; 624 SCTLR sctlr = Sctlr; 625 pNPC = URa; 626 uint32_t newCpsr = 627 cpsrWriteByInstr(cpsrOrCondCodes, URb, 628 0xF, true, sctlr.nmfi); 629 Cpsr = ~CondCodesMask & newCpsr; 630 NextThumb = ((CPSR)newCpsr).t; 631 NextJazelle = ((CPSR)newCpsr).j; 632 NextItState = ((((CPSR)URb).it2 << 2) & 0xFC) 633 | (((CPSR)URb).it1 & 0x3); 634 CondCodes = CondCodesMask & newCpsr; 635 ''' 636 637 microUopSetPCCPSRIop = InstObjParams('uopSet_uop', 'MicroUopSetPCCPSR', 638 'MicroSetPCCPSR', 639 {'code': setPCCPSRDecl, 640 'predicate_test': predicateTest}, 641 ['IsMicroop']) 642 643 header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \ 644 MicroIntImmDeclare.subst(microSubiUopIop) + \ 645 MicroIntRegDeclare.subst(microAddUopIop) + \ 646 MicroIntRegDeclare.subst(microSubUopIop) + \ 647 MicroIntMovDeclare.subst(microUopRegMovIop) + \ 648 MicroIntMovDeclare.subst(microUopRegMovRetIop) + \ 649 MicroSetPCCPSRDeclare.subst(microUopSetPCCPSRIop) 650 651 decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \ 652 MicroIntImmConstructor.subst(microSubiUopIop) + \ 653 MicroIntRegConstructor.subst(microAddUopIop) + \ 654 MicroIntRegConstructor.subst(microSubUopIop) + \ 655 MicroIntMovConstructor.subst(microUopRegMovIop) + \ 656 MicroIntMovConstructor.subst(microUopRegMovRetIop) + \ 657 MicroSetPCCPSRConstructor.subst(microUopSetPCCPSRIop) 658 659 exec_output = PredOpExecute.subst(microAddiUopIop) + \ 660 PredOpExecute.subst(microSubiUopIop) + \ 661 PredOpExecute.subst(microAddUopIop) + \ 662 PredOpExecute.subst(microSubUopIop) + \ 663 PredOpExecute.subst(microUopRegMovIop) + \ 664 PredOpExecute.subst(microUopRegMovRetIop) + \ 665 PredOpExecute.subst(microUopSetPCCPSRIop) 666 667}}; 668 669let {{ 670 iop = InstObjParams("ldmstm", "LdmStm", 'MacroMemOp', "", []) 671 header_output = MacroMemDeclare.subst(iop) 672 decoder_output = MacroMemConstructor.subst(iop) 673 674 iop = InstObjParams("vldmult", "VldMult", 'VldMultOp', "", []) 675 header_output += VMemMultDeclare.subst(iop) 676 decoder_output += VMemMultConstructor.subst(iop) 677 678 iop = InstObjParams("vldsingle", "VldSingle", 'VldSingleOp', "", []) 679 header_output += VMemSingleDeclare.subst(iop) 680 decoder_output += VMemSingleConstructor.subst(iop) 681 682 iop = InstObjParams("vstmult", "VstMult", 'VstMultOp', "", []) 683 header_output += VMemMultDeclare.subst(iop) 684 decoder_output += VMemMultConstructor.subst(iop) 685 686 iop = InstObjParams("vstsingle", "VstSingle", 'VstSingleOp', "", []) 687 header_output += VMemSingleDeclare.subst(iop) 688 decoder_output += VMemSingleConstructor.subst(iop) 689 690 vfpIop = InstObjParams("vldmstm", "VLdmStm", 'MacroVFPMemOp', "", []) 691 header_output += MacroVFPMemDeclare.subst(vfpIop) 692 decoder_output += MacroVFPMemConstructor.subst(vfpIop) 693}}; 694