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