misc.isa revision 11939
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2013,2017 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 svcCode = ''' 43 fault = std::make_shared<SupervisorCall>(machInst, imm); 44 ''' 45 46 svcIop = InstObjParams("svc", "Svc", "ImmOp", 47 { "code": svcCode, 48 "predicate_test": predicateTest }, 49 ["IsSyscall", "IsNonSpeculative", "IsSerializeAfter"]) 50 header_output = ImmOpDeclare.subst(svcIop) 51 decoder_output = ImmOpConstructor.subst(svcIop) 52 exec_output = PredOpExecute.subst(svcIop) 53 54 smcCode = ''' 55 HCR hcr = Hcr; 56 CPSR cpsr = Cpsr; 57 SCR scr = Scr; 58 59 if ((cpsr.mode != MODE_USER) && FullSystem) { 60 if (ArmSystem::haveVirtualization(xc->tcBase()) && 61 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) && hcr.tsc) { 62 fault = std::make_shared<HypervisorTrap>(machInst, 0, 63 EC_SMC_TO_HYP); 64 } else { 65 if (scr.scd) { 66 fault = disabledFault(); 67 } else { 68 fault = std::make_shared<SecureMonitorCall>(machInst); 69 } 70 } 71 } else { 72 fault = disabledFault(); 73 } 74 ''' 75 76 smcIop = InstObjParams("smc", "Smc", "PredOp", 77 { "code": smcCode, 78 "predicate_test": predicateTest }, 79 ["IsNonSpeculative", "IsSerializeAfter"]) 80 header_output += BasicDeclare.subst(smcIop) 81 decoder_output += BasicConstructor.subst(smcIop) 82 exec_output += PredOpExecute.subst(smcIop) 83 84 hvcCode = ''' 85 CPSR cpsr = Cpsr; 86 SCR scr = Scr; 87 88 // Filter out the various cases where this instruction isn't defined 89 if (!FullSystem || !ArmSystem::haveVirtualization(xc->tcBase()) || 90 (cpsr.mode == MODE_USER) || 91 (ArmSystem::haveSecurity(xc->tcBase()) && (!scr.ns || !scr.hce))) { 92 fault = disabledFault(); 93 } else { 94 fault = std::make_shared<HypervisorCall>(machInst, imm); 95 } 96 ''' 97 98 hvcIop = InstObjParams("hvc", "Hvc", "ImmOp", 99 { "code": hvcCode, 100 "predicate_test": predicateTest }, 101 ["IsNonSpeculative", "IsSerializeAfter"]) 102 header_output += ImmOpDeclare.subst(hvcIop) 103 decoder_output += ImmOpConstructor.subst(hvcIop) 104 exec_output += PredOpExecute.subst(hvcIop) 105 106 eretCode = ''' 107 SCTLR sctlr = Sctlr; 108 CPSR old_cpsr = Cpsr; 109 old_cpsr.nz = CondCodesNZ; 110 old_cpsr.c = CondCodesC; 111 old_cpsr.v = CondCodesV; 112 old_cpsr.ge = CondCodesGE; 113 114 CPSR new_cpsr = cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF, 115 true, sctlr.nmfi, xc->tcBase()); 116 Cpsr = ~CondCodesMask & new_cpsr; 117 CondCodesNZ = new_cpsr.nz; 118 CondCodesC = new_cpsr.c; 119 CondCodesV = new_cpsr.v; 120 CondCodesGE = new_cpsr.ge; 121 122 NextThumb = (new_cpsr).t; 123 NextJazelle = (new_cpsr).j; 124 NextItState = (((new_cpsr).it2 << 2) & 0xFC) 125 | ((new_cpsr).it1 & 0x3); 126 127 NPC = (old_cpsr.mode == MODE_HYP) ? ElrHyp : LR; 128 ''' 129 130 eretIop = InstObjParams("eret", "Eret", "PredOp", 131 { "code": eretCode, 132 "predicate_test": predicateTest }, 133 ["IsNonSpeculative", "IsSerializeAfter", 134 "IsSquashAfter"]) 135 header_output += BasicDeclare.subst(eretIop) 136 decoder_output += BasicConstructor.subst(eretIop) 137 exec_output += PredOpExecute.subst(eretIop) 138 139 140 141}}; 142 143let {{ 144 145 header_output = decoder_output = exec_output = "" 146 147 mrsCpsrCode = ''' 148 CPSR cpsr = Cpsr; 149 cpsr.nz = CondCodesNZ; 150 cpsr.c = CondCodesC; 151 cpsr.v = CondCodesV; 152 cpsr.ge = CondCodesGE; 153 Dest = cpsr & 0xF8FF03DF 154 ''' 155 156 mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp", 157 { "code": mrsCpsrCode, 158 "predicate_test": condPredicateTest }, 159 ["IsSerializeBefore"]) 160 header_output += MrsDeclare.subst(mrsCpsrIop) 161 decoder_output += MrsConstructor.subst(mrsCpsrIop) 162 exec_output += PredOpExecute.subst(mrsCpsrIop) 163 164 mrsSpsrCode = "Dest = Spsr" 165 mrsSpsrIop = InstObjParams("mrs", "MrsSpsr", "MrsOp", 166 { "code": mrsSpsrCode, 167 "predicate_test": predicateTest }, 168 ["IsSerializeBefore"]) 169 header_output += MrsDeclare.subst(mrsSpsrIop) 170 decoder_output += MrsConstructor.subst(mrsSpsrIop) 171 exec_output += PredOpExecute.subst(mrsSpsrIop) 172 173 mrsBankedRegCode = ''' 174 bool isIntReg; 175 int regIdx; 176 177 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) { 178 if (isIntReg) { 179 Dest = DecodedBankedIntReg; 180 } else { 181 Dest = xc->readMiscReg(regIdx); 182 } 183 } else { 184 return std::make_shared<UndefinedInstruction>(machInst, false, 185 mnemonic); 186 } 187 ''' 188 mrsBankedRegIop = InstObjParams("mrs", "MrsBankedReg", "MrsOp", 189 { "code": mrsBankedRegCode, 190 "predicate_test": predicateTest }, 191 ["IsSerializeBefore"]) 192 header_output += MrsBankedRegDeclare.subst(mrsBankedRegIop) 193 decoder_output += MrsBankedRegConstructor.subst(mrsBankedRegIop) 194 exec_output += PredOpExecute.subst(mrsBankedRegIop) 195 196 msrBankedRegCode = ''' 197 bool isIntReg; 198 int regIdx; 199 200 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) { 201 if (isIntReg) { 202 // This is a bit nasty, you would have thought that 203 // DecodedBankedIntReg wouldn't be written to unless the 204 // conditions on the IF statements above are met, however if 205 // you look at the generated C code you'll find that they are. 206 // However this is safe as DecodedBankedIntReg (which is used 207 // in operands.isa to get the index of DecodedBankedIntReg) 208 // will return INTREG_DUMMY if its not a valid integer 209 // register, so redirecting the write to somewhere we don't 210 // care about. 211 DecodedBankedIntReg = Op1; 212 } else { 213 xc->setMiscReg(regIdx, Op1); 214 } 215 } else { 216 return std::make_shared<UndefinedInstruction>(machInst, false, 217 mnemonic); 218 } 219 ''' 220 msrBankedRegIop = InstObjParams("msr", "MsrBankedReg", "MsrRegOp", 221 { "code": msrBankedRegCode, 222 "predicate_test": predicateTest }, 223 ["IsSerializeAfter", "IsNonSpeculative"]) 224 header_output += MsrBankedRegDeclare.subst(msrBankedRegIop) 225 decoder_output += MsrBankedRegConstructor.subst(msrBankedRegIop) 226 exec_output += PredOpExecute.subst(msrBankedRegIop) 227 228 msrCpsrRegCode = ''' 229 SCTLR sctlr = Sctlr; 230 CPSR old_cpsr = Cpsr; 231 old_cpsr.nz = CondCodesNZ; 232 old_cpsr.c = CondCodesC; 233 old_cpsr.v = CondCodesV; 234 old_cpsr.ge = CondCodesGE; 235 236 CPSR new_cpsr = 237 cpsrWriteByInstr(old_cpsr, Op1, Scr, Nsacr, byteMask, false, 238 sctlr.nmfi, xc->tcBase()); 239 Cpsr = ~CondCodesMask & new_cpsr; 240 CondCodesNZ = new_cpsr.nz; 241 CondCodesC = new_cpsr.c; 242 CondCodesV = new_cpsr.v; 243 CondCodesGE = new_cpsr.ge; 244 ''' 245 msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp", 246 { "code": msrCpsrRegCode, 247 "predicate_test": condPredicateTest }, 248 ["IsSerializeAfter","IsNonSpeculative"]) 249 header_output += MsrRegDeclare.subst(msrCpsrRegIop) 250 decoder_output += MsrRegConstructor.subst(msrCpsrRegIop) 251 exec_output += PredOpExecute.subst(msrCpsrRegIop) 252 253 msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);" 254 msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp", 255 { "code": msrSpsrRegCode, 256 "predicate_test": predicateTest }, 257 ["IsSerializeAfter","IsNonSpeculative"]) 258 header_output += MsrRegDeclare.subst(msrSpsrRegIop) 259 decoder_output += MsrRegConstructor.subst(msrSpsrRegIop) 260 exec_output += PredOpExecute.subst(msrSpsrRegIop) 261 262 msrCpsrImmCode = ''' 263 SCTLR sctlr = Sctlr; 264 CPSR old_cpsr = Cpsr; 265 old_cpsr.nz = CondCodesNZ; 266 old_cpsr.c = CondCodesC; 267 old_cpsr.v = CondCodesV; 268 old_cpsr.ge = CondCodesGE; 269 CPSR new_cpsr = 270 cpsrWriteByInstr(old_cpsr, imm, Scr, Nsacr, byteMask, false, 271 sctlr.nmfi, xc->tcBase()); 272 Cpsr = ~CondCodesMask & new_cpsr; 273 CondCodesNZ = new_cpsr.nz; 274 CondCodesC = new_cpsr.c; 275 CondCodesV = new_cpsr.v; 276 CondCodesGE = new_cpsr.ge; 277 ''' 278 msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp", 279 { "code": msrCpsrImmCode, 280 "predicate_test": condPredicateTest }, 281 ["IsSerializeAfter","IsNonSpeculative"]) 282 header_output += MsrImmDeclare.subst(msrCpsrImmIop) 283 decoder_output += MsrImmConstructor.subst(msrCpsrImmIop) 284 exec_output += PredOpExecute.subst(msrCpsrImmIop) 285 286 msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);" 287 msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp", 288 { "code": msrSpsrImmCode, 289 "predicate_test": predicateTest }, 290 ["IsSerializeAfter","IsNonSpeculative"]) 291 header_output += MsrImmDeclare.subst(msrSpsrImmIop) 292 decoder_output += MsrImmConstructor.subst(msrSpsrImmIop) 293 exec_output += PredOpExecute.subst(msrSpsrImmIop) 294 295 revCode = ''' 296 uint32_t val = Op1; 297 Dest = swap_byte(val); 298 ''' 299 revIop = InstObjParams("rev", "Rev", "RegRegOp", 300 { "code": revCode, 301 "predicate_test": predicateTest }, []) 302 header_output += RegRegOpDeclare.subst(revIop) 303 decoder_output += RegRegOpConstructor.subst(revIop) 304 exec_output += PredOpExecute.subst(revIop) 305 306 rev16Code = ''' 307 uint32_t val = Op1; 308 Dest = (bits(val, 15, 8) << 0) | 309 (bits(val, 7, 0) << 8) | 310 (bits(val, 31, 24) << 16) | 311 (bits(val, 23, 16) << 24); 312 ''' 313 rev16Iop = InstObjParams("rev16", "Rev16", "RegRegOp", 314 { "code": rev16Code, 315 "predicate_test": predicateTest }, []) 316 header_output += RegRegOpDeclare.subst(rev16Iop) 317 decoder_output += RegRegOpConstructor.subst(rev16Iop) 318 exec_output += PredOpExecute.subst(rev16Iop) 319 320 revshCode = ''' 321 uint16_t val = Op1; 322 Dest = sext<16>(swap_byte(val)); 323 ''' 324 revshIop = InstObjParams("revsh", "Revsh", "RegRegOp", 325 { "code": revshCode, 326 "predicate_test": predicateTest }, []) 327 header_output += RegRegOpDeclare.subst(revshIop) 328 decoder_output += RegRegOpConstructor.subst(revshIop) 329 exec_output += PredOpExecute.subst(revshIop) 330 331 rbitCode = ''' 332 uint8_t *opBytes = (uint8_t *)&Op1; 333 uint32_t resTemp; 334 uint8_t *destBytes = (uint8_t *)&resTemp; 335 // This reverses the bytes and bits of the input, or so says the 336 // internet. 337 for (int i = 0; i < 4; i++) { 338 uint32_t temp = opBytes[i]; 339 temp = (temp * 0x0802 & 0x22110) | (temp * 0x8020 & 0x88440); 340 destBytes[3 - i] = (temp * 0x10101) >> 16; 341 } 342 Dest = resTemp; 343 ''' 344 rbitIop = InstObjParams("rbit", "Rbit", "RegRegOp", 345 { "code": rbitCode, 346 "predicate_test": predicateTest }, []) 347 header_output += RegRegOpDeclare.subst(rbitIop) 348 decoder_output += RegRegOpConstructor.subst(rbitIop) 349 exec_output += PredOpExecute.subst(rbitIop) 350 351 clzCode = ''' 352 Dest = (Op1 == 0) ? 32 : (31 - findMsbSet(Op1)); 353 ''' 354 clzIop = InstObjParams("clz", "Clz", "RegRegOp", 355 { "code": clzCode, 356 "predicate_test": predicateTest }, []) 357 header_output += RegRegOpDeclare.subst(clzIop) 358 decoder_output += RegRegOpConstructor.subst(clzIop) 359 exec_output += PredOpExecute.subst(clzIop) 360 361 ssatCode = ''' 362 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0); 363 int32_t res; 364 if (satInt(res, operand, imm)) 365 CpsrQ = 1 << 27; 366 Dest = res; 367 ''' 368 ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp", 369 { "code": ssatCode, 370 "predicate_test": pickPredicate(ssatCode) }, []) 371 header_output += RegImmRegShiftOpDeclare.subst(ssatIop) 372 decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop) 373 exec_output += PredOpExecute.subst(ssatIop) 374 375 usatCode = ''' 376 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0); 377 int32_t res; 378 if (uSatInt(res, operand, imm)) 379 CpsrQ = 1 << 27; 380 Dest = res; 381 ''' 382 usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp", 383 { "code": usatCode, 384 "predicate_test": pickPredicate(usatCode) }, []) 385 header_output += RegImmRegShiftOpDeclare.subst(usatIop) 386 decoder_output += RegImmRegShiftOpConstructor.subst(usatIop) 387 exec_output += PredOpExecute.subst(usatIop) 388 389 ssat16Code = ''' 390 int32_t res; 391 uint32_t resTemp = 0; 392 int32_t argLow = sext<16>(bits(Op1, 15, 0)); 393 int32_t argHigh = sext<16>(bits(Op1, 31, 16)); 394 if (satInt(res, argLow, imm)) 395 CpsrQ = 1 << 27; 396 replaceBits(resTemp, 15, 0, res); 397 if (satInt(res, argHigh, imm)) 398 CpsrQ = 1 << 27; 399 replaceBits(resTemp, 31, 16, res); 400 Dest = resTemp; 401 ''' 402 ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp", 403 { "code": ssat16Code, 404 "predicate_test": pickPredicate(ssat16Code) }, []) 405 header_output += RegImmRegOpDeclare.subst(ssat16Iop) 406 decoder_output += RegImmRegOpConstructor.subst(ssat16Iop) 407 exec_output += PredOpExecute.subst(ssat16Iop) 408 409 usat16Code = ''' 410 int32_t res; 411 uint32_t resTemp = 0; 412 int32_t argLow = sext<16>(bits(Op1, 15, 0)); 413 int32_t argHigh = sext<16>(bits(Op1, 31, 16)); 414 if (uSatInt(res, argLow, imm)) 415 CpsrQ = 1 << 27; 416 replaceBits(resTemp, 15, 0, res); 417 if (uSatInt(res, argHigh, imm)) 418 CpsrQ = 1 << 27; 419 replaceBits(resTemp, 31, 16, res); 420 Dest = resTemp; 421 ''' 422 usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp", 423 { "code": usat16Code, 424 "predicate_test": pickPredicate(usat16Code) }, []) 425 header_output += RegImmRegOpDeclare.subst(usat16Iop) 426 decoder_output += RegImmRegOpConstructor.subst(usat16Iop) 427 exec_output += PredOpExecute.subst(usat16Iop) 428 429 sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp", 430 { "code": 431 "Dest = sext<8>((uint8_t)(Op1_ud >> imm));", 432 "predicate_test": predicateTest }, []) 433 header_output += RegImmRegOpDeclare.subst(sxtbIop) 434 decoder_output += RegImmRegOpConstructor.subst(sxtbIop) 435 exec_output += PredOpExecute.subst(sxtbIop) 436 437 sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp", 438 { "code": 439 ''' 440 Dest = sext<8>((uint8_t)(Op2_ud >> imm)) + 441 Op1; 442 ''', 443 "predicate_test": predicateTest }, []) 444 header_output += RegRegRegImmOpDeclare.subst(sxtabIop) 445 decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop) 446 exec_output += PredOpExecute.subst(sxtabIop) 447 448 sxtb16Code = ''' 449 uint32_t resTemp = 0; 450 replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm))); 451 replaceBits(resTemp, 31, 16, 452 sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32))); 453 Dest = resTemp; 454 ''' 455 sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp", 456 { "code": sxtb16Code, 457 "predicate_test": predicateTest }, []) 458 header_output += RegImmRegOpDeclare.subst(sxtb16Iop) 459 decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop) 460 exec_output += PredOpExecute.subst(sxtb16Iop) 461 462 sxtab16Code = ''' 463 uint32_t resTemp = 0; 464 replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) + 465 bits(Op1, 15, 0)); 466 replaceBits(resTemp, 31, 16, 467 sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) + 468 bits(Op1, 31, 16)); 469 Dest = resTemp; 470 ''' 471 sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp", 472 { "code": sxtab16Code, 473 "predicate_test": predicateTest }, []) 474 header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop) 475 decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop) 476 exec_output += PredOpExecute.subst(sxtab16Iop) 477 478 sxthCode = ''' 479 uint64_t rotated = (uint32_t)Op1; 480 rotated = (rotated | (rotated << 32)) >> imm; 481 Dest = sext<16>((uint16_t)rotated); 482 ''' 483 sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp", 484 { "code": sxthCode, 485 "predicate_test": predicateTest }, []) 486 header_output += RegImmRegOpDeclare.subst(sxthIop) 487 decoder_output += RegImmRegOpConstructor.subst(sxthIop) 488 exec_output += PredOpExecute.subst(sxthIop) 489 490 sxtahCode = ''' 491 uint64_t rotated = (uint32_t)Op2; 492 rotated = (rotated | (rotated << 32)) >> imm; 493 Dest = sext<16>((uint16_t)rotated) + Op1; 494 ''' 495 sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp", 496 { "code": sxtahCode, 497 "predicate_test": predicateTest }, []) 498 header_output += RegRegRegImmOpDeclare.subst(sxtahIop) 499 decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop) 500 exec_output += PredOpExecute.subst(sxtahIop) 501 502 uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp", 503 { "code": "Dest = (uint8_t)(Op1_ud >> imm);", 504 "predicate_test": predicateTest }, []) 505 header_output += RegImmRegOpDeclare.subst(uxtbIop) 506 decoder_output += RegImmRegOpConstructor.subst(uxtbIop) 507 exec_output += PredOpExecute.subst(uxtbIop) 508 509 uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp", 510 { "code": 511 "Dest = (uint8_t)(Op2_ud >> imm) + Op1;", 512 "predicate_test": predicateTest }, []) 513 header_output += RegRegRegImmOpDeclare.subst(uxtabIop) 514 decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop) 515 exec_output += PredOpExecute.subst(uxtabIop) 516 517 uxtb16Code = ''' 518 uint32_t resTemp = 0; 519 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm))); 520 replaceBits(resTemp, 31, 16, 521 (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32))); 522 Dest = resTemp; 523 ''' 524 uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp", 525 { "code": uxtb16Code, 526 "predicate_test": predicateTest }, []) 527 header_output += RegImmRegOpDeclare.subst(uxtb16Iop) 528 decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop) 529 exec_output += PredOpExecute.subst(uxtb16Iop) 530 531 uxtab16Code = ''' 532 uint32_t resTemp = 0; 533 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) + 534 bits(Op1, 15, 0)); 535 replaceBits(resTemp, 31, 16, 536 (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) + 537 bits(Op1, 31, 16)); 538 Dest = resTemp; 539 ''' 540 uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp", 541 { "code": uxtab16Code, 542 "predicate_test": predicateTest }, []) 543 header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop) 544 decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop) 545 exec_output += PredOpExecute.subst(uxtab16Iop) 546 547 uxthCode = ''' 548 uint64_t rotated = (uint32_t)Op1; 549 rotated = (rotated | (rotated << 32)) >> imm; 550 Dest = (uint16_t)rotated; 551 ''' 552 uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp", 553 { "code": uxthCode, 554 "predicate_test": predicateTest }, []) 555 header_output += RegImmRegOpDeclare.subst(uxthIop) 556 decoder_output += RegImmRegOpConstructor.subst(uxthIop) 557 exec_output += PredOpExecute.subst(uxthIop) 558 559 uxtahCode = ''' 560 uint64_t rotated = (uint32_t)Op2; 561 rotated = (rotated | (rotated << 32)) >> imm; 562 Dest = (uint16_t)rotated + Op1; 563 ''' 564 uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp", 565 { "code": uxtahCode, 566 "predicate_test": predicateTest }, []) 567 header_output += RegRegRegImmOpDeclare.subst(uxtahIop) 568 decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop) 569 exec_output += PredOpExecute.subst(uxtahIop) 570 571 selCode = ''' 572 uint32_t resTemp = 0; 573 for (unsigned i = 0; i < 4; i++) { 574 int low = i * 8; 575 int high = low + 7; 576 replaceBits(resTemp, high, low, 577 bits(CondCodesGE, i) ? 578 bits(Op1, high, low) : bits(Op2, high, low)); 579 } 580 Dest = resTemp; 581 ''' 582 selIop = InstObjParams("sel", "Sel", "RegRegRegOp", 583 { "code": selCode, 584 "predicate_test": predicateTest }, []) 585 header_output += RegRegRegOpDeclare.subst(selIop) 586 decoder_output += RegRegRegOpConstructor.subst(selIop) 587 exec_output += PredOpExecute.subst(selIop) 588 589 usad8Code = ''' 590 uint32_t resTemp = 0; 591 for (unsigned i = 0; i < 4; i++) { 592 int low = i * 8; 593 int high = low + 7; 594 int32_t diff = bits(Op1, high, low) - 595 bits(Op2, high, low); 596 resTemp += ((diff < 0) ? -diff : diff); 597 } 598 Dest = resTemp; 599 ''' 600 usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp", 601 { "code": usad8Code, 602 "predicate_test": predicateTest }, []) 603 header_output += RegRegRegOpDeclare.subst(usad8Iop) 604 decoder_output += RegRegRegOpConstructor.subst(usad8Iop) 605 exec_output += PredOpExecute.subst(usad8Iop) 606 607 usada8Code = ''' 608 uint32_t resTemp = 0; 609 for (unsigned i = 0; i < 4; i++) { 610 int low = i * 8; 611 int high = low + 7; 612 int32_t diff = bits(Op1, high, low) - 613 bits(Op2, high, low); 614 resTemp += ((diff < 0) ? -diff : diff); 615 } 616 Dest = Op3 + resTemp; 617 ''' 618 usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp", 619 { "code": usada8Code, 620 "predicate_test": predicateTest }, []) 621 header_output += RegRegRegRegOpDeclare.subst(usada8Iop) 622 decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop) 623 exec_output += PredOpExecute.subst(usada8Iop) 624 625 bkptCode = 'return std::make_shared<PrefetchAbort>(PC, ArmFault::DebugEvent);\n' 626 bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode) 627 header_output += BasicDeclare.subst(bkptIop) 628 decoder_output += BasicConstructor.subst(bkptIop) 629 exec_output += BasicExecute.subst(bkptIop) 630 631 nopIop = InstObjParams("nop", "NopInst", "ArmStaticInst", "", ['IsNop']) 632 header_output += BasicDeclare.subst(nopIop) 633 decoder_output += BasicConstructor64.subst(nopIop) 634 exec_output += BasicExecute.subst(nopIop) 635 636 yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \ 637 { "code" : "", "predicate_test" : predicateTest }) 638 header_output += BasicDeclare.subst(yieldIop) 639 decoder_output += BasicConstructor.subst(yieldIop) 640 exec_output += PredOpExecute.subst(yieldIop) 641 642 wfeCode = ''' 643 HCR hcr = Hcr; 644 CPSR cpsr = Cpsr; 645 SCR scr = Scr64; 646 SCTLR sctlr = Sctlr; 647 648 // WFE Sleeps if SevMailbox==0 and no unmasked interrupts are pending, 649 ThreadContext *tc = xc->tcBase(); 650 if (SevMailbox == 1) { 651 SevMailbox = 0; 652 PseudoInst::quiesceSkip(tc); 653 } else if (tc->getCpuPtr()->getInterruptController( 654 tc->threadId())->checkInterrupts(tc)) { 655 PseudoInst::quiesceSkip(tc); 656 } else if (cpsr.el == EL0 && !sctlr.ntwe) { 657 PseudoInst::quiesceSkip(tc); 658 fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00001, 659 EC_TRAPPED_WFI_WFE); 660 } else if (ArmSystem::haveVirtualization(tc) && 661 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) && 662 hcr.twe) { 663 PseudoInst::quiesceSkip(tc); 664 fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00001, 665 EC_TRAPPED_WFI_WFE); 666 } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twe) { 667 PseudoInst::quiesceSkip(tc); 668 fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00001, 669 EC_TRAPPED_WFI_WFE); 670 } else { 671 PseudoInst::quiesce(tc); 672 } 673 ''' 674 wfePredFixUpCode = ''' 675 // WFE is predicated false, reset SevMailbox to reduce spurious sleeps 676 // and SEV interrupts 677 SevMailbox = 1; 678 ''' 679 wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \ 680 { "code" : wfeCode, 681 "pred_fixup" : wfePredFixUpCode, 682 "predicate_test" : predicateTest }, 683 ["IsNonSpeculative", "IsQuiesce", 684 "IsSerializeAfter", "IsUnverifiable"]) 685 header_output += BasicDeclare.subst(wfeIop) 686 decoder_output += BasicConstructor.subst(wfeIop) 687 exec_output += QuiescePredOpExecuteWithFixup.subst(wfeIop) 688 689 wfiCode = ''' 690 HCR hcr = Hcr; 691 CPSR cpsr = Cpsr; 692 SCR scr = Scr64; 693 SCTLR sctlr = Sctlr; 694 695 // WFI doesn't sleep if interrupts are pending (masked or not) 696 ThreadContext *tc = xc->tcBase(); 697 if (tc->getCpuPtr()->getInterruptController( 698 tc->threadId())->checkWfiWake(hcr, cpsr, scr)) { 699 PseudoInst::quiesceSkip(tc); 700 } else if (cpsr.el == EL0 && !sctlr.ntwi) { 701 PseudoInst::quiesceSkip(tc); 702 fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00000, 703 EC_TRAPPED_WFI_WFE); 704 } else if (ArmSystem::haveVirtualization(tc) && hcr.twi && 705 (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr)) { 706 PseudoInst::quiesceSkip(tc); 707 fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00000, 708 EC_TRAPPED_WFI_WFE); 709 } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twi) { 710 PseudoInst::quiesceSkip(tc); 711 fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000, 712 EC_TRAPPED_WFI_WFE); 713 } else { 714 PseudoInst::quiesce(tc); 715 } 716 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0); 717 ''' 718 wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \ 719 { "code" : wfiCode, "predicate_test" : predicateTest }, 720 ["IsNonSpeculative", "IsQuiesce", 721 "IsSerializeAfter", "IsUnverifiable"]) 722 header_output += BasicDeclare.subst(wfiIop) 723 decoder_output += BasicConstructor.subst(wfiIop) 724 exec_output += QuiescePredOpExecute.subst(wfiIop) 725 726 sevCode = ''' 727 SevMailbox = 1; 728 System *sys = xc->tcBase()->getSystemPtr(); 729 for (int x = 0; x < sys->numContexts(); x++) { 730 ThreadContext *oc = sys->getThreadContext(x); 731 if (oc == xc->tcBase()) 732 continue; 733 // Wake CPU with interrupt if they were sleeping 734 if (oc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) { 735 // Post Interrupt and wake cpu if needed 736 oc->getCpuPtr()->postInterrupt(oc->threadId(), INT_SEV, 0); 737 } 738 } 739 ''' 740 sevIop = InstObjParams("sev", "SevInst", "PredOp", \ 741 { "code" : sevCode, "predicate_test" : predicateTest }, 742 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"]) 743 header_output += BasicDeclare.subst(sevIop) 744 decoder_output += BasicConstructor.subst(sevIop) 745 exec_output += PredOpExecute.subst(sevIop) 746 747 sevlCode = ''' 748 SevMailbox = 1; 749 ''' 750 sevlIop = InstObjParams("sevl", "SevlInst", "PredOp", \ 751 { "code" : sevlCode, "predicate_test" : predicateTest }, 752 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"]) 753 header_output += BasicDeclare.subst(sevlIop) 754 decoder_output += BasicConstructor.subst(sevlIop) 755 exec_output += BasicExecute.subst(sevlIop) 756 757 itIop = InstObjParams("it", "ItInst", "PredOp", \ 758 { "code" : ";", 759 "predicate_test" : predicateTest }, []) 760 header_output += BasicDeclare.subst(itIop) 761 decoder_output += BasicConstructor.subst(itIop) 762 exec_output += PredOpExecute.subst(itIop) 763 unknownCode = ''' 764 return std::make_shared<UndefinedInstruction>(machInst, true); 765 ''' 766 unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \ 767 { "code": unknownCode, 768 "predicate_test": predicateTest }) 769 header_output += BasicDeclare.subst(unknownIop) 770 decoder_output += BasicConstructor.subst(unknownIop) 771 exec_output += PredOpExecute.subst(unknownIop) 772 773 ubfxCode = ''' 774 Dest = bits(Op1, imm2, imm1); 775 ''' 776 ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp", 777 { "code": ubfxCode, 778 "predicate_test": predicateTest }, []) 779 header_output += RegRegImmImmOpDeclare.subst(ubfxIop) 780 decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop) 781 exec_output += PredOpExecute.subst(ubfxIop) 782 783 sbfxCode = ''' 784 int32_t resTemp = bits(Op1, imm2, imm1); 785 Dest = resTemp | -(resTemp & (1 << (imm2 - imm1))); 786 ''' 787 sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp", 788 { "code": sbfxCode, 789 "predicate_test": predicateTest }, []) 790 header_output += RegRegImmImmOpDeclare.subst(sbfxIop) 791 decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop) 792 exec_output += PredOpExecute.subst(sbfxIop) 793 794 bfcCode = ''' 795 Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1); 796 ''' 797 bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp", 798 { "code": bfcCode, 799 "predicate_test": predicateTest }, []) 800 header_output += RegRegImmImmOpDeclare.subst(bfcIop) 801 decoder_output += RegRegImmImmOpConstructor.subst(bfcIop) 802 exec_output += PredOpExecute.subst(bfcIop) 803 804 bfiCode = ''' 805 uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1); 806 Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask); 807 ''' 808 bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp", 809 { "code": bfiCode, 810 "predicate_test": predicateTest }, []) 811 header_output += RegRegImmImmOpDeclare.subst(bfiIop) 812 decoder_output += RegRegImmImmOpConstructor.subst(bfiIop) 813 exec_output += PredOpExecute.subst(bfiIop) 814 815 mrc14code = ''' 816 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(op1); 817 bool can_read, undefined; 818 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); 819 if (!can_read || undefined) { 820 return std::make_shared<UndefinedInstruction>(machInst, false, 821 mnemonic); 822 } 823 if (mcrMrc14TrapToHyp((const MiscRegIndex) op1, Hcr, Cpsr, Scr, Hdcr, 824 Hstr, Hcptr, imm)) { 825 return std::make_shared<HypervisorTrap>(machInst, imm, 826 EC_TRAPPED_CP14_MCR_MRC); 827 } 828 Dest = MiscOp1; 829 ''' 830 831 mrc14Iop = InstObjParams("mrc", "Mrc14", "RegRegImmOp", 832 { "code": mrc14code, 833 "predicate_test": predicateTest }, []) 834 header_output += RegRegImmOpDeclare.subst(mrc14Iop) 835 decoder_output += RegRegImmOpConstructor.subst(mrc14Iop) 836 exec_output += PredOpExecute.subst(mrc14Iop) 837 838 839 mcr14code = ''' 840 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest); 841 bool can_write, undefined; 842 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); 843 if (undefined || !can_write) { 844 return std::make_shared<UndefinedInstruction>(machInst, false, 845 mnemonic); 846 } 847 if (mcrMrc14TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, 848 Hstr, Hcptr, imm)) { 849 return std::make_shared<HypervisorTrap>(machInst, imm, 850 EC_TRAPPED_CP14_MCR_MRC); 851 } 852 MiscDest = Op1; 853 ''' 854 mcr14Iop = InstObjParams("mcr", "Mcr14", "RegRegImmOp", 855 { "code": mcr14code, 856 "predicate_test": predicateTest }, 857 ["IsSerializeAfter","IsNonSpeculative"]) 858 header_output += RegRegImmOpDeclare.subst(mcr14Iop) 859 decoder_output += RegRegImmOpConstructor.subst(mcr14Iop) 860 exec_output += PredOpExecute.subst(mcr14Iop) 861 862 mrc15code = ''' 863 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase()); 864 MiscRegIndex miscReg = (MiscRegIndex) 865 xc->tcBase()->flattenMiscIndex(preFlatOp1); 866 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, 867 Hcptr, imm); 868 bool can_read, undefined; 869 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); 870 // if we're in non secure PL1 mode then we can trap regargless of whether 871 // the register is accessable, in other modes we trap if only if the register 872 // IS accessable. 873 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && 874 !inSecureState(Scr, Cpsr)))) { 875 return std::make_shared<UndefinedInstruction>(machInst, false, 876 mnemonic); 877 } 878 if (hypTrap) { 879 return std::make_shared<HypervisorTrap>(machInst, imm, 880 EC_TRAPPED_CP15_MCR_MRC); 881 } 882 Dest = MiscNsBankedOp1; 883 ''' 884 885 mrc15Iop = InstObjParams("mrc", "Mrc15", "RegMiscRegImmOp", 886 { "code": mrc15code, 887 "predicate_test": predicateTest }, []) 888 header_output += RegMiscRegImmOpDeclare.subst(mrc15Iop) 889 decoder_output += RegMiscRegImmOpConstructor.subst(mrc15Iop) 890 exec_output += PredOpExecute.subst(mrc15Iop) 891 892 893 mcr15code = ''' 894 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase()); 895 MiscRegIndex miscReg = (MiscRegIndex) 896 xc->tcBase()->flattenMiscIndex(preFlatDest); 897 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, 898 Hcptr, imm); 899 bool can_write, undefined; 900 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); 901 902 // if we're in non secure PL1 mode then we can trap regargless of whether 903 // the register is accessable, in other modes we trap if only if the register 904 // IS accessable. 905 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && 906 !inSecureState(Scr, Cpsr)))) { 907 return std::make_shared<UndefinedInstruction>(machInst, false, 908 mnemonic); 909 } 910 if (hypTrap) { 911 return std::make_shared<HypervisorTrap>(machInst, imm, 912 EC_TRAPPED_CP15_MCR_MRC); 913 } 914 MiscNsBankedDest = Op1; 915 ''' 916 mcr15Iop = InstObjParams("mcr", "Mcr15", "MiscRegRegImmOp", 917 { "code": mcr15code, 918 "predicate_test": predicateTest }, 919 ["IsSerializeAfter","IsNonSpeculative"]) 920 header_output += MiscRegRegImmOpDeclare.subst(mcr15Iop) 921 decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop) 922 exec_output += PredOpExecute.subst(mcr15Iop) 923 924 925 mrrc15code = ''' 926 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase()); 927 MiscRegIndex miscReg = (MiscRegIndex) 928 xc->tcBase()->flattenMiscIndex(preFlatOp1); 929 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); 930 bool can_read, undefined; 931 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); 932 // if we're in non secure PL1 mode then we can trap regargless of whether 933 // the register is accessable, in other modes we trap if only if the register 934 // IS accessable. 935 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && 936 !inSecureState(Scr, Cpsr)))) { 937 return std::make_shared<UndefinedInstruction>(machInst, false, 938 mnemonic); 939 } 940 if (hypTrap) { 941 return std::make_shared<HypervisorTrap>(machInst, imm, 942 EC_TRAPPED_CP15_MCRR_MRRC); 943 } 944 Dest = bits(MiscNsBankedOp164, 63, 32); 945 Dest2 = bits(MiscNsBankedOp164, 31, 0); 946 ''' 947 mrrc15Iop = InstObjParams("mrrc", "Mrrc15", "MrrcOp", 948 { "code": mrrc15code, 949 "predicate_test": predicateTest }, []) 950 header_output += MrrcOpDeclare.subst(mrrc15Iop) 951 decoder_output += MrrcOpConstructor.subst(mrrc15Iop) 952 exec_output += PredOpExecute.subst(mrrc15Iop) 953 954 955 mcrr15code = ''' 956 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase()); 957 MiscRegIndex miscReg = (MiscRegIndex) 958 xc->tcBase()->flattenMiscIndex(preFlatDest); 959 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); 960 bool can_write, undefined; 961 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); 962 963 // if we're in non secure PL1 mode then we can trap regargless of whether 964 // the register is accessable, in other modes we trap if only if the register 965 // IS accessable. 966 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && 967 !inSecureState(Scr, Cpsr)))) { 968 return std::make_shared<UndefinedInstruction>(machInst, false, 969 mnemonic); 970 } 971 if (hypTrap) { 972 return std::make_shared<HypervisorTrap>(machInst, imm, 973 EC_TRAPPED_CP15_MCRR_MRRC); 974 } 975 MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2; 976 ''' 977 mcrr15Iop = InstObjParams("mcrr", "Mcrr15", "McrrOp", 978 { "code": mcrr15code, 979 "predicate_test": predicateTest }, []) 980 header_output += McrrOpDeclare.subst(mcrr15Iop) 981 decoder_output += McrrOpConstructor.subst(mcrr15Iop) 982 exec_output += PredOpExecute.subst(mcrr15Iop) 983 984 985 enterxCode = ''' 986 NextThumb = true; 987 NextJazelle = true; 988 ''' 989 enterxIop = InstObjParams("enterx", "Enterx", "PredOp", 990 { "code": enterxCode, 991 "predicate_test": predicateTest }, []) 992 header_output += BasicDeclare.subst(enterxIop) 993 decoder_output += BasicConstructor.subst(enterxIop) 994 exec_output += PredOpExecute.subst(enterxIop) 995 996 leavexCode = ''' 997 NextThumb = true; 998 NextJazelle = false; 999 ''' 1000 leavexIop = InstObjParams("leavex", "Leavex", "PredOp", 1001 { "code": leavexCode, 1002 "predicate_test": predicateTest }, []) 1003 header_output += BasicDeclare.subst(leavexIop) 1004 decoder_output += BasicConstructor.subst(leavexIop) 1005 exec_output += PredOpExecute.subst(leavexIop) 1006 1007 setendCode = ''' 1008 CPSR cpsr = Cpsr; 1009 cpsr.e = imm; 1010 Cpsr = cpsr; 1011 ''' 1012 setendIop = InstObjParams("setend", "Setend", "ImmOp", 1013 { "code": setendCode, 1014 "predicate_test": predicateTest }, 1015 ["IsSerializeAfter","IsNonSpeculative"]) 1016 header_output += ImmOpDeclare.subst(setendIop) 1017 decoder_output += ImmOpConstructor.subst(setendIop) 1018 exec_output += PredOpExecute.subst(setendIop) 1019 1020 clrexCode = ''' 1021 LLSCLock = 0; 1022 ''' 1023 clrexIop = InstObjParams("clrex", "Clrex","PredOp", 1024 { "code": clrexCode, 1025 "predicate_test": predicateTest },[]) 1026 header_output += BasicDeclare.subst(clrexIop) 1027 decoder_output += BasicConstructor.subst(clrexIop) 1028 exec_output += PredOpExecute.subst(clrexIop) 1029 1030 isbCode = ''' 1031 // If the barrier is due to a CP15 access check for hyp traps 1032 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB, Hcr, Cpsr, Scr, 1033 Hdcr, Hstr, Hcptr, imm)) { 1034 return std::make_shared<HypervisorTrap>(machInst, imm, 1035 EC_TRAPPED_CP15_MCR_MRC); 1036 } 1037 fault = std::make_shared<FlushPipe>(); 1038 ''' 1039 isbIop = InstObjParams("isb", "Isb", "ImmOp", 1040 {"code": isbCode, 1041 "predicate_test": predicateTest}, 1042 ['IsSerializeAfter']) 1043 header_output += ImmOpDeclare.subst(isbIop) 1044 decoder_output += ImmOpConstructor.subst(isbIop) 1045 exec_output += PredOpExecute.subst(isbIop) 1046 1047 dsbCode = ''' 1048 // If the barrier is due to a CP15 access check for hyp traps 1049 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DSB, Hcr, Cpsr, Scr, 1050 Hdcr, Hstr, Hcptr, imm)) { 1051 return std::make_shared<HypervisorTrap>(machInst, imm, 1052 EC_TRAPPED_CP15_MCR_MRC); 1053 } 1054 fault = std::make_shared<FlushPipe>(); 1055 ''' 1056 dsbIop = InstObjParams("dsb", "Dsb", "ImmOp", 1057 {"code": dsbCode, 1058 "predicate_test": predicateTest}, 1059 ['IsMemBarrier', 'IsSerializeAfter']) 1060 header_output += ImmOpDeclare.subst(dsbIop) 1061 decoder_output += ImmOpConstructor.subst(dsbIop) 1062 exec_output += PredOpExecute.subst(dsbIop) 1063 1064 dmbCode = ''' 1065 // If the barrier is due to a CP15 access check for hyp traps 1066 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DMB, Hcr, Cpsr, Scr, 1067 Hdcr, Hstr, Hcptr, imm)) { 1068 return std::make_shared<HypervisorTrap>(machInst, imm, 1069 EC_TRAPPED_CP15_MCR_MRC); 1070 } 1071 ''' 1072 dmbIop = InstObjParams("dmb", "Dmb", "ImmOp", 1073 {"code": dmbCode, 1074 "predicate_test": predicateTest}, 1075 ['IsMemBarrier']) 1076 header_output += ImmOpDeclare.subst(dmbIop) 1077 decoder_output += ImmOpConstructor.subst(dmbIop) 1078 exec_output += PredOpExecute.subst(dmbIop) 1079 1080 dbgCode = ''' 1081 ''' 1082 dbgIop = InstObjParams("dbg", "Dbg", "PredOp", 1083 {"code": dbgCode, 1084 "predicate_test": predicateTest}) 1085 header_output += BasicDeclare.subst(dbgIop) 1086 decoder_output += BasicConstructor.subst(dbgIop) 1087 exec_output += PredOpExecute.subst(dbgIop) 1088 1089 cpsCode = ''' 1090 uint32_t mode = bits(imm, 4, 0); 1091 uint32_t f = bits(imm, 5); 1092 uint32_t i = bits(imm, 6); 1093 uint32_t a = bits(imm, 7); 1094 bool setMode = bits(imm, 8); 1095 bool enable = bits(imm, 9); 1096 CPSR cpsr = Cpsr; 1097 SCTLR sctlr = Sctlr; 1098 if (cpsr.mode != MODE_USER) { 1099 if (enable) { 1100 if (f) cpsr.f = 0; 1101 if (i) cpsr.i = 0; 1102 if (a) cpsr.a = 0; 1103 } else { 1104 if (f && !sctlr.nmfi) cpsr.f = 1; 1105 if (i) cpsr.i = 1; 1106 if (a) cpsr.a = 1; 1107 } 1108 if (setMode) { 1109 cpsr.mode = mode; 1110 } 1111 } 1112 Cpsr = cpsr; 1113 ''' 1114 cpsIop = InstObjParams("cps", "Cps", "ImmOp", 1115 { "code": cpsCode, 1116 "predicate_test": predicateTest }, 1117 ["IsSerializeAfter","IsNonSpeculative"]) 1118 header_output += ImmOpDeclare.subst(cpsIop) 1119 decoder_output += ImmOpConstructor.subst(cpsIop) 1120 exec_output += PredOpExecute.subst(cpsIop) 1121}}; 1122