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