returns TRUE - if this IL continues FALSE - if this IL terminates a block */
| 527 | /* returns TRUE - if this IL continues |
| 528 | FALSE - if this IL terminates a block */ |
| 529 | bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il, |
| 530 | const uint8_t* data, uint64_t addr, decomp_result *res, bool le) |
| 531 | { |
| 532 | int i; |
| 533 | bool rc = true; |
| 534 | struct cs_insn *insn = 0; |
| 535 | struct cs_detail *detail = 0; |
| 536 | struct cs_ppc *ppc = 0; |
| 537 | size_t addressSize_l = 0; |
| 538 | int extend_l = 0; |
| 539 | uint32_t rawInsn = *(const uint32_t *) data; |
| 540 | |
| 541 | // for ppc_ps |
| 542 | // ppc_reg_bn gqr_l = (ppc_reg_bn)0; |
| 543 | // int w_l = 0; |
| 544 | |
| 545 | addressSize_l = arch->GetAddressSize(); |
| 546 | if (!le) |
| 547 | { |
| 548 | rawInsn = bswap32(rawInsn); |
| 549 | } |
| 550 | |
| 551 | |
| 552 | /* bypass capstone path for *all* branching instructions; capstone |
| 553 | * is too difficult to work with and is outright broken for some |
| 554 | * branch instructions (bdnz, etc.) |
| 555 | */ |
| 556 | if (LiftBranches(arch, il, data, addr, le)) |
| 557 | return true; |
| 558 | |
| 559 | insn = &(res->insn); |
| 560 | detail = &(res->detail); |
| 561 | ppc = &(detail->ppc); |
| 562 | |
| 563 | /* There is a simplifying reduction available for: |
| 564 | * rlwinm <reg>, <reg>, <rol_amt>, <mask_begin>, <mask_end> |
| 565 | * When <rol_amt> == <mask_begin> == 0, this can be translated to: |
| 566 | * clrwi <reg>, <reg>, 31-<mask_end> |
| 567 | * |
| 568 | * Unfortunately capstone screws this up, replacing just the instruction id with PPC_INSN_CLRWI. |
| 569 | * The mnemonic ("rlwinm"), operands, etc. all stay the same. |
| 570 | */ |
| 571 | if (insn->id == PPC_INS_CLRLWI && insn->mnemonic[0] == 'r') |
| 572 | { |
| 573 | insn->id = PPC_INS_RLWINM; |
| 574 | } |
| 575 | |
| 576 | /* create convenient access to instruction operands */ |
| 577 | cs_ppc_op *oper0=NULL, *oper1=NULL, *oper2=NULL, *oper3=NULL, *oper4=NULL; |
| 578 | #define REQUIRE1OP if(!oper0) goto ReturnUnimpl; |
| 579 | #define REQUIRE2OPS if(!oper0 || !oper1) goto ReturnUnimpl; |
| 580 | #define REQUIRE3OPS if(!oper0 || !oper1 || !oper2) goto ReturnUnimpl; |
| 581 | #define REQUIRE4OPS if(!oper0 || !oper1 || !oper2 || !oper3) goto ReturnUnimpl; |
| 582 | #define REQUIRE5OPS if(!oper0 || !oper1 || !oper2 || !oper3 || !oper4) goto ReturnUnimpl; |
| 583 | |
| 584 | switch(ppc->op_count) { |
| 585 | default: |
| 586 | case 5: oper4 = &(ppc->operands[4]); FALL_THROUGH |
no test coverage detected