data.isa revision 8285
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 SevMailbox = 1; 251 ''' 252 buildImmDataInst(mnem + 's', code, flagType, 253 suffix = "ImmPclr", buildCc = False, 254 instFlags = ["IsSerializeAfter","IsNonSpeculative"]) 255 buildRegDataInst(mnem + 's', code, flagType, 256 suffix = "RegPclr", buildCc = False, 257 instFlags = ["IsSerializeAfter","IsNonSpeculative"]) 258 259 buildDataInst("and", "Dest = resTemp = Op1 & secondOp;") 260 buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;") 261 buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub") 262 buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb") 263 buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add") 264 buildImmDataInst("adr", ''' 265 Dest = resTemp = (PC & ~0x3) + 266 (op1 ? secondOp : -secondOp); 267 ''') 268 buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add") 269 buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub") 270 buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb") 271 buildDataInst("tst", "resTemp = Op1 & secondOp;", aiw = False) 272 buildDataInst("teq", "resTemp = Op1 ^ secondOp;", aiw = False) 273 buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub", aiw = False) 274 buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add", aiw = False) 275 buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;") 276 buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;", aiw = False) 277 buildDataInst("mov", "Dest = resTemp = secondOp;", regRegAiw = False, 278 isRasPop = "op1 == INTREG_LR", isBranch = "dest == INTREG_PC") 279 buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;") 280 buildDataInst("mvn", "Dest = resTemp = ~secondOp;") 281 buildDataInst("movt", 282 "Dest = resTemp = insertBits(Op1, 31, 16, secondOp);", 283 aiw = False) 284 285 buildRegDataInst("qadd", ''' 286 int32_t midRes; 287 resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw); 288 Dest = midRes; 289 ''', flagType="saturate", buildNonCc=False) 290 buildRegDataInst("qadd16", ''' 291 int32_t midRes; 292 for (unsigned i = 0; i < 2; i++) { 293 int high = (i + 1) * 16 - 1; 294 int low = i * 16; 295 int64_t arg1 = sext<16>(bits(Op1.sw, high, low)); 296 int64_t arg2 = sext<16>(bits(Op2.sw, high, low)); 297 saturateOp<16>(midRes, arg1, arg2); 298 replaceBits(resTemp, high, low, midRes); 299 } 300 Dest = resTemp; 301 ''', flagType="none", buildCc=False) 302 buildRegDataInst("qadd8", ''' 303 int32_t midRes; 304 for (unsigned i = 0; i < 4; i++) { 305 int high = (i + 1) * 8 - 1; 306 int low = i * 8; 307 int64_t arg1 = sext<8>(bits(Op1.sw, high, low)); 308 int64_t arg2 = sext<8>(bits(Op2.sw, high, low)); 309 saturateOp<8>(midRes, arg1, arg2); 310 replaceBits(resTemp, high, low, midRes); 311 } 312 Dest = resTemp; 313 ''', flagType="none", buildCc=False) 314 buildRegDataInst("qdadd", ''' 315 int32_t midRes; 316 resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) | 317 saturateOp<32>(midRes, Op1.sw, midRes); 318 Dest = midRes; 319 ''', flagType="saturate", buildNonCc=False) 320 buildRegDataInst("qsub", ''' 321 int32_t midRes; 322 resTemp = saturateOp<32>(midRes, Op1.sw, Op2.sw, true); 323 Dest = midRes; 324 ''', flagType="saturate") 325 buildRegDataInst("qsub16", ''' 326 int32_t midRes; 327 for (unsigned i = 0; i < 2; i++) { 328 int high = (i + 1) * 16 - 1; 329 int low = i * 16; 330 int64_t arg1 = sext<16>(bits(Op1.sw, high, low)); 331 int64_t arg2 = sext<16>(bits(Op2.sw, high, low)); 332 saturateOp<16>(midRes, arg1, arg2, true); 333 replaceBits(resTemp, high, low, midRes); 334 } 335 Dest = resTemp; 336 ''', flagType="none", buildCc=False) 337 buildRegDataInst("qsub8", ''' 338 int32_t midRes; 339 for (unsigned i = 0; i < 4; i++) { 340 int high = (i + 1) * 8 - 1; 341 int low = i * 8; 342 int64_t arg1 = sext<8>(bits(Op1.sw, high, low)); 343 int64_t arg2 = sext<8>(bits(Op2.sw, high, low)); 344 saturateOp<8>(midRes, arg1, arg2, true); 345 replaceBits(resTemp, high, low, midRes); 346 } 347 Dest = resTemp; 348 ''', flagType="none", buildCc=False) 349 buildRegDataInst("qdsub", ''' 350 int32_t midRes; 351 resTemp = saturateOp<32>(midRes, Op2.sw, Op2.sw) | 352 saturateOp<32>(midRes, Op1.sw, midRes, true); 353 Dest = midRes; 354 ''', flagType="saturate", buildNonCc=False) 355 buildRegDataInst("qasx", ''' 356 int32_t midRes; 357 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 358 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 359 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 360 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 361 saturateOp<16>(midRes, arg1Low, arg2High, true); 362 replaceBits(resTemp, 15, 0, midRes); 363 saturateOp<16>(midRes, arg1High, arg2Low); 364 replaceBits(resTemp, 31, 16, midRes); 365 Dest = resTemp; 366 ''', flagType="none", buildCc=False) 367 buildRegDataInst("qsax", ''' 368 int32_t midRes; 369 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 370 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 371 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 372 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 373 saturateOp<16>(midRes, arg1Low, arg2High); 374 replaceBits(resTemp, 15, 0, midRes); 375 saturateOp<16>(midRes, arg1High, arg2Low, true); 376 replaceBits(resTemp, 31, 16, midRes); 377 Dest = resTemp; 378 ''', flagType="none", buildCc=False) 379 380 buildRegDataInst("sadd8", ''' 381 uint32_t geBits = 0; 382 resTemp = 0; 383 for (unsigned i = 0; i < 4; i++) { 384 int high = (i + 1) * 8 - 1; 385 int low = i * 8; 386 int32_t midRes = sext<8>(bits(Op1.sw, high, low)) + 387 sext<8>(bits(Op2.sw, high, low)); 388 replaceBits(resTemp, high, low, midRes); 389 if (midRes >= 0) { 390 geBits = geBits | (1 << i); 391 } 392 } 393 Dest = resTemp; 394 resTemp = geBits; 395 ''', flagType="ge", buildNonCc=False) 396 buildRegDataInst("sadd16", ''' 397 uint32_t geBits = 0; 398 resTemp = 0; 399 for (unsigned i = 0; i < 2; i++) { 400 int high = (i + 1) * 16 - 1; 401 int low = i * 16; 402 int32_t midRes = sext<16>(bits(Op1.sw, high, low)) + 403 sext<16>(bits(Op2.sw, high, low)); 404 replaceBits(resTemp, high, low, midRes); 405 if (midRes >= 0) { 406 geBits = geBits | (0x3 << (i * 2)); 407 } 408 } 409 Dest = resTemp; 410 resTemp = geBits; 411 ''', flagType="ge", buildNonCc=False) 412 413 buildRegDataInst("ssub8", ''' 414 uint32_t geBits = 0; 415 resTemp = 0; 416 for (unsigned i = 0; i < 4; i++) { 417 int high = (i + 1) * 8 - 1; 418 int low = i * 8; 419 int32_t midRes = sext<8>(bits(Op1.sw, high, low)) - 420 sext<8>(bits(Op2.sw, high, low)); 421 replaceBits(resTemp, high, low, midRes); 422 if (midRes >= 0) { 423 geBits = geBits | (1 << i); 424 } 425 } 426 Dest = resTemp; 427 resTemp = geBits; 428 ''', flagType="ge", buildNonCc=False) 429 buildRegDataInst("ssub16", ''' 430 uint32_t geBits = 0; 431 resTemp = 0; 432 for (unsigned i = 0; i < 2; i++) { 433 int high = (i + 1) * 16 - 1; 434 int low = i * 16; 435 int32_t midRes = sext<16>(bits(Op1.sw, high, low)) - 436 sext<16>(bits(Op2.sw, high, low)); 437 replaceBits(resTemp, high, low, midRes); 438 if (midRes >= 0) { 439 geBits = geBits | (0x3 << (i * 2)); 440 } 441 } 442 Dest = resTemp; 443 resTemp = geBits; 444 ''', flagType="ge", buildNonCc=False) 445 buildRegDataInst("sasx", ''' 446 int32_t midRes, geBits = 0; 447 resTemp = 0; 448 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 449 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 450 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 451 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 452 midRes = arg1Low - arg2High; 453 if (midRes >= 0) { 454 geBits = geBits | 0x3; 455 } 456 replaceBits(resTemp, 15, 0, midRes); 457 midRes = arg1High + arg2Low; 458 if (midRes >= 0) { 459 geBits = geBits | 0xc; 460 } 461 replaceBits(resTemp, 31, 16, midRes); 462 Dest = resTemp; 463 resTemp = geBits; 464 ''', flagType="ge", buildNonCc=True) 465 buildRegDataInst("ssax", ''' 466 int32_t midRes, geBits = 0; 467 resTemp = 0; 468 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 469 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 470 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 471 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 472 midRes = arg1Low + arg2High; 473 if (midRes >= 0) { 474 geBits = geBits | 0x3; 475 } 476 replaceBits(resTemp, 15, 0, midRes); 477 midRes = arg1High - arg2Low; 478 if (midRes >= 0) { 479 geBits = geBits | 0xc; 480 } 481 replaceBits(resTemp, 31, 16, midRes); 482 Dest = resTemp; 483 resTemp = geBits; 484 ''', flagType="ge", buildNonCc=True) 485 486 buildRegDataInst("shadd8", ''' 487 resTemp = 0; 488 for (unsigned i = 0; i < 4; i++) { 489 int high = (i + 1) * 8 - 1; 490 int low = i * 8; 491 int32_t midRes = 492 (uint64_t)(sext<8>(bits(Op1.sw, high, low)) + 493 sext<8>(bits(Op2.sw, high, low))) >> 1; 494 replaceBits(resTemp, high, low, midRes); 495 } 496 Dest = resTemp; 497 ''', flagType="none", buildCc=False) 498 buildRegDataInst("shadd16", ''' 499 resTemp = 0; 500 for (unsigned i = 0; i < 2; i++) { 501 int high = (i + 1) * 16 - 1; 502 int low = i * 16; 503 int32_t midRes = 504 (uint64_t)(sext<16>(bits(Op1.sw, high, low)) + 505 sext<16>(bits(Op2.sw, high, low))) >> 1; 506 replaceBits(resTemp, high, low, midRes); 507 } 508 Dest = resTemp; 509 ''', flagType="none", buildCc=False) 510 buildRegDataInst("shsub8", ''' 511 resTemp = 0; 512 for (unsigned i = 0; i < 4; i++) { 513 int high = (i + 1) * 8 - 1; 514 int low = i * 8; 515 int32_t midRes = 516 (uint64_t)(sext<8>(bits(Op1.sw, high, low)) - 517 sext<8>(bits(Op2.sw, high, low))) >> 1; 518 replaceBits(resTemp, high, low, midRes); 519 } 520 Dest = resTemp; 521 ''', flagType="none", buildCc=False) 522 buildRegDataInst("shsub16", ''' 523 resTemp = 0; 524 for (unsigned i = 0; i < 2; i++) { 525 int high = (i + 1) * 16 - 1; 526 int low = i * 16; 527 int32_t midRes = 528 (uint64_t)(sext<16>(bits(Op1.sw, high, low)) - 529 sext<16>(bits(Op2.sw, high, low))) >> 1; 530 replaceBits(resTemp, high, low, midRes); 531 } 532 Dest = resTemp; 533 ''', flagType="none", buildCc=False) 534 buildRegDataInst("shasx", ''' 535 int32_t midRes; 536 resTemp = 0; 537 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 538 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 539 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 540 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 541 midRes = (uint64_t)(arg1Low - arg2High) >> 1; 542 replaceBits(resTemp, 15, 0, midRes); 543 midRes = (arg1High + arg2Low) >> 1; 544 replaceBits(resTemp, 31, 16, midRes); 545 Dest = resTemp; 546 ''', flagType="none", buildCc=True) 547 buildRegDataInst("shsax", ''' 548 int32_t midRes; 549 resTemp = 0; 550 int64_t arg1Low = sext<16>(bits(Op1.sw, 15, 0)); 551 int64_t arg1High = sext<16>(bits(Op1.sw, 31, 16)); 552 int64_t arg2Low = sext<16>(bits(Op2.sw, 15, 0)); 553 int64_t arg2High = sext<16>(bits(Op2.sw, 31, 16)); 554 midRes = (uint64_t)(arg1Low + arg2High) >> 1; 555 replaceBits(resTemp, 15, 0, midRes); 556 midRes = (uint64_t)(arg1High - arg2Low) >> 1; 557 replaceBits(resTemp, 31, 16, midRes); 558 Dest = resTemp; 559 ''', flagType="none", buildCc=True) 560 561 buildRegDataInst("uqadd16", ''' 562 uint32_t midRes; 563 for (unsigned i = 0; i < 2; i++) { 564 int high = (i + 1) * 16 - 1; 565 int low = i * 16; 566 uint64_t arg1 = bits(Op1, high, low); 567 uint64_t arg2 = bits(Op2, high, low); 568 uSaturateOp<16>(midRes, arg1, arg2); 569 replaceBits(resTemp, high, low, midRes); 570 } 571 Dest = resTemp; 572 ''', flagType="none", buildCc=False) 573 buildRegDataInst("uqadd8", ''' 574 uint32_t midRes; 575 for (unsigned i = 0; i < 4; i++) { 576 int high = (i + 1) * 8 - 1; 577 int low = i * 8; 578 uint64_t arg1 = bits(Op1, high, low); 579 uint64_t arg2 = bits(Op2, high, low); 580 uSaturateOp<8>(midRes, arg1, arg2); 581 replaceBits(resTemp, high, low, midRes); 582 } 583 Dest = resTemp; 584 ''', flagType="none", buildCc=False) 585 buildRegDataInst("uqsub16", ''' 586 uint32_t midRes; 587 for (unsigned i = 0; i < 2; i++) { 588 int high = (i + 1) * 16 - 1; 589 int low = i * 16; 590 uint64_t arg1 = bits(Op1, high, low); 591 uint64_t arg2 = bits(Op2, high, low); 592 uSaturateOp<16>(midRes, arg1, arg2, true); 593 replaceBits(resTemp, high, low, midRes); 594 } 595 Dest = resTemp; 596 ''', flagType="none", buildCc=False) 597 buildRegDataInst("uqsub8", ''' 598 uint32_t midRes; 599 for (unsigned i = 0; i < 4; i++) { 600 int high = (i + 1) * 8 - 1; 601 int low = i * 8; 602 uint64_t arg1 = bits(Op1, high, low); 603 uint64_t arg2 = bits(Op2, high, low); 604 uSaturateOp<8>(midRes, arg1, arg2, true); 605 replaceBits(resTemp, high, low, midRes); 606 } 607 Dest = resTemp; 608 ''', flagType="none", buildCc=False) 609 buildRegDataInst("uqasx", ''' 610 uint32_t midRes; 611 uint64_t arg1Low = bits(Op1.sw, 15, 0); 612 uint64_t arg1High = bits(Op1.sw, 31, 16); 613 uint64_t arg2Low = bits(Op2.sw, 15, 0); 614 uint64_t arg2High = bits(Op2.sw, 31, 16); 615 uSaturateOp<16>(midRes, arg1Low, arg2High, true); 616 replaceBits(resTemp, 15, 0, midRes); 617 uSaturateOp<16>(midRes, arg1High, arg2Low); 618 replaceBits(resTemp, 31, 16, midRes); 619 Dest = resTemp; 620 ''', flagType="none", buildCc=False) 621 buildRegDataInst("uqsax", ''' 622 uint32_t midRes; 623 uint64_t arg1Low = bits(Op1.sw, 15, 0); 624 uint64_t arg1High = bits(Op1.sw, 31, 16); 625 uint64_t arg2Low = bits(Op2.sw, 15, 0); 626 uint64_t arg2High = bits(Op2.sw, 31, 16); 627 uSaturateOp<16>(midRes, arg1Low, arg2High); 628 replaceBits(resTemp, 15, 0, midRes); 629 uSaturateOp<16>(midRes, arg1High, arg2Low, true); 630 replaceBits(resTemp, 31, 16, midRes); 631 Dest = resTemp; 632 ''', flagType="none", buildCc=False) 633 634 buildRegDataInst("uadd16", ''' 635 uint32_t geBits = 0; 636 resTemp = 0; 637 for (unsigned i = 0; i < 2; i++) { 638 int high = (i + 1) * 16 - 1; 639 int low = i * 16; 640 int32_t midRes = bits(Op1, high, low) + 641 bits(Op2, high, low); 642 if (midRes >= 0x10000) { 643 geBits = geBits | (0x3 << (i * 2)); 644 } 645 replaceBits(resTemp, high, low, midRes); 646 } 647 Dest = resTemp; 648 resTemp = geBits; 649 ''', flagType="ge", buildNonCc=False) 650 buildRegDataInst("uadd8", ''' 651 uint32_t geBits = 0; 652 resTemp = 0; 653 for (unsigned i = 0; i < 4; i++) { 654 int high = (i + 1) * 8 - 1; 655 int low = i * 8; 656 int32_t midRes = bits(Op1, high, low) + 657 bits(Op2, high, low); 658 if (midRes >= 0x100) { 659 geBits = geBits | (1 << i); 660 } 661 replaceBits(resTemp, high, low, midRes); 662 } 663 Dest = resTemp; 664 resTemp = geBits; 665 ''', flagType="ge", buildNonCc=False) 666 buildRegDataInst("usub16", ''' 667 uint32_t geBits = 0; 668 resTemp = 0; 669 for (unsigned i = 0; i < 2; i++) { 670 int high = (i + 1) * 16 - 1; 671 int low = i * 16; 672 int32_t midRes = bits(Op1, high, low) - 673 bits(Op2, high, low); 674 if (midRes >= 0) { 675 geBits = geBits | (0x3 << (i * 2)); 676 } 677 replaceBits(resTemp, high, low, midRes); 678 } 679 Dest = resTemp; 680 resTemp = geBits; 681 ''', flagType="ge", buildNonCc=False) 682 buildRegDataInst("usub8", ''' 683 uint32_t geBits = 0; 684 resTemp = 0; 685 for (unsigned i = 0; i < 4; i++) { 686 int high = (i + 1) * 8 - 1; 687 int low = i * 8; 688 int32_t midRes = bits(Op1, high, low) - 689 bits(Op2, high, low); 690 if (midRes >= 0) { 691 geBits = geBits | (1 << i); 692 } 693 replaceBits(resTemp, high, low, midRes); 694 } 695 Dest = resTemp; 696 resTemp = geBits; 697 ''', flagType="ge", buildNonCc=False) 698 buildRegDataInst("uasx", ''' 699 int32_t midRes, geBits = 0; 700 resTemp = 0; 701 int64_t arg1Low = bits(Op1.sw, 15, 0); 702 int64_t arg1High = bits(Op1.sw, 31, 16); 703 int64_t arg2Low = bits(Op2.sw, 15, 0); 704 int64_t arg2High = bits(Op2.sw, 31, 16); 705 midRes = arg1Low - arg2High; 706 if (midRes >= 0) { 707 geBits = geBits | 0x3; 708 } 709 replaceBits(resTemp, 15, 0, midRes); 710 midRes = arg1High + arg2Low; 711 if (midRes >= 0x10000) { 712 geBits = geBits | 0xc; 713 } 714 replaceBits(resTemp, 31, 16, midRes); 715 Dest = resTemp; 716 resTemp = geBits; 717 ''', flagType="ge", buildNonCc=False) 718 buildRegDataInst("usax", ''' 719 int32_t midRes, geBits = 0; 720 resTemp = 0; 721 int64_t arg1Low = bits(Op1.sw, 15, 0); 722 int64_t arg1High = bits(Op1.sw, 31, 16); 723 int64_t arg2Low = bits(Op2.sw, 15, 0); 724 int64_t arg2High = bits(Op2.sw, 31, 16); 725 midRes = arg1Low + arg2High; 726 if (midRes >= 0x10000) { 727 geBits = geBits | 0x3; 728 } 729 replaceBits(resTemp, 15, 0, midRes); 730 midRes = arg1High - arg2Low; 731 if (midRes >= 0) { 732 geBits = geBits | 0xc; 733 } 734 replaceBits(resTemp, 31, 16, midRes); 735 Dest = resTemp; 736 resTemp = geBits; 737 ''', flagType="ge", buildNonCc=False) 738 739 buildRegDataInst("uhadd16", ''' 740 resTemp = 0; 741 for (unsigned i = 0; i < 2; i++) { 742 int high = (i + 1) * 16 - 1; 743 int low = i * 16; 744 int32_t midRes = (bits(Op1, high, low) + 745 bits(Op2, high, low)) >> 1; 746 replaceBits(resTemp, high, low, midRes); 747 } 748 Dest = resTemp; 749 ''', flagType="none", buildCc=False) 750 buildRegDataInst("uhadd8", ''' 751 resTemp = 0; 752 for (unsigned i = 0; i < 4; i++) { 753 int high = (i + 1) * 8 - 1; 754 int low = i * 8; 755 int32_t midRes = (bits(Op1, high, low) + 756 bits(Op2, high, low)) >> 1; 757 replaceBits(resTemp, high, low, midRes); 758 } 759 Dest = resTemp; 760 ''', flagType="none", buildCc=False) 761 buildRegDataInst("uhsub16", ''' 762 resTemp = 0; 763 for (unsigned i = 0; i < 2; i++) { 764 int high = (i + 1) * 16 - 1; 765 int low = i * 16; 766 int32_t midRes = (bits(Op1, high, low) - 767 bits(Op2, high, low)) >> 1; 768 replaceBits(resTemp, high, low, midRes); 769 } 770 Dest = resTemp; 771 ''', flagType="none", buildCc=False) 772 buildRegDataInst("uhsub8", ''' 773 resTemp = 0; 774 for (unsigned i = 0; i < 4; i++) { 775 int high = (i + 1) * 8 - 1; 776 int low = i * 8; 777 int32_t midRes = (bits(Op1, high, low) - 778 bits(Op2, high, low)) >> 1; 779 replaceBits(resTemp, high, low, midRes); 780 } 781 Dest = resTemp; 782 ''', flagType="none", buildCc=False) 783 buildRegDataInst("uhasx", ''' 784 int32_t midRes; 785 resTemp = 0; 786 int64_t arg1Low = bits(Op1.sw, 15, 0); 787 int64_t arg1High = bits(Op1.sw, 31, 16); 788 int64_t arg2Low = bits(Op2.sw, 15, 0); 789 int64_t arg2High = bits(Op2.sw, 31, 16); 790 midRes = (arg1Low - arg2High) >> 1; 791 replaceBits(resTemp, 15, 0, midRes); 792 midRes = (arg1High + arg2Low) >> 1; 793 replaceBits(resTemp, 31, 16, midRes); 794 Dest = resTemp; 795 ''', flagType="none", buildCc=False) 796 buildRegDataInst("uhsax", ''' 797 int32_t midRes; 798 resTemp = 0; 799 int64_t arg1Low = bits(Op1.sw, 15, 0); 800 int64_t arg1High = bits(Op1.sw, 31, 16); 801 int64_t arg2Low = bits(Op2.sw, 15, 0); 802 int64_t arg2High = bits(Op2.sw, 31, 16); 803 midRes = (arg1Low + arg2High) >> 1; 804 replaceBits(resTemp, 15, 0, midRes); 805 midRes = (arg1High - arg2Low) >> 1; 806 replaceBits(resTemp, 31, 16, midRes); 807 Dest = resTemp; 808 ''', flagType="none", buildCc=False) 809 810 buildRegDataInst("pkhbt", ''' 811 uint32_t resTemp = 0; 812 uint16_t arg1Low = bits(Op1, 15, 0); 813 uint16_t arg2High = bits(secondOp, 31, 16); 814 replaceBits(resTemp, 15, 0, arg1Low); 815 replaceBits(resTemp, 31, 16, arg2High); 816 Dest = resTemp; 817 ''', flagType="none", buildCc=False) 818 buildRegDataInst("pkhtb", ''' 819 uint32_t resTemp = 0; 820 uint16_t arg1High = bits(Op1, 31, 16); 821 uint16_t arg2Low = bits(secondOp, 15, 0); 822 replaceBits(resTemp, 15, 0, arg2Low); 823 replaceBits(resTemp, 31, 16, arg1High); 824 Dest = resTemp; 825 ''', flagType="none", buildCc=False) 826}}; 827