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