misc.isa revision 12106
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()->flattenRegId( 817 RegId(MiscRegClass, op1)).index(); 818 bool can_read, undefined; 819 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); 820 if (!can_read || undefined) { 821 return std::make_shared<UndefinedInstruction>(machInst, false, 822 mnemonic); 823 } 824 if (mcrMrc14TrapToHyp((const MiscRegIndex) op1, Hcr, Cpsr, Scr, Hdcr, 825 Hstr, Hcptr, imm)) { 826 return std::make_shared<HypervisorTrap>(machInst, imm, 827 EC_TRAPPED_CP14_MCR_MRC); 828 } 829 Dest = MiscOp1; 830 ''' 831 832 mrc14Iop = InstObjParams("mrc", "Mrc14", "RegRegImmOp", 833 { "code": mrc14code, 834 "predicate_test": predicateTest }, []) 835 header_output += RegRegImmOpDeclare.subst(mrc14Iop) 836 decoder_output += RegRegImmOpConstructor.subst(mrc14Iop) 837 exec_output += PredOpExecute.subst(mrc14Iop) 838 839 840 mcr14code = ''' 841 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId( 842 RegId(MiscRegClass, dest)).index(); 843 bool can_write, undefined; 844 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); 845 if (undefined || !can_write) { 846 return std::make_shared<UndefinedInstruction>(machInst, false, 847 mnemonic); 848 } 849 if (mcrMrc14TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, 850 Hstr, Hcptr, imm)) { 851 return std::make_shared<HypervisorTrap>(machInst, imm, 852 EC_TRAPPED_CP14_MCR_MRC); 853 } 854 MiscDest = Op1; 855 ''' 856 mcr14Iop = InstObjParams("mcr", "Mcr14", "RegRegImmOp", 857 { "code": mcr14code, 858 "predicate_test": predicateTest }, 859 ["IsSerializeAfter","IsNonSpeculative"]) 860 header_output += RegRegImmOpDeclare.subst(mcr14Iop) 861 decoder_output += RegRegImmOpConstructor.subst(mcr14Iop) 862 exec_output += PredOpExecute.subst(mcr14Iop) 863 864 mrc15code = ''' 865 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase()); 866 MiscRegIndex miscReg = (MiscRegIndex) 867 xc->tcBase()->flattenRegId(RegId(MiscRegClass, 868 preFlatOp1)).index(); 869 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, 870 Hcptr, imm); 871 bool can_read, undefined; 872 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); 873 // if we're in non secure PL1 mode then we can trap regargless of whether 874 // the register is accessable, in other modes we trap if only if the register 875 // IS accessable. 876 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && 877 !inSecureState(Scr, Cpsr)))) { 878 return std::make_shared<UndefinedInstruction>(machInst, false, 879 mnemonic); 880 } 881 if (hypTrap) { 882 return std::make_shared<HypervisorTrap>(machInst, imm, 883 EC_TRAPPED_CP15_MCR_MRC); 884 } 885 Dest = MiscNsBankedOp1; 886 ''' 887 888 mrc15Iop = InstObjParams("mrc", "Mrc15", "RegMiscRegImmOp", 889 { "code": mrc15code, 890 "predicate_test": predicateTest }, []) 891 header_output += RegMiscRegImmOpDeclare.subst(mrc15Iop) 892 decoder_output += RegMiscRegImmOpConstructor.subst(mrc15Iop) 893 exec_output += PredOpExecute.subst(mrc15Iop) 894 895 896 mcr15code = ''' 897 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase()); 898 MiscRegIndex miscReg = (MiscRegIndex) 899 xc->tcBase()->flattenRegId(RegId(MiscRegClass, 900 preFlatDest)).index(); 901 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, 902 Hcptr, imm); 903 bool can_write, undefined; 904 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); 905 906 // if we're in non secure PL1 mode then we can trap regargless of whether 907 // the register is accessable, in other modes we trap if only if the register 908 // IS accessable. 909 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && 910 !inSecureState(Scr, Cpsr)))) { 911 return std::make_shared<UndefinedInstruction>(machInst, false, 912 mnemonic); 913 } 914 if (hypTrap) { 915 return std::make_shared<HypervisorTrap>(machInst, imm, 916 EC_TRAPPED_CP15_MCR_MRC); 917 } 918 MiscNsBankedDest = Op1; 919 ''' 920 mcr15Iop = InstObjParams("mcr", "Mcr15", "MiscRegRegImmOp", 921 { "code": mcr15code, 922 "predicate_test": predicateTest }, 923 ["IsSerializeAfter","IsNonSpeculative"]) 924 header_output += MiscRegRegImmOpDeclare.subst(mcr15Iop) 925 decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop) 926 exec_output += PredOpExecute.subst(mcr15Iop) 927 928 929 mrrc15code = ''' 930 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase()); 931 MiscRegIndex miscReg = (MiscRegIndex) 932 xc->tcBase()->flattenRegId(RegId(MiscRegClass, 933 preFlatOp1)).index(); 934 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); 935 bool can_read, undefined; 936 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); 937 // if we're in non secure PL1 mode then we can trap regargless of whether 938 // the register is accessable, in other modes we trap if only if the register 939 // IS accessable. 940 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && 941 !inSecureState(Scr, Cpsr)))) { 942 return std::make_shared<UndefinedInstruction>(machInst, false, 943 mnemonic); 944 } 945 if (hypTrap) { 946 return std::make_shared<HypervisorTrap>(machInst, imm, 947 EC_TRAPPED_CP15_MCRR_MRRC); 948 } 949 Dest = bits(MiscNsBankedOp164, 63, 32); 950 Dest2 = bits(MiscNsBankedOp164, 31, 0); 951 ''' 952 mrrc15Iop = InstObjParams("mrrc", "Mrrc15", "MrrcOp", 953 { "code": mrrc15code, 954 "predicate_test": predicateTest }, []) 955 header_output += MrrcOpDeclare.subst(mrrc15Iop) 956 decoder_output += MrrcOpConstructor.subst(mrrc15Iop) 957 exec_output += PredOpExecute.subst(mrrc15Iop) 958 959 960 mcrr15code = ''' 961 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase()); 962 MiscRegIndex miscReg = (MiscRegIndex) 963 xc->tcBase()->flattenRegId(RegId(MiscRegClass, 964 preFlatDest)).index(); 965 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); 966 bool can_write, undefined; 967 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); 968 969 // if we're in non secure PL1 mode then we can trap regargless of whether 970 // the register is accessable, in other modes we trap if only if the register 971 // IS accessable. 972 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && 973 !inSecureState(Scr, Cpsr)))) { 974 return std::make_shared<UndefinedInstruction>(machInst, false, 975 mnemonic); 976 } 977 if (hypTrap) { 978 return std::make_shared<HypervisorTrap>(machInst, imm, 979 EC_TRAPPED_CP15_MCRR_MRRC); 980 } 981 MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2; 982 ''' 983 mcrr15Iop = InstObjParams("mcrr", "Mcrr15", "McrrOp", 984 { "code": mcrr15code, 985 "predicate_test": predicateTest }, []) 986 header_output += McrrOpDeclare.subst(mcrr15Iop) 987 decoder_output += McrrOpConstructor.subst(mcrr15Iop) 988 exec_output += PredOpExecute.subst(mcrr15Iop) 989 990 991 enterxCode = ''' 992 NextThumb = true; 993 NextJazelle = true; 994 ''' 995 enterxIop = InstObjParams("enterx", "Enterx", "PredOp", 996 { "code": enterxCode, 997 "predicate_test": predicateTest }, []) 998 header_output += BasicDeclare.subst(enterxIop) 999 decoder_output += BasicConstructor.subst(enterxIop) 1000 exec_output += PredOpExecute.subst(enterxIop) 1001 1002 leavexCode = ''' 1003 NextThumb = true; 1004 NextJazelle = false; 1005 ''' 1006 leavexIop = InstObjParams("leavex", "Leavex", "PredOp", 1007 { "code": leavexCode, 1008 "predicate_test": predicateTest }, []) 1009 header_output += BasicDeclare.subst(leavexIop) 1010 decoder_output += BasicConstructor.subst(leavexIop) 1011 exec_output += PredOpExecute.subst(leavexIop) 1012 1013 setendCode = ''' 1014 CPSR cpsr = Cpsr; 1015 cpsr.e = imm; 1016 Cpsr = cpsr; 1017 ''' 1018 setendIop = InstObjParams("setend", "Setend", "ImmOp", 1019 { "code": setendCode, 1020 "predicate_test": predicateTest }, 1021 ["IsSerializeAfter","IsNonSpeculative"]) 1022 header_output += ImmOpDeclare.subst(setendIop) 1023 decoder_output += ImmOpConstructor.subst(setendIop) 1024 exec_output += PredOpExecute.subst(setendIop) 1025 1026 clrexCode = ''' 1027 LLSCLock = 0; 1028 ''' 1029 clrexIop = InstObjParams("clrex", "Clrex","PredOp", 1030 { "code": clrexCode, 1031 "predicate_test": predicateTest },[]) 1032 header_output += BasicDeclare.subst(clrexIop) 1033 decoder_output += BasicConstructor.subst(clrexIop) 1034 exec_output += PredOpExecute.subst(clrexIop) 1035 1036 isbCode = ''' 1037 // If the barrier is due to a CP15 access check for hyp traps 1038 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB, Hcr, Cpsr, Scr, 1039 Hdcr, Hstr, Hcptr, imm)) { 1040 return std::make_shared<HypervisorTrap>(machInst, imm, 1041 EC_TRAPPED_CP15_MCR_MRC); 1042 } 1043 fault = std::make_shared<FlushPipe>(); 1044 ''' 1045 isbIop = InstObjParams("isb", "Isb", "ImmOp", 1046 {"code": isbCode, 1047 "predicate_test": predicateTest}, 1048 ['IsSerializeAfter']) 1049 header_output += ImmOpDeclare.subst(isbIop) 1050 decoder_output += ImmOpConstructor.subst(isbIop) 1051 exec_output += PredOpExecute.subst(isbIop) 1052 1053 dsbCode = ''' 1054 // If the barrier is due to a CP15 access check for hyp traps 1055 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DSB, Hcr, Cpsr, Scr, 1056 Hdcr, Hstr, Hcptr, imm)) { 1057 return std::make_shared<HypervisorTrap>(machInst, imm, 1058 EC_TRAPPED_CP15_MCR_MRC); 1059 } 1060 fault = std::make_shared<FlushPipe>(); 1061 ''' 1062 dsbIop = InstObjParams("dsb", "Dsb", "ImmOp", 1063 {"code": dsbCode, 1064 "predicate_test": predicateTest}, 1065 ['IsMemBarrier', 'IsSerializeAfter']) 1066 header_output += ImmOpDeclare.subst(dsbIop) 1067 decoder_output += ImmOpConstructor.subst(dsbIop) 1068 exec_output += PredOpExecute.subst(dsbIop) 1069 1070 dmbCode = ''' 1071 // If the barrier is due to a CP15 access check for hyp traps 1072 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DMB, Hcr, Cpsr, Scr, 1073 Hdcr, Hstr, Hcptr, imm)) { 1074 return std::make_shared<HypervisorTrap>(machInst, imm, 1075 EC_TRAPPED_CP15_MCR_MRC); 1076 } 1077 ''' 1078 dmbIop = InstObjParams("dmb", "Dmb", "ImmOp", 1079 {"code": dmbCode, 1080 "predicate_test": predicateTest}, 1081 ['IsMemBarrier']) 1082 header_output += ImmOpDeclare.subst(dmbIop) 1083 decoder_output += ImmOpConstructor.subst(dmbIop) 1084 exec_output += PredOpExecute.subst(dmbIop) 1085 1086 dbgCode = ''' 1087 ''' 1088 dbgIop = InstObjParams("dbg", "Dbg", "PredOp", 1089 {"code": dbgCode, 1090 "predicate_test": predicateTest}) 1091 header_output += BasicDeclare.subst(dbgIop) 1092 decoder_output += BasicConstructor.subst(dbgIop) 1093 exec_output += PredOpExecute.subst(dbgIop) 1094 1095 cpsCode = ''' 1096 uint32_t mode = bits(imm, 4, 0); 1097 uint32_t f = bits(imm, 5); 1098 uint32_t i = bits(imm, 6); 1099 uint32_t a = bits(imm, 7); 1100 bool setMode = bits(imm, 8); 1101 bool enable = bits(imm, 9); 1102 CPSR cpsr = Cpsr; 1103 SCTLR sctlr = Sctlr; 1104 if (cpsr.mode != MODE_USER) { 1105 if (enable) { 1106 if (f) cpsr.f = 0; 1107 if (i) cpsr.i = 0; 1108 if (a) cpsr.a = 0; 1109 } else { 1110 if (f && !sctlr.nmfi) cpsr.f = 1; 1111 if (i) cpsr.i = 1; 1112 if (a) cpsr.a = 1; 1113 } 1114 if (setMode) { 1115 cpsr.mode = mode; 1116 } 1117 } 1118 Cpsr = cpsr; 1119 ''' 1120 cpsIop = InstObjParams("cps", "Cps", "ImmOp", 1121 { "code": cpsCode, 1122 "predicate_test": predicateTest }, 1123 ["IsSerializeAfter","IsNonSpeculative"]) 1124 header_output += ImmOpDeclare.subst(cpsIop) 1125 decoder_output += ImmOpConstructor.subst(cpsIop) 1126 exec_output += PredOpExecute.subst(cpsIop) 1127}}; 1128