data.isa revision 7210:10d2d0e1e39d
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 return new WarnUnimplemented("rev", machInst); 169 } else if (op2 == 0x3) { 170 if (a == 0xf) { 171 return new WarnUnimplemented("sxth", machInst); 172 } else { 173 return new WarnUnimplemented("sxtah", machInst); 174 } 175 } else if (op2 == 0x5) { 176 return new WarnUnimplemented("rev16", machInst); 177 } 178 break; 179 case 0x4: 180 if (op2 == 0x3) { 181 if (a == 0xf) { 182 return new WarnUnimplemented("uxtb16", machInst); 183 } else { 184 return new WarnUnimplemented("uxtab16", machInst); 185 } 186 } 187 break; 188 case 0x6: 189 if (op2 == 0x1) { 190 return new WarnUnimplemented("usat16", machInst); 191 } else if (op2 == 0x3) { 192 if (a == 0xf) { 193 return new WarnUnimplemented("uxtb", machInst); 194 } else { 195 return new WarnUnimplemented("uxtab", machInst); 196 } 197 } 198 break; 199 case 0x7: 200 if (op2 == 0x1) { 201 return new WarnUnimplemented("rbit", machInst); 202 } else if (op2 == 0x3) { 203 if (a == 0xf) { 204 return new WarnUnimplemented("uxth", machInst); 205 } else { 206 return new WarnUnimplemented("uxtah", machInst); 207 } 208 } else if (op2 == 0x5) { 209 return new WarnUnimplemented("revsh", machInst); 210 } 211 break; 212 } 213 return new Unknown(machInst); 214 } 215 ''' 216}}; 217 218def format ArmParallelAddSubtract() {{ 219 decode_block=''' 220 { 221 const uint32_t op1 = bits(machInst, 21, 20); 222 const uint32_t op2 = bits(machInst, 7, 5); 223 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 224 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 225 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 226 if (bits(machInst, 22) == 0) { 227 switch (op1) { 228 case 0x1: 229 switch (op2) { 230 case 0x0: 231 return new WarnUnimplemented("sadd16", machInst); 232 case 0x1: 233 return new WarnUnimplemented("sasx", machInst); 234 case 0x2: 235 return new WarnUnimplemented("ssax", machInst); 236 case 0x3: 237 return new WarnUnimplemented("ssub16", machInst); 238 case 0x4: 239 return new WarnUnimplemented("sadd8", machInst); 240 case 0x7: 241 return new WarnUnimplemented("ssub8", machInst); 242 } 243 break; 244 case 0x2: 245 switch (op2) { 246 case 0x0: 247 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL); 248 case 0x1: 249 return new QasxReg(machInst, rd, rn, rm, 0, LSL); 250 case 0x2: 251 return new QsaxReg(machInst, rd, rn, rm, 0, LSL); 252 case 0x3: 253 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL); 254 case 0x4: 255 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL); 256 case 0x7: 257 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL); 258 } 259 break; 260 case 0x3: 261 switch (op2) { 262 case 0x0: 263 return new WarnUnimplemented("shadd16", machInst); 264 case 0x1: 265 return new WarnUnimplemented("shasx", machInst); 266 case 0x2: 267 return new WarnUnimplemented("shsax", machInst); 268 case 0x3: 269 return new WarnUnimplemented("shsub16", machInst); 270 case 0x4: 271 return new WarnUnimplemented("shadd8", machInst); 272 case 0x7: 273 return new WarnUnimplemented("shsub8", machInst); 274 } 275 break; 276 } 277 } else { 278 switch (op1) { 279 case 0x1: 280 switch (op2) { 281 case 0x0: 282 return new WarnUnimplemented("uadd16", machInst); 283 case 0x1: 284 return new WarnUnimplemented("uasx", machInst); 285 case 0x2: 286 return new WarnUnimplemented("usax", machInst); 287 case 0x3: 288 return new WarnUnimplemented("usub16", machInst); 289 case 0x4: 290 return new WarnUnimplemented("uadd8", machInst); 291 case 0x7: 292 return new WarnUnimplemented("usub8", machInst); 293 } 294 break; 295 case 0x2: 296 switch (op2) { 297 case 0x0: 298 return new WarnUnimplemented("uqadd16", machInst); 299 case 0x1: 300 return new WarnUnimplemented("uqasx", machInst); 301 case 0x2: 302 return new WarnUnimplemented("uqsax", machInst); 303 case 0x3: 304 return new WarnUnimplemented("uqsub16", machInst); 305 case 0x4: 306 return new WarnUnimplemented("uqadd8", machInst); 307 case 0x7: 308 return new WarnUnimplemented("uqsub8", machInst); 309 } 310 break; 311 case 0x3: 312 switch (op2) { 313 case 0x0: 314 return new WarnUnimplemented("uhadd16", machInst); 315 case 0x1: 316 return new WarnUnimplemented("uhasx", machInst); 317 case 0x2: 318 return new WarnUnimplemented("uhsax", machInst); 319 case 0x3: 320 return new WarnUnimplemented("uhsub16", machInst); 321 case 0x4: 322 return new WarnUnimplemented("uhadd8", machInst); 323 case 0x7: 324 return new WarnUnimplemented("uhsub8", machInst); 325 } 326 break; 327 } 328 } 329 return new Unknown(machInst); 330 } 331 ''' 332}}; 333 334def format ArmDataProcImm() {{ 335 pclr = ''' 336 return new %(className)ssImmPclr(machInst, %(dest)s, 337 %(op1)s, imm, false); 338 ''' 339 adr = ''' 340 return new AdrImm(machInst, %(dest)s, %(add)s, 341 imm, false); 342 ''' 343 instDecode = ''' 344 case %(opcode)#x: 345 if (setCc) { 346 if (%(pclrInst)s && %(dest)s == INTREG_PC) { 347 %(pclr)s 348 } else { 349 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s, 350 imm, rotC); 351 } 352 } else { 353 if (%(adrInst)s && %(op1)s == INTREG_PC) { 354 %(adr)s 355 } else { 356 return new %(className)sImm(machInst, %(dest)s, %(op1)s, 357 imm, rotC); 358 } 359 } 360 break; 361 ''' 362 363 def instCode(opcode, mnem, useDest = True, useOp1 = True): 364 global instDecode, pclr, adr 365 if useDest: 366 dest = "rd" 367 else: 368 dest = "INTREG_ZERO" 369 if useOp1: 370 op1 = "rn" 371 else: 372 op1 = "INTREG_ZERO" 373 substDict = { "className": mnem.capitalize(), 374 "opcode": opcode, 375 "dest": dest, 376 "op1": op1, 377 "adr": "", 378 "adrInst": "false" } 379 if useDest: 380 substDict["pclrInst"] = "true" 381 substDict["pclr"] = pclr % substDict 382 else: 383 substDict["pclrInst"] = "false" 384 substDict["pclr"] = "" 385 return instDecode % substDict 386 387 def adrCode(opcode, mnem, add="1"): 388 global instDecode, pclr, adr 389 substDict = { "className": mnem.capitalize(), 390 "opcode": opcode, 391 "dest": "rd", 392 "op1": "rn", 393 "add": add, 394 "pclrInst": "true", 395 "adrInst": "true" } 396 substDict["pclr"] = pclr % substDict 397 substDict["adr"] = adr % substDict 398 return instDecode % substDict 399 400 decode_block = ''' 401 { 402 const bool setCc = (bits(machInst, 20) == 1); 403 const uint32_t unrotated = bits(machInst, 7, 0); 404 const uint32_t rotation = (bits(machInst, 11, 8) << 1); 405 const bool rotC = (rotation != 0); 406 const uint32_t imm = rotate_imm(unrotated, rotation); 407 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 408 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 409 switch (OPCODE) { 410 ''' 411 decode_block += instCode(0x0, "and") 412 decode_block += instCode(0x1, "eor") 413 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0") 414 decode_block += instCode(0x3, "rsb") 415 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1") 416 decode_block += instCode(0x5, "adc") 417 decode_block += instCode(0x6, "sbc") 418 decode_block += instCode(0x7, "rsc") 419 decode_block += instCode(0x8, "tst", useDest = False) 420 decode_block += instCode(0x9, "teq", useDest = False) 421 decode_block += instCode(0xa, "cmp", useDest = False) 422 decode_block += instCode(0xb, "cmn", useDest = False) 423 decode_block += instCode(0xc, "orr") 424 decode_block += instCode(0xd, "mov", useOp1 = False) 425 decode_block += instCode(0xe, "bic") 426 decode_block += instCode(0xf, "mvn", useOp1 = False) 427 decode_block += ''' 428 default: 429 return new Unknown(machInst); 430 } 431 } 432 ''' 433}}; 434 435def format ArmSatAddSub() {{ 436 decode_block = ''' 437 { 438 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 439 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 440 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 441 switch (OPCODE) { 442 case 0x8: 443 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL); 444 case 0x9: 445 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL); 446 case 0xa: 447 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL); 448 case 0xb: 449 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL); 450 default: 451 return new Unknown(machInst); 452 } 453 } 454 ''' 455}}; 456 457def format Thumb16ShiftAddSubMoveCmp() {{ 458 decode_block = ''' 459 { 460 const uint32_t imm5 = bits(machInst, 10, 6); 461 const uint32_t imm3 = bits(machInst, 8, 6); 462 const uint32_t imm8 = bits(machInst, 7, 0); 463 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 464 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 465 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 466 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6); 467 switch (bits(machInst, 13, 11)) { 468 case 0x0: // lsl 469 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL); 470 case 0x1: // lsr 471 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR); 472 case 0x2: // asr 473 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR); 474 case 0x3: 475 switch (bits(machInst, 10, 9)) { 476 case 0x0: 477 return new AddRegCc(machInst, rd, rn, rm, 0, LSL); 478 case 0x1: 479 return new SubRegCc(machInst, rd, rn, rm, 0, LSL); 480 case 0x2: 481 return new AddImmCc(machInst, rd, rn, imm3, true); 482 case 0x3: 483 return new SubImmCc(machInst, rd, rn, imm3, true); 484 } 485 case 0x4: 486 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false); 487 case 0x5: 488 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true); 489 case 0x6: 490 return new AddImmCc(machInst, rd8, rd8, imm8, true); 491 case 0x7: 492 return new SubImmCc(machInst, rd8, rd8, imm8, true); 493 } 494 } 495 ''' 496}}; 497 498def format Thumb16DataProcessing() {{ 499 decode_block = ''' 500 { 501 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 502 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 503 switch (bits(machInst, 9, 6)) { 504 case 0x0: 505 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL); 506 case 0x1: 507 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL); 508 case 0x2: //lsl 509 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL); 510 case 0x3: //lsr 511 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR); 512 case 0x4: //asr 513 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR); 514 case 0x5: 515 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL); 516 case 0x6: 517 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL); 518 case 0x7: // ror 519 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR); 520 case 0x8: 521 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 522 case 0x9: 523 return new RsbImmCc(machInst, rdn, rm, 0, true); 524 case 0xa: 525 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 526 case 0xb: 527 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 528 case 0xc: 529 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL); 530 case 0xd: 531 return new MulCc(machInst, rdn, rm, rdn); 532 case 0xe: 533 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL); 534 case 0xf: 535 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 536 } 537 } 538 ''' 539}}; 540 541def format Thumb16SpecDataAndBx() {{ 542 decode_block = ''' 543 { 544 const IntRegIndex rdn = 545 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) | 546 (bits(machInst, 7) << 3)); 547 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3); 548 switch (bits(machInst, 9, 8)) { 549 case 0x0: 550 return new AddReg(machInst, rdn, rdn, rm, 0, LSL); 551 case 0x1: 552 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 553 case 0x2: 554 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 555 case 0x3: 556 if (bits(machInst, 7) == 0) { 557 return new BxReg(machInst, 558 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 559 COND_UC); 560 } else { 561 return new BlxReg(machInst, 562 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 563 COND_UC); 564 } 565 } 566 } 567 ''' 568}}; 569 570def format Thumb16Adr() {{ 571 decode_block = ''' 572 { 573 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 574 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 575 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false); 576 } 577 ''' 578}}; 579 580def format Thumb16AddSp() {{ 581 decode_block = ''' 582 { 583 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 584 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 585 return new AddImm(machInst, rd, INTREG_SP, imm8, true); 586 } 587 ''' 588}}; 589 590def format Thumb16Misc() {{ 591 decode_block = ''' 592 { 593 switch (bits(machInst, 11, 8)) { 594 case 0x0: 595 if (bits(machInst, 7)) { 596 return new SubImm(machInst, INTREG_SP, INTREG_SP, 597 bits(machInst, 6, 0) << 2, true); 598 } else { 599 return new AddImm(machInst, INTREG_SP, INTREG_SP, 600 bits(machInst, 6, 0) << 2, true); 601 } 602 case 0x1: 603 return new Cbz(machInst, 604 (bits(machInst, 9) << 6) | 605 (bits(machInst, 7, 3) << 1), 606 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 607 case 0x2: 608 switch (bits(machInst, 7, 6)) { 609 case 0x0: 610 return new WarnUnimplemented("sxth", machInst); 611 case 0x1: 612 return new WarnUnimplemented("sxtb", machInst); 613 case 0x2: 614 return new WarnUnimplemented("uxth", machInst); 615 case 0x3: 616 return new WarnUnimplemented("uxtb", machInst); 617 } 618 case 0x3: 619 return new Cbz(machInst, 620 (bits(machInst, 9) << 6) | 621 (bits(machInst, 7, 3) << 1), 622 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 623 case 0x4: 624 case 0x5: 625 { 626 const uint32_t m = bits(machInst, 8); 627 const uint32_t regList = bits(machInst, 7, 0) | (m << 14); 628 return new LdmStm(machInst, INTREG_SP, false, false, false, 629 true, false, regList); 630 } 631 case 0x6: 632 { 633 const uint32_t opBits = bits(machInst, 7, 5); 634 if (opBits == 2) { 635 return new WarnUnimplemented("setend", machInst); 636 } else if (opBits == 3) { 637 return new WarnUnimplemented("cps", machInst); 638 } 639 } 640 case 0x9: 641 return new Cbnz(machInst, 642 (bits(machInst, 9) << 6) | 643 (bits(machInst, 7, 3) << 1), 644 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 645 case 0xa: 646 switch (bits(machInst, 7, 5)) { 647 case 0x0: 648 return new WarnUnimplemented("rev", machInst); 649 case 0x1: 650 return new WarnUnimplemented("rev16", machInst); 651 case 0x3: 652 return new WarnUnimplemented("revsh", machInst); 653 default: 654 break; 655 } 656 break; 657 case 0xb: 658 return new Cbnz(machInst, 659 (bits(machInst, 9) << 6) | 660 (bits(machInst, 7, 3) << 1), 661 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 662 case 0xc: 663 case 0xd: 664 { 665 const uint32_t p = bits(machInst, 8); 666 const uint32_t regList = bits(machInst, 7, 0) | (p << 15); 667 return new LdmStm(machInst, INTREG_SP, true, true, false, 668 true, true, regList); 669 } 670 case 0xe: 671 return new WarnUnimplemented("bkpt", machInst); 672 case 0xf: 673 if (bits(machInst, 3, 0) != 0) 674 return new WarnUnimplemented("it", machInst); 675 switch (bits(machInst, 7, 4)) { 676 case 0x0: 677 return new WarnUnimplemented("nop", machInst); 678 case 0x1: 679 return new WarnUnimplemented("yield", machInst); 680 case 0x2: 681 return new WarnUnimplemented("wfe", machInst); 682 case 0x3: 683 return new WarnUnimplemented("wfi", machInst); 684 case 0x4: 685 return new WarnUnimplemented("sev", machInst); 686 default: 687 return new WarnUnimplemented("unallocated_hint", machInst); 688 } 689 default: 690 break; 691 } 692 return new Unknown(machInst); 693 } 694 ''' 695}}; 696 697def format Thumb32DataProcModImm() {{ 698 699 def decInst(mnem, dest="rd", op1="rn"): 700 return ''' 701 if (s) { 702 return new %(mnem)sImmCc(machInst, %(dest)s, 703 %(op1)s, imm, rotC); 704 } else { 705 return new %(mnem)sImm(machInst, %(dest)s, 706 %(op1)s, imm, rotC); 707 } 708 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 709 710 decode_block = ''' 711 { 712 const uint32_t op = bits(machInst, 24, 21); 713 const bool s = (bits(machInst, 20) == 1); 714 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 715 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 716 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 | 717 bits(machInst, 14, 12); 718 const bool rotC = ctrlImm > 3; 719 const uint32_t dataImm = bits(machInst, 7, 0); 720 const uint32_t imm = modified_imm(ctrlImm, dataImm); 721 switch (op) { 722 case 0x0: 723 if (rd == INTREG_PC) { 724 %(tst)s 725 } else { 726 %(and)s 727 } 728 case 0x1: 729 %(bic)s 730 case 0x2: 731 if (rn == INTREG_PC) { 732 %(mov)s 733 } else { 734 %(orr)s 735 } 736 case 0x3: 737 if (rn == INTREG_PC) { 738 %(mvn)s 739 } else { 740 %(orn)s 741 } 742 case 0x4: 743 if (rd == INTREG_PC) { 744 %(teq)s 745 } else { 746 %(eor)s 747 } 748 case 0x8: 749 if (rd == INTREG_PC) { 750 %(cmn)s 751 } else { 752 %(add)s 753 } 754 case 0xa: 755 %(adc)s 756 case 0xb: 757 %(sbc)s 758 case 0xd: 759 if (rd == INTREG_PC) { 760 %(cmp)s 761 } else { 762 %(sub)s 763 } 764 case 0xe: 765 %(rsb)s 766 default: 767 return new Unknown(machInst); 768 } 769 } 770 ''' % { 771 "tst" : decInst("Tst", "INTREG_ZERO"), 772 "and" : decInst("And"), 773 "bic" : decInst("Bic"), 774 "mov" : decInst("Mov", op1="INTREG_ZERO"), 775 "orr" : decInst("Orr"), 776 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 777 "orn" : decInst("Orn"), 778 "teq" : decInst("Teq", dest="INTREG_ZERO"), 779 "eor" : decInst("Eor"), 780 "cmn" : decInst("Cmn", dest="INTREG_ZERO"), 781 "add" : decInst("Add"), 782 "adc" : decInst("Adc"), 783 "sbc" : decInst("Sbc"), 784 "cmp" : decInst("Cmp", dest="INTREG_ZERO"), 785 "sub" : decInst("Sub"), 786 "rsb" : decInst("Rsb") 787 } 788}}; 789 790def format Thumb32DataProcPlainBin() {{ 791 decode_block = ''' 792 { 793 const uint32_t op = bits(machInst, 24, 20); 794 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 795 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 796 switch (op) { 797 case 0x0: 798 { 799 const uint32_t imm = bits(machInst, 7, 0) | 800 (bits(machInst, 14, 12) << 8) | 801 (bits(machInst, 26) << 11); 802 if (rn == 0xf) { 803 return new AdrImm(machInst, rd, (IntRegIndex)1, 804 imm, false); 805 } else { 806 return new AddImm(machInst, rd, rn, imm, true); 807 } 808 } 809 case 0x4: 810 { 811 const uint32_t imm = bits(machInst, 7, 0) | 812 (bits(machInst, 14, 12) << 8) | 813 (bits(machInst, 26) << 11) | 814 (bits(machInst, 19, 16) << 12); 815 return new MovImm(machInst, rd, INTREG_ZERO, imm, true); 816 } 817 case 0xa: 818 { 819 const uint32_t imm = bits(machInst, 7, 0) | 820 (bits(machInst, 14, 12) << 8) | 821 (bits(machInst, 26) << 11); 822 if (rn == 0xf) { 823 return new AdrImm(machInst, rd, (IntRegIndex)0, 824 imm, false); 825 } else { 826 return new SubImm(machInst, rd, rn, imm, true); 827 } 828 } 829 case 0xc: 830 { 831 const uint32_t imm = bits(machInst, 7, 0) | 832 (bits(machInst, 14, 12) << 8) | 833 (bits(machInst, 26) << 11) | 834 (bits(machInst, 19, 16) << 12); 835 return new MovtImm(machInst, rd, rd, imm, true); 836 } 837 case 0x12: 838 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 839 return new WarnUnimplemented("ssat16", machInst); 840 } 841 // Fall through on purpose... 842 case 0x10: 843 return new WarnUnimplemented("ssat", machInst); 844 case 0x14: 845 return new WarnUnimplemented("sbfx", machInst); 846 case 0x16: 847 if (rn == 0xf) { 848 return new WarnUnimplemented("bfc", machInst); 849 } else { 850 return new WarnUnimplemented("bfi", machInst); 851 } 852 case 0x1a: 853 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 854 return new WarnUnimplemented("usat16", machInst); 855 } 856 // Fall through on purpose... 857 case 0x18: 858 return new WarnUnimplemented("usat", machInst); 859 case 0x1c: 860 return new WarnUnimplemented("ubfx", machInst); 861 default: 862 return new Unknown(machInst); 863 } 864 } 865 ''' 866}}; 867 868def format Thumb32DataProcShiftReg() {{ 869 870 def decInst(mnem, dest="rd", op1="rn"): 871 return ''' 872 if (s) { 873 return new %(mnem)sRegCc(machInst, %(dest)s, 874 %(op1)s, rm, amt, type); 875 } else { 876 return new %(mnem)sReg(machInst, %(dest)s, 877 %(op1)s, rm, amt, type); 878 } 879 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 880 881 decode_block = ''' 882 { 883 const uint32_t op = bits(machInst, 24, 21); 884 const bool s = (bits(machInst, 20) == 1); 885 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 886 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 887 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 888 const uint32_t amt = (bits(machInst, 14, 12) << 2) | 889 bits(machInst, 7, 6); 890 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4); 891 switch (op) { 892 case 0x0: 893 if (rd == INTREG_PC) { 894 %(tst)s 895 } else { 896 %(and)s 897 } 898 case 0x1: 899 %(bic)s 900 case 0x2: 901 if (rn == INTREG_PC) { 902 %(mov)s 903 } else { 904 %(orr)s 905 } 906 case 0x3: 907 if (rn == INTREG_PC) { 908 %(mvn)s 909 } else { 910 %(orn)s 911 } 912 case 0x4: 913 if (rd == INTREG_PC) { 914 %(teq)s 915 } else { 916 %(eor)s 917 } 918 case 0x6: 919 return new WarnUnimplemented("pkh", machInst); 920 case 0x8: 921 if (rd == INTREG_PC) { 922 %(cmn)s 923 } else { 924 %(add)s 925 } 926 case 0xa: 927 %(adc)s 928 case 0xb: 929 %(sbc)s 930 case 0xd: 931 if (rd == INTREG_PC) { 932 %(cmp)s 933 } else { 934 %(sub)s 935 } 936 case 0xe: 937 %(rsb)s 938 default: 939 return new Unknown(machInst); 940 } 941 } 942 ''' % { 943 "tst" : decInst("Tst", "INTREG_ZERO"), 944 "and" : decInst("And"), 945 "bic" : decInst("Bic"), 946 "mov" : decInst("Mov", op1="INTREG_ZERO"), 947 "orr" : decInst("Orr"), 948 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 949 "orn" : decInst("Orn"), 950 "teq" : decInst("Teq", "INTREG_ZERO"), 951 "eor" : decInst("Eor"), 952 "cmn" : decInst("Cmn", "INTREG_ZERO"), 953 "add" : decInst("Add"), 954 "adc" : decInst("Adc"), 955 "sbc" : decInst("Sbc"), 956 "cmp" : decInst("Cmp", "INTREG_ZERO"), 957 "sub" : decInst("Sub"), 958 "rsb" : decInst("Rsb") 959 } 960}}; 961