data.isa revision 7255
1// Copyright (c) 2010 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Gabe Black 37 38def format ArmMiscMedia() {{ 39 decode_block = ''' 40 { 41 const uint32_t op1 = bits(machInst, 22, 20); 42 const uint32_t op2 = bits(machInst, 7, 5); 43 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 44 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 45 if (op1 == 0 && op2 == 0) { 46 const IntRegIndex rd = 47 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 48 const IntRegIndex rm = 49 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 50 if (ra == 0xf) { 51 return new Usad8(machInst, rd, rn, rm); 52 } else { 53 return new Usada8(machInst, rd, rn, rm, ra); 54 } 55 } else if (bits(op2, 1, 0) == 0x2) { 56 if (bits(op1, 2, 1) == 0x3) { 57 return new WarnUnimplemented("ubfx", machInst); 58 } else if (bits(op1, 2, 1) == 0x1) { 59 return new WarnUnimplemented("sbfx", machInst); 60 } 61 } else if (bits(op2, 1, 0) == 0x0 && bits(op1, 2, 1) == 0x2) { 62 if (rn == 0xf) { 63 return new WarnUnimplemented("bfc", machInst); 64 } else { 65 return new WarnUnimplemented("bfi", machInst); 66 } 67 } 68 return new Unknown(machInst); 69 } 70 ''' 71}}; 72 73def format ArmDataProcReg() {{ 74 pclr = ''' 75 return new %(className)ssRegPclr(machInst, %(dest)s, 76 %(op1)s, rm, imm5, 77 type); 78 ''' 79 instDecode = ''' 80 case %(opcode)#x: 81 if (immShift) { 82 if (setCc) { 83 if (%(dest)s == INTREG_PC) { 84 %(pclr)s 85 } else { 86 return new %(className)sRegCc(machInst, %(dest)s, 87 %(op1)s, rm, imm5, type); 88 } 89 } else { 90 return new %(className)sReg(machInst, %(dest)s, %(op1)s, 91 rm, imm5, type); 92 } 93 } else { 94 if (setCc) { 95 return new %(className)sRegRegCc(machInst, %(dest)s, 96 %(op1)s, rm, rs, type); 97 } else { 98 return new %(className)sRegReg(machInst, %(dest)s, 99 %(op1)s, rm, rs, type); 100 } 101 } 102 break; 103 ''' 104 105 def instCode(opcode, mnem, useDest = True, useOp1 = True): 106 global pclr 107 if useDest: 108 dest = "rd" 109 else: 110 dest = "INTREG_ZERO" 111 if useOp1: 112 op1 = "rn" 113 else: 114 op1 = "INTREG_ZERO" 115 global instDecode, pclrCode 116 substDict = { "className": mnem.capitalize(), 117 "opcode": opcode, 118 "dest": dest, 119 "op1": op1 } 120 if useDest: 121 substDict["pclr"] = pclr % substDict 122 else: 123 substDict["pclr"] = "" 124 return instDecode % substDict 125 126 decode_block = ''' 127 { 128 const bool immShift = (bits(machInst, 4) == 0); 129 const bool setCc = (bits(machInst, 20) == 1); 130 const uint32_t imm5 = bits(machInst, 11, 7); 131 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5); 132 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 133 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 134 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM; 135 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS; 136 switch (OPCODE) { 137 ''' 138 decode_block += instCode(0x0, "and") 139 decode_block += instCode(0x1, "eor") 140 decode_block += instCode(0x2, "sub") 141 decode_block += instCode(0x3, "rsb") 142 decode_block += instCode(0x4, "add") 143 decode_block += instCode(0x5, "adc") 144 decode_block += instCode(0x6, "sbc") 145 decode_block += instCode(0x7, "rsc") 146 decode_block += instCode(0x8, "tst", useDest = False) 147 decode_block += instCode(0x9, "teq", useDest = False) 148 decode_block += instCode(0xa, "cmp", useDest = False) 149 decode_block += instCode(0xb, "cmn", useDest = False) 150 decode_block += instCode(0xc, "orr") 151 decode_block += instCode(0xd, "mov", useOp1 = False) 152 decode_block += instCode(0xe, "bic") 153 decode_block += instCode(0xf, "mvn", useOp1 = False) 154 decode_block += ''' 155 default: 156 return new Unknown(machInst); 157 } 158 } 159 ''' 160}}; 161 162def format ArmPackUnpackSatReverse() {{ 163 decode_block = ''' 164 { 165 const uint32_t op1 = bits(machInst, 22, 20); 166 const uint32_t a = bits(machInst, 19, 16); 167 const uint32_t op2 = bits(machInst, 7, 5); 168 if (bits(op2, 0) == 0) { 169 const IntRegIndex rn = 170 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 171 const IntRegIndex rd = 172 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 173 const uint32_t satImm = bits(machInst, 20, 16); 174 const uint32_t imm = bits(machInst, 11, 7); 175 const ArmShiftType type = 176 (ArmShiftType)(uint32_t)bits(machInst, 6, 5); 177 if (op1 == 0) { 178 if (type) { 179 return new PkhtbReg(machInst, rd, (IntRegIndex)a, 180 rn, imm, type); 181 } else { 182 return new PkhbtReg(machInst, rd, (IntRegIndex)a, 183 rn, imm, type); 184 } 185 } else if (bits(op1, 2, 1) == 1) { 186 return new Ssat(machInst, rd, satImm + 1, rn, imm, type); 187 } else if (bits(op1, 2, 1) == 3) { 188 return new Usat(machInst, rd, satImm, rn, imm, type); 189 } 190 return new Unknown(machInst); 191 } 192 switch (op1) { 193 case 0x0: 194 { 195 const IntRegIndex rn = 196 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 197 const IntRegIndex rd = 198 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 199 const IntRegIndex rm = 200 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 201 if (op2 == 0x3) { 202 const uint32_t rotation = 203 (uint32_t)bits(machInst, 11, 10) << 3; 204 if (a == 0xf) { 205 return new Sxtb16(machInst, rd, rotation, rm); 206 } else { 207 return new Sxtab16(machInst, rd, rn, rm, rotation); 208 } 209 } else if (op2 == 0x5) { 210 return new Sel(machInst, rd, rn, rm); 211 } 212 } 213 break; 214 case 0x2: 215 if (op2 == 0x1) { 216 const IntRegIndex rn = 217 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 218 const IntRegIndex rd = 219 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 220 const uint32_t satImm = bits(machInst, 20, 16); 221 return new Ssat16(machInst, rd, satImm + 1, rn); 222 } else if (op2 == 0x3) { 223 const IntRegIndex rn = 224 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 225 const IntRegIndex rd = 226 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 227 const IntRegIndex rm = 228 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 229 const uint32_t rotation = 230 (uint32_t)bits(machInst, 11, 10) << 3; 231 if (a == 0xf) { 232 return new Sxtb(machInst, rd, rotation, rm); 233 } else { 234 return new Sxtab(machInst, rd, rn, rm, rotation); 235 } 236 } 237 break; 238 case 0x3: 239 if (op2 == 0x1) { 240 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 241 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 242 return new Rev(machInst, rd, rm); 243 } else if (op2 == 0x3) { 244 const IntRegIndex rn = 245 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 246 const IntRegIndex rd = 247 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 248 const IntRegIndex rm = 249 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 250 const uint32_t rotation = 251 (uint32_t)bits(machInst, 11, 10) << 3; 252 if (a == 0xf) { 253 return new Sxth(machInst, rd, rotation, rm); 254 } else { 255 return new Sxtah(machInst, rd, rn, rm, rotation); 256 } 257 } else if (op2 == 0x5) { 258 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 259 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 260 return new Rev16(machInst, rd, rm); 261 } 262 break; 263 case 0x4: 264 if (op2 == 0x3) { 265 const IntRegIndex rn = 266 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 267 const IntRegIndex rd = 268 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 269 const IntRegIndex rm = 270 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 271 const uint32_t rotation = 272 (uint32_t)bits(machInst, 11, 10) << 3; 273 if (a == 0xf) { 274 return new Uxtb16(machInst, rd, rotation, rm); 275 } else { 276 return new Uxtab16(machInst, rd, rn, rm, rotation); 277 } 278 } 279 break; 280 case 0x6: 281 if (op2 == 0x1) { 282 const IntRegIndex rn = 283 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 284 const IntRegIndex rd = 285 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 286 const uint32_t satImm = bits(machInst, 20, 16); 287 return new Usat16(machInst, rd, satImm, rn); 288 } else if (op2 == 0x3) { 289 const IntRegIndex rn = 290 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 291 const IntRegIndex rd = 292 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 293 const IntRegIndex rm = 294 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 295 const uint32_t rotation = 296 (uint32_t)bits(machInst, 11, 10) << 3; 297 if (a == 0xf) { 298 return new Uxtb(machInst, rd, rotation, rm); 299 } else { 300 return new Uxtab(machInst, rd, rn, rm, rotation); 301 } 302 } 303 break; 304 case 0x7: 305 { 306 const IntRegIndex rn = 307 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 308 const IntRegIndex rd = 309 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 310 const IntRegIndex rm = 311 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 312 if (op2 == 0x1) { 313 return new Rbit(machInst, rd, rm); 314 } else if (op2 == 0x3) { 315 const uint32_t rotation = 316 (uint32_t)bits(machInst, 11, 10) << 3; 317 if (a == 0xf) { 318 return new Uxth(machInst, rd, rotation, rm); 319 } else { 320 return new Uxtah(machInst, rd, rn, rm, rotation); 321 } 322 } else if (op2 == 0x5) { 323 return new Revsh(machInst, rd, rm); 324 } 325 } 326 break; 327 } 328 return new Unknown(machInst); 329 } 330 ''' 331}}; 332 333def format ArmParallelAddSubtract() {{ 334 decode_block=''' 335 { 336 const uint32_t op1 = bits(machInst, 21, 20); 337 const uint32_t op2 = bits(machInst, 7, 5); 338 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 339 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 340 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 341 if (bits(machInst, 22) == 0) { 342 switch (op1) { 343 case 0x1: 344 switch (op2) { 345 case 0x0: 346 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL); 347 case 0x1: 348 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL); 349 case 0x2: 350 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL); 351 case 0x3: 352 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL); 353 case 0x4: 354 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL); 355 case 0x7: 356 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL); 357 } 358 break; 359 case 0x2: 360 switch (op2) { 361 case 0x0: 362 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL); 363 case 0x1: 364 return new QasxReg(machInst, rd, rn, rm, 0, LSL); 365 case 0x2: 366 return new QsaxReg(machInst, rd, rn, rm, 0, LSL); 367 case 0x3: 368 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL); 369 case 0x4: 370 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL); 371 case 0x7: 372 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL); 373 } 374 break; 375 case 0x3: 376 switch (op2) { 377 case 0x0: 378 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL); 379 case 0x1: 380 return new ShasxReg(machInst, rd, rn, rm, 0, LSL); 381 case 0x2: 382 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL); 383 case 0x3: 384 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL); 385 case 0x4: 386 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL); 387 case 0x7: 388 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL); 389 } 390 break; 391 } 392 } else { 393 switch (op1) { 394 case 0x1: 395 switch (op2) { 396 case 0x0: 397 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL); 398 case 0x1: 399 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL); 400 case 0x2: 401 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL); 402 case 0x3: 403 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL); 404 case 0x4: 405 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL); 406 case 0x7: 407 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL); 408 } 409 break; 410 case 0x2: 411 switch (op2) { 412 case 0x0: 413 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL); 414 case 0x1: 415 return new UqasxReg(machInst, rd, rn, rm, 0, LSL); 416 case 0x2: 417 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL); 418 case 0x3: 419 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL); 420 case 0x4: 421 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL); 422 case 0x7: 423 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL); 424 } 425 break; 426 case 0x3: 427 switch (op2) { 428 case 0x0: 429 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL); 430 case 0x1: 431 return new UhasxReg(machInst, rd, rn, rm, 0, LSL); 432 case 0x2: 433 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL); 434 case 0x3: 435 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL); 436 case 0x4: 437 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL); 438 case 0x7: 439 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL); 440 } 441 break; 442 } 443 } 444 return new Unknown(machInst); 445 } 446 ''' 447}}; 448 449def format ArmDataProcImm() {{ 450 pclr = ''' 451 return new %(className)ssImmPclr(machInst, %(dest)s, 452 %(op1)s, imm, false); 453 ''' 454 adr = ''' 455 return new AdrImm(machInst, %(dest)s, %(add)s, 456 imm, false); 457 ''' 458 instDecode = ''' 459 case %(opcode)#x: 460 if (setCc) { 461 if (%(pclrInst)s && %(dest)s == INTREG_PC) { 462 %(pclr)s 463 } else { 464 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s, 465 imm, rotC); 466 } 467 } else { 468 if (%(adrInst)s && %(op1)s == INTREG_PC) { 469 %(adr)s 470 } else { 471 return new %(className)sImm(machInst, %(dest)s, %(op1)s, 472 imm, rotC); 473 } 474 } 475 break; 476 ''' 477 478 def instCode(opcode, mnem, useDest = True, useOp1 = True): 479 global instDecode, pclr, adr 480 if useDest: 481 dest = "rd" 482 else: 483 dest = "INTREG_ZERO" 484 if useOp1: 485 op1 = "rn" 486 else: 487 op1 = "INTREG_ZERO" 488 substDict = { "className": mnem.capitalize(), 489 "opcode": opcode, 490 "dest": dest, 491 "op1": op1, 492 "adr": "", 493 "adrInst": "false" } 494 if useDest: 495 substDict["pclrInst"] = "true" 496 substDict["pclr"] = pclr % substDict 497 else: 498 substDict["pclrInst"] = "false" 499 substDict["pclr"] = "" 500 return instDecode % substDict 501 502 def adrCode(opcode, mnem, add="1"): 503 global instDecode, pclr, adr 504 substDict = { "className": mnem.capitalize(), 505 "opcode": opcode, 506 "dest": "rd", 507 "op1": "rn", 508 "add": add, 509 "pclrInst": "true", 510 "adrInst": "true" } 511 substDict["pclr"] = pclr % substDict 512 substDict["adr"] = adr % substDict 513 return instDecode % substDict 514 515 decode_block = ''' 516 { 517 const bool setCc = (bits(machInst, 20) == 1); 518 const uint32_t unrotated = bits(machInst, 7, 0); 519 const uint32_t rotation = (bits(machInst, 11, 8) << 1); 520 const bool rotC = (rotation != 0); 521 const uint32_t imm = rotate_imm(unrotated, rotation); 522 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 523 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 524 switch (OPCODE) { 525 ''' 526 decode_block += instCode(0x0, "and") 527 decode_block += instCode(0x1, "eor") 528 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0") 529 decode_block += instCode(0x3, "rsb") 530 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1") 531 decode_block += instCode(0x5, "adc") 532 decode_block += instCode(0x6, "sbc") 533 decode_block += instCode(0x7, "rsc") 534 decode_block += instCode(0x8, "tst", useDest = False) 535 decode_block += instCode(0x9, "teq", useDest = False) 536 decode_block += instCode(0xa, "cmp", useDest = False) 537 decode_block += instCode(0xb, "cmn", useDest = False) 538 decode_block += instCode(0xc, "orr") 539 decode_block += instCode(0xd, "mov", useOp1 = False) 540 decode_block += instCode(0xe, "bic") 541 decode_block += instCode(0xf, "mvn", useOp1 = False) 542 decode_block += ''' 543 default: 544 return new Unknown(machInst); 545 } 546 } 547 ''' 548}}; 549 550def format ArmSatAddSub() {{ 551 decode_block = ''' 552 { 553 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 554 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 555 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 556 switch (OPCODE) { 557 case 0x8: 558 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL); 559 case 0x9: 560 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL); 561 case 0xa: 562 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL); 563 case 0xb: 564 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL); 565 default: 566 return new Unknown(machInst); 567 } 568 } 569 ''' 570}}; 571 572def format Thumb32DataProcReg() {{ 573 decode_block = ''' 574 { 575 const uint32_t op1 = bits(machInst, 23, 20); 576 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 577 const uint32_t op2 = bits(machInst, 7, 4); 578 if (bits(op1, 3) != 1) { 579 if (op2 == 0) { 580 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 581 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 582 switch (bits(op1, 2, 0)) { 583 case 0x0: 584 return new MovRegReg(machInst, rd, 585 INTREG_ZERO, rn, rm, LSL); 586 case 0x1: 587 return new MovRegRegCc(machInst, rd, 588 INTREG_ZERO, rn, rm, LSL); 589 case 0x2: 590 return new MovRegReg(machInst, rd, 591 INTREG_ZERO, rn, rm, LSR); 592 case 0x3: 593 return new MovRegRegCc(machInst, rd, 594 INTREG_ZERO, rn, rm, LSR); 595 case 0x4: 596 return new MovRegReg(machInst, rd, 597 INTREG_ZERO, rn, rm, ASR); 598 case 0x5: 599 return new MovRegRegCc(machInst, rd, 600 INTREG_ZERO, rn, rm, ASR); 601 case 0x6: 602 return new MovRegReg(machInst, rd, 603 INTREG_ZERO, rn, rm, ROR); 604 case 0x7: 605 return new MovRegRegCc(machInst, rd, 606 INTREG_ZERO, rn, rm, ROR); 607 } 608 } 609 { 610 const IntRegIndex rd = 611 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 612 const IntRegIndex rm = 613 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 614 const uint32_t rotation = 615 (uint32_t)bits(machInst, 5, 4) << 3; 616 switch (bits(op1, 2, 0)) { 617 case 0x0: 618 if (rn == 0xf) { 619 return new Sxth(machInst, rd, rotation, rm); 620 } else { 621 return new Sxtah(machInst, rd, rn, rm, rotation); 622 } 623 case 0x1: 624 if (rn == 0xf) { 625 return new Uxth(machInst, rd, rotation, rm); 626 } else { 627 return new Uxtah(machInst, rd, rn, rm, rotation); 628 } 629 case 0x2: 630 if (rn == 0xf) { 631 return new Sxtb16(machInst, rd, rotation, rm); 632 } else { 633 return new Sxtab16(machInst, rd, rn, rm, rotation); 634 } 635 case 0x3: 636 if (rn == 0xf) { 637 return new Uxtb16(machInst, rd, rotation, rm); 638 } else { 639 return new Uxtab16(machInst, rd, rn, rm, rotation); 640 } 641 case 0x4: 642 if (rn == 0xf) { 643 return new Sxtb(machInst, rd, rotation, rm); 644 } else { 645 return new Sxtab(machInst, rd, rn, rm, rotation); 646 } 647 case 0x5: 648 if (rn == 0xf) { 649 return new Uxtb(machInst, rd, rotation, rm); 650 } else { 651 return new Uxtab(machInst, rd, rn, rm, rotation); 652 } 653 default: 654 return new Unknown(machInst); 655 } 656 } 657 } else { 658 if (bits(op2, 3) == 0) { 659 const IntRegIndex rd = 660 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 661 const IntRegIndex rm = 662 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 663 if (bits(op2, 2) == 0x0) { 664 const uint32_t op1 = bits(machInst, 22, 20); 665 const uint32_t op2 = bits(machInst, 5, 4); 666 switch (op2) { 667 case 0x0: 668 switch (op1) { 669 case 0x1: 670 return new Sadd16RegCc(machInst, rd, 671 rn, rm, 0, LSL); 672 case 0x2: 673 return new SasxRegCc(machInst, rd, 674 rn, rm, 0, LSL); 675 case 0x6: 676 return new SsaxRegCc(machInst, rd, 677 rn, rm, 0, LSL); 678 case 0x5: 679 return new Ssub16RegCc(machInst, rd, 680 rn, rm, 0, LSL); 681 case 0x0: 682 return new Sadd8RegCc(machInst, rd, 683 rn, rm, 0, LSL); 684 case 0x4: 685 return new Ssub8RegCc(machInst, rd, 686 rn, rm, 0, LSL); 687 } 688 break; 689 case 0x1: 690 switch (op1) { 691 case 0x1: 692 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL); 693 case 0x2: 694 return new QasxReg(machInst, rd, rn, rm, 0, LSL); 695 case 0x6: 696 return new QsaxReg(machInst, rd, rn, rm, 0, LSL); 697 case 0x5: 698 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL); 699 case 0x0: 700 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL); 701 case 0x4: 702 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL); 703 } 704 break; 705 case 0x2: 706 switch (op1) { 707 case 0x1: 708 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL); 709 case 0x2: 710 return new ShasxReg(machInst, rd, rn, rm, 0, LSL); 711 case 0x6: 712 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL); 713 case 0x5: 714 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL); 715 case 0x0: 716 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL); 717 case 0x4: 718 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL); 719 } 720 break; 721 } 722 } else { 723 const uint32_t op1 = bits(machInst, 22, 20); 724 const uint32_t op2 = bits(machInst, 5, 4); 725 switch (op2) { 726 case 0x0: 727 switch (op1) { 728 case 0x1: 729 return new Uadd16RegCc(machInst, rd, 730 rn, rm, 0, LSL); 731 case 0x2: 732 return new UasxRegCc(machInst, rd, 733 rn, rm, 0, LSL); 734 case 0x6: 735 return new UsaxRegCc(machInst, rd, 736 rn, rm, 0, LSL); 737 case 0x5: 738 return new Usub16RegCc(machInst, rd, 739 rn, rm, 0, LSL); 740 case 0x0: 741 return new Uadd8RegCc(machInst, rd, 742 rn, rm, 0, LSL); 743 case 0x4: 744 return new Usub8RegCc(machInst, rd, 745 rn, rm, 0, LSL); 746 } 747 break; 748 case 0x1: 749 switch (op1) { 750 case 0x1: 751 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL); 752 case 0x2: 753 return new UqasxReg(machInst, rd, rn, rm, 0, LSL); 754 case 0x6: 755 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL); 756 case 0x5: 757 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL); 758 case 0x0: 759 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL); 760 case 0x4: 761 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL); 762 } 763 break; 764 case 0x2: 765 switch (op1) { 766 case 0x1: 767 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL); 768 case 0x2: 769 return new UhasxReg(machInst, rd, rn, rm, 0, LSL); 770 case 0x6: 771 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL); 772 case 0x5: 773 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL); 774 case 0x0: 775 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL); 776 case 0x4: 777 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL); 778 } 779 break; 780 } 781 } 782 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) { 783 const uint32_t op1 = bits(machInst, 21, 20); 784 const uint32_t op2 = bits(machInst, 5, 4); 785 const IntRegIndex rd = 786 (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 787 const IntRegIndex rm = 788 (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 789 switch (op1) { 790 case 0x0: 791 switch (op2) { 792 case 0x0: 793 return new QaddRegCc(machInst, rd, 794 rm, rn, 0, LSL); 795 case 0x1: 796 return new QdaddRegCc(machInst, rd, 797 rm, rn, 0, LSL); 798 case 0x2: 799 return new QsubRegCc(machInst, rd, 800 rm, rn, 0, LSL); 801 case 0x3: 802 return new QdsubRegCc(machInst, rd, 803 rm, rn, 0, LSL); 804 } 805 break; 806 case 0x1: 807 switch (op2) { 808 case 0x0: 809 return new Rev(machInst, rd, rn); 810 case 0x1: 811 return new Rev16(machInst, rd, rn); 812 case 0x2: 813 return new Rbit(machInst, rd, rm); 814 case 0x3: 815 return new Revsh(machInst, rd, rn); 816 } 817 break; 818 case 0x2: 819 if (op2 == 0) { 820 return new Sel(machInst, rd, rn, rm); 821 } 822 break; 823 case 0x3: 824 if (op2 == 0) { 825 return new Clz(machInst, rd, rm); 826 } 827 } 828 } 829 return new Unknown(machInst); 830 } 831 } 832 ''' 833}}; 834 835def format Thumb16ShiftAddSubMoveCmp() {{ 836 decode_block = ''' 837 { 838 const uint32_t imm5 = bits(machInst, 10, 6); 839 const uint32_t imm3 = bits(machInst, 8, 6); 840 const uint32_t imm8 = bits(machInst, 7, 0); 841 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 842 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 843 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 844 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6); 845 switch (bits(machInst, 13, 11)) { 846 case 0x0: // lsl 847 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL); 848 case 0x1: // lsr 849 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR); 850 case 0x2: // asr 851 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR); 852 case 0x3: 853 switch (bits(machInst, 10, 9)) { 854 case 0x0: 855 return new AddRegCc(machInst, rd, rn, rm, 0, LSL); 856 case 0x1: 857 return new SubRegCc(machInst, rd, rn, rm, 0, LSL); 858 case 0x2: 859 return new AddImmCc(machInst, rd, rn, imm3, true); 860 case 0x3: 861 return new SubImmCc(machInst, rd, rn, imm3, true); 862 } 863 case 0x4: 864 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false); 865 case 0x5: 866 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true); 867 case 0x6: 868 return new AddImmCc(machInst, rd8, rd8, imm8, true); 869 case 0x7: 870 return new SubImmCc(machInst, rd8, rd8, imm8, true); 871 } 872 } 873 ''' 874}}; 875 876def format Thumb16DataProcessing() {{ 877 decode_block = ''' 878 { 879 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 880 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 881 switch (bits(machInst, 9, 6)) { 882 case 0x0: 883 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL); 884 case 0x1: 885 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL); 886 case 0x2: //lsl 887 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL); 888 case 0x3: //lsr 889 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR); 890 case 0x4: //asr 891 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR); 892 case 0x5: 893 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL); 894 case 0x6: 895 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL); 896 case 0x7: // ror 897 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR); 898 case 0x8: 899 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 900 case 0x9: 901 return new RsbImmCc(machInst, rdn, rm, 0, true); 902 case 0xa: 903 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 904 case 0xb: 905 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 906 case 0xc: 907 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL); 908 case 0xd: 909 return new MulCc(machInst, rdn, rm, rdn); 910 case 0xe: 911 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL); 912 case 0xf: 913 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 914 } 915 } 916 ''' 917}}; 918 919def format Thumb16SpecDataAndBx() {{ 920 decode_block = ''' 921 { 922 const IntRegIndex rdn = 923 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) | 924 (bits(machInst, 7) << 3)); 925 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3); 926 switch (bits(machInst, 9, 8)) { 927 case 0x0: 928 return new AddReg(machInst, rdn, rdn, rm, 0, LSL); 929 case 0x1: 930 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 931 case 0x2: 932 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 933 case 0x3: 934 if (bits(machInst, 7) == 0) { 935 return new BxReg(machInst, 936 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 937 COND_UC); 938 } else { 939 return new BlxReg(machInst, 940 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 941 COND_UC); 942 } 943 } 944 } 945 ''' 946}}; 947 948def format Thumb16Adr() {{ 949 decode_block = ''' 950 { 951 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 952 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 953 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false); 954 } 955 ''' 956}}; 957 958def format Thumb16AddSp() {{ 959 decode_block = ''' 960 { 961 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 962 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 963 return new AddImm(machInst, rd, INTREG_SP, imm8, true); 964 } 965 ''' 966}}; 967 968def format Thumb16Misc() {{ 969 decode_block = ''' 970 { 971 switch (bits(machInst, 11, 8)) { 972 case 0x0: 973 if (bits(machInst, 7)) { 974 return new SubImm(machInst, INTREG_SP, INTREG_SP, 975 bits(machInst, 6, 0) << 2, true); 976 } else { 977 return new AddImm(machInst, INTREG_SP, INTREG_SP, 978 bits(machInst, 6, 0) << 2, true); 979 } 980 case 0x1: 981 return new Cbz(machInst, 982 (bits(machInst, 9) << 6) | 983 (bits(machInst, 7, 3) << 1), 984 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 985 case 0x2: 986 { 987 const IntRegIndex rd = 988 (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 989 const IntRegIndex rm = 990 (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 991 switch (bits(machInst, 7, 6)) { 992 case 0x0: 993 return new Sxth(machInst, rd, 0, rm); 994 case 0x1: 995 return new Sxtb(machInst, rd, 0, rm); 996 case 0x2: 997 return new Uxth(machInst, rd, 0, rm); 998 case 0x3: 999 return new Uxtb(machInst, rd, 0, rm); 1000 } 1001 } 1002 case 0x3: 1003 return new Cbz(machInst, 1004 (bits(machInst, 9) << 6) | 1005 (bits(machInst, 7, 3) << 1), 1006 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 1007 case 0x4: 1008 case 0x5: 1009 { 1010 const uint32_t m = bits(machInst, 8); 1011 const uint32_t regList = bits(machInst, 7, 0) | (m << 14); 1012 return new LdmStm(machInst, INTREG_SP, false, false, false, 1013 true, false, regList); 1014 } 1015 case 0x6: 1016 { 1017 const uint32_t opBits = bits(machInst, 7, 5); 1018 if (opBits == 2) { 1019 return new WarnUnimplemented("setend", machInst); 1020 } else if (opBits == 3) { 1021 return new WarnUnimplemented("cps", machInst); 1022 } 1023 } 1024 case 0x9: 1025 return new Cbnz(machInst, 1026 (bits(machInst, 9) << 6) | 1027 (bits(machInst, 7, 3) << 1), 1028 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 1029 case 0xa: 1030 { 1031 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 1032 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 1033 switch (bits(machInst, 7, 6)) { 1034 case 0x0: 1035 return new Rev(machInst, rd, rm); 1036 case 0x1: 1037 return new Rev16(machInst, rd, rm); 1038 case 0x3: 1039 return new Revsh(machInst, rd, rm); 1040 default: 1041 break; 1042 } 1043 } 1044 break; 1045 case 0xb: 1046 return new Cbnz(machInst, 1047 (bits(machInst, 9) << 6) | 1048 (bits(machInst, 7, 3) << 1), 1049 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 1050 case 0xc: 1051 case 0xd: 1052 { 1053 const uint32_t p = bits(machInst, 8); 1054 const uint32_t regList = bits(machInst, 7, 0) | (p << 15); 1055 return new LdmStm(machInst, INTREG_SP, true, true, false, 1056 true, true, regList); 1057 } 1058 case 0xe: 1059 return new WarnUnimplemented("bkpt", machInst); 1060 case 0xf: 1061 if (bits(machInst, 3, 0) != 0) 1062 return new WarnUnimplemented("it", machInst); 1063 switch (bits(machInst, 7, 4)) { 1064 case 0x0: 1065 return new NopInst(machInst); 1066 case 0x1: 1067 return new WarnUnimplemented("yield", machInst); 1068 case 0x2: 1069 return new WarnUnimplemented("wfe", machInst); 1070 case 0x3: 1071 return new WarnUnimplemented("wfi", machInst); 1072 case 0x4: 1073 return new WarnUnimplemented("sev", machInst); 1074 default: 1075 return new WarnUnimplemented("unallocated_hint", machInst); 1076 } 1077 default: 1078 break; 1079 } 1080 return new Unknown(machInst); 1081 } 1082 ''' 1083}}; 1084 1085def format Thumb32DataProcModImm() {{ 1086 1087 def decInst(mnem, dest="rd", op1="rn"): 1088 return ''' 1089 if (s) { 1090 return new %(mnem)sImmCc(machInst, %(dest)s, 1091 %(op1)s, imm, rotC); 1092 } else { 1093 return new %(mnem)sImm(machInst, %(dest)s, 1094 %(op1)s, imm, rotC); 1095 } 1096 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 1097 1098 decode_block = ''' 1099 { 1100 const uint32_t op = bits(machInst, 24, 21); 1101 const bool s = (bits(machInst, 20) == 1); 1102 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1103 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1104 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 | 1105 bits(machInst, 14, 12); 1106 const bool rotC = ctrlImm > 3; 1107 const uint32_t dataImm = bits(machInst, 7, 0); 1108 const uint32_t imm = modified_imm(ctrlImm, dataImm); 1109 switch (op) { 1110 case 0x0: 1111 if (rd == INTREG_PC) { 1112 %(tst)s 1113 } else { 1114 %(and)s 1115 } 1116 case 0x1: 1117 %(bic)s 1118 case 0x2: 1119 if (rn == INTREG_PC) { 1120 %(mov)s 1121 } else { 1122 %(orr)s 1123 } 1124 case 0x3: 1125 if (rn == INTREG_PC) { 1126 %(mvn)s 1127 } else { 1128 %(orn)s 1129 } 1130 case 0x4: 1131 if (rd == INTREG_PC) { 1132 %(teq)s 1133 } else { 1134 %(eor)s 1135 } 1136 case 0x8: 1137 if (rd == INTREG_PC) { 1138 %(cmn)s 1139 } else { 1140 %(add)s 1141 } 1142 case 0xa: 1143 %(adc)s 1144 case 0xb: 1145 %(sbc)s 1146 case 0xd: 1147 if (rd == INTREG_PC) { 1148 %(cmp)s 1149 } else { 1150 %(sub)s 1151 } 1152 case 0xe: 1153 %(rsb)s 1154 default: 1155 return new Unknown(machInst); 1156 } 1157 } 1158 ''' % { 1159 "tst" : decInst("Tst", "INTREG_ZERO"), 1160 "and" : decInst("And"), 1161 "bic" : decInst("Bic"), 1162 "mov" : decInst("Mov", op1="INTREG_ZERO"), 1163 "orr" : decInst("Orr"), 1164 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 1165 "orn" : decInst("Orn"), 1166 "teq" : decInst("Teq", dest="INTREG_ZERO"), 1167 "eor" : decInst("Eor"), 1168 "cmn" : decInst("Cmn", dest="INTREG_ZERO"), 1169 "add" : decInst("Add"), 1170 "adc" : decInst("Adc"), 1171 "sbc" : decInst("Sbc"), 1172 "cmp" : decInst("Cmp", dest="INTREG_ZERO"), 1173 "sub" : decInst("Sub"), 1174 "rsb" : decInst("Rsb") 1175 } 1176}}; 1177 1178def format Thumb32DataProcPlainBin() {{ 1179 decode_block = ''' 1180 { 1181 const uint32_t op = bits(machInst, 24, 20); 1182 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1183 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1184 switch (op) { 1185 case 0x0: 1186 { 1187 const uint32_t imm = bits(machInst, 7, 0) | 1188 (bits(machInst, 14, 12) << 8) | 1189 (bits(machInst, 26) << 11); 1190 if (rn == 0xf) { 1191 return new AdrImm(machInst, rd, (IntRegIndex)1, 1192 imm, false); 1193 } else { 1194 return new AddImm(machInst, rd, rn, imm, true); 1195 } 1196 } 1197 case 0x4: 1198 { 1199 const uint32_t imm = bits(machInst, 7, 0) | 1200 (bits(machInst, 14, 12) << 8) | 1201 (bits(machInst, 26) << 11) | 1202 (bits(machInst, 19, 16) << 12); 1203 return new MovImm(machInst, rd, INTREG_ZERO, imm, true); 1204 } 1205 case 0xa: 1206 { 1207 const uint32_t imm = bits(machInst, 7, 0) | 1208 (bits(machInst, 14, 12) << 8) | 1209 (bits(machInst, 26) << 11); 1210 if (rn == 0xf) { 1211 return new AdrImm(machInst, rd, (IntRegIndex)0, 1212 imm, false); 1213 } else { 1214 return new SubImm(machInst, rd, rn, imm, true); 1215 } 1216 } 1217 case 0xc: 1218 { 1219 const uint32_t imm = bits(machInst, 7, 0) | 1220 (bits(machInst, 14, 12) << 8) | 1221 (bits(machInst, 26) << 11) | 1222 (bits(machInst, 19, 16) << 12); 1223 return new MovtImm(machInst, rd, rd, imm, true); 1224 } 1225 case 0x12: 1226 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 1227 const uint32_t satImm = bits(machInst, 4, 0); 1228 return new Ssat16(machInst, rd, satImm + 1, rn); 1229 } 1230 // Fall through on purpose... 1231 case 0x10: 1232 { 1233 const uint32_t satImm = bits(machInst, 4, 0); 1234 const uint32_t imm = bits(machInst, 7, 6) | 1235 (bits(machInst, 14, 12) << 2); 1236 const ArmShiftType type = 1237 (ArmShiftType)(uint32_t)bits(machInst, 21, 20); 1238 return new Ssat(machInst, rd, satImm + 1, rn, imm, type); 1239 } 1240 case 0x14: 1241 return new WarnUnimplemented("sbfx", machInst); 1242 case 0x16: 1243 if (rn == 0xf) { 1244 return new WarnUnimplemented("bfc", machInst); 1245 } else { 1246 return new WarnUnimplemented("bfi", machInst); 1247 } 1248 case 0x1a: 1249 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 1250 const uint32_t satImm = bits(machInst, 4, 0); 1251 return new Usat16(machInst, rd, satImm, rn); 1252 } 1253 // Fall through on purpose... 1254 case 0x18: 1255 { 1256 const uint32_t satImm = bits(machInst, 4, 0); 1257 const uint32_t imm = bits(machInst, 7, 6) | 1258 (bits(machInst, 14, 12) << 2); 1259 const ArmShiftType type = 1260 (ArmShiftType)(uint32_t)bits(machInst, 21, 20); 1261 return new Usat(machInst, rd, satImm, rn, imm, type); 1262 } 1263 case 0x1c: 1264 return new WarnUnimplemented("ubfx", machInst); 1265 default: 1266 return new Unknown(machInst); 1267 } 1268 } 1269 ''' 1270}}; 1271 1272def format Thumb32DataProcShiftReg() {{ 1273 1274 def decInst(mnem, dest="rd", op1="rn"): 1275 return ''' 1276 if (s) { 1277 return new %(mnem)sRegCc(machInst, %(dest)s, 1278 %(op1)s, rm, amt, type); 1279 } else { 1280 return new %(mnem)sReg(machInst, %(dest)s, 1281 %(op1)s, rm, amt, type); 1282 } 1283 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 1284 1285 decode_block = ''' 1286 { 1287 const uint32_t op = bits(machInst, 24, 21); 1288 const bool s = (bits(machInst, 20) == 1); 1289 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1290 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 1291 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 1292 const uint32_t amt = (bits(machInst, 14, 12) << 2) | 1293 bits(machInst, 7, 6); 1294 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4); 1295 switch (op) { 1296 case 0x0: 1297 if (rd == INTREG_PC) { 1298 %(tst)s 1299 } else { 1300 %(and)s 1301 } 1302 case 0x1: 1303 %(bic)s 1304 case 0x2: 1305 if (rn == INTREG_PC) { 1306 %(mov)s 1307 } else { 1308 %(orr)s 1309 } 1310 case 0x3: 1311 if (rn == INTREG_PC) { 1312 %(mvn)s 1313 } else { 1314 %(orn)s 1315 } 1316 case 0x4: 1317 if (rd == INTREG_PC) { 1318 %(teq)s 1319 } else { 1320 %(eor)s 1321 } 1322 case 0x6: 1323 if (type) { 1324 return new PkhtbReg(machInst, rd, rn, rm, amt, type); 1325 } else { 1326 return new PkhbtReg(machInst, rd, rn, rm, amt, type); 1327 } 1328 case 0x8: 1329 if (rd == INTREG_PC) { 1330 %(cmn)s 1331 } else { 1332 %(add)s 1333 } 1334 case 0xa: 1335 %(adc)s 1336 case 0xb: 1337 %(sbc)s 1338 case 0xd: 1339 if (rd == INTREG_PC) { 1340 %(cmp)s 1341 } else { 1342 %(sub)s 1343 } 1344 case 0xe: 1345 %(rsb)s 1346 default: 1347 return new Unknown(machInst); 1348 } 1349 } 1350 ''' % { 1351 "tst" : decInst("Tst", "INTREG_ZERO"), 1352 "and" : decInst("And"), 1353 "bic" : decInst("Bic"), 1354 "mov" : decInst("Mov", op1="INTREG_ZERO"), 1355 "orr" : decInst("Orr"), 1356 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 1357 "orn" : decInst("Orn"), 1358 "teq" : decInst("Teq", "INTREG_ZERO"), 1359 "eor" : decInst("Eor"), 1360 "cmn" : decInst("Cmn", "INTREG_ZERO"), 1361 "add" : decInst("Add"), 1362 "adc" : decInst("Adc"), 1363 "sbc" : decInst("Sbc"), 1364 "cmp" : decInst("Cmp", "INTREG_ZERO"), 1365 "sub" : decInst("Sub"), 1366 "rsb" : decInst("Rsb") 1367 } 1368}}; 1369