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