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