data.isa revision 7188:1310866e4ed5
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 ArmDataProcImm() {{ 128 pclr = ''' 129 return new %(className)ssImmPclr(machInst, %(dest)s, 130 %(op1)s, imm, false); 131 ''' 132 adr = ''' 133 return new AdrImm(machInst, %(dest)s, %(add)s, 134 imm, false); 135 ''' 136 instDecode = ''' 137 case %(opcode)#x: 138 if (setCc) { 139 if (%(pclrInst)s && %(dest)s == INTREG_PC) { 140 %(pclr)s 141 } else { 142 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s, 143 imm, rotC); 144 } 145 } else { 146 if (%(adrInst)s && %(op1)s == INTREG_PC) { 147 %(adr)s 148 } else { 149 return new %(className)sImm(machInst, %(dest)s, %(op1)s, 150 imm, rotC); 151 } 152 } 153 break; 154 ''' 155 156 def instCode(opcode, mnem, useDest = True, useOp1 = True): 157 global instDecode, pclr, adr 158 if useDest: 159 dest = "rd" 160 else: 161 dest = "INTREG_ZERO" 162 if useOp1: 163 op1 = "rn" 164 else: 165 op1 = "INTREG_ZERO" 166 substDict = { "className": mnem.capitalize(), 167 "opcode": opcode, 168 "dest": dest, 169 "op1": op1, 170 "adr": "", 171 "adrInst": "false" } 172 if useDest: 173 substDict["pclrInst"] = "true" 174 substDict["pclr"] = pclr % substDict 175 else: 176 substDict["pclrInst"] = "false" 177 substDict["pclr"] = "" 178 return instDecode % substDict 179 180 def adrCode(opcode, mnem, add="1"): 181 global instDecode, pclr, adr 182 substDict = { "className": mnem.capitalize(), 183 "opcode": opcode, 184 "dest": "rd", 185 "op1": "rn", 186 "add": add, 187 "pclrInst": "true", 188 "adrInst": "true" } 189 substDict["pclr"] = pclr % substDict 190 substDict["adr"] = adr % substDict 191 return instDecode % substDict 192 193 decode_block = ''' 194 { 195 const bool setCc = (bits(machInst, 20) == 1); 196 const uint32_t unrotated = bits(machInst, 7, 0); 197 const uint32_t rotation = (bits(machInst, 11, 8) << 1); 198 const bool rotC = (rotation != 0); 199 const uint32_t imm = rotate_imm(unrotated, rotation); 200 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD; 201 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN; 202 switch (OPCODE) { 203 ''' 204 decode_block += instCode(0x0, "and") 205 decode_block += instCode(0x1, "eor") 206 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0") 207 decode_block += instCode(0x3, "rsb") 208 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1") 209 decode_block += instCode(0x5, "adc") 210 decode_block += instCode(0x6, "sbc") 211 decode_block += instCode(0x7, "rsc") 212 decode_block += instCode(0x8, "tst", useDest = False) 213 decode_block += instCode(0x9, "teq", useDest = False) 214 decode_block += instCode(0xa, "cmp", useDest = False) 215 decode_block += instCode(0xb, "cmn", useDest = False) 216 decode_block += instCode(0xc, "orr") 217 decode_block += instCode(0xd, "mov", useOp1 = False) 218 decode_block += instCode(0xe, "bic") 219 decode_block += instCode(0xf, "mvn", useOp1 = False) 220 decode_block += ''' 221 default: 222 return new Unknown(machInst); 223 } 224 } 225 ''' 226}}; 227 228def format Thumb16ShiftAddSubMoveCmp() {{ 229 decode_block = ''' 230 { 231 const uint32_t imm5 = bits(machInst, 10, 6); 232 const uint32_t imm3 = bits(machInst, 8, 6); 233 const uint32_t imm8 = bits(machInst, 7, 0); 234 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 235 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 236 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 237 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6); 238 switch (bits(machInst, 13, 11)) { 239 case 0x0: // lsl 240 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL); 241 case 0x1: // lsr 242 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR); 243 case 0x2: // asr 244 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR); 245 case 0x3: 246 switch (bits(machInst, 10, 9)) { 247 case 0x0: 248 return new AddRegCc(machInst, rd, rn, rm, 0, LSL); 249 case 0x1: 250 return new SubRegCc(machInst, rd, rn, rm, 0, LSL); 251 case 0x2: 252 return new AddImmCc(machInst, rd, rn, imm3, true); 253 case 0x3: 254 return new SubImmCc(machInst, rd, rn, imm3, true); 255 } 256 case 0x4: 257 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false); 258 case 0x5: 259 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true); 260 case 0x6: 261 return new AddImmCc(machInst, rd8, rd8, imm8, true); 262 case 0x7: 263 return new SubImmCc(machInst, rd8, rd8, imm8, true); 264 } 265 } 266 ''' 267}}; 268 269def format Thumb16DataProcessing() {{ 270 decode_block = ''' 271 { 272 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0); 273 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3); 274 switch (bits(machInst, 9, 6)) { 275 case 0x0: 276 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL); 277 case 0x1: 278 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL); 279 case 0x2: //lsl 280 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL); 281 case 0x3: //lsr 282 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR); 283 case 0x4: //asr 284 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR); 285 case 0x5: 286 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL); 287 case 0x6: 288 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL); 289 case 0x7: // ror 290 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR); 291 case 0x8: 292 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 293 case 0x9: 294 return new RsbImmCc(machInst, rdn, rm, 0, true); 295 case 0xa: 296 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 297 case 0xb: 298 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 299 case 0xc: 300 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL); 301 case 0xd: 302 return new MulCc(machInst, rdn, rm, rdn); 303 case 0xe: 304 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL); 305 case 0xf: 306 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 307 } 308 } 309 ''' 310}}; 311 312def format Thumb16SpecDataAndBx() {{ 313 decode_block = ''' 314 { 315 const IntRegIndex rdn = 316 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) | 317 (bits(machInst, 7) << 3)); 318 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3); 319 switch (bits(machInst, 9, 8)) { 320 case 0x0: 321 return new AddReg(machInst, rdn, rdn, rm, 0, LSL); 322 case 0x1: 323 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL); 324 case 0x2: 325 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL); 326 case 0x3: 327 if (bits(machInst, 7) == 0) { 328 return new BxReg(machInst, 329 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 330 COND_UC); 331 } else { 332 return new BlxReg(machInst, 333 (IntRegIndex)(uint32_t)bits(machInst, 6, 3), 334 COND_UC); 335 } 336 } 337 } 338 ''' 339}}; 340 341def format Thumb16Adr() {{ 342 decode_block = ''' 343 { 344 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 345 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 346 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false); 347 } 348 ''' 349}}; 350 351def format Thumb16AddSp() {{ 352 decode_block = ''' 353 { 354 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8); 355 const uint32_t imm8 = bits(machInst, 7, 0) << 2; 356 return new AddImm(machInst, rd, INTREG_SP, imm8, true); 357 } 358 ''' 359}}; 360 361def format Thumb16Misc() {{ 362 decode_block = ''' 363 { 364 switch (bits(machInst, 11, 8)) { 365 case 0x0: 366 if (bits(machInst, 7)) { 367 return new SubImm(machInst, INTREG_SP, INTREG_SP, 368 bits(machInst, 6, 0) << 2, true); 369 } else { 370 return new AddImm(machInst, INTREG_SP, INTREG_SP, 371 bits(machInst, 6, 0) << 2, true); 372 } 373 case 0x1: 374 return new Cbz(machInst, 375 (bits(machInst, 9) << 6) | 376 (bits(machInst, 7, 3) << 1), 377 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 378 case 0x2: 379 switch (bits(machInst, 7, 6)) { 380 case 0x0: 381 return new WarnUnimplemented("sxth", machInst); 382 case 0x1: 383 return new WarnUnimplemented("sxtb", machInst); 384 case 0x2: 385 return new WarnUnimplemented("uxth", machInst); 386 case 0x3: 387 return new WarnUnimplemented("uxtb", machInst); 388 } 389 case 0x3: 390 return new Cbz(machInst, 391 (bits(machInst, 9) << 6) | 392 (bits(machInst, 7, 3) << 1), 393 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 394 case 0x4: 395 case 0x5: 396 return new WarnUnimplemented("push", machInst); 397 case 0x6: 398 { 399 const uint32_t opBits = bits(machInst, 7, 5); 400 if (opBits == 2) { 401 return new WarnUnimplemented("setend", machInst); 402 } else if (opBits == 3) { 403 return new WarnUnimplemented("cps", machInst); 404 } 405 } 406 case 0x9: 407 return new Cbnz(machInst, 408 (bits(machInst, 9) << 6) | 409 (bits(machInst, 7, 3) << 1), 410 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 411 case 0xa: 412 switch (bits(machInst, 7, 5)) { 413 case 0x0: 414 return new WarnUnimplemented("rev", machInst); 415 case 0x1: 416 return new WarnUnimplemented("rev16", machInst); 417 case 0x3: 418 return new WarnUnimplemented("revsh", machInst); 419 default: 420 break; 421 } 422 break; 423 case 0xb: 424 return new Cbnz(machInst, 425 (bits(machInst, 9) << 6) | 426 (bits(machInst, 7, 3) << 1), 427 (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); 428 case 0xc: 429 case 0xd: 430 return new WarnUnimplemented("pop", machInst); 431 case 0xe: 432 return new WarnUnimplemented("bkpt", machInst); 433 case 0xf: 434 if (bits(machInst, 3, 0) != 0) 435 return new WarnUnimplemented("it", machInst); 436 switch (bits(machInst, 7, 4)) { 437 case 0x0: 438 return new WarnUnimplemented("nop", machInst); 439 case 0x1: 440 return new WarnUnimplemented("yield", machInst); 441 case 0x2: 442 return new WarnUnimplemented("wfe", machInst); 443 case 0x3: 444 return new WarnUnimplemented("wfi", machInst); 445 case 0x4: 446 return new WarnUnimplemented("sev", machInst); 447 default: 448 return new WarnUnimplemented("unallocated_hint", machInst); 449 } 450 default: 451 break; 452 } 453 return new Unknown(machInst); 454 } 455 ''' 456}}; 457 458def format Thumb32DataProcModImm() {{ 459 460 def decInst(mnem, dest="rd", op1="rn"): 461 return ''' 462 if (s) { 463 return new %(mnem)sImmCc(machInst, %(dest)s, 464 %(op1)s, imm, rotC); 465 } else { 466 return new %(mnem)sImm(machInst, %(dest)s, 467 %(op1)s, imm, rotC); 468 } 469 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 470 471 decode_block = ''' 472 { 473 const uint32_t op = bits(machInst, 24, 21); 474 const bool s = (bits(machInst, 20) == 1); 475 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 476 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 477 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 | 478 bits(machInst, 14, 12); 479 const bool rotC = ctrlImm > 3; 480 const uint32_t dataImm = bits(machInst, 7, 0); 481 const uint32_t imm = modified_imm(ctrlImm, dataImm); 482 switch (op) { 483 case 0x0: 484 if (rd == INTREG_PC) { 485 %(tst)s 486 } else { 487 %(and)s 488 } 489 case 0x1: 490 %(bic)s 491 case 0x2: 492 if (rn == INTREG_PC) { 493 %(mov)s 494 } else { 495 %(orr)s 496 } 497 case 0x3: 498 if (rn == INTREG_PC) { 499 %(mvn)s 500 } else { 501 %(orn)s 502 } 503 case 0x4: 504 if (rd == INTREG_PC) { 505 %(teq)s 506 } else { 507 %(eor)s 508 } 509 case 0x8: 510 if (rd == INTREG_PC) { 511 %(cmn)s 512 } else { 513 %(add)s 514 } 515 case 0xa: 516 %(adc)s 517 case 0xb: 518 %(sbc)s 519 case 0xd: 520 if (rd == INTREG_PC) { 521 %(cmp)s 522 } else { 523 %(sub)s 524 } 525 case 0xe: 526 %(rsb)s 527 default: 528 return new Unknown(machInst); 529 } 530 } 531 ''' % { 532 "tst" : decInst("Tst", "INTREG_ZERO"), 533 "and" : decInst("And"), 534 "bic" : decInst("Bic"), 535 "mov" : decInst("Mov", op1="INTREG_ZERO"), 536 "orr" : decInst("Orr"), 537 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 538 "orn" : decInst("Orn"), 539 "teq" : decInst("Teq", dest="INTREG_ZERO"), 540 "eor" : decInst("Eor"), 541 "cmn" : decInst("Cmn", dest="INTREG_ZERO"), 542 "add" : decInst("Add"), 543 "adc" : decInst("Adc"), 544 "sbc" : decInst("Sbc"), 545 "cmp" : decInst("Cmp", dest="INTREG_ZERO"), 546 "sub" : decInst("Sub"), 547 "rsb" : decInst("Rsb") 548 } 549}}; 550 551def format Thumb32DataProcPlainBin() {{ 552 decode_block = ''' 553 { 554 const uint32_t op = bits(machInst, 24, 20); 555 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 556 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 557 switch (op) { 558 case 0x0: 559 { 560 const uint32_t imm = bits(machInst, 7, 0) | 561 (bits(machInst, 14, 12) << 8) | 562 (bits(machInst, 26) << 11); 563 if (rn == 0xf) { 564 return new AdrImm(machInst, rd, (IntRegIndex)1, 565 imm, false); 566 } else { 567 return new AddImm(machInst, rd, rn, imm, true); 568 } 569 } 570 case 0x4: 571 { 572 const uint32_t imm = bits(machInst, 7, 0) | 573 (bits(machInst, 14, 12) << 8) | 574 (bits(machInst, 26) << 11) | 575 (bits(machInst, 19, 16) << 12); 576 return new MovImm(machInst, rd, INTREG_ZERO, imm, true); 577 } 578 case 0xa: 579 { 580 const uint32_t imm = bits(machInst, 7, 0) | 581 (bits(machInst, 14, 12) << 8) | 582 (bits(machInst, 26) << 11); 583 if (rn == 0xf) { 584 return new AdrImm(machInst, rd, (IntRegIndex)0, 585 imm, false); 586 } else { 587 return new SubImm(machInst, rd, rn, imm, true); 588 } 589 } 590 case 0xc: 591 { 592 const uint32_t imm = bits(machInst, 7, 0) | 593 (bits(machInst, 14, 12) << 8) | 594 (bits(machInst, 26) << 11) | 595 (bits(machInst, 19, 16) << 12); 596 return new MovtImm(machInst, rd, rd, imm, true); 597 } 598 case 0x12: 599 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 600 return new WarnUnimplemented("ssat16", machInst); 601 } 602 // Fall through on purpose... 603 case 0x10: 604 return new WarnUnimplemented("ssat", machInst); 605 case 0x14: 606 return new WarnUnimplemented("sbfx", machInst); 607 case 0x16: 608 if (rn == 0xf) { 609 return new WarnUnimplemented("bfc", machInst); 610 } else { 611 return new WarnUnimplemented("bfi", machInst); 612 } 613 case 0x1a: 614 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) { 615 return new WarnUnimplemented("usat16", machInst); 616 } 617 // Fall through on purpose... 618 case 0x18: 619 return new WarnUnimplemented("usat", machInst); 620 case 0x1c: 621 return new WarnUnimplemented("ubfx", machInst); 622 default: 623 return new Unknown(machInst); 624 } 625 } 626 ''' 627}}; 628 629def format Thumb32DataProcShiftReg() {{ 630 631 def decInst(mnem, dest="rd", op1="rn"): 632 return ''' 633 if (s) { 634 return new %(mnem)sRegCc(machInst, %(dest)s, 635 %(op1)s, rm, amt, type); 636 } else { 637 return new %(mnem)sReg(machInst, %(dest)s, 638 %(op1)s, rm, amt, type); 639 } 640 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1} 641 642 decode_block = ''' 643 { 644 const uint32_t op = bits(machInst, 24, 21); 645 const bool s = (bits(machInst, 20) == 1); 646 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 647 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 648 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 649 const uint32_t amt = (bits(machInst, 14, 12) << 2) | 650 bits(machInst, 7, 6); 651 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4); 652 switch (op) { 653 case 0x0: 654 if (rd == INTREG_PC) { 655 %(tst)s 656 } else { 657 %(and)s 658 } 659 case 0x1: 660 %(bic)s 661 case 0x2: 662 if (rn == INTREG_PC) { 663 %(mov)s 664 } else { 665 %(orr)s 666 } 667 case 0x3: 668 if (rn == INTREG_PC) { 669 %(mvn)s 670 } else { 671 %(orn)s 672 } 673 case 0x4: 674 if (rd == INTREG_PC) { 675 %(teq)s 676 } else { 677 %(eor)s 678 } 679 case 0x6: 680 return new WarnUnimplemented("pkh", machInst); 681 case 0x8: 682 if (rd == INTREG_PC) { 683 %(cmn)s 684 } else { 685 %(add)s 686 } 687 case 0xa: 688 %(adc)s 689 case 0xb: 690 %(sbc)s 691 case 0xd: 692 if (rd == INTREG_PC) { 693 %(cmp)s 694 } else { 695 %(sub)s 696 } 697 case 0xe: 698 %(rsb)s 699 default: 700 return new Unknown(machInst); 701 } 702 } 703 ''' % { 704 "tst" : decInst("Tst", "INTREG_ZERO"), 705 "and" : decInst("And"), 706 "bic" : decInst("Bic"), 707 "mov" : decInst("Mov", op1="INTREG_ZERO"), 708 "orr" : decInst("Orr"), 709 "mvn" : decInst("Mvn", op1="INTREG_ZERO"), 710 "orn" : decInst("Orn"), 711 "teq" : decInst("Teq", "INTREG_ZERO"), 712 "eor" : decInst("Eor"), 713 "cmn" : decInst("Cmn", "INTREG_ZERO"), 714 "add" : decInst("Add"), 715 "adc" : decInst("Adc"), 716 "sbc" : decInst("Sbc"), 717 "cmp" : decInst("Cmp", "INTREG_ZERO"), 718 "sub" : decInst("Sub"), 719 "rsb" : decInst("Rsb") 720 } 721}}; 722