data.isa revision 8205:7ecbffb674aa
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// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40let {{ 41 42 header_output = "" 43 decoder_output = "" 44 exec_output = "" 45 46 calcGECode = ''' 47 CondCodes = insertBits(CondCodes, 19, 16, resTemp); 48 ''' 49 50 calcQCode = ''' 51 CondCodes = CondCodes | ((resTemp & 1) << 27); 52 ''' 53 54 calcCcCode = ''' 55 uint16_t _ic, _iv, _iz, _in; 56 _in = (resTemp >> %(negBit)d) & 1; 57 _iz = (resTemp == 0); 58 _iv = %(ivValue)s & 1; 59 _ic = %(icValue)s & 1; 60 61 CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | 62 (CondCodes & 0x0FFFFFFF); 63 64 DPRINTF(Arm, "(in, iz, ic, iv) = (%%d, %%d, %%d, %%d)\\n", 65 _in, _iz, _ic, _iv); 66 ''' 67 68 # Dict of code to set the carry flag. (imm, reg, reg-reg) 69 oldC = 'CondCodes<29:>' 70 oldV = 'CondCodes<28:>' 71 carryCode = { 72 "none": (oldC, oldC, oldC), 73 "llbit": (oldC, oldC, oldC), 74 "saturate": ('0', '0', '0'), 75 "overflow": ('0', '0', '0'), 76 "ge": ('0', '0', '0'), 77 "add": ('findCarry(32, resTemp, Op1, secondOp)', 78 'findCarry(32, resTemp, Op1, secondOp)', 79 'findCarry(32, resTemp, Op1, secondOp)'), 80 "sub": ('findCarry(32, resTemp, Op1, ~secondOp)', 81 'findCarry(32, resTemp, Op1, ~secondOp)', 82 'findCarry(32, resTemp, Op1, ~secondOp)'), 83 "rsb": ('findCarry(32, resTemp, secondOp, ~Op1)', 84 'findCarry(32, resTemp, secondOp, ~Op1)', 85 'findCarry(32, resTemp, secondOp, ~Op1)'), 86 "logic": ('(rotC ? bits(secondOp, 31) : %s)' % oldC, 87 'shift_carry_imm(Op2, shiftAmt, shiftType, %s)' % oldC, 88 'shift_carry_rs(Op2, Shift<7:0>, shiftType, %s)' % oldC) 89 } 90 # Dict of code to set the overflow flag. 91 overflowCode = { 92 "none": oldV, 93 "llbit": oldV, 94 "saturate": '0', 95 "overflow": '0', 96 "ge": '0', 97 "add": 'findOverflow(32, resTemp, Op1, secondOp)', 98 "sub": 'findOverflow(32, resTemp, Op1, ~secondOp)', 99 "rsb": 'findOverflow(32, resTemp, secondOp, ~Op1)', 100 "logic": oldV 101 } 102 103 secondOpRe = re.compile("secondOp") 104 immOp2 = "imm" 105 regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodes<29:>)" 106 regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodes<29:>)" 107 108 def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \ 109 buildCc = True, buildNonCc = True, instFlags = []): 110 cCode = carryCode[flagType] 111 vCode = overflowCode[flagType] 112 negBit = 31 113 if flagType == "llbit": 114 negBit = 63 115 if flagType == "saturate": 116 immCcCode = calcQCode 117 elif flagType == "ge": 118 immCcCode = calcGECode 119 else: 120 immCcCode = calcCcCode % { 121 "icValue": secondOpRe.sub(immOp2, cCode[0]), 122 "ivValue": secondOpRe.sub(immOp2, vCode), 123 "negBit": negBit 124 } 125 immCode = secondOpRe.sub(immOp2, code) 126 immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp", 127 {"code" : immCode, 128 "predicate_test": predicateTest}, instFlags) 129 immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc", 130 "DataImmOp", 131 {"code" : immCode + immCcCode, 132 "predicate_test": condPredicateTest}, instFlags) 133 134 def subst(iop): 135 global header_output, decoder_output, exec_output 136 header_output += DataImmDeclare.subst(iop) 137 decoder_output += DataImmConstructor.subst(iop) 138 exec_output += PredOpExecute.subst(iop) 139 140 if buildNonCc: 141 subst(immIop) 142 if buildCc: 143 subst(immIopCc) 144 145 def buildRegDataInst(mnem, code, flagType = "logic", suffix = "Reg", \ 146 buildCc = True, buildNonCc = True, isRasPop = "0", \ 147 isBranch = "0", instFlags = []): 148 cCode = carryCode[flagType] 149 vCode = overflowCode[flagType] 150 negBit = 31 151 if flagType == "llbit": 152 negBit = 63 153 if flagType == "saturate": 154 regCcCode = calcQCode 155 elif flagType == "ge": 156 regCcCode = calcGECode 157 else: 158 regCcCode = calcCcCode % { 159 "icValue": secondOpRe.sub(regOp2, cCode[1]), 160 "ivValue": secondOpRe.sub(regOp2, vCode), 161 "negBit": negBit 162 } 163 regCode = secondOpRe.sub(regOp2, code) 164 regIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataRegOp", 165 {"code" : regCode, "is_ras_pop" : isRasPop, 166 "is_branch" : isBranch, 167 "predicate_test": predicateTest}, instFlags) 168 regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc", 169 "DataRegOp", 170 {"code" : regCode + regCcCode, 171 "predicate_test": condPredicateTest, 172 "is_ras_pop" : isRasPop, 173 "is_branch" : isBranch}, instFlags) 174 175 def subst(iop): 176 global header_output, decoder_output, exec_output 177 header_output += DataRegDeclare.subst(iop) 178 decoder_output += DataRegConstructor.subst(iop) 179 exec_output += PredOpExecute.subst(iop) 180 181 if buildNonCc: 182 subst(regIop) 183 if buildCc: 184 subst(regIopCc) 185 186 def buildRegRegDataInst(mnem, code, flagType = "logic", \ 187 suffix = "RegReg", \ 188 buildCc = True, buildNonCc = True): 189 cCode = carryCode[flagType] 190 vCode = overflowCode[flagType] 191 negBit = 31 192 if flagType == "llbit": 193 negBit = 63 194 if flagType == "saturate": 195 regRegCcCode = calcQCode 196 elif flagType == "ge": 197 regRegCcCode = calcGECode 198 else: 199 regRegCcCode = calcCcCode % { 200 "icValue": secondOpRe.sub(regRegOp2, cCode[2]), 201 "ivValue": secondOpRe.sub(regRegOp2, vCode), 202 "negBit": negBit 203 } 204 regRegCode = secondOpRe.sub(regRegOp2, code) 205 regRegIop = InstObjParams(mnem, mnem.capitalize() + suffix, 206 "DataRegRegOp", 207 {"code" : regRegCode, 208 "predicate_test": predicateTest}) 209 regRegIopCc = InstObjParams(mnem + "s", 210 mnem.capitalize() + suffix + "Cc", 211 "DataRegRegOp", 212 {"code" : regRegCode + regRegCcCode, 213 "predicate_test": condPredicateTest}) 214 215 def subst(iop): 216 global header_output, decoder_output, exec_output 217 header_output += DataRegRegDeclare.subst(iop) 218 decoder_output += DataRegRegConstructor.subst(iop) 219 exec_output += PredOpExecute.subst(iop) 220 221 if buildNonCc: 222 subst(regRegIop) 223 if buildCc: 224 subst(regRegIopCc) 225 226 def buildDataInst(mnem, code, flagType = "logic", \ 227 aiw = True, regRegAiw = True, 228 subsPcLr = True, isRasPop = "0", isBranch = "0"): 229 regRegCode = instCode = code 230 if aiw: 231 instCode = "AIW" + instCode 232 if regRegAiw: 233 regRegCode = "AIW" + regRegCode 234 235 buildImmDataInst(mnem, instCode, flagType) 236 buildRegDataInst(mnem, instCode, flagType, 237 isRasPop = isRasPop, isBranch = isBranch) 238 buildRegRegDataInst(mnem, regRegCode, flagType) 239 if subsPcLr: 240 code += ''' 241 SCTLR sctlr = Sctlr; 242 uint32_t newCpsr = 243 cpsrWriteByInstr(Cpsr | CondCodes, Spsr, 0xF, true, sctlr.nmfi); 244 Cpsr = ~CondCodesMask & newCpsr; 245 CondCodes = CondCodesMask & newCpsr; 246 NextThumb = ((CPSR)newCpsr).t; 247 NextJazelle = ((CPSR)newCpsr).j; 248 NextItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC) 249 | (((CPSR)newCpsr).it1 & 0x3); 250 ''' 251 buildImmDataInst(mnem + 's', code, flagType, 252 suffix = "ImmPclr", buildCc = False, 253 instFlags = ["IsSerializeAfter","IsNonSpeculative"]) 254 buildRegDataInst(mnem + 's', code, flagType, 255 suffix = "RegPclr", buildCc = False, 256 instFlags = ["IsSerializeAfter","IsNonSpeculative"]) 257 258 buildDataInst("and", "Dest = resTemp = Op1 & secondOp;") 259 buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;") 260 buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub") 261 buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb") 262 buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add") 263 buildImmDataInst("adr", ''' 264 Dest = resTemp = (PC & ~0x3) + 265 (op1 ? secondOp : -secondOp); 266 ''') 267 buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add") 268 buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub") 269 buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb") 270 buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False) 271 buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False) 272 buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False) 273 buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False) 274 buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;") 275 buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False) 276 buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False, 277 isRasPop = "op1 == INTREG_LR", isBranch = "dest == INTREG_PC") 278 buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;") 279 buildDataInst("mvn", "Dest = resTemp = ~secondOp;") 280 buildDataInst("movt", 281 "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);", 282 aiw = False) 283 284 buildRegDataInst("qadd", ''' 285 int32_t midRes; 286 resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw); 287 Dest = midRes; 288 ''', flagType="saturate", buildNonCc=False) 289 buildRegDataInst("qadd16", ''' 290 int32_t midRes; 291 for (unsigned i = 0; i < 2; i++) { 292 int high = (i + 1) * 16 - 1; 293 int low = i * 16; 294 int64_t arg1 = sext<16>(bits(Op1.sw, high, low)); 295 int64_t arg2 = sext<16>(bits(Op2.sw, high, low)); 296 saturateOp<16>(midRes, arg1, arg2); 297 replaceBits(resTemp, high, low, midRes); 298 } 299 Dest = resTemp; 300 ''', flagType="none", buildCc=False) 301 buildRegDataInst("qadd8", ''' 302 int32_t midRes; 303 for (unsigned i = 0; i < 4; i++) { 304 int high = (i + 1) * 8 - 1; 305 int low = i * 8; 306 int64_t arg1 = sext<8>(bits(Op1.sw, high, low)); 307 int64_t arg2 = sext<8>(bits(Op2.sw, high, low)); 308 saturateOp<8>(midRes, arg1, arg2); 309 replaceBits(resTemp, high, low, midRes); 310 } 311 Dest = resTemp; 312 ''', flagType="none", buildCc=False) 313 buildRegDataInst("qdadd", ''' 314 int32_t midRes; 315 resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) | 316 saturateOp<32>(midRes, Op1.sw, midRes); 317 Dest = midRes; 318 ''', flagType="saturate", buildNonCc=False) 319 buildRegDataInst("qsub", ''' 320 int32_t midRes; 321 resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw, true); 322 Dest = midRes; 323 ''', flagType="saturate") 324 buildRegDataInst("qsub16", ''' 325 int32_t midRes; 326 for (unsigned i = 0; i < 2; i++) { 327 int high = (i + 1) * 16 - 1; 328 int low = i * 16; 329 int64_t arg1 = sext<16>(bits(Op1.sw, high, low)); 330 int64_t arg2 = sext<16>(bits(Op2.sw, high, low)); 331 saturateOp<16>(midRes, arg1, arg2, true); 332 replaceBits(resTemp, high, low, midRes); 333 } 334 Dest = resTemp; 335 ''', flagType="none", buildCc=False) 336 buildRegDataInst("qsub8", ''' 337 int32_t midRes; 338 for (unsigned i = 0; i < 4; i++) { 339 int high = (i + 1) * 8 - 1; 340 int low = i * 8; 341 int64_t arg1 = sext<8>(bits(Op1.sw, high, low)); 342 int64_t arg2 = sext<8>(bits(Op2.sw, high, low)); 343 saturateOp<8>(midRes, arg1, arg2, true); 344 replaceBits(resTemp, high, low, midRes); 345 } 346 Dest = resTemp; 347 ''', flagType="none", buildCc=False) 348 buildRegDataInst("qdsub", ''' 349 int32_t midRes; 350 resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) | 351 saturateOp<32>(midRes, Op1.sw, midRes, true); 352 Dest = midRes; 353 ''', flagType="saturate", buildNonCc=False) 354 buildRegDataInst("qasx", ''' 355 int32_t midRes; 356 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 357 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 358 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 359 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 360 saturateOp<16>(midRes, arg1Low, arg2High, true); 361 replaceBits(resTemp, 15, 0, midRes); 362 saturateOp<16>(midRes, arg1High, arg2Low); 363 replaceBits(resTemp, 31, 16, midRes); 364 Dest = resTemp; 365 ''', flagType="none", buildCc=False) 366 buildRegDataInst("qsax", ''' 367 int32_t midRes; 368 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 369 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 370 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 371 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 372 saturateOp<16>(midRes, arg1Low, arg2High); 373 replaceBits(resTemp, 15, 0, midRes); 374 saturateOp<16>(midRes, arg1High, arg2Low, true); 375 replaceBits(resTemp, 31, 16, midRes); 376 Dest = resTemp; 377 ''', flagType="none", buildCc=False) 378 379 buildRegDataInst("sadd8", ''' 380 uint32_t geBits = 0; 381 resTemp = 0; 382 for (unsigned i = 0; i < 4; i++) { 383 int high = (i + 1) * 8 - 1; 384 int low = i * 8; 385 int32_t midRes = sext<8>(bits(Op1.sw, high, low)) + 386 sext<8>(bits(Op2.sw, high, low)); 387 replaceBits(resTemp, high, low, midRes); 388 if (midRes >= 0) { 389 geBits = geBits | (1 << i); 390 } 391 } 392 Dest = resTemp; 393 resTemp = geBits; 394 ''', flagType="ge", buildNonCc=False) 395 buildRegDataInst("sadd16", ''' 396 uint32_t geBits = 0; 397 resTemp = 0; 398 for (unsigned i = 0; i < 2; i++) { 399 int high = (i + 1) * 16 - 1; 400 int low = i * 16; 401 int32_t midRes = sext<16>(bits(Op1.sw, high, low)) + 402 sext<16>(bits(Op2.sw, high, low)); 403 replaceBits(resTemp, high, low, midRes); 404 if (midRes >= 0) { 405 geBits = geBits | (0x3 << (i * 2)); 406 } 407 } 408 Dest = resTemp; 409 resTemp = geBits; 410 ''', flagType="ge", buildNonCc=False) 411 412 buildRegDataInst("ssub8", ''' 413 uint32_t geBits = 0; 414 resTemp = 0; 415 for (unsigned i = 0; i < 4; i++) { 416 int high = (i + 1) * 8 - 1; 417 int low = i * 8; 418 int32_t midRes = sext<8>(bits(Op1.sw, high, low)) - 419 sext<8>(bits(Op2.sw, high, low)); 420 replaceBits(resTemp, high, low, midRes); 421 if (midRes >= 0) { 422 geBits = geBits | (1 << i); 423 } 424 } 425 Dest = resTemp; 426 resTemp = geBits; 427 ''', flagType="ge", buildNonCc=False) 428 buildRegDataInst("ssub16", ''' 429 uint32_t geBits = 0; 430 resTemp = 0; 431 for (unsigned i = 0; i < 2; i++) { 432 int high = (i + 1) * 16 - 1; 433 int low = i * 16; 434 int32_t midRes = sext<16>(bits(Op1.sw, high, low)) - 435 sext<16>(bits(Op2.sw, high, low)); 436 replaceBits(resTemp, high, low, midRes); 437 if (midRes >= 0) { 438 geBits = geBits | (0x3 << (i * 2)); 439 } 440 } 441 Dest = resTemp; 442 resTemp = geBits; 443 ''', flagType="ge", buildNonCc=False) 444 buildRegDataInst("sasx", ''' 445 int32_t midRes, geBits = 0; 446 resTemp = 0; 447 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 448 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 449 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 450 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 451 midRes = arg1Low - arg2High; 452 if (midRes >= 0) { 453 geBits = geBits | 0x3; 454 } 455 replaceBits(resTemp, 15, 0, midRes); 456 midRes = arg1High + arg2Low; 457 if (midRes >= 0) { 458 geBits = geBits | 0xc; 459 } 460 replaceBits(resTemp, 31, 16, midRes); 461 Dest = resTemp; 462 resTemp = geBits; 463 ''', flagType="ge", buildNonCc=True) 464 buildRegDataInst("ssax", ''' 465 int32_t midRes, geBits = 0; 466 resTemp = 0; 467 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 468 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 469 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 470 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 471 midRes = arg1Low + arg2High; 472 if (midRes >= 0) { 473 geBits = geBits | 0x3; 474 } 475 replaceBits(resTemp, 15, 0, midRes); 476 midRes = arg1High - arg2Low; 477 if (midRes >= 0) { 478 geBits = geBits | 0xc; 479 } 480 replaceBits(resTemp, 31, 16, midRes); 481 Dest = resTemp; 482 resTemp = geBits; 483 ''', flagType="ge", buildNonCc=True) 484 485 buildRegDataInst("shadd8", ''' 486 resTemp = 0; 487 for (unsigned i = 0; i < 4; i++) { 488 int high = (i + 1) * 8 - 1; 489 int low = i * 8; 490 int32_t midRes = 491 (uint64_t)(sext<8>(bits(Op1.sw, high, low)) + 492 sext<8>(bits(Op2.sw, high, low))) >> 1; 493 replaceBits(resTemp, high, low, midRes); 494 } 495 Dest = resTemp; 496 ''', flagType="none", buildCc=False) 497 buildRegDataInst("shadd16", ''' 498 resTemp = 0; 499 for (unsigned i = 0; i < 2; i++) { 500 int high = (i + 1) * 16 - 1; 501 int low = i * 16; 502 int32_t midRes = 503 (uint64_t)(sext<16>(bits(Op1.sw, high, low)) + 504 sext<16>(bits(Op2.sw, high, low))) >> 1; 505 replaceBits(resTemp, high, low, midRes); 506 } 507 Dest = resTemp; 508 ''', flagType="none", buildCc=False) 509 buildRegDataInst("shsub8", ''' 510 resTemp = 0; 511 for (unsigned i = 0; i < 4; i++) { 512 int high = (i + 1) * 8 - 1; 513 int low = i * 8; 514 int32_t midRes = 515 (uint64_t)(sext<8>(bits(Op1.sw, high, low)) - 516 sext<8>(bits(Op2.sw, high, low))) >> 1; 517 replaceBits(resTemp, high, low, midRes); 518 } 519 Dest = resTemp; 520 ''', flagType="none", buildCc=False) 521 buildRegDataInst("shsub16", ''' 522 resTemp = 0; 523 for (unsigned i = 0; i < 2; i++) { 524 int high = (i + 1) * 16 - 1; 525 int low = i * 16; 526 int32_t midRes = 527 (uint64_t)(sext<16>(bits(Op1.sw, high, low)) - 528 sext<16>(bits(Op2.sw, high, low))) >> 1; 529 replaceBits(resTemp, high, low, midRes); 530 } 531 Dest = resTemp; 532 ''', flagType="none", buildCc=False) 533 buildRegDataInst("shasx", ''' 534 int32_t midRes; 535 resTemp = 0; 536 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 537 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 538 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 539 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 540 midRes = (uint64_t)(arg1Low - arg2High) >> 1; 541 replaceBits(resTemp, 15, 0, midRes); 542 midRes = (arg1High + arg2Low) >> 1; 543 replaceBits(resTemp, 31, 16, midRes); 544 Dest = resTemp; 545 ''', flagType="none", buildCc=True) 546 buildRegDataInst("shsax", ''' 547 int32_t midRes; 548 resTemp = 0; 549 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 550 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 551 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 552 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 553 midRes = (uint64_t)(arg1Low + arg2High) >> 1; 554 replaceBits(resTemp, 15, 0, midRes); 555 midRes = (uint64_t)(arg1High - arg2Low) >> 1; 556 replaceBits(resTemp, 31, 16, midRes); 557 Dest = resTemp; 558 ''', flagType="none", buildCc=True) 559 560 buildRegDataInst("uqadd16", ''' 561 uint32_t midRes; 562 for (unsigned i = 0; i < 2; i++) { 563 int high = (i + 1) * 16 - 1; 564 int low = i * 16; 565 uint64_t arg1 = bits(Op1, high, low); 566 uint64_t arg2 = bits(Op2, high, low); 567 uSaturateOp<16>(midRes, arg1, arg2); 568 replaceBits(resTemp, high, low, midRes); 569 } 570 Dest = resTemp; 571 ''', flagType="none", buildCc=False) 572 buildRegDataInst("uqadd8", ''' 573 uint32_t midRes; 574 for (unsigned i = 0; i < 4; i++) { 575 int high = (i + 1) * 8 - 1; 576 int low = i * 8; 577 uint64_t arg1 = bits(Op1, high, low); 578 uint64_t arg2 = bits(Op2, high, low); 579 uSaturateOp<8>(midRes, arg1, arg2); 580 replaceBits(resTemp, high, low, midRes); 581 } 582 Dest = resTemp; 583 ''', flagType="none", buildCc=False) 584 buildRegDataInst("uqsub16", ''' 585 uint32_t midRes; 586 for (unsigned i = 0; i < 2; i++) { 587 int high = (i + 1) * 16 - 1; 588 int low = i * 16; 589 uint64_t arg1 = bits(Op1, high, low); 590 uint64_t arg2 = bits(Op2, high, low); 591 uSaturateOp<16>(midRes, arg1, arg2, true); 592 replaceBits(resTemp, high, low, midRes); 593 } 594 Dest = resTemp; 595 ''', flagType="none", buildCc=False) 596 buildRegDataInst("uqsub8", ''' 597 uint32_t midRes; 598 for (unsigned i = 0; i < 4; i++) { 599 int high = (i + 1) * 8 - 1; 600 int low = i * 8; 601 uint64_t arg1 = bits(Op1, high, low); 602 uint64_t arg2 = bits(Op2, high, low); 603 uSaturateOp<8>(midRes, arg1, arg2, true); 604 replaceBits(resTemp, high, low, midRes); 605 } 606 Dest = resTemp; 607 ''', flagType="none", buildCc=False) 608 buildRegDataInst("uqasx", ''' 609 uint32_t midRes; 610 uint64_t arg1Low = bits(Op1.sw, 15, 0); 611 uint64_t arg1High = bits(Op1.sw, 31, 16); 612 uint64_t arg2Low = bits(Op2.sw, 15, 0); 613 uint64_t arg2High = bits(Op2.sw, 31, 16); 614 uSaturateOp<16>(midRes, arg1Low, arg2High, true); 615 replaceBits(resTemp, 15, 0, midRes); 616 uSaturateOp<16>(midRes, arg1High, arg2Low); 617 replaceBits(resTemp, 31, 16, midRes); 618 Dest = resTemp; 619 ''', flagType="none", buildCc=False) 620 buildRegDataInst("uqsax", ''' 621 uint32_t midRes; 622 uint64_t arg1Low = bits(Op1.sw, 15, 0); 623 uint64_t arg1High = bits(Op1.sw, 31, 16); 624 uint64_t arg2Low = bits(Op2.sw, 15, 0); 625 uint64_t arg2High = bits(Op2.sw, 31, 16); 626 uSaturateOp<16>(midRes, arg1Low, arg2High); 627 replaceBits(resTemp, 15, 0, midRes); 628 uSaturateOp<16>(midRes, arg1High, arg2Low, true); 629 replaceBits(resTemp, 31, 16, midRes); 630 Dest = resTemp; 631 ''', flagType="none", buildCc=False) 632 633 buildRegDataInst("uadd16", ''' 634 uint32_t geBits = 0; 635 resTemp = 0; 636 for (unsigned i = 0; i < 2; i++) { 637 int high = (i + 1) * 16 - 1; 638 int low = i * 16; 639 int32_t midRes = bits(Op1, high, low) + 640 bits(Op2, high, low); 641 if (midRes >= 0x10000) { 642 geBits = geBits | (0x3 << (i * 2)); 643 } 644 replaceBits(resTemp, high, low, midRes); 645 } 646 Dest = resTemp; 647 resTemp = geBits; 648 ''', flagType="ge", buildNonCc=False) 649 buildRegDataInst("uadd8", ''' 650 uint32_t geBits = 0; 651 resTemp = 0; 652 for (unsigned i = 0; i < 4; i++) { 653 int high = (i + 1) * 8 - 1; 654 int low = i * 8; 655 int32_t midRes = bits(Op1, high, low) + 656 bits(Op2, high, low); 657 if (midRes >= 0x100) { 658 geBits = geBits | (1 << i); 659 } 660 replaceBits(resTemp, high, low, midRes); 661 } 662 Dest = resTemp; 663 resTemp = geBits; 664 ''', flagType="ge", buildNonCc=False) 665 buildRegDataInst("usub16", ''' 666 uint32_t geBits = 0; 667 resTemp = 0; 668 for (unsigned i = 0; i < 2; i++) { 669 int high = (i + 1) * 16 - 1; 670 int low = i * 16; 671 int32_t midRes = bits(Op1, high, low) - 672 bits(Op2, high, low); 673 if (midRes >= 0) { 674 geBits = geBits | (0x3 << (i * 2)); 675 } 676 replaceBits(resTemp, high, low, midRes); 677 } 678 Dest = resTemp; 679 resTemp = geBits; 680 ''', flagType="ge", buildNonCc=False) 681 buildRegDataInst("usub8", ''' 682 uint32_t geBits = 0; 683 resTemp = 0; 684 for (unsigned i = 0; i < 4; i++) { 685 int high = (i + 1) * 8 - 1; 686 int low = i * 8; 687 int32_t midRes = bits(Op1, high, low) - 688 bits(Op2, high, low); 689 if (midRes >= 0) { 690 geBits = geBits | (1 << i); 691 } 692 replaceBits(resTemp, high, low, midRes); 693 } 694 Dest = resTemp; 695 resTemp = geBits; 696 ''', flagType="ge", buildNonCc=False) 697 buildRegDataInst("uasx", ''' 698 int32_t midRes, geBits = 0; 699 resTemp = 0; 700 int64_t arg1Low = bits(Op1.sw, 15, 0); 701 int64_t arg1High = bits(Op1.sw, 31, 16); 702 int64_t arg2Low = bits(Op2.sw, 15, 0); 703 int64_t arg2High = bits(Op2.sw, 31, 16); 704 midRes = arg1Low - arg2High; 705 if (midRes >= 0) { 706 geBits = geBits | 0x3; 707 } 708 replaceBits(resTemp, 15, 0, midRes); 709 midRes = arg1High + arg2Low; 710 if (midRes >= 0x10000) { 711 geBits = geBits | 0xc; 712 } 713 replaceBits(resTemp, 31, 16, midRes); 714 Dest = resTemp; 715 resTemp = geBits; 716 ''', flagType="ge", buildNonCc=False) 717 buildRegDataInst("usax", ''' 718 int32_t midRes, geBits = 0; 719 resTemp = 0; 720 int64_t arg1Low = bits(Op1.sw, 15, 0); 721 int64_t arg1High = bits(Op1.sw, 31, 16); 722 int64_t arg2Low = bits(Op2.sw, 15, 0); 723 int64_t arg2High = bits(Op2.sw, 31, 16); 724 midRes = arg1Low + arg2High; 725 if (midRes >= 0x10000) { 726 geBits = geBits | 0x3; 727 } 728 replaceBits(resTemp, 15, 0, midRes); 729 midRes = arg1High - arg2Low; 730 if (midRes >= 0) { 731 geBits = geBits | 0xc; 732 } 733 replaceBits(resTemp, 31, 16, midRes); 734 Dest = resTemp; 735 resTemp = geBits; 736 ''', flagType="ge", buildNonCc=False) 737 738 buildRegDataInst("uhadd16", ''' 739 resTemp = 0; 740 for (unsigned i = 0; i < 2; i++) { 741 int high = (i + 1) * 16 - 1; 742 int low = i * 16; 743 int32_t midRes = (bits(Op1, high, low) + 744 bits(Op2, high, low)) >> 1; 745 replaceBits(resTemp, high, low, midRes); 746 } 747 Dest = resTemp; 748 ''', flagType="none", buildCc=False) 749 buildRegDataInst("uhadd8", ''' 750 resTemp = 0; 751 for (unsigned i = 0; i < 4; i++) { 752 int high = (i + 1) * 8 - 1; 753 int low = i * 8; 754 int32_t midRes = (bits(Op1, high, low) + 755 bits(Op2, high, low)) >> 1; 756 replaceBits(resTemp, high, low, midRes); 757 } 758 Dest = resTemp; 759 ''', flagType="none", buildCc=False) 760 buildRegDataInst("uhsub16", ''' 761 resTemp = 0; 762 for (unsigned i = 0; i < 2; i++) { 763 int high = (i + 1) * 16 - 1; 764 int low = i * 16; 765 int32_t midRes = (bits(Op1, high, low) - 766 bits(Op2, high, low)) >> 1; 767 replaceBits(resTemp, high, low, midRes); 768 } 769 Dest = resTemp; 770 ''', flagType="none", buildCc=False) 771 buildRegDataInst("uhsub8", ''' 772 resTemp = 0; 773 for (unsigned i = 0; i < 4; i++) { 774 int high = (i + 1) * 8 - 1; 775 int low = i * 8; 776 int32_t midRes = (bits(Op1, high, low) - 777 bits(Op2, high, low)) >> 1; 778 replaceBits(resTemp, high, low, midRes); 779 } 780 Dest = resTemp; 781 ''', flagType="none", buildCc=False) 782 buildRegDataInst("uhasx", ''' 783 int32_t midRes; 784 resTemp = 0; 785 int64_t arg1Low = bits(Op1.sw, 15, 0); 786 int64_t arg1High = bits(Op1.sw, 31, 16); 787 int64_t arg2Low = bits(Op2.sw, 15, 0); 788 int64_t arg2High = bits(Op2.sw, 31, 16); 789 midRes = (arg1Low - arg2High) >> 1; 790 replaceBits(resTemp, 15, 0, midRes); 791 midRes = (arg1High + arg2Low) >> 1; 792 replaceBits(resTemp, 31, 16, midRes); 793 Dest = resTemp; 794 ''', flagType="none", buildCc=False) 795 buildRegDataInst("uhsax", ''' 796 int32_t midRes; 797 resTemp = 0; 798 int64_t arg1Low = bits(Op1.sw, 15, 0); 799 int64_t arg1High = bits(Op1.sw, 31, 16); 800 int64_t arg2Low = bits(Op2.sw, 15, 0); 801 int64_t arg2High = bits(Op2.sw, 31, 16); 802 midRes = (arg1Low + arg2High) >> 1; 803 replaceBits(resTemp, 15, 0, midRes); 804 midRes = (arg1High - arg2Low) >> 1; 805 replaceBits(resTemp, 31, 16, midRes); 806 Dest = resTemp; 807 ''', flagType="none", buildCc=False) 808 809 buildRegDataInst("pkhbt", ''' 810 uint32_t resTemp = 0; 811 uint16_t arg1Low = bits(Op1, 15, 0); 812 uint16_t arg2High = bits(secondOp, 31, 16); 813 replaceBits(resTemp, 15, 0, arg1Low); 814 replaceBits(resTemp, 31, 16, arg2High); 815 Dest = resTemp; 816 ''', flagType="none", buildCc=False) 817 buildRegDataInst("pkhtb", ''' 818 uint32_t resTemp = 0; 819 uint16_t arg1High = bits(Op1, 31, 16); 820 uint16_t arg2Low = bits(secondOp, 15, 0); 821 replaceBits(resTemp, 15, 0, arg2Low); 822 replaceBits(resTemp, 31, 16, arg1High); 823 Dest = resTemp; 824 ''', flagType="none", buildCc=False) 825}}; 826