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