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