misc.isa revision 7249
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": predicateTest }, []) 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 uint32_t newCpsr = 81 cpsrWriteByInstr(Cpsr | CondCodes, Op1, byteMask, false); 82 Cpsr = ~CondCodesMask & newCpsr; 83 CondCodes = CondCodesMask & newCpsr; 84 ''' 85 msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp", 86 { "code": msrCpsrRegCode, 87 "predicate_test": predicateTest }, []) 88 header_output += MsrRegDeclare.subst(msrCpsrRegIop) 89 decoder_output += MsrRegConstructor.subst(msrCpsrRegIop) 90 exec_output += PredOpExecute.subst(msrCpsrRegIop) 91 92 msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);" 93 msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp", 94 { "code": msrSpsrRegCode, 95 "predicate_test": predicateTest }, []) 96 header_output += MsrRegDeclare.subst(msrSpsrRegIop) 97 decoder_output += MsrRegConstructor.subst(msrSpsrRegIop) 98 exec_output += PredOpExecute.subst(msrSpsrRegIop) 99 100 msrCpsrImmCode = ''' 101 uint32_t newCpsr = 102 cpsrWriteByInstr(Cpsr | CondCodes, imm, byteMask, false); 103 Cpsr = ~CondCodesMask & newCpsr; 104 CondCodes = CondCodesMask & newCpsr; 105 ''' 106 msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp", 107 { "code": msrCpsrImmCode, 108 "predicate_test": predicateTest }, []) 109 header_output += MsrImmDeclare.subst(msrCpsrImmIop) 110 decoder_output += MsrImmConstructor.subst(msrCpsrImmIop) 111 exec_output += PredOpExecute.subst(msrCpsrImmIop) 112 113 msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);" 114 msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp", 115 { "code": msrSpsrImmCode, 116 "predicate_test": predicateTest }, []) 117 header_output += MsrImmDeclare.subst(msrSpsrImmIop) 118 decoder_output += MsrImmConstructor.subst(msrSpsrImmIop) 119 exec_output += PredOpExecute.subst(msrSpsrImmIop) 120 121 revCode = ''' 122 uint32_t val = Op1; 123 Dest = swap_byte(val); 124 ''' 125 revIop = InstObjParams("rev", "Rev", "RevOp", 126 { "code": revCode, 127 "predicate_test": predicateTest }, []) 128 header_output += RevOpDeclare.subst(revIop) 129 decoder_output += RevOpConstructor.subst(revIop) 130 exec_output += PredOpExecute.subst(revIop) 131 132 rev16Code = ''' 133 uint32_t val = Op1; 134 Dest = (bits(val, 15, 8) << 0) | 135 (bits(val, 7, 0) << 8) | 136 (bits(val, 31, 24) << 16) | 137 (bits(val, 23, 16) << 24); 138 ''' 139 rev16Iop = InstObjParams("rev16", "Rev16", "RevOp", 140 { "code": rev16Code, 141 "predicate_test": predicateTest }, []) 142 header_output += RevOpDeclare.subst(rev16Iop) 143 decoder_output += RevOpConstructor.subst(rev16Iop) 144 exec_output += PredOpExecute.subst(rev16Iop) 145 146 revshCode = ''' 147 uint16_t val = Op1; 148 Dest = sext<16>(swap_byte(val)); 149 ''' 150 revshIop = InstObjParams("revsh", "Revsh", "RevOp", 151 { "code": revshCode, 152 "predicate_test": predicateTest }, []) 153 header_output += RevOpDeclare.subst(revshIop) 154 decoder_output += RevOpConstructor.subst(revshIop) 155 exec_output += PredOpExecute.subst(revshIop) 156 157 rbitCode = ''' 158 uint8_t *opBytes = (uint8_t *)&Op1; 159 uint32_t resTemp; 160 uint8_t *destBytes = (uint8_t *)&resTemp; 161 // This reverses the bytes and bits of the input, or so says the 162 // internet. 163 for (int i = 0; i < 4; i++) { 164 uint32_t temp = opBytes[i]; 165 temp = (temp * 0x0802 & 0x22110) | (temp * 0x8020 & 0x88440); 166 destBytes[3 - i] = (temp * 0x10101) >> 16; 167 } 168 Dest = resTemp; 169 ''' 170 rbitIop = InstObjParams("rbit", "Rbit", "RevOp", 171 { "code": rbitCode, 172 "predicate_test": predicateTest }, []) 173 header_output += RevOpDeclare.subst(rbitIop) 174 decoder_output += RevOpConstructor.subst(rbitIop) 175 exec_output += PredOpExecute.subst(rbitIop) 176 177 ssatCode = ''' 178 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0); 179 int32_t res; 180 if (satInt(res, operand, imm)) 181 CondCodes = CondCodes | (1 << 27); 182 else 183 CondCodes = CondCodes; 184 Dest = res; 185 ''' 186 ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp", 187 { "code": ssatCode, 188 "predicate_test": predicateTest }, []) 189 header_output += RegImmRegShiftOpDeclare.subst(ssatIop) 190 decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop) 191 exec_output += PredOpExecute.subst(ssatIop) 192 193 usatCode = ''' 194 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0); 195 int32_t res; 196 if (uSatInt(res, operand, imm)) 197 CondCodes = CondCodes | (1 << 27); 198 else 199 CondCodes = CondCodes; 200 Dest = res; 201 ''' 202 usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp", 203 { "code": usatCode, 204 "predicate_test": predicateTest }, []) 205 header_output += RegImmRegShiftOpDeclare.subst(usatIop) 206 decoder_output += RegImmRegShiftOpConstructor.subst(usatIop) 207 exec_output += PredOpExecute.subst(usatIop) 208 209 ssat16Code = ''' 210 int32_t res; 211 uint32_t resTemp = 0; 212 CondCodes = CondCodes; 213 int32_t argLow = sext<16>(bits(Op1, 15, 0)); 214 int32_t argHigh = sext<16>(bits(Op1, 31, 16)); 215 if (satInt(res, argLow, imm)) 216 CondCodes = CondCodes | (1 << 27); 217 replaceBits(resTemp, 15, 0, res); 218 if (satInt(res, argHigh, imm)) 219 CondCodes = CondCodes | (1 << 27); 220 replaceBits(resTemp, 31, 16, res); 221 Dest = resTemp; 222 ''' 223 ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp", 224 { "code": ssat16Code, 225 "predicate_test": predicateTest }, []) 226 header_output += RegImmRegOpDeclare.subst(ssat16Iop) 227 decoder_output += RegImmRegOpConstructor.subst(ssat16Iop) 228 exec_output += PredOpExecute.subst(ssat16Iop) 229 230 usat16Code = ''' 231 int32_t res; 232 uint32_t resTemp = 0; 233 CondCodes = CondCodes; 234 int32_t argLow = sext<16>(bits(Op1, 15, 0)); 235 int32_t argHigh = sext<16>(bits(Op1, 31, 16)); 236 if (uSatInt(res, argLow, imm)) 237 CondCodes = CondCodes | (1 << 27); 238 replaceBits(resTemp, 15, 0, res); 239 if (uSatInt(res, argHigh, imm)) 240 CondCodes = CondCodes | (1 << 27); 241 replaceBits(resTemp, 31, 16, res); 242 Dest = resTemp; 243 ''' 244 usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp", 245 { "code": usat16Code, 246 "predicate_test": predicateTest }, []) 247 header_output += RegImmRegOpDeclare.subst(usat16Iop) 248 decoder_output += RegImmRegOpConstructor.subst(usat16Iop) 249 exec_output += PredOpExecute.subst(usat16Iop) 250 251 sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp", 252 { "code": 253 "Dest = sext<8>((uint8_t)(Op1.ud >> imm));", 254 "predicate_test": predicateTest }, []) 255 header_output += RegImmRegOpDeclare.subst(sxtbIop) 256 decoder_output += RegImmRegOpConstructor.subst(sxtbIop) 257 exec_output += PredOpExecute.subst(sxtbIop) 258 259 sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp", 260 { "code": 261 ''' 262 Dest = sext<8>((uint8_t)(Op2.ud >> imm)) + 263 Op1; 264 ''', 265 "predicate_test": predicateTest }, []) 266 header_output += RegRegRegImmOpDeclare.subst(sxtabIop) 267 decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop) 268 exec_output += PredOpExecute.subst(sxtabIop) 269 270 sxtb16Code = ''' 271 uint32_t resTemp = 0; 272 replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm))); 273 replaceBits(resTemp, 31, 16, 274 sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32))); 275 Dest = resTemp; 276 ''' 277 sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp", 278 { "code": sxtb16Code, 279 "predicate_test": predicateTest }, []) 280 header_output += RegImmRegOpDeclare.subst(sxtb16Iop) 281 decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop) 282 exec_output += PredOpExecute.subst(sxtb16Iop) 283 284 sxtab16Code = ''' 285 uint32_t resTemp = 0; 286 replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) + 287 bits(Op1, 15, 0)); 288 replaceBits(resTemp, 31, 16, 289 sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) + 290 bits(Op1, 31, 16)); 291 Dest = resTemp; 292 ''' 293 sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp", 294 { "code": sxtab16Code, 295 "predicate_test": predicateTest }, []) 296 header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop) 297 decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop) 298 exec_output += PredOpExecute.subst(sxtab16Iop) 299 300 sxthCode = ''' 301 uint64_t rotated = (uint32_t)Op1; 302 rotated = (rotated | (rotated << 32)) >> imm; 303 Dest = sext<16>((uint16_t)rotated); 304 ''' 305 sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp", 306 { "code": sxthCode, 307 "predicate_test": predicateTest }, []) 308 header_output += RegImmRegOpDeclare.subst(sxthIop) 309 decoder_output += RegImmRegOpConstructor.subst(sxthIop) 310 exec_output += PredOpExecute.subst(sxthIop) 311 312 sxtahCode = ''' 313 uint64_t rotated = (uint32_t)Op2; 314 rotated = (rotated | (rotated << 32)) >> imm; 315 Dest = sext<16>((uint16_t)rotated) + Op1; 316 ''' 317 sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp", 318 { "code": sxtahCode, 319 "predicate_test": predicateTest }, []) 320 header_output += RegRegRegImmOpDeclare.subst(sxtahIop) 321 decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop) 322 exec_output += PredOpExecute.subst(sxtahIop) 323 324 uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp", 325 { "code": "Dest = (uint8_t)(Op1.ud >> imm);", 326 "predicate_test": predicateTest }, []) 327 header_output += RegImmRegOpDeclare.subst(uxtbIop) 328 decoder_output += RegImmRegOpConstructor.subst(uxtbIop) 329 exec_output += PredOpExecute.subst(uxtbIop) 330 331 uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp", 332 { "code": 333 "Dest = (uint8_t)(Op2.ud >> imm) + Op1;", 334 "predicate_test": predicateTest }, []) 335 header_output += RegRegRegImmOpDeclare.subst(uxtabIop) 336 decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop) 337 exec_output += PredOpExecute.subst(uxtabIop) 338 339 uxtb16Code = ''' 340 uint32_t resTemp = 0; 341 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm))); 342 replaceBits(resTemp, 31, 16, 343 (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32))); 344 Dest = resTemp; 345 ''' 346 uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp", 347 { "code": uxtb16Code, 348 "predicate_test": predicateTest }, []) 349 header_output += RegImmRegOpDeclare.subst(uxtb16Iop) 350 decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop) 351 exec_output += PredOpExecute.subst(uxtb16Iop) 352 353 uxtab16Code = ''' 354 uint32_t resTemp = 0; 355 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) + 356 bits(Op1, 15, 0)); 357 replaceBits(resTemp, 31, 16, 358 (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) + 359 bits(Op1, 31, 16)); 360 Dest = resTemp; 361 ''' 362 uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp", 363 { "code": uxtab16Code, 364 "predicate_test": predicateTest }, []) 365 header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop) 366 decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop) 367 exec_output += PredOpExecute.subst(uxtab16Iop) 368 369 uxthCode = ''' 370 uint64_t rotated = (uint32_t)Op1; 371 rotated = (rotated | (rotated << 32)) >> imm; 372 Dest = (uint16_t)rotated; 373 ''' 374 uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp", 375 { "code": uxthCode, 376 "predicate_test": predicateTest }, []) 377 header_output += RegImmRegOpDeclare.subst(uxthIop) 378 decoder_output += RegImmRegOpConstructor.subst(uxthIop) 379 exec_output += PredOpExecute.subst(uxthIop) 380 381 uxtahCode = ''' 382 uint64_t rotated = (uint32_t)Op2; 383 rotated = (rotated | (rotated << 32)) >> imm; 384 Dest = (uint16_t)rotated + Op1; 385 ''' 386 uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp", 387 { "code": uxtahCode, 388 "predicate_test": predicateTest }, []) 389 header_output += RegRegRegImmOpDeclare.subst(uxtahIop) 390 decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop) 391 exec_output += PredOpExecute.subst(uxtahIop) 392 393 selCode = ''' 394 uint32_t resTemp = 0; 395 for (unsigned i = 0; i < 4; i++) { 396 int low = i * 8; 397 int high = low + 7; 398 replaceBits(resTemp, high, low, 399 bits(CondCodes, 16 + i) ? 400 bits(Op1, high, low) : bits(Op2, high, low)); 401 } 402 Dest = resTemp; 403 ''' 404 selIop = InstObjParams("sel", "Sel", "RegRegRegOp", 405 { "code": selCode, 406 "predicate_test": predicateTest }, []) 407 header_output += RegRegRegOpDeclare.subst(selIop) 408 decoder_output += RegRegRegOpConstructor.subst(selIop) 409 exec_output += PredOpExecute.subst(selIop) 410 411 usad8Code = ''' 412 uint32_t resTemp = 0; 413 for (unsigned i = 0; i < 4; i++) { 414 int low = i * 8; 415 int high = low + 7; 416 int32_t diff = bits(Op1, high, low) - 417 bits(Op2, high, low); 418 resTemp += ((diff < 0) ? -diff : diff); 419 } 420 Dest = resTemp; 421 ''' 422 usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp", 423 { "code": usad8Code, 424 "predicate_test": predicateTest }, []) 425 header_output += RegRegRegOpDeclare.subst(usad8Iop) 426 decoder_output += RegRegRegOpConstructor.subst(usad8Iop) 427 exec_output += PredOpExecute.subst(usad8Iop) 428 429 usada8Code = ''' 430 uint32_t resTemp = 0; 431 for (unsigned i = 0; i < 4; i++) { 432 int low = i * 8; 433 int high = low + 7; 434 int32_t diff = bits(Op1, high, low) - 435 bits(Op2, high, low); 436 resTemp += ((diff < 0) ? -diff : diff); 437 } 438 Dest = Op3 + resTemp; 439 ''' 440 usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp", 441 { "code": usada8Code, 442 "predicate_test": predicateTest }, []) 443 header_output += RegRegRegRegOpDeclare.subst(usada8Iop) 444 decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop) 445 exec_output += PredOpExecute.subst(usada8Iop) 446 447 nopIop = InstObjParams("nop", "NopInst", "ArmStaticInst", "", []) 448 header_output += BasicDeclare.subst(nopIop) 449 decoder_output += BasicConstructor.subst(nopIop) 450 exec_output += BasicExecute.subst(nopIop) 451}}; 452