187 return decode 188 189 def decodePuiw(load, d, size=4, sign=False): 190 global decodePuiwCase 191 decode = "switch (puiw) {\n" 192 for p in (0, 1): 193 for u in (0, 1): 194 for i in (0, 1): 195 for w in (0, 1): 196 decode += decodePuiwCase(load, d, p, u, i, w, 197 size, sign) 198 decode += ''' 199 default: 200 return new Unknown(machInst); 201 } 202 ''' 203 return decode 204 205 subs = { 206 "ldrh" : decodePuiw(True, False, size=2), 207 "strh" : decodePuiw(False, False, size=2), 208 "ldrsb" : decodePuiw(True, False, size=1, sign=True), 209 "ldrd" : decodePuiw(True, True), 210 "ldrsh" : decodePuiw(True, False, size=2, sign=True), 211 "strd" : decodePuiw(False, True) 212 } 213 decode_block = decode % subs 214}}; 215 216def format ArmSyncMem() {{ 217 decode_block = ''' 218 { 219 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 220 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 221 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 222 switch (PUBWL) { 223 case 0x10: 224 return new Swp(machInst, rt, rt2, rn); 225 case 0x14: 226 return new Swpb(machInst, rt, rt2, rn); 227 case 0x18: 228 return new WarnUnimplemented("strex", machInst); 229 case 0x19: 230 return new %(ldrex)s(machInst, rt, rn, true, 0); 231 case 0x1a: 232 return new WarnUnimplemented("strexd", machInst); 233 case 0x1b: 234 return new WarnUnimplemented("ldrexd", machInst); 235 case 0x1c: 236 return new WarnUnimplemented("strexb", machInst); 237 case 0x1d: 238 return new %(ldrexb)s(machInst, rt, rn, true, 0); 239 case 0x1e: 240 return new WarnUnimplemented("strexh", machInst); 241 case 0x1f: 242 return new %(ldrexh)s(machInst, rt, rn, true, 0); 243 default: 244 return new Unknown(machInst); 245 } 246 } 247 ''' % { 248 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 249 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 250 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) 251 } 252}}; 253 254def format Thumb32LdrStrDExTbh() {{ 255 decode_block = ''' 256 { 257 const uint32_t op1 = bits(machInst, 24, 23); 258 const uint32_t op2 = bits(machInst, 21, 20); 259 const uint32_t op3 = bits(machInst, 7, 4); 260 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 261 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 262 /* This isn't used yet, and that makes gcc upset. */ 263 //const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 264 if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 265 if (op1 == 0) { 266 const uint32_t imm = bits(machInst, 7, 0) << 2; 267 if (op2 == 0) { 268 return new WarnUnimplemented("strex", machInst); 269 } else { 270 return new %(ldrex)s(machInst, rt, rn, true, imm); 271 } 272 } else { 273 if (op2 == 0) { 274 switch (op3) { 275 case 0x4: 276 return new WarnUnimplemented("strexb", machInst); 277 case 0x5: 278 return new WarnUnimplemented("strexh", machInst); 279 case 0x7: 280 return new WarnUnimplemented("strexd", machInst); 281 default: 282 return new Unknown(machInst); 283 } 284 } else { 285 switch (op3) { 286 case 0x0: 287 return new WarnUnimplemented("tbb", machInst); 288 case 0x1: 289 return new WarnUnimplemented("tbh", machInst); 290 case 0x4: 291 return new %(ldrexb)s(machInst, rt, rn, true, 0); 292 case 0x5: 293 return new %(ldrexh)s(machInst, rt, rn, true, 0); 294 case 0x7: 295 return new WarnUnimplemented("ldrexd", machInst); 296 default: 297 return new Unknown(machInst); 298 } 299 } 300 } 301 } else { 302 if (bits(op2, 0) == 0) { 303 return new WarnUnimplemented("strd", machInst); 304 } else { 305 return new WarnUnimplemented("ldrd", machInst); 306 } 307 } 308 } 309 ''' % { 310 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 311 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 312 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) 313 } 314}}; 315 316def format Thumb32LoadWord() {{ 317 decode = ''' 318 { 319 uint32_t op1 = bits(machInst, 24, 23); 320 if (bits(op1, 1) == 0) { 321 uint32_t op2 = bits(machInst, 11, 6); 322 if (HTRN == 0xF) { 323 if (UP) { 324 return new %(literal_u)s(machInst, RT, INTREG_PC, 325 true, IMMED_11_0); 326 } else { 327 return new %(literal)s(machInst, RT, INTREG_PC, 328 false, IMMED_11_0); 329 } 330 } else if (op1 == 0x1) { 331 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 332 } else if (op2 == 0) { 333 return new %(register)s(machInst, RT, RN, UP, 334 bits(machInst, 5, 4), LSL, RM); 335 } else if ((op2 & 0x3c) == 0x38) { 336 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 337 } else if ((op2 & 0x3c) == 0x30 || //P 338 (op2 & 0x24) == 0x24) { //W 339 uint32_t puw = bits(machInst, 10, 8); 340 uint32_t imm = IMMED_7_0; 341 switch (puw) { 342 case 0: 343 case 2: 344 // If we're here, either P or W must have been set. 345 panic("Neither P or W set, but that " 346 "shouldn't be possible.\\n"); 347 case 1: 348 return new %(imm_w)s(machInst, RT, RN, false, imm); 349 case 3: 350 return new %(imm_uw)s(machInst, RT, RN, true, imm); 351 case 4: 352 return new %(imm_p)s(machInst, RT, RN, false, imm); 353 case 5: 354 return new %(imm_pw)s(machInst, RT, RN, false, imm); 355 case 6: 356 return new %(imm_pu)s(machInst, RT, RN, true, imm); 357 case 7: 358 return new %(imm_puw)s(machInst, RT, RN, true, imm); 359 } 360 } 361 } else { 362 return new Unknown(machInst); 363 } 364 } 365 ''' 366 classNames = { 367 "literal_u" : loadImmClassName(False, True, False), 368 "literal" : loadImmClassName(False, False, False), 369 "register" : loadRegClassName(False, True, False), 370 "ldrt" : loadImmClassName(False, True, False, user=True), 371 "imm_w" : loadImmClassName(True, False, True), 372 "imm_uw" : loadImmClassName(True, True, True), 373 "imm_p" : loadImmClassName(False, False, False), 374 "imm_pw" : loadImmClassName(False, False, True), 375 "imm_pu" : loadImmClassName(False, True, False), 376 "imm_puw" : loadImmClassName(False, True, True) 377 } 378 decode_block = decode % classNames 379}}; 380 381def format Thumb32StoreSingle() {{ 382 def buildPuwDecode(size): 383 puwDecode = ''' 384 { 385 uint32_t puw = bits(machInst, 10, 8); 386 uint32_t imm = IMMED_7_0; 387 switch (puw) { 388 case 0: 389 case 2: 390 // If we're here, either P or W must have been set. 391 panic("Neither P or W set, but that " 392 "shouldn't be possible.\\n"); 393 case 1: 394 return new %(imm_w)s(machInst, RT, RN, false, imm); 395 case 3: 396 return new %(imm_uw)s(machInst, RT, RN, true, imm); 397 case 4: 398 return new %(imm_p)s(machInst, RT, RN, false, imm); 399 case 5: 400 return new %(imm_pw)s(machInst, RT, RN, false, imm); 401 case 6: 402 return new %(imm_pu)s(machInst, RT, RN, true, imm); 403 case 7: 404 return new %(imm_puw)s(machInst, RT, RN, true, imm); 405 } 406 } 407 ''' 408 return puwDecode % { 409 "imm_w" : storeImmClassName(True, False, True, size=size), 410 "imm_uw" : storeImmClassName(True, True, True, size=size), 411 "imm_p" : storeImmClassName(False, False, False, size=size), 412 "imm_pw" : storeImmClassName(False, False, True, size=size), 413 "imm_pu" : storeImmClassName(False, True, False, size=size), 414 "imm_puw" : storeImmClassName(False, True, True, size=size) 415 } 416 decode = ''' 417 { 418 uint32_t op1 = bits(machInst, 23, 21); 419 uint32_t op2 = bits(machInst, 11, 6); 420 bool op2Puw = ((op2 & 0x24) == 0x24 || 421 (op2 & 0x3c) == 0x30); 422 if (op1 == 4) { 423 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 424 } else if (op1 == 0 && op2Puw) { 425 %(strb_puw)s; 426 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 427 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 428 } else if (op1 == 0 && op2 == 0) { 429 return new %(strb_reg)s(machInst, RT, RN, true, 430 bits(machInst, 5, 4), LSL, RM); 431 } else if (op1 == 5) { 432 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 433 } else if (op1 == 1 && op2Puw) { 434 %(strh_puw)s; 435 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 436 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 437 } else if (op1 == 1 && op2 == 0) { 438 return new %(strh_reg)s(machInst, RT, RN, true, 439 bits(machInst, 5, 4), LSL, RM); 440 } else if (op1 == 6) { 441 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 442 } else if (op1 == 2 && op2Puw) { 443 %(str_puw)s; 444 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 445 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 446 } else if (op1 == 2 && op2 == 0) { 447 return new %(str_reg)s(machInst, RT, RN, true, 448 bits(machInst, 5, 4), LSL, RM); 449 } else { 450 return new Unknown(machInst); 451 } 452 } 453 ''' 454 classNames = { 455 "strb_imm" : storeImmClassName(False, True, False, size=1), 456 "strb_puw" : buildPuwDecode(1), 457 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 458 "strb_reg" : storeRegClassName(False, True, False, size=1), 459 "strh_imm" : storeImmClassName(False, True, False, size=2), 460 "strh_puw" : buildPuwDecode(2), 461 "strht" : storeImmClassName(False, True, False, user=True, size=2), 462 "strh_reg" : storeRegClassName(False, True, False, size=2), 463 "str_imm" : storeImmClassName(False, True, False), 464 "str_puw" : buildPuwDecode(4), 465 "strt" : storeImmClassName(False, True, False, user=True), 466 "str_reg" : storeRegClassName(False, True, False) 467 } 468 decode_block = decode % classNames 469}}; 470 471def format LoadByteMemoryHints() {{ 472 decode = ''' 473 { 474 const uint32_t op1 = bits(machInst, 24, 23); 475 const uint32_t op2 = bits(machInst, 11, 6); 476 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 477 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 478 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 479 const uint32_t imm12 = bits(machInst, 11, 0); 480 const uint32_t imm8 = bits(machInst, 7, 0); 481 bool pldw = bits(machInst, 21); 482 const uint32_t imm2 = bits(machInst, 5, 4); 483 if (rn == 0xf) { 484 if (rt == 0xf) { 485 const bool add = bits(machInst, 23); 486 if (bits(op1, 1) == 1) { 487 if (add) { 488 return new %(pli_iulit)s(machInst, INTREG_ZERO, 489 INTREG_PC, true, imm12); 490 } else { 491 return new %(pli_ilit)s(machInst, INTREG_ZERO, 492 INTREG_PC, false, imm12); 493 } 494 } else { 495 if (add) { 496 return new %(pld_iulit)s(machInst, INTREG_ZERO, 497 INTREG_PC, true, imm12); 498 } else { 499 return new %(pld_ilit)s(machInst, INTREG_ZERO, 500 INTREG_PC, false, imm12); 501 } 502 } 503 } else { 504 if (bits(op1, 1) == 1) { 505 if (bits(machInst, 23)) { 506 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 507 true, imm12); 508 } else { 509 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 510 false, imm12); 511 } 512 } else { 513 if (bits(machInst, 23)) { 514 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 515 true, imm12); 516 } else { 517 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 518 false, imm12); 519 } 520 } 521 } 522 } else if (rt == 0xf) { 523 switch (op1) { 524 case 0x0: 525 if (op2 == 0x0) { 526 if (pldw) { 527 return new %(pldw_radd)s(machInst, INTREG_ZERO, 528 rn, true, imm2, LSL, rm); 529 } else { 530 return new %(pld_radd)s(machInst, INTREG_ZERO, 531 rn, true, imm2, LSL, rm); 532 } 533 } else if (bits(op2, 5, 2) == 0xc) { 534 if (pldw) { 535 return new %(pldw_isub)s(machInst, INTREG_ZERO, 536 rn, false, imm8); 537 } else { 538 return new %(pld_isub)s(machInst, INTREG_ZERO, 539 rn, false, imm8); 540 } 541 } 542 break; 543 case 0x1: 544 if (pldw) { 545 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 546 rn, true, imm12); 547 } else { 548 return new %(pld_iadd)s(machInst, INTREG_ZERO, 549 rn, true, imm12); 550 } 551 case 0x2: 552 if (op2 == 0x0) { 553 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 554 true, imm2, LSL, rm); 555 } else if (bits(op2, 5, 2) == 0xc) { 556 return new %(pli_ilit)s(machInst, INTREG_ZERO, 557 INTREG_PC, false, imm8); 558 } 559 break; 560 case 0x3: 561 return new %(pli_iulit)s(machInst, INTREG_ZERO, 562 INTREG_PC, true, imm12); 563 } 564 return new Unknown(machInst); 565 } else { 566 switch (op1) { 567 case 0x0: 568 if (op2 == 0) { 569 return new %(ldrb_radd)s(machInst, rt, rn, true, 570 imm2, LSL, rm); 571 } else if (bits(op2, 5, 2) == 0xe) { 572 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 573 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 574 const uint32_t puw = bits(machInst, 10, 8); 575 switch (puw) { 576 case 0x1: 577 return new %(ldrb_iw)s(machInst, rt, 578 rn, false, imm8); 579 case 0x3: 580 return new %(ldrb_iuw)s(machInst, rt, 581 rn, true, imm8); 582 case 0x4: 583 return new %(ldrb_ip)s(machInst, rt, 584 rn, false, imm8); 585 case 0x5: 586 return new %(ldrb_ipw)s(machInst, rt, 587 rn, false, imm8); 588 case 0x7: 589 return new %(ldrb_ipuw)s(machInst, rt, 590 rn, true, imm8); 591 } 592 } 593 break; 594 case 0x1: 595 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 596 case 0x2: 597 if (op2 == 0) { 598 return new %(ldrsb_radd)s(machInst, rt, rn, true, 599 imm2, LSL, rm); 600 } else if (bits(op2, 5, 2) == 0xe) { 601 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 602 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 603 const uint32_t puw = bits(machInst, 10, 8); 604 switch (puw) { 605 case 0x1: 606 return new %(ldrsb_iw)s(machInst, rt, 607 rn, false, imm8); 608 case 0x3: 609 return new %(ldrsb_iuw)s(machInst, rt, 610 rn, true, imm8); 611 case 0x4: 612 return new %(ldrsb_ip)s(machInst, rt, 613 rn, false, imm8); 614 case 0x5: 615 return new %(ldrsb_ipw)s(machInst, rt, 616 rn, false, imm8); 617 case 0x7: 618 return new %(ldrsb_ipuw)s(machInst, rt, 619 rn, true, imm8); 620 } 621 } 622 break; 623 case 0x3: 624 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 625 } 626 return new Unknown(machInst); 627 } 628 } 629 ''' 630 substDict = { 631 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 632 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 633 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 634 "ldrb_lit" : loadImmClassName(False, False, False, 1), 635 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 636 "ldrb_radd" : loadRegClassName(False, True, False, 1), 637 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 638 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 639 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 640 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 641 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 642 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 643 "ldrb_iw" : loadImmClassName(True, False, True, 1), 644 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 645 "ldrb_ip" : loadImmClassName(False, False, False, 1), 646 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 647 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 648 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 649 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 650 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 651 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 652 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 653 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 654 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 655 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 656 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 657 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 658 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 659 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 660 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 661 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 662 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 663 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 664 } 665 decode_block = decode % substDict 666}}; 667 668def format LoadHalfwordMemoryHints() {{ 669 decode = ''' 670 { 671 const uint32_t op1 = bits(machInst, 24, 23); 672 const uint32_t op2 = bits(machInst, 11, 6); 673 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 674 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 675 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 676 const uint32_t imm12 = bits(machInst, 11, 0); 677 const uint32_t imm8 = bits(machInst, 7, 0); 678 bool pldw = bits(machInst, 21); 679 const uint32_t imm2 = bits(machInst, 5, 4); 680 if (rn == 0xf) { 681 if (rt == 0xf) { 682 if (bits(op1, 1) == 1) { 683 // Unallocated memory hint 684 return new NopInst(machInst); 685 } else { 686 return new Unknown(machInst); 687 } 688 } else { 689 if (bits(op1, 1) == 1) { 690 if (bits(machInst, 23)) { 691 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 692 true, imm12); 693 } else { 694 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 695 false, imm12); 696 } 697 } else { 698 if (bits(machInst, 23)) { 699 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 700 true, imm12); 701 } else { 702 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 703 false, imm12); 704 } 705 } 706 } 707 } else if (rt == 0xf) { 708 switch (op1) { 709 case 0x0: 710 if (op2 == 0x0) { 711 if (pldw) { 712 return new %(pldw_radd)s(machInst, INTREG_ZERO, 713 rn, true, imm2, LSL, rm); 714 } else { 715 return new %(pld_radd)s(machInst, INTREG_ZERO, 716 rn, true, imm2, LSL, rm); 717 } 718 } else if (bits(op2, 5, 2) == 0xc) { 719 if (pldw) { 720 return new %(pldw_isub)s(machInst, INTREG_ZERO, 721 rn, false, imm8); 722 } else { 723 return new %(pld_isub)s(machInst, INTREG_ZERO, 724 rn, false, imm8); 725 } 726 } 727 break; 728 case 0x1: 729 if (pldw) { 730 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 731 rn, true, imm12); 732 } else { 733 return new %(pld_iadd)s(machInst, INTREG_ZERO, 734 rn, true, imm12); 735 } 736 case 0x2: 737 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 738 // Unallocated memory hint 739 return new NopInst(machInst); 740 } 741 break; 742 case 0x3: 743 return new NopInst(machInst); 744 } 745 return new Unknown(machInst); 746 } else { 747 switch (op1) { 748 case 0x0: 749 if (op2 == 0) { 750 return new %(ldrh_radd)s(machInst, rt, rn, true, 751 imm2, LSL, rm); 752 } else if (bits(op2, 5, 2) == 0xe) { 753 return new %(ldrht)s(machInst, rt, rn, true, imm8); 754 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 755 const uint32_t puw = bits(machInst, 10, 8); 756 switch (puw) { 757 case 0x1: 758 return new %(ldrh_iw)s(machInst, rt, 759 rn, false, imm8); 760 case 0x3: 761 return new %(ldrh_iuw)s(machInst, rt, 762 rn, true, imm8); 763 case 0x4: 764 return new %(ldrh_ip)s(machInst, rt, 765 rn, false, imm8); 766 case 0x5: 767 return new %(ldrh_ipw)s(machInst, rt, 768 rn, false, imm8); 769 case 0x7: 770 return new %(ldrh_ipuw)s(machInst, rt, 771 rn, true, imm8); 772 } 773 } 774 break; 775 case 0x1: 776 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 777 case 0x2: 778 if (op2 == 0) { 779 return new %(ldrsh_radd)s(machInst, rt, rn, true, 780 imm2, LSL, rm); 781 } else if (bits(op2, 5, 2) == 0xe) { 782 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 783 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 784 const uint32_t puw = bits(machInst, 10, 8); 785 switch (puw) { 786 case 0x1: 787 return new %(ldrsh_iw)s(machInst, rt, 788 rn, false, imm8); 789 case 0x3: 790 return new %(ldrsh_iuw)s(machInst, rt, 791 rn, true, imm8); 792 case 0x4: 793 return new %(ldrsh_ip)s(machInst, rt, 794 rn, false, imm8); 795 case 0x5: 796 return new %(ldrsh_ipw)s(machInst, rt, 797 rn, false, imm8); 798 case 0x7: 799 return new %(ldrsh_ipuw)s(machInst, rt, 800 rn, true, imm8); 801 } 802 } 803 break; 804 case 0x3: 805 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 806 } 807 return new Unknown(machInst); 808 } 809 } 810 ''' 811 substDict = { 812 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 813 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 814 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 815 "ldrh_lit" : loadImmClassName(False, False, False, 2), 816 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 817 "ldrh_radd" : loadRegClassName(False, True, False, 2), 818 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 819 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 820 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 821 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 822 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 823 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 824 "ldrh_iw" : loadImmClassName(True, False, True, 2), 825 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 826 "ldrh_ip" : loadImmClassName(False, False, False, 2), 827 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 828 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 829 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 830 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 831 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 832 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 833 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 834 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 835 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 836 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 837 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 838 } 839 decode_block = decode % substDict 840}}; 841 842def format Thumb16MemReg() {{ 843 decode = ''' 844 { 845 const uint32_t opb = bits(machInst, 11, 9); 846 const uint32_t rt = bits(machInst, 2, 0); 847 const uint32_t rn = bits(machInst, 5, 3); 848 const uint32_t rm = bits(machInst, 8, 6); 849 switch (opb) { 850 case 0x0: 851 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 852 case 0x1: 853 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 854 case 0x2: 855 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 856 case 0x3: 857 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 858 case 0x4: 859 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 860 case 0x5: 861 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 862 case 0x6: 863 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 864 case 0x7: 865 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 866 } 867 } 868 ''' 869 classNames = { 870 "str" : storeRegClassName(False, True, False), 871 "strh" : storeRegClassName(False, True, False, size=2), 872 "strb" : storeRegClassName(False, True, False, size=1), 873 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 874 "ldr" : loadRegClassName(False, True, False), 875 "ldrh" : loadRegClassName(False, True, False, size=2), 876 "ldrb" : loadRegClassName(False, True, False, size=1), 877 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 878 } 879 decode_block = decode % classNames 880}}; 881 882def format Thumb16MemImm() {{ 883 decode = ''' 884 { 885 const uint32_t opa = bits(machInst, 15, 12); 886 const uint32_t opb = bits(machInst, 11, 9); 887 const uint32_t lrt = bits(machInst, 2, 0); 888 const uint32_t lrn = bits(machInst, 5, 3); 889 const uint32_t hrt = bits(machInst, 10, 8); 890 const uint32_t imm5 = bits(machInst, 10, 6); 891 const uint32_t imm8 = bits(machInst, 7, 0); 892 const bool load = bits(opb, 2); 893 switch (opa) { 894 case 0x6: 895 if (load) { 896 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 897 } else { 898 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 899 } 900 case 0x7: 901 if (load) { 902 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 903 } else { 904 return new %(strb)s(machInst, lrt, lrn, true, imm5); 905 } 906 case 0x8: 907 if (load) { 908 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 909 } else { 910 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 911 } 912 case 0x9: 913 if (load) { 914 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 915 } else { 916 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 917 } 918 default: 919 return new Unknown(machInst); 920 } 921 } 922 ''' 923 classNames = { 924 "ldr" : loadImmClassName(False, True, False), 925 "str" : storeImmClassName(False, True, False), 926 "ldrh" : loadImmClassName(False, True, False, size=2), 927 "strh" : storeImmClassName(False, True, False, size=2), 928 "ldrb" : loadImmClassName(False, True, False, size=1), 929 "strb" : storeImmClassName(False, True, False, size=1), 930 } 931 decode_block = decode % classNames 932}}; 933 934def format Thumb16MemLit() {{ 935 decode_block = ''' 936 { 937 const uint32_t rt = bits(machInst, 10, 8); 938 const uint32_t imm8 = bits(machInst, 7, 0); 939 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 940 } 941 ''' % loadImmClassName(False, True, False) 942}}; 943
| 191 return decode 192 193 def decodePuiw(load, d, size=4, sign=False): 194 global decodePuiwCase 195 decode = "switch (puiw) {\n" 196 for p in (0, 1): 197 for u in (0, 1): 198 for i in (0, 1): 199 for w in (0, 1): 200 decode += decodePuiwCase(load, d, p, u, i, w, 201 size, sign) 202 decode += ''' 203 default: 204 return new Unknown(machInst); 205 } 206 ''' 207 return decode 208 209 subs = { 210 "ldrh" : decodePuiw(True, False, size=2), 211 "strh" : decodePuiw(False, False, size=2), 212 "ldrsb" : decodePuiw(True, False, size=1, sign=True), 213 "ldrd" : decodePuiw(True, True), 214 "ldrsh" : decodePuiw(True, False, size=2, sign=True), 215 "strd" : decodePuiw(False, True) 216 } 217 decode_block = decode % subs 218}}; 219 220def format ArmSyncMem() {{ 221 decode_block = ''' 222 { 223 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 224 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 225 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 226 switch (PUBWL) { 227 case 0x10: 228 return new Swp(machInst, rt, rt2, rn); 229 case 0x14: 230 return new Swpb(machInst, rt, rt2, rn); 231 case 0x18: 232 return new WarnUnimplemented("strex", machInst); 233 case 0x19: 234 return new %(ldrex)s(machInst, rt, rn, true, 0); 235 case 0x1a: 236 return new WarnUnimplemented("strexd", machInst); 237 case 0x1b: 238 return new WarnUnimplemented("ldrexd", machInst); 239 case 0x1c: 240 return new WarnUnimplemented("strexb", machInst); 241 case 0x1d: 242 return new %(ldrexb)s(machInst, rt, rn, true, 0); 243 case 0x1e: 244 return new WarnUnimplemented("strexh", machInst); 245 case 0x1f: 246 return new %(ldrexh)s(machInst, rt, rn, true, 0); 247 default: 248 return new Unknown(machInst); 249 } 250 } 251 ''' % { 252 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 253 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 254 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) 255 } 256}}; 257 258def format Thumb32LdrStrDExTbh() {{ 259 decode_block = ''' 260 { 261 const uint32_t op1 = bits(machInst, 24, 23); 262 const uint32_t op2 = bits(machInst, 21, 20); 263 const uint32_t op3 = bits(machInst, 7, 4); 264 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 265 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 266 /* This isn't used yet, and that makes gcc upset. */ 267 //const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 268 if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 269 if (op1 == 0) { 270 const uint32_t imm = bits(machInst, 7, 0) << 2; 271 if (op2 == 0) { 272 return new WarnUnimplemented("strex", machInst); 273 } else { 274 return new %(ldrex)s(machInst, rt, rn, true, imm); 275 } 276 } else { 277 if (op2 == 0) { 278 switch (op3) { 279 case 0x4: 280 return new WarnUnimplemented("strexb", machInst); 281 case 0x5: 282 return new WarnUnimplemented("strexh", machInst); 283 case 0x7: 284 return new WarnUnimplemented("strexd", machInst); 285 default: 286 return new Unknown(machInst); 287 } 288 } else { 289 switch (op3) { 290 case 0x0: 291 return new WarnUnimplemented("tbb", machInst); 292 case 0x1: 293 return new WarnUnimplemented("tbh", machInst); 294 case 0x4: 295 return new %(ldrexb)s(machInst, rt, rn, true, 0); 296 case 0x5: 297 return new %(ldrexh)s(machInst, rt, rn, true, 0); 298 case 0x7: 299 return new WarnUnimplemented("ldrexd", machInst); 300 default: 301 return new Unknown(machInst); 302 } 303 } 304 } 305 } else { 306 if (bits(op2, 0) == 0) { 307 return new WarnUnimplemented("strd", machInst); 308 } else { 309 return new WarnUnimplemented("ldrd", machInst); 310 } 311 } 312 } 313 ''' % { 314 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 315 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 316 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) 317 } 318}}; 319 320def format Thumb32LoadWord() {{ 321 decode = ''' 322 { 323 uint32_t op1 = bits(machInst, 24, 23); 324 if (bits(op1, 1) == 0) { 325 uint32_t op2 = bits(machInst, 11, 6); 326 if (HTRN == 0xF) { 327 if (UP) { 328 return new %(literal_u)s(machInst, RT, INTREG_PC, 329 true, IMMED_11_0); 330 } else { 331 return new %(literal)s(machInst, RT, INTREG_PC, 332 false, IMMED_11_0); 333 } 334 } else if (op1 == 0x1) { 335 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 336 } else if (op2 == 0) { 337 return new %(register)s(machInst, RT, RN, UP, 338 bits(machInst, 5, 4), LSL, RM); 339 } else if ((op2 & 0x3c) == 0x38) { 340 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 341 } else if ((op2 & 0x3c) == 0x30 || //P 342 (op2 & 0x24) == 0x24) { //W 343 uint32_t puw = bits(machInst, 10, 8); 344 uint32_t imm = IMMED_7_0; 345 switch (puw) { 346 case 0: 347 case 2: 348 // If we're here, either P or W must have been set. 349 panic("Neither P or W set, but that " 350 "shouldn't be possible.\\n"); 351 case 1: 352 return new %(imm_w)s(machInst, RT, RN, false, imm); 353 case 3: 354 return new %(imm_uw)s(machInst, RT, RN, true, imm); 355 case 4: 356 return new %(imm_p)s(machInst, RT, RN, false, imm); 357 case 5: 358 return new %(imm_pw)s(machInst, RT, RN, false, imm); 359 case 6: 360 return new %(imm_pu)s(machInst, RT, RN, true, imm); 361 case 7: 362 return new %(imm_puw)s(machInst, RT, RN, true, imm); 363 } 364 } 365 } else { 366 return new Unknown(machInst); 367 } 368 } 369 ''' 370 classNames = { 371 "literal_u" : loadImmClassName(False, True, False), 372 "literal" : loadImmClassName(False, False, False), 373 "register" : loadRegClassName(False, True, False), 374 "ldrt" : loadImmClassName(False, True, False, user=True), 375 "imm_w" : loadImmClassName(True, False, True), 376 "imm_uw" : loadImmClassName(True, True, True), 377 "imm_p" : loadImmClassName(False, False, False), 378 "imm_pw" : loadImmClassName(False, False, True), 379 "imm_pu" : loadImmClassName(False, True, False), 380 "imm_puw" : loadImmClassName(False, True, True) 381 } 382 decode_block = decode % classNames 383}}; 384 385def format Thumb32StoreSingle() {{ 386 def buildPuwDecode(size): 387 puwDecode = ''' 388 { 389 uint32_t puw = bits(machInst, 10, 8); 390 uint32_t imm = IMMED_7_0; 391 switch (puw) { 392 case 0: 393 case 2: 394 // If we're here, either P or W must have been set. 395 panic("Neither P or W set, but that " 396 "shouldn't be possible.\\n"); 397 case 1: 398 return new %(imm_w)s(machInst, RT, RN, false, imm); 399 case 3: 400 return new %(imm_uw)s(machInst, RT, RN, true, imm); 401 case 4: 402 return new %(imm_p)s(machInst, RT, RN, false, imm); 403 case 5: 404 return new %(imm_pw)s(machInst, RT, RN, false, imm); 405 case 6: 406 return new %(imm_pu)s(machInst, RT, RN, true, imm); 407 case 7: 408 return new %(imm_puw)s(machInst, RT, RN, true, imm); 409 } 410 } 411 ''' 412 return puwDecode % { 413 "imm_w" : storeImmClassName(True, False, True, size=size), 414 "imm_uw" : storeImmClassName(True, True, True, size=size), 415 "imm_p" : storeImmClassName(False, False, False, size=size), 416 "imm_pw" : storeImmClassName(False, False, True, size=size), 417 "imm_pu" : storeImmClassName(False, True, False, size=size), 418 "imm_puw" : storeImmClassName(False, True, True, size=size) 419 } 420 decode = ''' 421 { 422 uint32_t op1 = bits(machInst, 23, 21); 423 uint32_t op2 = bits(machInst, 11, 6); 424 bool op2Puw = ((op2 & 0x24) == 0x24 || 425 (op2 & 0x3c) == 0x30); 426 if (op1 == 4) { 427 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 428 } else if (op1 == 0 && op2Puw) { 429 %(strb_puw)s; 430 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 431 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 432 } else if (op1 == 0 && op2 == 0) { 433 return new %(strb_reg)s(machInst, RT, RN, true, 434 bits(machInst, 5, 4), LSL, RM); 435 } else if (op1 == 5) { 436 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 437 } else if (op1 == 1 && op2Puw) { 438 %(strh_puw)s; 439 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 440 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 441 } else if (op1 == 1 && op2 == 0) { 442 return new %(strh_reg)s(machInst, RT, RN, true, 443 bits(machInst, 5, 4), LSL, RM); 444 } else if (op1 == 6) { 445 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 446 } else if (op1 == 2 && op2Puw) { 447 %(str_puw)s; 448 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 449 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 450 } else if (op1 == 2 && op2 == 0) { 451 return new %(str_reg)s(machInst, RT, RN, true, 452 bits(machInst, 5, 4), LSL, RM); 453 } else { 454 return new Unknown(machInst); 455 } 456 } 457 ''' 458 classNames = { 459 "strb_imm" : storeImmClassName(False, True, False, size=1), 460 "strb_puw" : buildPuwDecode(1), 461 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 462 "strb_reg" : storeRegClassName(False, True, False, size=1), 463 "strh_imm" : storeImmClassName(False, True, False, size=2), 464 "strh_puw" : buildPuwDecode(2), 465 "strht" : storeImmClassName(False, True, False, user=True, size=2), 466 "strh_reg" : storeRegClassName(False, True, False, size=2), 467 "str_imm" : storeImmClassName(False, True, False), 468 "str_puw" : buildPuwDecode(4), 469 "strt" : storeImmClassName(False, True, False, user=True), 470 "str_reg" : storeRegClassName(False, True, False) 471 } 472 decode_block = decode % classNames 473}}; 474 475def format LoadByteMemoryHints() {{ 476 decode = ''' 477 { 478 const uint32_t op1 = bits(machInst, 24, 23); 479 const uint32_t op2 = bits(machInst, 11, 6); 480 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 481 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 482 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 483 const uint32_t imm12 = bits(machInst, 11, 0); 484 const uint32_t imm8 = bits(machInst, 7, 0); 485 bool pldw = bits(machInst, 21); 486 const uint32_t imm2 = bits(machInst, 5, 4); 487 if (rn == 0xf) { 488 if (rt == 0xf) { 489 const bool add = bits(machInst, 23); 490 if (bits(op1, 1) == 1) { 491 if (add) { 492 return new %(pli_iulit)s(machInst, INTREG_ZERO, 493 INTREG_PC, true, imm12); 494 } else { 495 return new %(pli_ilit)s(machInst, INTREG_ZERO, 496 INTREG_PC, false, imm12); 497 } 498 } else { 499 if (add) { 500 return new %(pld_iulit)s(machInst, INTREG_ZERO, 501 INTREG_PC, true, imm12); 502 } else { 503 return new %(pld_ilit)s(machInst, INTREG_ZERO, 504 INTREG_PC, false, imm12); 505 } 506 } 507 } else { 508 if (bits(op1, 1) == 1) { 509 if (bits(machInst, 23)) { 510 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 511 true, imm12); 512 } else { 513 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 514 false, imm12); 515 } 516 } else { 517 if (bits(machInst, 23)) { 518 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 519 true, imm12); 520 } else { 521 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 522 false, imm12); 523 } 524 } 525 } 526 } else if (rt == 0xf) { 527 switch (op1) { 528 case 0x0: 529 if (op2 == 0x0) { 530 if (pldw) { 531 return new %(pldw_radd)s(machInst, INTREG_ZERO, 532 rn, true, imm2, LSL, rm); 533 } else { 534 return new %(pld_radd)s(machInst, INTREG_ZERO, 535 rn, true, imm2, LSL, rm); 536 } 537 } else if (bits(op2, 5, 2) == 0xc) { 538 if (pldw) { 539 return new %(pldw_isub)s(machInst, INTREG_ZERO, 540 rn, false, imm8); 541 } else { 542 return new %(pld_isub)s(machInst, INTREG_ZERO, 543 rn, false, imm8); 544 } 545 } 546 break; 547 case 0x1: 548 if (pldw) { 549 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 550 rn, true, imm12); 551 } else { 552 return new %(pld_iadd)s(machInst, INTREG_ZERO, 553 rn, true, imm12); 554 } 555 case 0x2: 556 if (op2 == 0x0) { 557 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 558 true, imm2, LSL, rm); 559 } else if (bits(op2, 5, 2) == 0xc) { 560 return new %(pli_ilit)s(machInst, INTREG_ZERO, 561 INTREG_PC, false, imm8); 562 } 563 break; 564 case 0x3: 565 return new %(pli_iulit)s(machInst, INTREG_ZERO, 566 INTREG_PC, true, imm12); 567 } 568 return new Unknown(machInst); 569 } else { 570 switch (op1) { 571 case 0x0: 572 if (op2 == 0) { 573 return new %(ldrb_radd)s(machInst, rt, rn, true, 574 imm2, LSL, rm); 575 } else if (bits(op2, 5, 2) == 0xe) { 576 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 577 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 578 const uint32_t puw = bits(machInst, 10, 8); 579 switch (puw) { 580 case 0x1: 581 return new %(ldrb_iw)s(machInst, rt, 582 rn, false, imm8); 583 case 0x3: 584 return new %(ldrb_iuw)s(machInst, rt, 585 rn, true, imm8); 586 case 0x4: 587 return new %(ldrb_ip)s(machInst, rt, 588 rn, false, imm8); 589 case 0x5: 590 return new %(ldrb_ipw)s(machInst, rt, 591 rn, false, imm8); 592 case 0x7: 593 return new %(ldrb_ipuw)s(machInst, rt, 594 rn, true, imm8); 595 } 596 } 597 break; 598 case 0x1: 599 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 600 case 0x2: 601 if (op2 == 0) { 602 return new %(ldrsb_radd)s(machInst, rt, rn, true, 603 imm2, LSL, rm); 604 } else if (bits(op2, 5, 2) == 0xe) { 605 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 606 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 607 const uint32_t puw = bits(machInst, 10, 8); 608 switch (puw) { 609 case 0x1: 610 return new %(ldrsb_iw)s(machInst, rt, 611 rn, false, imm8); 612 case 0x3: 613 return new %(ldrsb_iuw)s(machInst, rt, 614 rn, true, imm8); 615 case 0x4: 616 return new %(ldrsb_ip)s(machInst, rt, 617 rn, false, imm8); 618 case 0x5: 619 return new %(ldrsb_ipw)s(machInst, rt, 620 rn, false, imm8); 621 case 0x7: 622 return new %(ldrsb_ipuw)s(machInst, rt, 623 rn, true, imm8); 624 } 625 } 626 break; 627 case 0x3: 628 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 629 } 630 return new Unknown(machInst); 631 } 632 } 633 ''' 634 substDict = { 635 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 636 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 637 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 638 "ldrb_lit" : loadImmClassName(False, False, False, 1), 639 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 640 "ldrb_radd" : loadRegClassName(False, True, False, 1), 641 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 642 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 643 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 644 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 645 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 646 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 647 "ldrb_iw" : loadImmClassName(True, False, True, 1), 648 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 649 "ldrb_ip" : loadImmClassName(False, False, False, 1), 650 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 651 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 652 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 653 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 654 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 655 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 656 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 657 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 658 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 659 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 660 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 661 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 662 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 663 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 664 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 665 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 666 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 667 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 668 } 669 decode_block = decode % substDict 670}}; 671 672def format LoadHalfwordMemoryHints() {{ 673 decode = ''' 674 { 675 const uint32_t op1 = bits(machInst, 24, 23); 676 const uint32_t op2 = bits(machInst, 11, 6); 677 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 678 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 679 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 680 const uint32_t imm12 = bits(machInst, 11, 0); 681 const uint32_t imm8 = bits(machInst, 7, 0); 682 bool pldw = bits(machInst, 21); 683 const uint32_t imm2 = bits(machInst, 5, 4); 684 if (rn == 0xf) { 685 if (rt == 0xf) { 686 if (bits(op1, 1) == 1) { 687 // Unallocated memory hint 688 return new NopInst(machInst); 689 } else { 690 return new Unknown(machInst); 691 } 692 } else { 693 if (bits(op1, 1) == 1) { 694 if (bits(machInst, 23)) { 695 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 696 true, imm12); 697 } else { 698 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 699 false, imm12); 700 } 701 } else { 702 if (bits(machInst, 23)) { 703 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 704 true, imm12); 705 } else { 706 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 707 false, imm12); 708 } 709 } 710 } 711 } else if (rt == 0xf) { 712 switch (op1) { 713 case 0x0: 714 if (op2 == 0x0) { 715 if (pldw) { 716 return new %(pldw_radd)s(machInst, INTREG_ZERO, 717 rn, true, imm2, LSL, rm); 718 } else { 719 return new %(pld_radd)s(machInst, INTREG_ZERO, 720 rn, true, imm2, LSL, rm); 721 } 722 } else if (bits(op2, 5, 2) == 0xc) { 723 if (pldw) { 724 return new %(pldw_isub)s(machInst, INTREG_ZERO, 725 rn, false, imm8); 726 } else { 727 return new %(pld_isub)s(machInst, INTREG_ZERO, 728 rn, false, imm8); 729 } 730 } 731 break; 732 case 0x1: 733 if (pldw) { 734 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 735 rn, true, imm12); 736 } else { 737 return new %(pld_iadd)s(machInst, INTREG_ZERO, 738 rn, true, imm12); 739 } 740 case 0x2: 741 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 742 // Unallocated memory hint 743 return new NopInst(machInst); 744 } 745 break; 746 case 0x3: 747 return new NopInst(machInst); 748 } 749 return new Unknown(machInst); 750 } else { 751 switch (op1) { 752 case 0x0: 753 if (op2 == 0) { 754 return new %(ldrh_radd)s(machInst, rt, rn, true, 755 imm2, LSL, rm); 756 } else if (bits(op2, 5, 2) == 0xe) { 757 return new %(ldrht)s(machInst, rt, rn, true, imm8); 758 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 759 const uint32_t puw = bits(machInst, 10, 8); 760 switch (puw) { 761 case 0x1: 762 return new %(ldrh_iw)s(machInst, rt, 763 rn, false, imm8); 764 case 0x3: 765 return new %(ldrh_iuw)s(machInst, rt, 766 rn, true, imm8); 767 case 0x4: 768 return new %(ldrh_ip)s(machInst, rt, 769 rn, false, imm8); 770 case 0x5: 771 return new %(ldrh_ipw)s(machInst, rt, 772 rn, false, imm8); 773 case 0x7: 774 return new %(ldrh_ipuw)s(machInst, rt, 775 rn, true, imm8); 776 } 777 } 778 break; 779 case 0x1: 780 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 781 case 0x2: 782 if (op2 == 0) { 783 return new %(ldrsh_radd)s(machInst, rt, rn, true, 784 imm2, LSL, rm); 785 } else if (bits(op2, 5, 2) == 0xe) { 786 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 787 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 788 const uint32_t puw = bits(machInst, 10, 8); 789 switch (puw) { 790 case 0x1: 791 return new %(ldrsh_iw)s(machInst, rt, 792 rn, false, imm8); 793 case 0x3: 794 return new %(ldrsh_iuw)s(machInst, rt, 795 rn, true, imm8); 796 case 0x4: 797 return new %(ldrsh_ip)s(machInst, rt, 798 rn, false, imm8); 799 case 0x5: 800 return new %(ldrsh_ipw)s(machInst, rt, 801 rn, false, imm8); 802 case 0x7: 803 return new %(ldrsh_ipuw)s(machInst, rt, 804 rn, true, imm8); 805 } 806 } 807 break; 808 case 0x3: 809 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 810 } 811 return new Unknown(machInst); 812 } 813 } 814 ''' 815 substDict = { 816 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 817 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 818 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 819 "ldrh_lit" : loadImmClassName(False, False, False, 2), 820 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 821 "ldrh_radd" : loadRegClassName(False, True, False, 2), 822 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 823 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 824 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 825 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 826 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 827 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 828 "ldrh_iw" : loadImmClassName(True, False, True, 2), 829 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 830 "ldrh_ip" : loadImmClassName(False, False, False, 2), 831 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 832 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 833 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 834 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 835 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 836 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 837 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 838 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 839 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 840 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 841 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 842 } 843 decode_block = decode % substDict 844}}; 845 846def format Thumb16MemReg() {{ 847 decode = ''' 848 { 849 const uint32_t opb = bits(machInst, 11, 9); 850 const uint32_t rt = bits(machInst, 2, 0); 851 const uint32_t rn = bits(machInst, 5, 3); 852 const uint32_t rm = bits(machInst, 8, 6); 853 switch (opb) { 854 case 0x0: 855 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 856 case 0x1: 857 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 858 case 0x2: 859 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 860 case 0x3: 861 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 862 case 0x4: 863 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 864 case 0x5: 865 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 866 case 0x6: 867 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 868 case 0x7: 869 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 870 } 871 } 872 ''' 873 classNames = { 874 "str" : storeRegClassName(False, True, False), 875 "strh" : storeRegClassName(False, True, False, size=2), 876 "strb" : storeRegClassName(False, True, False, size=1), 877 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 878 "ldr" : loadRegClassName(False, True, False), 879 "ldrh" : loadRegClassName(False, True, False, size=2), 880 "ldrb" : loadRegClassName(False, True, False, size=1), 881 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 882 } 883 decode_block = decode % classNames 884}}; 885 886def format Thumb16MemImm() {{ 887 decode = ''' 888 { 889 const uint32_t opa = bits(machInst, 15, 12); 890 const uint32_t opb = bits(machInst, 11, 9); 891 const uint32_t lrt = bits(machInst, 2, 0); 892 const uint32_t lrn = bits(machInst, 5, 3); 893 const uint32_t hrt = bits(machInst, 10, 8); 894 const uint32_t imm5 = bits(machInst, 10, 6); 895 const uint32_t imm8 = bits(machInst, 7, 0); 896 const bool load = bits(opb, 2); 897 switch (opa) { 898 case 0x6: 899 if (load) { 900 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 901 } else { 902 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 903 } 904 case 0x7: 905 if (load) { 906 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 907 } else { 908 return new %(strb)s(machInst, lrt, lrn, true, imm5); 909 } 910 case 0x8: 911 if (load) { 912 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 913 } else { 914 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 915 } 916 case 0x9: 917 if (load) { 918 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 919 } else { 920 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 921 } 922 default: 923 return new Unknown(machInst); 924 } 925 } 926 ''' 927 classNames = { 928 "ldr" : loadImmClassName(False, True, False), 929 "str" : storeImmClassName(False, True, False), 930 "ldrh" : loadImmClassName(False, True, False, size=2), 931 "strh" : storeImmClassName(False, True, False, size=2), 932 "ldrb" : loadImmClassName(False, True, False, size=1), 933 "strb" : storeImmClassName(False, True, False, size=1), 934 } 935 decode_block = decode % classNames 936}}; 937 938def format Thumb16MemLit() {{ 939 decode_block = ''' 940 { 941 const uint32_t rt = bits(machInst, 10, 8); 942 const uint32_t imm8 = bits(machInst, 7, 0); 943 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 944 } 945 ''' % loadImmClassName(False, True, False) 946}}; 947
|