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