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