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