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