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