misc.isa revision 7422
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40let {{ 41 42 svcCode = ''' 43#if FULL_SYSTEM 44 fault = new SupervisorCall; 45#else 46 fault = new SupervisorCall(machInst); 47#endif 48 ''' 49 50 svcIop = InstObjParams("svc", "Svc", "PredOp", 51 { "code": svcCode, 52 "predicate_test": predicateTest }, ["IsSyscall"]) 53 header_output = BasicDeclare.subst(svcIop) 54 decoder_output = BasicConstructor.subst(svcIop) 55 exec_output = PredOpExecute.subst(svcIop) 56 57}}; 58 59let {{ 60 61 header_output = decoder_output = exec_output = "" 62 63 mrsCpsrCode = "Dest = (Cpsr | CondCodes) & 0xF8FF03DF" 64 mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp", 65 { "code": mrsCpsrCode, 66 "predicate_test": condPredicateTest }, []) 67 header_output += MrsDeclare.subst(mrsCpsrIop) 68 decoder_output += MrsConstructor.subst(mrsCpsrIop) 69 exec_output += PredOpExecute.subst(mrsCpsrIop) 70 71 mrsSpsrCode = "Dest = Spsr" 72 mrsSpsrIop = InstObjParams("mrs", "MrsSpsr", "MrsOp", 73 { "code": mrsSpsrCode, 74 "predicate_test": predicateTest }, []) 75 header_output += MrsDeclare.subst(mrsSpsrIop) 76 decoder_output += MrsConstructor.subst(mrsSpsrIop) 77 exec_output += PredOpExecute.subst(mrsSpsrIop) 78 79 msrCpsrRegCode = ''' 80 SCTLR sctlr = Sctlr; 81 uint32_t newCpsr = 82 cpsrWriteByInstr(Cpsr | CondCodes, Op1, byteMask, false, sctlr.nmfi); 83 Cpsr = ~CondCodesMask & newCpsr; 84 CondCodes = CondCodesMask & newCpsr; 85 ''' 86 msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp", 87 { "code": msrCpsrRegCode, 88 "predicate_test": condPredicateTest }, []) 89 header_output += MsrRegDeclare.subst(msrCpsrRegIop) 90 decoder_output += MsrRegConstructor.subst(msrCpsrRegIop) 91 exec_output += PredOpExecute.subst(msrCpsrRegIop) 92 93 msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);" 94 msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp", 95 { "code": msrSpsrRegCode, 96 "predicate_test": predicateTest }, []) 97 header_output += MsrRegDeclare.subst(msrSpsrRegIop) 98 decoder_output += MsrRegConstructor.subst(msrSpsrRegIop) 99 exec_output += PredOpExecute.subst(msrSpsrRegIop) 100 101 msrCpsrImmCode = ''' 102 SCTLR sctlr = Sctlr; 103 uint32_t newCpsr = 104 cpsrWriteByInstr(Cpsr | CondCodes, imm, byteMask, false, sctlr.nmfi); 105 Cpsr = ~CondCodesMask & newCpsr; 106 CondCodes = CondCodesMask & newCpsr; 107 ''' 108 msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp", 109 { "code": msrCpsrImmCode, 110 "predicate_test": condPredicateTest }, []) 111 header_output += MsrImmDeclare.subst(msrCpsrImmIop) 112 decoder_output += MsrImmConstructor.subst(msrCpsrImmIop) 113 exec_output += PredOpExecute.subst(msrCpsrImmIop) 114 115 msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);" 116 msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp", 117 { "code": msrSpsrImmCode, 118 "predicate_test": predicateTest }, []) 119 header_output += MsrImmDeclare.subst(msrSpsrImmIop) 120 decoder_output += MsrImmConstructor.subst(msrSpsrImmIop) 121 exec_output += PredOpExecute.subst(msrSpsrImmIop) 122 123 revCode = ''' 124 uint32_t val = Op1; 125 Dest = swap_byte(val); 126 ''' 127 revIop = InstObjParams("rev", "Rev", "RegRegOp", 128 { "code": revCode, 129 "predicate_test": predicateTest }, []) 130 header_output += RegRegOpDeclare.subst(revIop) 131 decoder_output += RegRegOpConstructor.subst(revIop) 132 exec_output += PredOpExecute.subst(revIop) 133 134 rev16Code = ''' 135 uint32_t val = Op1; 136 Dest = (bits(val, 15, 8) << 0) | 137 (bits(val, 7, 0) << 8) | 138 (bits(val, 31, 24) << 16) | 139 (bits(val, 23, 16) << 24); 140 ''' 141 rev16Iop = InstObjParams("rev16", "Rev16", "RegRegOp", 142 { "code": rev16Code, 143 "predicate_test": predicateTest }, []) 144 header_output += RegRegOpDeclare.subst(rev16Iop) 145 decoder_output += RegRegOpConstructor.subst(rev16Iop) 146 exec_output += PredOpExecute.subst(rev16Iop) 147 148 revshCode = ''' 149 uint16_t val = Op1; 150 Dest = sext<16>(swap_byte(val)); 151 ''' 152 revshIop = InstObjParams("revsh", "Revsh", "RegRegOp", 153 { "code": revshCode, 154 "predicate_test": predicateTest }, []) 155 header_output += RegRegOpDeclare.subst(revshIop) 156 decoder_output += RegRegOpConstructor.subst(revshIop) 157 exec_output += PredOpExecute.subst(revshIop) 158 159 rbitCode = ''' 160 uint8_t *opBytes = (uint8_t *)&Op1; 161 uint32_t resTemp; 162 uint8_t *destBytes = (uint8_t *)&resTemp; 163 // This reverses the bytes and bits of the input, or so says the 164 // internet. 165 for (int i = 0; i < 4; i++) { 166 uint32_t temp = opBytes[i]; 167 temp = (temp * 0x0802 & 0x22110) | (temp * 0x8020 & 0x88440); 168 destBytes[3 - i] = (temp * 0x10101) >> 16; 169 } 170 Dest = resTemp; 171 ''' 172 rbitIop = InstObjParams("rbit", "Rbit", "RegRegOp", 173 { "code": rbitCode, 174 "predicate_test": predicateTest }, []) 175 header_output += RegRegOpDeclare.subst(rbitIop) 176 decoder_output += RegRegOpConstructor.subst(rbitIop) 177 exec_output += PredOpExecute.subst(rbitIop) 178 179 clzCode = ''' 180 Dest = (Op1 == 0) ? 32 : (31 - findMsbSet(Op1)); 181 ''' 182 clzIop = InstObjParams("clz", "Clz", "RegRegOp", 183 { "code": clzCode, 184 "predicate_test": predicateTest }, []) 185 header_output += RegRegOpDeclare.subst(clzIop) 186 decoder_output += RegRegOpConstructor.subst(clzIop) 187 exec_output += PredOpExecute.subst(clzIop) 188 189 ssatCode = ''' 190 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0); 191 int32_t res; 192 if (satInt(res, operand, imm)) 193 CondCodes = CondCodes | (1 << 27); 194 else 195 CondCodes = CondCodes; 196 Dest = res; 197 ''' 198 ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp", 199 { "code": ssatCode, 200 "predicate_test": condPredicateTest }, []) 201 header_output += RegImmRegShiftOpDeclare.subst(ssatIop) 202 decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop) 203 exec_output += PredOpExecute.subst(ssatIop) 204 205 usatCode = ''' 206 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0); 207 int32_t res; 208 if (uSatInt(res, operand, imm)) 209 CondCodes = CondCodes | (1 << 27); 210 else 211 CondCodes = CondCodes; 212 Dest = res; 213 ''' 214 usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp", 215 { "code": usatCode, 216 "predicate_test": condPredicateTest }, []) 217 header_output += RegImmRegShiftOpDeclare.subst(usatIop) 218 decoder_output += RegImmRegShiftOpConstructor.subst(usatIop) 219 exec_output += PredOpExecute.subst(usatIop) 220 221 ssat16Code = ''' 222 int32_t res; 223 uint32_t resTemp = 0; 224 CondCodes = CondCodes; 225 int32_t argLow = sext<16>(bits(Op1, 15, 0)); 226 int32_t argHigh = sext<16>(bits(Op1, 31, 16)); 227 if (satInt(res, argLow, imm)) 228 CondCodes = CondCodes | (1 << 27); 229 replaceBits(resTemp, 15, 0, res); 230 if (satInt(res, argHigh, imm)) 231 CondCodes = CondCodes | (1 << 27); 232 replaceBits(resTemp, 31, 16, res); 233 Dest = resTemp; 234 ''' 235 ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp", 236 { "code": ssat16Code, 237 "predicate_test": condPredicateTest }, []) 238 header_output += RegImmRegOpDeclare.subst(ssat16Iop) 239 decoder_output += RegImmRegOpConstructor.subst(ssat16Iop) 240 exec_output += PredOpExecute.subst(ssat16Iop) 241 242 usat16Code = ''' 243 int32_t res; 244 uint32_t resTemp = 0; 245 CondCodes = CondCodes; 246 int32_t argLow = sext<16>(bits(Op1, 15, 0)); 247 int32_t argHigh = sext<16>(bits(Op1, 31, 16)); 248 if (uSatInt(res, argLow, imm)) 249 CondCodes = CondCodes | (1 << 27); 250 replaceBits(resTemp, 15, 0, res); 251 if (uSatInt(res, argHigh, imm)) 252 CondCodes = CondCodes | (1 << 27); 253 replaceBits(resTemp, 31, 16, res); 254 Dest = resTemp; 255 ''' 256 usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp", 257 { "code": usat16Code, 258 "predicate_test": condPredicateTest }, []) 259 header_output += RegImmRegOpDeclare.subst(usat16Iop) 260 decoder_output += RegImmRegOpConstructor.subst(usat16Iop) 261 exec_output += PredOpExecute.subst(usat16Iop) 262 263 sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp", 264 { "code": 265 "Dest = sext<8>((uint8_t)(Op1.ud >> imm));", 266 "predicate_test": predicateTest }, []) 267 header_output += RegImmRegOpDeclare.subst(sxtbIop) 268 decoder_output += RegImmRegOpConstructor.subst(sxtbIop) 269 exec_output += PredOpExecute.subst(sxtbIop) 270 271 sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp", 272 { "code": 273 ''' 274 Dest = sext<8>((uint8_t)(Op2.ud >> imm)) + 275 Op1; 276 ''', 277 "predicate_test": predicateTest }, []) 278 header_output += RegRegRegImmOpDeclare.subst(sxtabIop) 279 decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop) 280 exec_output += PredOpExecute.subst(sxtabIop) 281 282 sxtb16Code = ''' 283 uint32_t resTemp = 0; 284 replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm))); 285 replaceBits(resTemp, 31, 16, 286 sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32))); 287 Dest = resTemp; 288 ''' 289 sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp", 290 { "code": sxtb16Code, 291 "predicate_test": predicateTest }, []) 292 header_output += RegImmRegOpDeclare.subst(sxtb16Iop) 293 decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop) 294 exec_output += PredOpExecute.subst(sxtb16Iop) 295 296 sxtab16Code = ''' 297 uint32_t resTemp = 0; 298 replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) + 299 bits(Op1, 15, 0)); 300 replaceBits(resTemp, 31, 16, 301 sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) + 302 bits(Op1, 31, 16)); 303 Dest = resTemp; 304 ''' 305 sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp", 306 { "code": sxtab16Code, 307 "predicate_test": predicateTest }, []) 308 header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop) 309 decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop) 310 exec_output += PredOpExecute.subst(sxtab16Iop) 311 312 sxthCode = ''' 313 uint64_t rotated = (uint32_t)Op1; 314 rotated = (rotated | (rotated << 32)) >> imm; 315 Dest = sext<16>((uint16_t)rotated); 316 ''' 317 sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp", 318 { "code": sxthCode, 319 "predicate_test": predicateTest }, []) 320 header_output += RegImmRegOpDeclare.subst(sxthIop) 321 decoder_output += RegImmRegOpConstructor.subst(sxthIop) 322 exec_output += PredOpExecute.subst(sxthIop) 323 324 sxtahCode = ''' 325 uint64_t rotated = (uint32_t)Op2; 326 rotated = (rotated | (rotated << 32)) >> imm; 327 Dest = sext<16>((uint16_t)rotated) + Op1; 328 ''' 329 sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp", 330 { "code": sxtahCode, 331 "predicate_test": predicateTest }, []) 332 header_output += RegRegRegImmOpDeclare.subst(sxtahIop) 333 decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop) 334 exec_output += PredOpExecute.subst(sxtahIop) 335 336 uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp", 337 { "code": "Dest = (uint8_t)(Op1.ud >> imm);", 338 "predicate_test": predicateTest }, []) 339 header_output += RegImmRegOpDeclare.subst(uxtbIop) 340 decoder_output += RegImmRegOpConstructor.subst(uxtbIop) 341 exec_output += PredOpExecute.subst(uxtbIop) 342 343 uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp", 344 { "code": 345 "Dest = (uint8_t)(Op2.ud >> imm) + Op1;", 346 "predicate_test": predicateTest }, []) 347 header_output += RegRegRegImmOpDeclare.subst(uxtabIop) 348 decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop) 349 exec_output += PredOpExecute.subst(uxtabIop) 350 351 uxtb16Code = ''' 352 uint32_t resTemp = 0; 353 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm))); 354 replaceBits(resTemp, 31, 16, 355 (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32))); 356 Dest = resTemp; 357 ''' 358 uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp", 359 { "code": uxtb16Code, 360 "predicate_test": predicateTest }, []) 361 header_output += RegImmRegOpDeclare.subst(uxtb16Iop) 362 decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop) 363 exec_output += PredOpExecute.subst(uxtb16Iop) 364 365 uxtab16Code = ''' 366 uint32_t resTemp = 0; 367 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) + 368 bits(Op1, 15, 0)); 369 replaceBits(resTemp, 31, 16, 370 (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) + 371 bits(Op1, 31, 16)); 372 Dest = resTemp; 373 ''' 374 uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp", 375 { "code": uxtab16Code, 376 "predicate_test": predicateTest }, []) 377 header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop) 378 decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop) 379 exec_output += PredOpExecute.subst(uxtab16Iop) 380 381 uxthCode = ''' 382 uint64_t rotated = (uint32_t)Op1; 383 rotated = (rotated | (rotated << 32)) >> imm; 384 Dest = (uint16_t)rotated; 385 ''' 386 uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp", 387 { "code": uxthCode, 388 "predicate_test": predicateTest }, []) 389 header_output += RegImmRegOpDeclare.subst(uxthIop) 390 decoder_output += RegImmRegOpConstructor.subst(uxthIop) 391 exec_output += PredOpExecute.subst(uxthIop) 392 393 uxtahCode = ''' 394 uint64_t rotated = (uint32_t)Op2; 395 rotated = (rotated | (rotated << 32)) >> imm; 396 Dest = (uint16_t)rotated + Op1; 397 ''' 398 uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp", 399 { "code": uxtahCode, 400 "predicate_test": predicateTest }, []) 401 header_output += RegRegRegImmOpDeclare.subst(uxtahIop) 402 decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop) 403 exec_output += PredOpExecute.subst(uxtahIop) 404 405 selCode = ''' 406 uint32_t resTemp = 0; 407 for (unsigned i = 0; i < 4; i++) { 408 int low = i * 8; 409 int high = low + 7; 410 replaceBits(resTemp, high, low, 411 bits(CondCodes, 16 + i) ? 412 bits(Op1, high, low) : bits(Op2, high, low)); 413 } 414 Dest = resTemp; 415 ''' 416 selIop = InstObjParams("sel", "Sel", "RegRegRegOp", 417 { "code": selCode, 418 "predicate_test": condPredicateTest }, []) 419 header_output += RegRegRegOpDeclare.subst(selIop) 420 decoder_output += RegRegRegOpConstructor.subst(selIop) 421 exec_output += PredOpExecute.subst(selIop) 422 423 usad8Code = ''' 424 uint32_t resTemp = 0; 425 for (unsigned i = 0; i < 4; i++) { 426 int low = i * 8; 427 int high = low + 7; 428 int32_t diff = bits(Op1, high, low) - 429 bits(Op2, high, low); 430 resTemp += ((diff < 0) ? -diff : diff); 431 } 432 Dest = resTemp; 433 ''' 434 usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp", 435 { "code": usad8Code, 436 "predicate_test": predicateTest }, []) 437 header_output += RegRegRegOpDeclare.subst(usad8Iop) 438 decoder_output += RegRegRegOpConstructor.subst(usad8Iop) 439 exec_output += PredOpExecute.subst(usad8Iop) 440 441 usada8Code = ''' 442 uint32_t resTemp = 0; 443 for (unsigned i = 0; i < 4; i++) { 444 int low = i * 8; 445 int high = low + 7; 446 int32_t diff = bits(Op1, high, low) - 447 bits(Op2, high, low); 448 resTemp += ((diff < 0) ? -diff : diff); 449 } 450 Dest = Op3 + resTemp; 451 ''' 452 usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp", 453 { "code": usada8Code, 454 "predicate_test": predicateTest }, []) 455 header_output += RegRegRegRegOpDeclare.subst(usada8Iop) 456 decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop) 457 exec_output += PredOpExecute.subst(usada8Iop) 458 459 bkptIop = InstObjParams("bkpt", "BkptInst", "ArmStaticInst", 460 "return new PrefetchAbort(PC, ArmFault::DebugEvent);") 461 header_output += BasicDeclare.subst(bkptIop) 462 decoder_output += BasicConstructor.subst(bkptIop) 463 exec_output += BasicExecute.subst(bkptIop) 464 465 nopIop = InstObjParams("nop", "NopInst", "PredOp", \ 466 { "code" : "", "predicate_test" : predicateTest }) 467 header_output += BasicDeclare.subst(nopIop) 468 decoder_output += BasicConstructor.subst(nopIop) 469 exec_output += PredOpExecute.subst(nopIop) 470 471 yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \ 472 { "code" : "", "predicate_test" : predicateTest }) 473 header_output += BasicDeclare.subst(yieldIop) 474 decoder_output += BasicConstructor.subst(yieldIop) 475 exec_output += PredOpExecute.subst(yieldIop) 476 477 wfeCode = ''' 478#if FULL_SYSTEM 479 if (SevMailbox) 480 SevMailbox = 0; 481 else 482 PseudoInst::quiesce(xc->tcBase()); 483#endif 484 ''' 485 wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \ 486 { "code" : wfeCode, "predicate_test" : predicateTest }, 487 ["IsNonSpeculative", "IsQuiesce"]) 488 header_output += BasicDeclare.subst(wfeIop) 489 decoder_output += BasicConstructor.subst(wfeIop) 490 exec_output += PredOpExecute.subst(wfeIop) 491 492 wfiCode = ''' 493#if FULL_SYSTEM 494 PseudoInst::quiesce(xc->tcBase()); 495#endif 496 ''' 497 wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \ 498 { "code" : wfiCode, "predicate_test" : predicateTest }, 499 ["IsNonSpeculative", "IsQuiesce"]) 500 header_output += BasicDeclare.subst(wfiIop) 501 decoder_output += BasicConstructor.subst(wfiIop) 502 exec_output += PredOpExecute.subst(wfiIop) 503 504 sevCode = ''' 505 // Need a way for O3 to not scoreboard these accesses as pipe flushes. 506 System *sys = xc->tcBase()->getSystemPtr(); 507 for (int x = 0; x < sys->numContexts(); x++) { 508 ThreadContext *oc = sys->getThreadContext(x); 509 oc->setMiscReg(MISCREG_SEV_MAILBOX, 1); 510 } 511 ''' 512 sevIop = InstObjParams("sev", "SevInst", "PredOp", \ 513 { "code" : sevCode, "predicate_test" : predicateTest }, 514 ["IsNonSpeculative", "IsQuiesce"]) 515 header_output += BasicDeclare.subst(sevIop) 516 decoder_output += BasicConstructor.subst(sevIop) 517 exec_output += PredOpExecute.subst(sevIop) 518 519 itIop = InstObjParams("it", "ItInst", "PredOp", \ 520 { "code" : "Itstate = machInst.newItstate;", 521 "predicate_test" : predicateTest }) 522 header_output += BasicDeclare.subst(itIop) 523 decoder_output += BasicConstructor.subst(itIop) 524 exec_output += PredOpExecute.subst(itIop) 525 unknownCode = ''' 526#if FULL_SYSTEM 527 return new UndefinedInstruction; 528#else 529 return new UndefinedInstruction(machInst, true); 530#endif 531 ''' 532 unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \ 533 { "code": unknownCode, 534 "predicate_test": predicateTest }) 535 header_output += BasicDeclare.subst(unknownIop) 536 decoder_output += BasicConstructor.subst(unknownIop) 537 exec_output += PredOpExecute.subst(unknownIop) 538 539 ubfxCode = ''' 540 Dest = bits(Op1, imm2, imm1); 541 ''' 542 ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp", 543 { "code": ubfxCode, 544 "predicate_test": predicateTest }, []) 545 header_output += RegRegImmImmOpDeclare.subst(ubfxIop) 546 decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop) 547 exec_output += PredOpExecute.subst(ubfxIop) 548 549 sbfxCode = ''' 550 int32_t resTemp = bits(Op1, imm2, imm1); 551 Dest = resTemp | -(resTemp & (1 << (imm2 - imm1))); 552 ''' 553 sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp", 554 { "code": sbfxCode, 555 "predicate_test": predicateTest }, []) 556 header_output += RegRegImmImmOpDeclare.subst(sbfxIop) 557 decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop) 558 exec_output += PredOpExecute.subst(sbfxIop) 559 560 bfcCode = ''' 561 Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1); 562 ''' 563 bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp", 564 { "code": bfcCode, 565 "predicate_test": predicateTest }, []) 566 header_output += RegRegImmImmOpDeclare.subst(bfcIop) 567 decoder_output += RegRegImmImmOpConstructor.subst(bfcIop) 568 exec_output += PredOpExecute.subst(bfcIop) 569 570 bfiCode = ''' 571 uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1); 572 Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask); 573 ''' 574 bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp", 575 { "code": bfiCode, 576 "predicate_test": predicateTest }, []) 577 header_output += RegRegImmImmOpDeclare.subst(bfiIop) 578 decoder_output += RegRegImmImmOpConstructor.subst(bfiIop) 579 exec_output += PredOpExecute.subst(bfiIop) 580 581 mrc15code = ''' 582 CPSR cpsr = Cpsr; 583 if (cpsr.mode == MODE_USER) 584#if FULL_SYSTEM 585 return new UndefinedInstruction; 586#else 587 return new UndefinedInstruction(false, mnemonic); 588#endif 589 Dest = MiscOp1; 590 ''' 591 592 mrc15Iop = InstObjParams("mrc", "Mrc15", "RegRegOp", 593 { "code": mrc15code, 594 "predicate_test": predicateTest }, []) 595 header_output += RegRegOpDeclare.subst(mrc15Iop) 596 decoder_output += RegRegOpConstructor.subst(mrc15Iop) 597 exec_output += PredOpExecute.subst(mrc15Iop) 598 599 600 mcr15code = ''' 601 CPSR cpsr = Cpsr; 602 if (cpsr.mode == MODE_USER) 603#if FULL_SYSTEM 604 return new UndefinedInstruction; 605#else 606 return new UndefinedInstruction(false, mnemonic); 607#endif 608 MiscDest = Op1; 609 ''' 610 mcr15Iop = InstObjParams("mcr", "Mcr15", "RegRegOp", 611 { "code": mcr15code, 612 "predicate_test": predicateTest }, []) 613 header_output += RegRegOpDeclare.subst(mcr15Iop) 614 decoder_output += RegRegOpConstructor.subst(mcr15Iop) 615 exec_output += PredOpExecute.subst(mcr15Iop) 616 617 mrc15UserIop = InstObjParams("mrc", "Mrc15User", "RegRegOp", 618 { "code": "Dest = MiscOp1;", 619 "predicate_test": predicateTest }, []) 620 header_output += RegRegOpDeclare.subst(mrc15UserIop) 621 decoder_output += RegRegOpConstructor.subst(mrc15UserIop) 622 exec_output += PredOpExecute.subst(mrc15UserIop) 623 624 mcr15UserIop = InstObjParams("mcr", "Mcr15User", "RegRegOp", 625 { "code": "MiscDest = Op1", 626 "predicate_test": predicateTest }, []) 627 header_output += RegRegOpDeclare.subst(mcr15UserIop) 628 decoder_output += RegRegOpConstructor.subst(mcr15UserIop) 629 exec_output += PredOpExecute.subst(mcr15UserIop) 630 631 enterxCode = ''' 632 FNPC = NPC | (1ULL << PcJBitShift) | (1ULL << PcTBitShift); 633 ''' 634 enterxIop = InstObjParams("enterx", "Enterx", "PredOp", 635 { "code": enterxCode, 636 "predicate_test": predicateTest }, []) 637 header_output += BasicDeclare.subst(enterxIop) 638 decoder_output += BasicConstructor.subst(enterxIop) 639 exec_output += PredOpExecute.subst(enterxIop) 640 641 leavexCode = ''' 642 FNPC = (NPC & ~(1ULL << PcJBitShift)) | (1ULL << PcTBitShift); 643 ''' 644 leavexIop = InstObjParams("leavex", "Leavex", "PredOp", 645 { "code": leavexCode, 646 "predicate_test": predicateTest }, []) 647 header_output += BasicDeclare.subst(leavexIop) 648 decoder_output += BasicConstructor.subst(leavexIop) 649 exec_output += PredOpExecute.subst(leavexIop) 650 651 setendCode = ''' 652 CPSR cpsr = Cpsr; 653 cpsr.e = imm; 654 Cpsr = cpsr; 655 ''' 656 setendIop = InstObjParams("setend", "Setend", "ImmOp", 657 { "code": setendCode, 658 "predicate_test": predicateTest }, []) 659 header_output += ImmOpDeclare.subst(setendIop) 660 decoder_output += ImmOpConstructor.subst(setendIop) 661 exec_output += PredOpExecute.subst(setendIop) 662 663 cpsCode = ''' 664 uint32_t mode = bits(imm, 4, 0); 665 uint32_t f = bits(imm, 5); 666 uint32_t i = bits(imm, 6); 667 uint32_t a = bits(imm, 7); 668 bool setMode = bits(imm, 8); 669 bool enable = bits(imm, 9); 670 CPSR cpsr = Cpsr; 671 SCTLR sctlr = Sctlr; 672 if (cpsr.mode != MODE_USER) { 673 if (enable) { 674 if (f) cpsr.f = 0; 675 if (i) cpsr.i = 0; 676 if (a) cpsr.a = 0; 677 } else { 678 if (f && !sctlr.nmfi) cpsr.f = 1; 679 if (i) cpsr.i = 1; 680 if (a) cpsr.a = 1; 681 } 682 if (setMode) { 683 cpsr.mode = mode; 684 } 685 } 686 Cpsr = cpsr; 687 ''' 688 cpsIop = InstObjParams("cps", "Cps", "ImmOp", 689 { "code": cpsCode, 690 "predicate_test": predicateTest }, []) 691 header_output += ImmOpDeclare.subst(cpsIop) 692 decoder_output += ImmOpConstructor.subst(cpsIop) 693 exec_output += PredOpExecute.subst(cpsIop) 694}}; 695