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