PPC uplifting to RzIL (#2823)

* Print a warning if config for VM was NULL.
* Add warning if register is not added to VM due to overlap.
* Update PPC register profile.
* Add vector and float registers. As well as some control and system registers.
* Enable to write values 4bit registers.
* PPC: Uplift most common instructions.
* Print warning if reserved SPR instruction is encountered.
* Update PC/LR addresses and add ca32 writes.
* Write cache needs to get flushed so load and store tests don't share the same memory.
* Add missing T/F branch mnemonics.
* Add Move to/from CR/CR0-7
* Fix TA address calculation for branch instructions.
* Add branch tests for branch mnemonics.
* Add XNOP
* NOP cache touch instructions.
* Add undocumented ATTN instruction to the not_implemented group.
* Add isel instruction.
* Implement CRCLR, CRSET, CROR.
* Add CNTLZ instructions.
* Add mcrf instructions.
* Add inacive test for cmpb.
* Add Load bytes reverse instructions.
* Add test and add address alignment to dcbz.
* Add eqv test
* Correct DIV and MUL operations
* Add div tests.
* Add tests and correct MT/MFXER
* Remove register ca32, ov32
* Remove explici setting of cr register because QEMU does not do it. Otherwise we get a mismatch in the trace
* Simplify carry set for add and sub. Sub instructions are exclusivly defined with addition. Hence no sub case needed.
* Unify BD and fix branch instructions. Fix: Check the single bit not the cr reg
* Document Conditional branches and replace NOPs with EMPTY
* Add mulli instruction to double word instructions.
* Fix ca set for shift instructions:
* ca value had to be determined before the shift happened. The wrong ca value was calculated if the src and target reg were the same.
* Replace NOP wit EMPTY.
* Use MSB isntead of SLT.
* Brought fixup of ADD and SUB instructions: The add and sub instructions had several issues which let to incorrect execution.
* The carry was incorrectly if three add operations happened (only the last add were checked, not both).
* The carry was incorrectly set if the src and target register matched.
* Same applies for the CR bit.
* It was too complex. Several local variables were introduced for this.
* Set result in local var, since it would change if src and target reg are the same.
* Remove MTMSR and MFMSR since it is too complex and untestable currently.
* Use unsigned int for shift. Otherwise the 0x1c shift produces a runtime error since 0xf is int as default.
* Fix mtxer: Only write flag bits.
* Let NOT_IMPLEMENTED macro return NULL.
* Mark st[wd]cx and l[wd]cx as not implemented.
* Increase dcache_line_size to 128 bytes.
* Fix cntlz for ppc32. m was set incorrectly, since it is 0 not 32 for 32bit cpus.
* Fix isel: Use op.crx reg instead of imm.
* Unify helper function names: Prependnig `ppc_` mark as IPI
* Add more "Move to SPR" cases.
* MULLI opeartes only on double word on 64bit CPUs.
* Most registers are now assigned the control register type and no longer show up in the ar command.
* Fix xor if dest and src registers match by saving result in local var.
* Fix BE/LE issue for Load BRX instructions.
* Fix shifts: Use only lower 6bits of n.
* User Pure local variables for ROT macros.
* Fix rldimi instructions.
* n was not inverted.
* more than 6 bits of n could be used
* Add 32bit emulateme tests.
* Add 64bit emulateme tests.
* Determine lg(v) in inline function.
* Calculate CR bit in C not in the VM.
* Check if `~mask = 0` and skip mask calculation if yes.
* Check for `sh == 0` and skip rotations where possible.
* Remove `la` instruction. `la` is a mnemonic for `addi`.
* Remove SPR instructions which are not supported by QEMU or not traced yet. For most set/read SPR instructions QEMU segfaults.


In case of SPR 1 (xer), 8 (lr) and 9 (ctr) the assembler resolves them to their mnemonics (mtxer, mtlr etc.). This means the code here is never reached.
To test the get_xer code MFXER was added again. The rz-tracetests will fail for this instructions (due to missing ca32, ov32). But this case is covert in an issue.
This commit is contained in:
Rot127 2022-08-10 20:41:15 -04:00 committed by GitHub
parent 4abd2028da
commit b46e7bd4f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 4246 additions and 255 deletions

View file

@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: 2022 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef PPC_ANALYSIS_H
#define PPC_ANALYSIS_H
#define INSOPS insn->detail->ppc.op_count
#define INSOP(n) insn->detail->ppc.operands[n]
#define OP_CNT insn->detail->ppc.op_count
#define IMM(x) (ut64)(insn->detail->ppc.operands[x].imm)
#define PPC_IN_BE_MODE (mode & CS_MODE_BIG_ENDIAN)
// Capstone does not extract the BO or BI fields of instructions. So we do it manually.
#define PPC_READ_BO_FIELD (((rz_read_ble32(insn->bytes, PPC_IN_BE_MODE)) & 0x03e00000) >> 21)
#define PPC_READ_BI_FIELD (((rz_read_ble32(insn->bytes, PPC_IN_BE_MODE)) & 0x001f0000) >> 16)
#define IN_BE_MODE (mode & CS_MODE_BIG_ENDIAN)
#define IN_64BIT_MODE (mode & CS_MODE_64)
#define PPC_ARCH_BITS (IN_64BIT_MODE ? 64 : 32)
#endif /* PPC_ANALYSIS_H */

View file

@ -0,0 +1,817 @@
// SPDX-FileCopyrightText: 2022 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include "ppc_il.h"
#include "ppc_analysis.h"
#include <capstone/ppc.h>
#include <rz_il/rz_il_opcodes.h>
#include <rz_util/rz_log.h>
#include <rz_util/rz_assert.h>
#include <rz_endian.h>
#include <rz_analysis.h>
#include <rz_il.h>
#include <rz_types.h>
#include <errno.h>
RZ_IPI RzAnalysisILConfig *rz_ppc_cs_64_il_config(bool big_endian) {
RzAnalysisILConfig *r = rz_analysis_il_config_new(64, big_endian, 64);
return r;
}
RZ_IPI RzAnalysisILConfig *rz_ppc_cs_32_il_config(bool big_endian) {
RzAnalysisILConfig *r = rz_analysis_il_config_new(32, big_endian, 32);
return r;
}
/**
* \brief Returns true if the given load/store instruction is in X form (uses register RB as second operand).
*
* \param insn_id The instruction id.
* \return bool True if the load/store instruction is in X form. False otherwise.
*/
RZ_IPI bool ppc_is_x_form(ut32 insn_id) {
switch (insn_id) {
default:
return false;
case PPC_INS_LBZCIX:
case PPC_INS_LBZUX:
case PPC_INS_LBZX:
case PPC_INS_LDARX:
case PPC_INS_LDBRX:
case PPC_INS_LDCIX:
case PPC_INS_LDUX:
case PPC_INS_LDX:
case PPC_INS_LHAUX:
case PPC_INS_LHAX:
case PPC_INS_LHBRX:
case PPC_INS_LHZCIX:
case PPC_INS_LHZUX:
case PPC_INS_LHZX:
case PPC_INS_LWARX:
case PPC_INS_LWAUX:
case PPC_INS_LWAX:
case PPC_INS_LWBRX:
case PPC_INS_LWZCIX:
case PPC_INS_LWZUX:
case PPC_INS_LWZX:
case PPC_INS_STBUX:
case PPC_INS_STHUX:
case PPC_INS_STWUX:
case PPC_INS_STDUX:
case PPC_INS_STBX:
case PPC_INS_STHX:
case PPC_INS_STWX:
case PPC_INS_STDX:
case PPC_INS_STBCIX:
case PPC_INS_STHCIX:
case PPC_INS_STWCIX:
case PPC_INS_STDCIX:
case PPC_INS_STDCX:
case PPC_INS_STWCX:
return true;
}
}
/**
* \brief Returns the memory access size in bytes for a given load/store instruction.
*
* \param insn_id The instruction id.
* \return st32 The memory access size in bytes.
* Or 0 if the load instruction does not access the memory.
* Or -1 if the instruction is no load/store instruction.
*/
RZ_IPI st32 ppc_get_mem_acc_size(ut32 insn_id) {
switch (insn_id) {
default:
RZ_LOG_INFO("Memory access size for instruction %d requested. But it is not in the switch case.\n", insn_id);
return -1;
case PPC_INS_LI:
case PPC_INS_LIS:
// Doesn't read from memory.
return 0;
case PPC_INS_LBZ:
case PPC_INS_LBZCIX:
case PPC_INS_LBZU:
case PPC_INS_LBZUX:
case PPC_INS_LBZX:
case PPC_INS_STB:
case PPC_INS_STBCIX:
case PPC_INS_STBU:
case PPC_INS_STBUX:
case PPC_INS_STBX:
return PPC_BYTE;
case PPC_INS_LHA:
case PPC_INS_LHAU:
case PPC_INS_LHAUX:
case PPC_INS_LHAX:
case PPC_INS_LHBRX:
case PPC_INS_LHZ:
case PPC_INS_LHZCIX:
case PPC_INS_LHZU:
case PPC_INS_LHZUX:
case PPC_INS_LHZX:
case PPC_INS_STH:
case PPC_INS_STHBRX:
case PPC_INS_STHCIX:
case PPC_INS_STHU:
case PPC_INS_STHUX:
case PPC_INS_STHX:
return PPC_HWORD;
case PPC_INS_LWA:
case PPC_INS_LWARX:
case PPC_INS_LWAUX:
case PPC_INS_LWAX:
case PPC_INS_LWBRX:
case PPC_INS_LWZ:
case PPC_INS_LWZCIX:
case PPC_INS_LWZU:
case PPC_INS_LWZUX:
case PPC_INS_LWZX:
case PPC_INS_LMW:
case PPC_INS_STW:
case PPC_INS_STWBRX:
case PPC_INS_STWCIX:
case PPC_INS_STWCX:
case PPC_INS_STWU:
case PPC_INS_STWUX:
case PPC_INS_STWX:
case PPC_INS_STMW:
return PPC_WORD;
case PPC_INS_LD:
case PPC_INS_LDARX:
case PPC_INS_LDBRX:
case PPC_INS_LDCIX:
case PPC_INS_LDU:
case PPC_INS_LDUX:
case PPC_INS_LDX:
case PPC_INS_STD:
case PPC_INS_STDBRX:
case PPC_INS_STDCIX:
case PPC_INS_STDCX:
case PPC_INS_STDU:
case PPC_INS_STDUX:
case PPC_INS_STDX:
return PPC_DWORD;
}
}
/**
* \brief Returns true if the given load/store instruction updates the RA register with EA after memory access.
*
* \param insn_id The instruction id.
* \return bool True if RA is set to EA after the instruction executed. False otherwise.
*/
RZ_IPI bool ppc_updates_ra_with_ea(ut32 insn_id) {
switch (insn_id) {
default:
return false;
case PPC_INS_LBZU:
case PPC_INS_LBZUX:
case PPC_INS_LDU:
case PPC_INS_LDUX:
case PPC_INS_LHAU:
case PPC_INS_LHAUX:
case PPC_INS_LHZU:
case PPC_INS_LHZUX:
case PPC_INS_LWAUX:
case PPC_INS_LWZU:
case PPC_INS_LWZUX:
case PPC_INS_LFDU:
case PPC_INS_LFDUX:
case PPC_INS_LFSU:
case PPC_INS_LFSUX:
case PPC_INS_STBU:
case PPC_INS_STDU:
case PPC_INS_STHU:
case PPC_INS_STWU:
case PPC_INS_STBUX:
case PPC_INS_STHUX:
case PPC_INS_STWUX:
case PPC_INS_STDUX:
case PPC_INS_STFDU:
case PPC_INS_STFDUX:
case PPC_INS_STFSU:
case PPC_INS_STFSUX:
return true;
}
}
/**
* \brief Returns true if the given load instruction is algebraic.
*
* \param insn_id The instruction id.
* \return bool True if the load instruction is algebraic. False otherwise.
*/
RZ_IPI bool ppc_is_algebraic(ut32 insn_id) {
switch (insn_id) {
default:
return false;
case PPC_INS_LA:
case PPC_INS_LDARX:
case PPC_INS_LHA:
case PPC_INS_LHAU:
case PPC_INS_LHAUX:
case PPC_INS_LHAX:
case PPC_INS_LWA:
case PPC_INS_LWAX:
case PPC_INS_LWARX:
case PPC_INS_LWAUX:
return true;
}
}
/**
* \brief Returns true if the given branch instruction sets the LR register.
*
* \param insn_id The instruction id.
* \return bool True if the branch instruction writes the LR register. False otherwise.
*/
RZ_IPI bool ppc_sets_lr(ut32 insn_id) {
switch (insn_id) {
default:
return false;
case PPC_INS_BCCTRL:
case PPC_INS_BCL:
case PPC_INS_BCLRL:
case PPC_INS_BCTRL:
case PPC_INS_BDNZL:
case PPC_INS_BDNZLA:
case PPC_INS_BDNZLRL:
case PPC_INS_BDZL:
case PPC_INS_BDZLA:
case PPC_INS_BDZLRL:
case PPC_INS_BL:
case PPC_INS_BLA:
case PPC_INS_BLRL:
case PPC_INS_BCLA:
case PPC_INS_BDNZTL:
case PPC_INS_BDNZTLA:
case PPC_INS_BDNZFL:
case PPC_INS_BDNZFLA:
case PPC_INS_BDZTL:
case PPC_INS_BDZTLA:
case PPC_INS_BDZFL:
case PPC_INS_BDZFLA:
return true;
}
}
/**
* \brief Returns true if the given branch instruction is conditional.
*
* \param insn_id The instruction id.
* \return bool True if the branch instruction only branches if a condition is met. False otherwise.
*/
RZ_IPI bool ppc_is_conditional(ut32 insn_id) {
switch (insn_id) {
default:
return false;
case PPC_INS_BC:
case PPC_INS_BCCTR:
case PPC_INS_BCCTRL:
case PPC_INS_BCL:
case PPC_INS_BCLR:
case PPC_INS_BCLRL:
case PPC_INS_BCA:
case PPC_INS_BCLA:
case PPC_INS_BDNZ:
case PPC_INS_BDNZA:
case PPC_INS_BDNZL:
case PPC_INS_BDNZLA:
case PPC_INS_BDNZLR:
case PPC_INS_BDNZLRL:
case PPC_INS_BDZ:
case PPC_INS_BDZA:
case PPC_INS_BDZL:
case PPC_INS_BDZLA:
case PPC_INS_BDZLR:
case PPC_INS_BDZLRL:
case PPC_INS_BDNZT:
case PPC_INS_BDNZTL:
case PPC_INS_BDNZTA:
case PPC_INS_BDNZTLA:
case PPC_INS_BDNZF:
case PPC_INS_BDNZFL:
case PPC_INS_BDNZFA:
case PPC_INS_BDNZFLA:
case PPC_INS_BDZT:
case PPC_INS_BDZTA:
case PPC_INS_BDZTL:
case PPC_INS_BDZTLA:
case PPC_INS_BDZF:
case PPC_INS_BDZFA:
case PPC_INS_BDZFL:
case PPC_INS_BDZFLA:
return true;
}
}
/**
* \brief Returns true if the given instruction sets a SPR register.
*
* \param insn_id The instruction id.
* \return bool True if the instructions moves a value to a SPR. False otherwise.
*/
RZ_IPI bool ppc_moves_to_spr(ut32 insn_id) {
switch (insn_id) {
default:
return false;
case PPC_INS_MTCTR:
case PPC_INS_MTCRF:
case PPC_INS_MTDCR:
case PPC_INS_MTFSB0:
case PPC_INS_MTFSB1:
case PPC_INS_MTFSF:
case PPC_INS_MTFSFI:
case PPC_INS_MTLR:
case PPC_INS_MTMSR:
case PPC_INS_MTMSRD:
case PPC_INS_MTOCRF:
case PPC_INS_MTSPR:
case PPC_INS_MTSR:
case PPC_INS_MTSRIN:
case PPC_INS_MTVSCR:
case PPC_INS_MTCR:
case PPC_INS_MTBR0:
case PPC_INS_MTBR1:
case PPC_INS_MTBR2:
case PPC_INS_MTBR3:
case PPC_INS_MTBR4:
case PPC_INS_MTBR5:
case PPC_INS_MTBR6:
case PPC_INS_MTBR7:
case PPC_INS_MTXER:
case PPC_INS_MTDSCR:
case PPC_INS_MTDSISR:
case PPC_INS_MTDAR:
case PPC_INS_MTSRR2:
case PPC_INS_MTSRR3:
case PPC_INS_MTCFAR:
case PPC_INS_MTAMR:
case PPC_INS_MTPID:
case PPC_INS_MTTBL:
case PPC_INS_MTTBU:
case PPC_INS_MTTBLO:
case PPC_INS_MTTBHI:
case PPC_INS_MTDBATU:
case PPC_INS_MTDBATL:
case PPC_INS_MTIBATU:
case PPC_INS_MTIBATL:
case PPC_INS_MTDCCR:
case PPC_INS_MTICCR:
case PPC_INS_MTDEAR:
case PPC_INS_MTESR:
case PPC_INS_MTSPEFSCR:
case PPC_INS_MTTCR:
case PPC_INS_MFSRIN:
return true;
}
}
/**
* \brief Returns true if the given branch instruction decrements the CTR register.
*
* \param insn Instruction id.
* \param mode Capstone mode.
* \return bool True if the instruction decrements the counter. False otherwise.
*/
RZ_IPI bool ppc_decrements_ctr(RZ_BORROW cs_insn *insn, const cs_mode mode) {
rz_return_val_if_fail(insn, false);
ut32 id = insn->id;
switch (id) {
default:
return false;
case PPC_INS_BC:
case PPC_INS_BCL:
case PPC_INS_BCA:
case PPC_INS_BCLA:
case PPC_INS_BCLR:
case PPC_INS_BCLRL:
case PPC_INS_BDNZ:
case PPC_INS_BDNZA:
case PPC_INS_BDNZL:
case PPC_INS_BDNZLA:
case PPC_INS_BDNZLR:
case PPC_INS_BDNZLRL:
case PPC_INS_BDZ:
case PPC_INS_BDZA:
case PPC_INS_BDZL:
case PPC_INS_BDZLA:
case PPC_INS_BDZLR:
case PPC_INS_BDZLRL:
case PPC_INS_BCT:
return !(0x4 & PPC_READ_BO_FIELD); // not BO_2
case PPC_INS_BDNZT:
case PPC_INS_BDNZTL:
case PPC_INS_BDNZTA:
case PPC_INS_BDNZTLA:
case PPC_INS_BDNZF:
case PPC_INS_BDNZFL:
case PPC_INS_BDNZFA:
case PPC_INS_BDNZFLA:
case PPC_INS_BDZT:
case PPC_INS_BDZTA:
case PPC_INS_BDZTL:
case PPC_INS_BDZTLA:
case PPC_INS_BDZF:
case PPC_INS_BDZFA:
case PPC_INS_BDZFL:
case PPC_INS_BDZFLA:
return true;
}
}
//
// IL helper BEGIN
//
#include <rz_il/rz_il_opbuilder_begin.h>
/**
* \brief Returns the value of the a bit at position \p pos in CR.
*
* NOTE: The Condition Register and its fields (cr0-cr7) start at bit 32.
* The CR reg is not defined for bits at positions smaller than 32 or larger than 63.
*
* \param pos The bit position to look up.
* \return RzILOpBool* The value of the bit at position \p pos in the CR register.
* Or IL_FALSE for invalid access.
*/
static RZ_OWN RzILOpBool *get_cr_bit(const ut8 pos) {
if (pos > 63 || pos < 32) {
RZ_LOG_WARN("Undefined access into CR register.\n");
return IL_FALSE;
}
ut8 field_bit;
RzILOpPure *cr_field;
if (pos < 36) {
field_bit = 0b1000 >> (pos - 32);
cr_field = VARG("cr0");
} else if (pos < 40) {
field_bit = 0b1000 >> (pos - 36);
cr_field = VARG("cr1");
} else if (pos < 44) {
field_bit = 0b1000 >> (pos - 40);
cr_field = VARG("cr2");
} else if (pos < 48) {
field_bit = 0b1000 >> (pos - 44);
cr_field = VARG("cr3");
} else if (pos < 52) {
field_bit = 0b1000 >> (pos - 48);
cr_field = VARG("cr4");
} else if (pos < 56) {
field_bit = 0b1000 >> (pos - 52);
cr_field = VARG("cr5");
} else if (pos < 60) {
field_bit = 0b1000 >> (pos - 56);
cr_field = VARG("cr6");
} else {
field_bit = 0b1000 >> (pos - 60);
cr_field = VARG("cr7");
}
return NON_ZERO(LOGAND(cr_field, UN(4, field_bit)));
}
/**
* \brief Synchronizes the CR register with the CR0-CR7 registers.
* Since CR contains CR0-CR7 but are separated in the register profile
* this function should be called before CR as a whole is read and after it was written.
*
* \param to_cr True: CR0-CR7 are copied to CR. False: CR is copied to CR0-CR7 according to \p cr_mask.
* \param cr_mask Masks the bits which are copied from CR to CR0-CR7. Ignored if \p crx_to_cr == true.
* \return RzILOpEffect* Sequence of effects to sync the CR/CRx registers.
*/
RZ_IPI RZ_OWN RzILOpEffect *ppc_sync_crx_cr(const bool crx_to_cr, const ut32 cr_mask) {
RzILOpEffect *effect;
if (crx_to_cr) {
effect = SETL("cr", LOGOR(UNSIGNED(32, VARG("cr7")), LOGOR(SHIFTL0(UNSIGNED(32, VARG("cr6")), U8(0x4)), LOGOR(SHIFTL0(UNSIGNED(32, VARG("cr5")), U8(0x8)), LOGOR(SHIFTL0(UNSIGNED(32, VARG("cr4")), U8(0xc)), LOGOR(SHIFTL0(UNSIGNED(32, VARG("cr3")), U8(0x10)), LOGOR(SHIFTL0(UNSIGNED(32, VARG("cr2")), U8(0x14)), LOGOR(SHIFTL0(UNSIGNED(32, VARG("cr1")), U8(0x18)), SHIFTL0(UNSIGNED(32, VARG("cr0")), U8(0x1c))))))))));
return effect;
}
effect = SEQN(10,
SETL("cr_mask", U32(cr_mask)),
SETL("crm", LOGAND(VARL("cr"), U32(cr_mask))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf))), EMPTY(), SETG("cr7", UNSIGNED(4, VARL("crm")))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf0))), EMPTY(), SETG("cr6", UNSIGNED(4, SHIFTR0(VARL("crm"), U8(0x4))))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf00))), EMPTY(), SETG("cr5", UNSIGNED(4, SHIFTR0(VARL("crm"), U8(0x8))))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf000))), EMPTY(), SETG("cr4", UNSIGNED(4, SHIFTR0(VARL("crm"), U8(0xc))))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf0000))), EMPTY(), SETG("cr3", UNSIGNED(4, SHIFTR0(VARL("crm"), U8(0x10))))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf00000))), EMPTY(), SETG("cr2", UNSIGNED(4, SHIFTR0(VARL("crm"), U8(0x14))))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf000000))), EMPTY(), SETG("cr1", UNSIGNED(4, SHIFTR0(VARL("crm"), U8(0x18))))),
BRANCH(IS_ZERO(LOGAND(VARL("cr_mask"), U32(0xf0000000))), EMPTY(), SETG("cr0", UNSIGNED(4, SHIFTR0(VARL("crm"), U8(0x1c))))));
return effect;
}
/**
* \brief Returns the mask for a given fxm operand.
* For details look up the "mtcrf" instruction in the Power ISA
*
* \param fmx The fmx value.
* \return ut32 The mask for writing to the CR register.
*/
RZ_IPI ut32 ppc_fmx_to_mask(const ut8 fmx) {
ut32 x = 0xf;
return (
(fmx & 0x80 ? x << 28 : 0) |
(fmx & 0x40 ? x << 24 : 0) |
(fmx & 0x20 ? x << 20 : 0) |
(fmx & 0x10 ? x << 16 : 0) |
(fmx & 0x08 ? x << 12 : 0) |
(fmx & 0x04 ? x << 8 : 0) |
(fmx & 0x02 ? x << 4 : 0) |
(fmx & 0x01 ? x : 0));
}
/**
* \brief Get the branch condition for a given instruction.
* Checkout the "Simple Branch Mnemonics" in Appendix C in PowerISA v3.1B and
* the chapter about branch instructions for an overview of possible conditions.
*
* NODE: This function *does not* decrement CTR, if required by the instruction.
* This should have been done before.
*
* \param insn The capstone instructions.
* \param mode The capstone mode.
* \return RzILOpPure* The condition the branch occurs as a Pure.
*/
RZ_IPI RZ_OWN RzILOpPure *ppc_get_branch_cond(const csh handle, RZ_BORROW cs_insn *insn, const cs_mode mode) {
rz_return_val_if_fail(insn, NULL);
ut32 id = insn->id;
ut8 bo = PPC_READ_BO_FIELD;
ut8 bi = PPC_READ_BI_FIELD;
RzILOpPure *ctr_ok;
RzILOpPure *cond_ok;
RzILOpPure *bo_0;
RzILOpPure *bo_1;
RzILOpPure *bo_2;
RzILOpPure *bo_3;
RzILOpPure *cr;
RzILOpPure *cr_bit;
switch (id) {
default:
RZ_LOG_WARN("Instruction %d has no condition implemented.\n", id);
return IL_FALSE;
// For learning how the conditions of BCxxx branch instructions are
// formed see the Power ISA
case PPC_INS_BC:
case PPC_INS_BCL:
case PPC_INS_BCA:
case PPC_INS_BCLA:
case PPC_INS_BCLR:
case PPC_INS_BCLRL:
// BO_2 == 0: Decrement CTR
// BO_2 == 1: Don't use CTR
bo_2 = NON_ZERO(LOGAND(UN(5, 0b00100), VARLP("bo")));
// BO_3 == 0: Check CTR != 0
// BO_3 == 1: Check CTR == 0
bo_3 = NON_ZERO(LOGAND(UN(5, 0b00010), VARLP("bo")));
ctr_ok = OR(bo_2, XOR(NON_ZERO(VARG("ctr")), bo_3)); // BO_2 | (CTR_M:63 ≠ 0) ⊕ BO_3
// BO_0 == 0: Check CR_bi
// BO_0 == 1: Don't check CR_bi
bo_0 = NON_ZERO(LOGAND(UN(5, 0b10000), VARLP("bo")));
// BO_1 == 0: Check CR_bi == 0
// BO_1 == 1: Check CR_bi == 1
bo_1 = NON_ZERO(LOGAND(UN(5, 0b01000), VARLP("bo")));
cond_ok = OR(bo_0, XOR(get_cr_bit(bi + 32), INV(bo_1))); // BO_0 | (CR_BI+32 ≡ BO_1)
return LET("bo", UN(5, bo), AND(cond_ok, ctr_ok));
case PPC_INS_BCCTR:
case PPC_INS_BCCTRL:
bo_0 = NON_ZERO(LOGAND(UN(5, 0b10000), VARLP("bo")));
bo_1 = NON_ZERO(LOGAND(UN(5, 0b01000), VARLP("bo")));
cond_ok = OR(bo_0, XOR(get_cr_bit(bi + 32), INV(bo_1))); // BO_0 | (CR_BI+32 ≡ BO_1)
return LET("bo", UN(5, bo), cond_ok);
// CTR != 0
case PPC_INS_BDNZ:
case PPC_INS_BDNZA:
case PPC_INS_BDNZL:
case PPC_INS_BDNZLA:
case PPC_INS_BDNZLR:
case PPC_INS_BDNZLRL:
return NON_ZERO(VARG("ctr"));
// CTR == 0
case PPC_INS_BDZ:
case PPC_INS_BDZA:
case PPC_INS_BDZL:
case PPC_INS_BDZLA:
case PPC_INS_BDZLR:
case PPC_INS_BDZLRL:
return IS_ZERO(VARG("ctr"));
// ctr != 0 && cr_bi == 1
case PPC_INS_BDNZT:
case PPC_INS_BDNZTL:
case PPC_INS_BDNZTA:
case PPC_INS_BDNZTLA:
// ctr == 0 && cr_bi == 1
case PPC_INS_BDZT:
case PPC_INS_BDZTL:
case PPC_INS_BDZTA:
case PPC_INS_BDZTLA:
if (insn->detail->ppc.op_count == 1) {
// If Capstone doesn't provide a CR register it means that the LT bit in cr0 is checked.
cr = VARG("cr0");
// LT bit
cr_bit = UN(4, 8);
} else {
cr = VARG(cs_reg_name(handle, INSOP(0).crx.reg));
ut32 cond = INSOP(0).crx.cond;
cr_bit = UN(4, ((cond & PPC_BC_SO) ? 1 : ((cond & PPC_BC_EQ) ? 2 : ((cond & PPC_BC_GT) ? 4 : 8))));
}
if (id == PPC_INS_BDZT || id == PPC_INS_BDZTL || id == PPC_INS_BDZTA || id == PPC_INS_BDZTLA) {
return AND(IS_ZERO(VARG("ctr")), NON_ZERO(LOGAND(cr, cr_bit)));
}
return AND(NON_ZERO(VARG("ctr")), NON_ZERO(LOGAND(cr, cr_bit)));
// ctr != 0 && cr_bi == 0
case PPC_INS_BDNZF:
case PPC_INS_BDNZFL:
case PPC_INS_BDNZFA:
case PPC_INS_BDNZFLA:
// ctr == 0 && cr_bi == 0
case PPC_INS_BDZF:
case PPC_INS_BDZFL:
case PPC_INS_BDZFA:
case PPC_INS_BDZFLA:
if (insn->detail->ppc.op_count == 1) {
cr = VARG("cr0");
cr_bit = UN(4, 8);
} else {
cr = VARG(cs_reg_name(handle, INSOP(0).crx.reg));
ut32 cond = INSOP(0).crx.cond;
cr_bit = UN(4, ((cond & PPC_BC_SO) ? 1 : ((cond & PPC_BC_EQ) ? 2 : ((cond & PPC_BC_GT) ? 4 : 8))));
}
cr = insn->detail->ppc.op_count == 1 ? VARG("cr0") : VARG(cs_reg_name(handle, INSOP(0).crx.reg));
if (id == PPC_INS_BDZF || id == PPC_INS_BDZFL || id == PPC_INS_BDZFA || id == PPC_INS_BDZFLA) {
return AND(IS_ZERO(VARG("ctr")), IS_ZERO(LOGAND(cr, cr_bit)));
}
return AND(NON_ZERO(VARG("ctr")), IS_ZERO(LOGAND(cr, cr_bit)));
}
}
/**
* \brief Get the branch instruction's target address.
* In case of conditional branches it returns the address if the condition would be fulfilled.
*
* There are five types of target addresses:
* * Absolute address
* * Relative address (relative to current instruction address)
* * Address stored in LR
* * Address stored in CTR
* * Address stored in TAR
*
* NOTE: Capstone calculates the NIA and fills the operand member with it.
* We don't need to do the shift, add and extend here.
*
* \param insn The capstone instructions.
* \param mode The capstone mode.
* \return RzILOpPure* The target address of the jump.
*/
RZ_IPI RZ_OWN RzILOpPure *ppc_get_branch_ta(RZ_BORROW cs_insn *insn, const cs_mode mode) {
rz_return_val_if_fail(insn, NULL);
ut32 id = insn->id;
switch (id) {
default:
RZ_LOG_WARN("Target address of branch instruction %d can not be resolved.\n", id);
return UA(0);
// Target address is pre-calculated by Capstone and stored in INSOP().imm
// The comments show only the TA calculation according to the ISA.
// Banch to absolute address
case PPC_INS_BA:
case PPC_INS_BLA:
case PPC_INS_BCA:
case PPC_INS_BCLA:
case PPC_INS_BDNZTA:
case PPC_INS_BDNZTLA:
case PPC_INS_BDNZFA:
case PPC_INS_BDNZFLA:
case PPC_INS_BDZTA:
case PPC_INS_BDZTLA:
case PPC_INS_BDZFA:
case PPC_INS_BDZFLA:
// EXTS(LI || 0b00)
// Branch to relative address
case PPC_INS_B:
case PPC_INS_BL:
case PPC_INS_BDZF:
case PPC_INS_BDZFL:
case PPC_INS_BDZT:
case PPC_INS_BDZTL:
case PPC_INS_BDNZF:
case PPC_INS_BDNZFL:
case PPC_INS_BDNZT:
case PPC_INS_BDNZTL:
// CIA + EXTS(LI || 0b00)
if (insn->detail->ppc.op_count == 2) {
return UA(INSOP(1).imm);
} else {
return UA(INSOP(0).imm);
}
case PPC_INS_BDZA:
case PPC_INS_BDZLA:
case PPC_INS_BDNZA:
case PPC_INS_BDNZLA:
// EXTS(BD || 0b00)
case PPC_INS_BC:
case PPC_INS_BCL:
case PPC_INS_BDZ:
case PPC_INS_BDZL:
case PPC_INS_BDNZ:
case PPC_INS_BDNZL:
// If bits in cr0 are checked, the opcount is 1.
// CIA + EXTS(BD || 0b00)
if (insn->detail->ppc.op_count == 2) {
return UA(INSOP(1).imm);
} else {
return UA(INSOP(0).imm);
}
// Branch to LR
case PPC_INS_BLR:
case PPC_INS_BLRL:
case PPC_INS_BCLR:
case PPC_INS_BDZLR:
case PPC_INS_BCLRL:
case PPC_INS_BDZLRL:
case PPC_INS_BDNZLR:
case PPC_INS_BDNZLRL:
// LR_0:61 || 0b00
return LOGAND(UA(-4), VARG("lr"));
// Branch to CTR
case PPC_INS_BCTR:
case PPC_INS_BCTRL:
case PPC_INS_BCCTR:
case PPC_INS_BCCTRL:
// CTR_0:61 || 0b00
return LOGAND(UA(-4), VARG("ctr"));
}
}
/**
* \brief Returns true if the multiplication instruction operates on double words.
*
* \param id The instruction id.
* \param mode The Capstone mode.
* \return bool True if the instruction operates on double words. False otherwise;
*/
RZ_IPI bool ppc_is_mul_div_d(const ut32 id, const cs_mode mode) {
return id == PPC_INS_MULHD || id == PPC_INS_MULLD || id == PPC_INS_MULHDU ||
id == PPC_INS_DIVD || id == PPC_INS_DIVDU || ((id == PPC_INS_MULLI) && IN_64BIT_MODE);
}
/**
* \brief Returns true if the division instruction operates on double words.
*
* \param id The instruction id.
* \param mode The Capstone mode.
* \return bool True if the instruction operates on double words. False otherwise;
*/
RZ_IPI bool ppc_is_mul_div_u(const ut32 id) {
return id == PPC_INS_MULHDU || id == PPC_INS_MULHWU || id == PPC_INS_DIVWU || id == PPC_INS_DIVDU;
}
/**
* \brief Assembles the current XER value by combining the values
* from the flag registers "so", "ov", "ca".
*
* \param mode The capstone mode.
* \return RzILOpPure* The Pure containing the current XER value.
*/
RZ_IPI RZ_OWN RzILOpPure *ppc_get_xer(cs_mode mode) {
RzILOpPure *so = SHIFTL0(EXTZ(BOOL_TO_BV(VARG("so"), 1)), U8(31));
RzILOpPure *ov = SHIFTL0(EXTZ(BOOL_TO_BV(VARG("ov"), 1)), U8(30));
RzILOpPure *ca = SHIFTL0(EXTZ(BOOL_TO_BV(VARG("ca"), 1)), U8(29));
// For ISA v3 CPUs register ca32 and ov32 should be handled here as well.
// Currently they are ignored. If you want to add them take a look at:
// https://github.com/Rot127/rizin/tree/Examples-ppc-rzil-isav3-regs
return LOGOR(LOGOR(so, ov), ca);
}
/**
* \brief Sets the XER register to \p val and updates the flag register "so", "ov", "ca" accordingly.
*
* \param val The new value of XER.
* \param mode The capstone mode.
* \return RzILOpEffect* The sequence of effects setting all registers to their respective values.
*/
RZ_IPI RZ_OWN RzILOpEffect *ppc_set_xer(RzILOpPure *val, cs_mode mode) {
rz_return_val_if_fail(val, NULL);
RzILOpPure *v = LOGAND(BIT_MASK(64, U8(32), U8(34)), UNSIGNED(64, val));
return SEQ5(SETL("v", v), SETG("xer", VARL("v")),
SETG("so", BIT_IS_SET(VARL("v"), 64, U8(32))),
SETG("ov", BIT_IS_SET(VARL("v"), 64, U8(33))),
SETG("ca", BIT_IS_SET(VARL("v"), 64, U8(34))));
// For ISA v3 CPUs register ca32 and ov32 should be handled here as well.
// Currently they are ignored. If you want to add them take a look at:
// https://github.com/Rot127/rizin/tree/Examples-ppc-rzil-isav3-regs
}
#include <rz_il/rz_il_opbuilder_end.h>
//
// IL helper END
//

View file

@ -0,0 +1,179 @@
// SPDX-FileCopyrightText: 2022 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef PPC_IL_H
#define PPC_IL_H
#include "ppc_analysis.h"
#include <rz_reg.h>
#include <rz_analysis.h>
#include <rz_il.h>
#include <rz_types.h>
#include <capstone.h>
#define PPC_BYTE 8
#define PPC_HWORD 16
#define PPC_WORD 32
#define PPC_DWORD 64
#define PPC_QWORD 128
/**
* \brief This value varies from implementation to implementation.
* Should be replaced with a plugin specific config option.
*/
#define DCACHE_LINE_SIZE 128
/**
* \brief Writes to the info log that an unimplemented instruction was encountered and returns an EMPTY() effect.
*/
#define NOT_IMPLEMENTED \
do { \
RZ_LOG_INFO("IL instruction not implemented."); \
return NULL; \
} while (0)
/**
* \brief Unsigned value \p i which is PPC_ARCH_BITS (32 or 64) wide.
*/
#define UA(i) (IN_64BIT_MODE ? U64(i) : U32(i))
/**
* \brief Signed value \p i which is PPC_ARCH_BITS (32 or 64) wide.
*/
#define SA(i) (IN_64BIT_MODE ? S64(i) : S32(i))
/**
* \brief Extend value \p v with sign bits to a width of \p n.
*/
#define EXTEND(n, v) LET("v", v, ITE(MSB(VARLP("v")), SIGNED(n, VARLP("v")), UNSIGNED(n, VARLP("v"))))
/**
* \brief Extend value with sign bits to a width of 32/64 bit.
*/
#define EXTS(v) SIGNED(PPC_ARCH_BITS, v)
/**
* \brief Extend value with 0s to a width of 32/64 bit.
*/
#define EXTZ(v) UNSIGNED(PPC_ARCH_BITS, v)
/**
* \brief Rotates a 64bit value. Rotate \p x left by \p y bits.
* \p y should be U8, \p x should be U32 and U64 respectively.
*/
#define ROTL64(x, y) LET("rotl64_x", x, \
LET("rotl64_y", y, \
(LOGOR(SHIFTL0(VARLP("rotl64_x"), VARLP("rotl64_y")), SHIFTR0(VARLP("rotl64_x"), SUB(U8(64), UNSIGNED(8, VARLP("rotl64_y"))))))))
/**
* \brief Rotates a 32bit value. If the the VM is in 64bit mode "ROTL64(x||x, y)" is executed instead.
*/
#define ROTL32(x, y) LET("rotl32_x", x, \
LET("rotl32_y", y, \
(IN_64BIT_MODE ? ROTL64(APPEND(VARLP("rotl32_x"), VARLP("rotl32_x")), VARLP("rotl32_y")) \
: LOGOR(SHIFTL0(VARLP("rotl32_x"), VARLP("rotl32_y")), SHIFTR0(VARLP("rotl32_x"), SUB(U8(32), UNSIGNED(8, VARLP("rotl32_y"))))))))
/**
* \brief Returns a Pure of width \p w with the \p i bit set.
* Please note: The left most bit is bit 0.
*/
#define BIT_I(w, i) SHIFTR0(SHIFTR(IL_TRUE, UN(w, 0), U8(1)), i)
/**
* \brief Sets bit \p i (=IL_TRUE) in the local variable with width \p w of the name \p vn.
* Please note: The left most bit is bit 0.
*/
#define SET_BIT(vn, w, i) SETL(vn, LOGOR(VARL(vn), BIT_I(w, i)))
/**
* \brief Unsets bit \p i (=IL_FALSE) in the local variable with width \p w of the name \p vn.
* Please note: The left most bit is bit 0.
*/
#define UNSET_BIT(vn, w, i) SETL(vn, LOGAND(VARL(vn), LOGNOT(BIT_MASK(w, i, i))))
/**
* \brief Returns a Pure of length \p l with bit \p i to \p j (inclusive \p j) set to IL_TRUE.
* \p i marks the left bit. \p j the right. \p i and \p j need to be U8.
* Please note: The left most bit is bit 0.
*/
#define BIT_MASK(l, i, j) LOGNOT(LOGOR(SHIFTR(IL_TRUE, UN(l, 0), i), SHIFTL(IL_TRUE, UN(l, 0), SUB(U8(l - 1), j))))
/**
* \brief Sets bit \p i to \p j of the variable \p v to the value stored in \p s.
* Both variables must be of width w.
* \p i and \p j should be U8
* Please note: The left most bit is bit 0.
*/
#define SET_RANGE(v, i, j, s, w) LOGOR(LOGAND(LOGNOT(BIT_MASK(w, i, j)), v), LOGAND(SHIFTL0(s, SUB(U8(w), j)), BIT_MASK(w, i, j)))
/**
* \brief Tests bit i in Pure value v with a width of w.
* Returns IL_TRUE if bit i is set. IL_FALSE otherwise.
* Please note: The left most bit is bit 0.
*/
#define BIT_IS_SET(val, w, i) NON_ZERO(LOGAND(val, BIT_I(w, i)))
/**
* \brief Implements the mask generation from the Reference Manual.
*
* if mstart mstop then
* mask[mstart:mstop] = ones
* mask[all other bits] = zeros
* else
* mask[mstart:63] = ones
* mask[0:mstop] = ones
* mask[all other bits] = zeros
*
* The algorithm implemented here is:
*
* ```
* m = 0
* while (mstart != mstop) {
* m[mstart] = 1
* mstart = (mstart + 1) % 64
* }
* m[mstop] = 1
* mask = (PPC_ARCH_BITS) m
* ```
*
* All computations are on 64 bit numbers.
* In case of a 32bit CPU the result will be casted to 32bit.
* The local variable "mask" will hold the mask
*/
#define SET_MASK(mstart, mstop) \
SEQ6(SETL("mstart", mstart), \
SETL("mstop", mstop), \
SETL("m", U64(0)), \
REPEAT(INV(EQ(VARL("mstart"), VARL("mstop"))), \
SEQ2(SET_BIT("m", 64, VARL("mstart")), \
SETL("mstart", MOD(ADD(VARL("mstart"), U8(1)), U8(64))))), \
SET_BIT("m", 64, VARL("mstop")), \
SETL("mask", CAST(PPC_ARCH_BITS, IL_FALSE, VARL("m"))))
RZ_IPI RzAnalysisILConfig *rz_ppc_cs_64_il_config(bool big_endian);
RZ_IPI RzAnalysisILConfig *rz_ppc_cs_32_il_config(bool big_endian);
RZ_IPI RzILOpEffect *rz_ppc_cs_get_il_op(RZ_BORROW csh handle, RZ_BORROW cs_insn *insn, const cs_mode mode);
RZ_IPI RZ_OWN RzILOpEffect *ppc_set_carry_add_sub(RZ_OWN RzILOpBitVector *a, RZ_OWN RzILOpBitVector *b, RZ_OWN RZ_NULLABLE RzILOpBitVector *c, cs_mode mode);
RZ_IPI RZ_OWN RzILOpEffect *ppc_cmp_set_cr(RZ_BORROW RzILOpPure *left, RZ_BORROW RzILOpPure *right, const bool signed_cmp, const char *crX, const cs_mode mode);
RZ_IPI bool ppc_is_x_form(ut32 insn_id);
RZ_IPI st32 ppc_get_mem_acc_size(ut32 insn_id);
RZ_IPI bool ppc_updates_ra_with_ea(ut32 insn_id);
RZ_IPI bool ppc_is_algebraic(ut32 insn_id);
RZ_IPI bool ppc_sets_lr(ut32 insn_id);
RZ_IPI bool ppc_is_conditional(ut32 insn_id);
RZ_IPI bool ppc_moves_to_spr(ut32 insn_id);
RZ_IPI bool ppc_is_mul_div_d(const ut32 id, const cs_mode mode);
RZ_IPI bool ppc_is_mul_div_u(const ut32 id);
RZ_IPI bool ppc_decrements_ctr(RZ_BORROW cs_insn *insn, const cs_mode mode);
RZ_IPI ut32 ppc_fmx_to_mask(const ut8 fmx);
RZ_IPI RZ_OWN RzILOpEffect *ppc_set_xer(RzILOpPure *val, cs_mode mode);
RZ_IPI RZ_OWN RzILOpPure *ppc_get_xer(cs_mode mode);
RZ_IPI RZ_OWN RzILOpPure *ppc_get_branch_ta(RZ_BORROW cs_insn *insn, const cs_mode mode);
RZ_IPI RZ_OWN RzILOpPure *ppc_get_branch_cond(const csh handle, RZ_BORROW cs_insn *insn, const cs_mode mode);
RZ_IPI RZ_OWN RzILOpEffect *ppc_sync_crx_cr(const bool to_cr, const ut32 cr_mask);
#endif /* PPC_IL_H */

View file

@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2022 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include "ppc_il.h"
#include "ppc_analysis.h"
#include "rz_il/rz_il_opcodes.h"
#include <rz_types.h>
#include <rz_il/rz_il_opbuilder_begin.h>
/**
* \brief Set "ca" bit if, after an add operation on \p a and \p b , the M+1 bit is set.
* If \p c is given the ca bit is set if the result of ( \p b + \p c ) or ( \p a + ( \p b + \p c )) has bit M+1 set.
*
* \param a Value a.
* \param b Value b.
* \param c Value c. Is optional and can be NULL
* \param mode Capstone mode.
* \return RzILOpEffect* Effect which sets the carry bits.
*/
RZ_IPI RZ_OWN RzILOpEffect *ppc_set_carry_add_sub(RZ_OWN RzILOpBitVector *a, RZ_OWN RzILOpBitVector *b, RZ_OWN RZ_NULLABLE RzILOpBitVector *c, cs_mode mode) {
rz_return_val_if_fail(a && b, NULL);
ut32 bits = PPC_ARCH_BITS;
RzILOpPure *r0, *r2;
if (c) {
r2 = ADD(UNSIGNED(bits + 1, a), VARLP("r1"));
r0 = LET("r1", ADD(UNSIGNED(bits + 1, b), UNSIGNED(bits + 1, c)), OR(MSB(VARLP("r1")), MSB(r2)));
} else {
r0 = MSB(ADD(UNSIGNED(bits + 1, a), UNSIGNED(bits + 1, b)));
}
// For ISA v3 CPU register ca32 should be handled here as well.
return SETG("ca", r0);
}
/**
* \brief Compares two values and sets the given cr field.
*
* \param left The left operand of the comparison.
* \param right The right operand of the comparison.
* \param signed_cmp True: Signed comparison. False: Unsigned comparison.
* \param crX The cr field to set.
* \param mode Capstone mode.
* \return RzILOpEffect* Sequence of effects which set the cr field accordingly.
*/
RZ_IPI RZ_OWN RzILOpEffect *ppc_cmp_set_cr(RZ_BORROW RzILOpPure *left, RZ_BORROW RzILOpPure *right, const bool signed_cmp, const char *crX, const cs_mode mode) {
rz_return_val_if_fail(left && right && crX, NULL);
RzILOpEffect *set_so = SETL("so_flag", BOOL_TO_BV(VARG("so"), 1));
RzILOpEffect *set_left = SETL("l", DUP(left));
RzILOpEffect *set_right = SETL("r", DUP(right));
RzILOpPure *cmp_gt = signed_cmp ? SGT(VARL("l"), VARL("r")) : UGT(VARL("l"), VARL("r"));
RzILOpPure *cmp_lt = signed_cmp ? SLT(VARL("l"), VARL("r")) : ULT(VARL("l"), VARL("r"));
RzILOpEffect *cond_geq = BRANCH(cmp_gt,
SETG(crX, APPEND(UN(3, 0b010), VARL("so_flag"))), // left > right
SETG(crX, APPEND(UN(3, 0b001), VARL("so_flag"))) // left == right
);
RzILOpEffect *cond_l = BRANCH(cmp_lt,
SETG(crX, APPEND(UN(3, 0b100), VARL("so_flag"))), // left < right
cond_geq);
return SEQ4(set_left, set_right, set_so, cond_l);
}
#include <rz_il/rz_il_opbuilder_end.h>

File diff suppressed because it is too large Load diff

View file

@ -286,6 +286,7 @@ RZ_API bool rz_analysis_il_vm_setup(RzAnalysis *analysis) {
rz_return_val_if_fail(analysis, false);
rz_analysis_il_vm_cleanup(analysis);
if (!analysis->cur || !analysis->cur->il_config) {
RZ_LOG_WARN("Could not set up VM. Analysis plugin or RZIL config was NULL.\n");
return false;
}
analysis->il_vm = rz_analysis_il_vm_new(analysis, analysis->reg);

View file

@ -161,6 +161,9 @@ rz_analysis_sources = [
'arch/avr/avr_il.c',
'arch/arm/arm_il32.c',
'arch/arm/arm_il64.c',
'arch/ppc/ppc_il.c',
'arch/ppc/ppc_il_ops.c',
'arch/ppc/ppc_il_flag_ops.c',
'arch/sh/sh_il.c',
'../asm/arch/amd29k/amd29k.c',
'../asm/arch/avr/disassembler.c',

View file

@ -6,6 +6,8 @@
#include <capstone/capstone.h>
#include <capstone/ppc.h>
#include "../../asm/arch/ppc/libvle/vle.h"
#include "../arch/ppc/ppc_analysis.h"
#include "../arch/ppc/ppc_il.h"
#define SPR_HID0 0x3f0 /* Hardware Implementation Register 0 */
#define SPR_HID1 0x3f1 /* Hardware Implementation Register 1 */
@ -20,10 +22,6 @@ struct Getarg {
int bits;
};
#define INSOPS insn->detail->ppc.op_count
#define INSOP(n) insn->detail->ppc.operands[n]
#define IMM(x) (ut64)(insn->detail->ppc.operands[x].imm)
#ifndef PFMT32x
#define PFMT32x "lx"
#endif
@ -209,12 +207,11 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) {
static char *get_reg_profile(RzAnalysis *analysis) {
const char *p = NULL;
if (analysis->bits == 32) {
if (analysis->bits == 64) {
p =
"=PC pc\n"
"=SP r1\n"
"=BP r31\n"
"=SR srr1\n" // status register ??
"=SN r3\n" // also for ret
"=A0 r3\n" // also for ret
"=A1 r4\n"
@ -223,99 +220,259 @@ static char *get_reg_profile(RzAnalysis *analysis) {
"=A4 r7\n"
"=A5 r8\n"
"=A6 r6\n"
"gpr srr0 .32 0 0\n"
"gpr srr1 .32 4 0\n"
"gpr r0 .32 8 0\n"
"gpr r1 .32 12 0\n"
"gpr r2 .32 16 0\n"
"gpr r3 .32 20 0\n"
"gpr r4 .32 24 0\n"
"gpr r5 .32 28 0\n"
"gpr r6 .32 32 0\n"
"gpr r7 .32 36 0\n"
"gpr r8 .32 40 0\n"
"gpr r9 .32 44 0\n"
"gpr r10 .32 48 0\n"
"gpr r11 .32 52 0\n"
"gpr r12 .32 56 0\n"
"gpr r13 .32 60 0\n"
"gpr r14 .32 64 0\n"
"gpr r15 .32 68 0\n"
"gpr r16 .32 72 0\n"
"gpr r17 .32 76 0\n"
"gpr r18 .32 80 0\n"
"gpr r19 .32 84 0\n"
"gpr r20 .32 88 0\n"
"gpr r21 .32 92 0\n"
"gpr r22 .32 96 0\n"
"gpr r23 .32 100 0\n"
"gpr r24 .32 104 0\n"
"gpr r25 .32 108 0\n"
"gpr r26 .32 112 0\n"
"gpr r27 .32 116 0\n"
"gpr r28 .32 120 0\n"
"gpr r29 .32 124 0\n"
"gpr r30 .32 128 0\n"
"gpr r31 .32 132 0\n"
"gpr lr .32 136 0\n"
"gpr ctr .32 140 0\n"
"gpr msr .32 144 0\n"
"gpr pc .32 148 0\n"
"gpr cr .64 152 0\n"
"gpr cr0 .8 152 0\n"
"gpr cr1 .8 153 0\n"
"gpr cr2 .8 154 0\n"
"gpr cr3 .8 155 0\n"
"gpr cr4 .8 156 0\n"
"gpr cr5 .8 157 0\n"
"gpr cr6 .8 158 0\n"
"gpr cr7 .8 159 0\n"
"gpr xer .32 160 0\n"
"gpr mq .32 164 0\n"
"gpr fpscr .32 168 0\n"
"gpr vrsave .32 172 0\n"
"gpr pvr .32 176 0\n"
"gpr dccr .32 180 0\n"
"gpr iccr .32 184 0\n"
"gpr dear .32 188 0\n"
"gpr hid0 .32 192 0\n"
"gpr hid1 .32 196 0\n"
"gpr hid2 .32 200 0\n"
"gpr hid3 .32 204 0\n"
"gpr hid4 .32 208 0\n"
"gpr hid5 .32 212 0\n"
"gpr hid6 .32 216 0\n"
"gpr ibat0 .64 220 0\n"
"gpr ibat1 .64 228 0\n"
"gpr ibat2 .64 236 0\n"
"gpr ibat3 .64 244 0\n"
"gpr ibat0l .32 220 0\n"
"gpr ibat1l .32 228 0\n"
"gpr ibat2l .32 236 0\n"
"gpr ibat3l .32 244 0\n"
"gpr ibat0u .32 224 0\n"
"gpr ibat1u .32 232 0\n"
"gpr ibat2u .32 240 0\n"
"gpr ibat3u .32 248 0\n"
"gpr dbat0 .64 256 0\n"
"gpr dbat1 .64 264 0\n"
"gpr dbat2 .64 272 0\n"
"gpr dbat3 .64 280 0\n"
"gpr dbat0l .32 256 0\n"
"gpr dbat1l .32 264 0\n"
"gpr dbat2l .32 272 0\n"
"gpr dbat3l .32 280 0\n"
"gpr dbat0u .32 260 0\n"
"gpr dbat1u .32 268 0\n"
"gpr dbat2u .32 276 0\n"
"gpr dbat3u .32 284 0\n"
"gpr mask .32 288 0\n";
"=OF ov\n"
"=CF ca\n"
"gpr r0 .64 0 0 \n"
"gpr r1 .64 8 0 \n"
"gpr r2 .64 16 0 \n"
"gpr r3 .64 24 0 \n"
"gpr r4 .64 32 0 \n"
"gpr r5 .64 40 0 \n"
"gpr r6 .64 48 0 \n"
"gpr r7 .64 56 0 \n"
"gpr r8 .64 64 0 \n"
"gpr r9 .64 72 0 \n"
"gpr r10 .64 80 0 \n"
"gpr r11 .64 88 0 \n"
"gpr r12 .64 96 0 \n"
"gpr r13 .64 104 0 \n"
"gpr r14 .64 112 0 \n"
"gpr r15 .64 120 0 \n"
"gpr r16 .64 128 0 \n"
"gpr r17 .64 136 0 \n"
"gpr r18 .64 144 0 \n"
"gpr r19 .64 152 0 \n"
"gpr r20 .64 160 0 \n"
"gpr r21 .64 168 0 \n"
"gpr r22 .64 176 0 \n"
"gpr r23 .64 184 0 \n"
"gpr r24 .64 192 0 \n"
"gpr r25 .64 200 0 \n"
"gpr r26 .64 208 0 \n"
"gpr r27 .64 216 0 \n"
"gpr r28 .64 224 0 \n"
"gpr r29 .64 232 0 \n"
"gpr r30 .64 240 0 \n"
"gpr r31 .64 248 0 \n"
"vc vs0 .128 256 0 \n"
"vc vs1 .128 272 0 \n"
"vc vs2 .128 288 0 \n"
"vc vs3 .128 304 0 \n"
"vc vs4 .128 320 0 \n"
"vc vs5 .128 336 0 \n"
"vc vs6 .128 352 0 \n"
"vc vs7 .128 368 0 \n"
"vc vs8 .128 384 0 \n"
"vc vs9 .128 400 0 \n"
"vc vs10 .128 416 0 \n"
"vc vs11 .128 432 0 \n"
"vc vs12 .128 448 0 \n"
"vc vs13 .128 464 0 \n"
"vc vs14 .128 480 0 \n"
"vc vs15 .128 496 0 \n"
"vc vs16 .128 512 0 \n"
"vc vs17 .128 528 0 \n"
"vc vs18 .128 544 0 \n"
"vc vs19 .128 560 0 \n"
"vc vs20 .128 576 0 \n"
"vc vs21 .128 592 0 \n"
"vc vs22 .128 608 0 \n"
"vc vs23 .128 624 0 \n"
"vc vs24 .128 640 0 \n"
"vc vs25 .128 656 0 \n"
"vc vs26 .128 672 0 \n"
"vc vs27 .128 688 0 \n"
"vc vs28 .128 704 0 \n"
"vc vs29 .128 720 0 \n"
"vc vs30 .128 736 0 \n"
"vc vs31 .128 752 0 \n"
"vc vs32 .128 768 0 \n"
"vc vs33 .128 784 0 \n"
"vc vs34 .128 800 0 \n"
"vc vs35 .128 816 0 \n"
"vc vs36 .128 832 0 \n"
"vc vs37 .128 848 0 \n"
"vc vs38 .128 864 0 \n"
"vc vs39 .128 880 0 \n"
"vc vs40 .128 896 0 \n"
"vc vs41 .128 912 0 \n"
"vc vs42 .128 928 0 \n"
"vc vs43 .128 944 0 \n"
"vc vs44 .128 960 0 \n"
"vc vs45 .128 976 0 \n"
"vc vs46 .128 992 0 \n"
"vc vs47 .128 1008 0 \n"
"vc vs48 .128 1024 0 \n"
"vc vs49 .128 1040 0 \n"
"vc vs50 .128 1056 0 \n"
"vc vs51 .128 1072 0 \n"
"vc vs52 .128 1088 0 \n"
"vc vs53 .128 1104 0 \n"
"vc vs54 .128 1120 0 \n"
"vc vs55 .128 1136 0 \n"
"vc vs56 .128 1152 0 \n"
"vc vs57 .128 1168 0 \n"
"vc vs58 .128 1184 0 \n"
"vc vs59 .128 1200 0 \n"
"vc vs60 .128 1216 0 \n"
"vc vs61 .128 1232 0 \n"
"vc vs62 .128 1248 0 \n"
"vc vs63 .128 1264 0 \n"
"fpu f0 .64 1280 0 \n"
"fpu f1 .64 1288 0 \n"
"fpu f2 .64 1296 0 \n"
"fpu f3 .64 1304 0 \n"
"fpu f4 .64 1312 0 \n"
"fpu f5 .64 1320 0 \n"
"fpu f6 .64 1328 0 \n"
"fpu f7 .64 1336 0 \n"
"fpu f8 .64 1344 0 \n"
"fpu f9 .64 1352 0 \n"
"fpu f10 .64 1360 0 \n"
"fpu f11 .64 1368 0 \n"
"fpu f12 .64 1376 0 \n"
"fpu f13 .64 1384 0 \n"
"fpu f14 .64 1392 0 \n"
"fpu f15 .64 1400 0 \n"
"fpu f16 .64 1408 0 \n"
"fpu f17 .64 1416 0 \n"
"fpu f18 .64 1424 0 \n"
"fpu f19 .64 1432 0 \n"
"fpu f20 .64 1440 0 \n"
"fpu f21 .64 1448 0 \n"
"fpu f22 .64 1456 0 \n"
"fpu f23 .64 1464 0 \n"
"fpu f24 .64 1472 0 \n"
"fpu f25 .64 1480 0 \n"
"fpu f26 .64 1488 0 \n"
"fpu f27 .64 1496 0 \n"
"fpu f28 .64 1504 0 \n"
"fpu f29 .64 1512 0 \n"
"fpu f30 .64 1520 0 \n"
"fpu f31 .64 1528 0 \n"
"vc v0 .128 1536 0 \n"
"vc v1 .128 1552 0 \n"
"vc v2 .128 1568 0 \n"
"vc v3 .128 1584 0 \n"
"vc v4 .128 1600 0 \n"
"vc v5 .128 1616 0 \n"
"vc v6 .128 1632 0 \n"
"vc v7 .128 1648 0 \n"
"vc v8 .128 1664 0 \n"
"vc v9 .128 1680 0 \n"
"vc v10 .128 1696 0 \n"
"vc v11 .128 1712 0 \n"
"vc v12 .128 1728 0 \n"
"vc v13 .128 1744 0 \n"
"vc v14 .128 1760 0 \n"
"vc v15 .128 1776 0 \n"
"vc v16 .128 1792 0 \n"
"vc v17 .128 1808 0 \n"
"vc v18 .128 1824 0 \n"
"vc v19 .128 1840 0 \n"
"vc v20 .128 1856 0 \n"
"vc v21 .128 1872 0 \n"
"vc v22 .128 1888 0 \n"
"vc v23 .128 1904 0 \n"
"vc v24 .128 1920 0 \n"
"vc v25 .128 1936 0 \n"
"vc v26 .128 1952 0 \n"
"vc v27 .128 1968 0 \n"
"vc v28 .128 1984 0 \n"
"vc v29 .128 2000 0 \n"
"vc v30 .128 2016 0 \n"
"vc v31 .128 2032 0 \n"
"ctr xer .64 2048 0 # Fixed-Point Exception Register\n"
"vcc vrsave .32 2056 0 # VR Save Register\n"
"ctr fpscr .64 2060 0 # Floating-Point Status and Control Register\n"
"vcc vscr .32 2068 0 # Vector Status and Control Register\n"
"ctr cr .32 2072 0 # Condition Register\n"
"ctr lr .64 2076 0 # Link Register\n"
"ctr ctr .64 2084 0 # Count Register\n"
"ctr tar .64 2092 0 # Target Address Register\n"
"ctr ppr .64 2100 0 # Process Priority Register\n"
"ctr dscr .64 2108 0 # Data Stream Control Register\n"
"ctr bescr .64 2116 0 # Branch Event Status and Control Register\n"
"ctr ebbhr .64 2124 0 # Event-Based Branch Handler Register\n"
"ctr ebbrr .64 2132 0 # Event-Based Branch Return Register\n"
"ctr lpcr .64 2140 0 # Logical Partitioning Control Register\n"
"ctr hrmor .64 2148 0 # Hypervisor Real Mode Offset Register\n"
"ctr lpidr .32 2156 0 # Logical Partition Identification Regiser\n"
"ctr pcr .64 2160 0 # Processor Compatibility Register\n"
"ctr tir .64 2168 0 # Thread Identification Register\n"
"ctr urmor .64 2176 0 # Ultravisor Real Mode Offset Register\n"
"ctr smfctrl .64 2184 0 # Secure Memory Facility Control Register\n"
"ctr msr .64 2192 0 # Machine State Register\n"
"ctr pvr .32 2200 0 # Processor Version Register\n"
"ctr pir .32 2204 0 # Processor Version Register\n"
"ctr pidr .32 2208 0 # Processor Identification Register\n"
"ctr ctrl .32 2212 0 # Control Register\n"
"ctr pspb .32 2216 0 # Problem State Priority Boost Register\n"
"ctr rpr .64 2220 0 # Relative Priority Register\n"
"ctr hashkey .64 2228 0 # Hash Key Register\n"
"ctr hashpkey .64 2236 0 # Hash Privileged Key Register\n"
"ctr sprg0 .64 2244 0 # Software-use SPR 0\n"
"ctr sprg1 .64 2252 0 # Software-use SPR 1\n"
"ctr sprg2 .64 2260 0 # Software-use SPR 2\n"
"ctr sprg3 .64 2268 0 # Software-use SPR 3\n"
"ctr hsprg0 .64 2276 0 # Hypervisor Software-use SPR 0\n"
"ctr hsprg1 .64 2284 0 # Hypervisor Software-use SPR 1\n"
"ctr usprg0 .64 2292 0 # Ultravisor Software-use SPR 0\n"
"ctr usprg1 .64 2300 0 # Ultravisor Software-use SPR 1\n"
"ctr srr0 .64 2308 0 # Machine Status Save/Restore Register 0\n"
"ctr srr1 .64 2316 0 # Machine Status Save/Restore Register 1\n"
"ctr hsrr0 .64 2324 0 # Hypervisor Machine Status Save/Restore Register 0\n"
"ctr hsrr1 .64 2332 0 # Hypervisor Machine Status Save/Restore Register 1\n"
"ctr usrr0 .64 2340 0 # Hypervisor Machine Status Save/Restore Register 0\n"
"ctr usrr1 .64 2348 0 # Ultravisor Machine Status Save/Restore Register 1\n"
"ctr asdr .64 2356 0 # Access Segment Descriptor Register\n"
"ctr dar .64 2364 0 # Data Address Register\n"
"ctr hdar .64 2372 0 # Hypervisor Data Address Register\n"
"ctr dsisr .32 2380 0 # Data Storage Interrupt Status Register\n"
"ctr hdsisr .32 2384 0 # Hypervisor Data Storage Interrupt Status Register\n"
"ctr heir .64 2388 0 # Hypervisor Emulation Instruction Register\n"
"ctr hmer .64 2396 0 # Hypervisor Maintenance Exception Register\n"
"ctr hmeer .64 2404 0 # Hypervisor Maintenance Exception Enable Register\n"
"ctr fscr .64 2412 0 # Facility Status and Control Register\n"
"ctr hfscr .64 2420 0 # Hypervisor Facility Status and Control Register\n"
"ctr purr .64 2428 0 # Process Utilization of Resources Register\n"
"ctr spurr .64 2436 0 # Scaled Process Utilization of Resources Register\n"
"ctr dexcr .64 2444 0 # Dynamic Execution Control Register\n"
"ctr hdexcr .64 2452 0 # Hypervisor Dynamic Execution Control Register\n"
"ctr udexcr .64 2460 0 # Ultravisor Dynamic Execution Control Register\n"
"ctr cfar .64 2468 0 # Come-From Address Register\n"
"ctr mmcr0 .64 2476 0 # Monitor Mode Control Register 0\n"
"ctr mmcr1 .64 2484 0 # Monitor Mode Control Register 1\n"
"ctr mmcr2 .64 2492 0 # Monitor Mode Control Register 2\n"
"ctr mmcra .64 2500 0 # Monitor Mode Control Register A\n"
"ctr siar .64 2508 0 # Sampled Instruction Address Register\n"
"ctr sdar .64 2516 0 # Sampled Data Address Register\n"
"ctr sier .64 2524 0 # Sampled Instruction Event Register\n"
"ctr sier2 .64 2532 0 # Sampled Instruction Event Register 2\n"
"ctr sier3 .64 2540 0 # Sampled Instruction Event Register 3\n"
"ctr mmcr3 .64 2548 0 # Monitor Mode Control Register 2\n"
"ctr dpdes .64 2556 0 # Directed Privileged Doorbell Exception State Register\n"
"ctr pc .64 2564 0 # Programm Counter\n"
"ctr cr0 .4 2572 0 # Condition Register Field 0\n"
"ctr cr1 .4 2573 0 # Condition Register Field 1\n"
"ctr cr2 .4 2574 0 # Condition Register Field 2\n"
"ctr cr3 .4 2575 0 # Condition Register Field 3\n"
"ctr cr4 .4 2576 0 # Condition Register Field 4\n"
"ctr cr5 .4 2577 0 # Condition Register Field 5\n"
"ctr cr6 .4 2578 0 # Condition Register Field 6\n"
"ctr cr7 .4 2579 0 # Condition Register Field 7\n"
"ctr ppr32 .32 2580 0 # Process Priority Register 32-bit\n"
"flg so .1 2584 0 # Summary Overflow\n"
"flg ov .1 2585 0 # Overflow\n"
"flg ca .1 2586 0 # Carry\n";
return strdup(p);
} else {
p =
"=PC pc\n"
"=SP r1\n"
"=SR srr1\n" // status register ??
"=SN r0\n" // also for ret
"=BP r31\n"
"=SN r3\n" // also for ret
"=A0 r3\n" // also for ret
"=A1 r4\n"
"=A2 r5\n"
@ -323,95 +480,254 @@ static char *get_reg_profile(RzAnalysis *analysis) {
"=A4 r7\n"
"=A5 r8\n"
"=A6 r6\n"
"gpr srr0 .64 0 0\n"
"gpr srr1 .64 8 0\n"
"gpr r0 .64 16 0\n"
"gpr r1 .64 24 0\n"
"gpr r2 .64 32 0\n"
"gpr r3 .64 40 0\n"
"gpr r4 .64 48 0\n"
"gpr r5 .64 56 0\n"
"gpr r6 .64 64 0\n"
"gpr r7 .64 72 0\n"
"gpr r8 .64 80 0\n"
"gpr r9 .64 88 0\n"
"gpr r10 .64 96 0\n"
"gpr r11 .64 104 0\n"
"gpr r12 .64 112 0\n"
"gpr r13 .64 120 0\n"
"gpr r14 .64 128 0\n"
"gpr r15 .64 136 0\n"
"gpr r16 .64 144 0\n"
"gpr r17 .64 152 0\n"
"gpr r18 .64 160 0\n"
"gpr r19 .64 168 0\n"
"gpr r20 .64 176 0\n"
"gpr r21 .64 184 0\n"
"gpr r22 .64 192 0\n"
"gpr r23 .64 200 0\n"
"gpr r24 .64 208 0\n"
"gpr r25 .64 216 0\n"
"gpr r26 .64 224 0\n"
"gpr r27 .64 232 0\n"
"gpr r28 .64 240 0\n"
"gpr r29 .64 248 0\n"
"gpr r30 .64 256 0\n"
"gpr r31 .64 264 0\n"
"gpr lr .64 272 0\n"
"gpr ctr .64 280 0\n"
"gpr msr .64 288 0\n"
"gpr pc .64 296 0\n"
"gpr cr .64 304 0\n"
"gpr cr0 .8 304 0\n"
"gpr cr1 .8 305 0\n"
"gpr cr2 .8 306 0\n"
"gpr cr3 .8 307 0\n"
"gpr cr4 .8 308 0\n"
"gpr cr5 .8 309 0\n"
"gpr cr6 .8 310 0\n"
"gpr cr7 .8 311 0\n"
"gpr xer .64 312 0\n"
"gpr mq .64 320 0\n"
"gpr fpscr .64 328 0\n"
"gpr vrsave .64 336 0\n"
"gpr pvr .64 344 0\n"
"gpr dccr .32 352 0\n"
"gpr iccr .32 356 0\n"
"gpr dear .32 360 0\n"
"gpr hid0 .64 364 0\n"
"gpr hid1 .64 372 0\n"
"gpr hid2 .64 380 0\n"
"gpr hid3 .64 388 0\n"
"gpr hid4 .64 396 0\n"
"gpr hid5 .64 404 0\n"
"gpr hid6 .64 412 0\n"
"gpr ibat0 .64 420 0\n"
"gpr ibat1 .64 428 0\n"
"gpr ibat2 .64 436 0\n"
"gpr ibat3 .64 444 0\n"
"gpr ibat0l .32 420 0\n"
"gpr ibat1l .32 428 0\n"
"gpr ibat2l .32 436 0\n"
"gpr ibat3l .32 444 0\n"
"gpr ibat0u .32 424 0\n"
"gpr ibat1u .32 432 0\n"
"gpr ibat2u .32 440 0\n"
"gpr ibat3u .32 448 0\n"
"gpr dbat0 .64 456 0\n"
"gpr dbat1 .64 464 0\n"
"gpr dbat2 .64 472 0\n"
"gpr dbat3 .64 480 0\n"
"gpr dbat0l .32 456 0\n"
"gpr dbat1l .32 464 0\n"
"gpr dbat2l .32 472 0\n"
"gpr dbat3l .32 480 0\n"
"gpr dbat0u .32 460 0\n"
"gpr dbat1u .32 468 0\n"
"gpr dbat2u .32 476 0\n"
"gpr dbat3u .32 484 0\n"
"gpr mask .64 488 0\n"; // not a real register used on complex functions
"=OF ov\n"
"=CF ca\n"
"gpr r0 .32 0 0 \n"
"gpr r1 .32 8 0 \n"
"gpr r2 .32 16 0 \n"
"gpr r3 .32 24 0 \n"
"gpr r4 .32 32 0 \n"
"gpr r5 .32 40 0 \n"
"gpr r6 .32 48 0 \n"
"gpr r7 .32 56 0 \n"
"gpr r8 .32 64 0 \n"
"gpr r9 .32 72 0 \n"
"gpr r10 .32 80 0 \n"
"gpr r11 .32 88 0 \n"
"gpr r12 .32 96 0 \n"
"gpr r13 .32 104 0 \n"
"gpr r14 .32 112 0 \n"
"gpr r15 .32 120 0 \n"
"gpr r16 .32 128 0 \n"
"gpr r17 .32 136 0 \n"
"gpr r18 .32 144 0 \n"
"gpr r19 .32 152 0 \n"
"gpr r20 .32 160 0 \n"
"gpr r21 .32 168 0 \n"
"gpr r22 .32 176 0 \n"
"gpr r23 .32 184 0 \n"
"gpr r24 .32 192 0 \n"
"gpr r25 .32 200 0 \n"
"gpr r26 .32 208 0 \n"
"gpr r27 .32 216 0 \n"
"gpr r28 .32 224 0 \n"
"gpr r29 .32 232 0 \n"
"gpr r30 .32 240 0 \n"
"gpr r31 .32 248 0 \n"
"vc vs0 .128 256 0 \n"
"vc vs1 .128 272 0 \n"
"vc vs2 .128 288 0 \n"
"vc vs3 .128 304 0 \n"
"vc vs4 .128 320 0 \n"
"vc vs5 .128 336 0 \n"
"vc vs6 .128 352 0 \n"
"vc vs7 .128 368 0 \n"
"vc vs8 .128 384 0 \n"
"vc vs9 .128 400 0 \n"
"vc vs10 .128 416 0 \n"
"vc vs11 .128 432 0 \n"
"vc vs12 .128 448 0 \n"
"vc vs13 .128 464 0 \n"
"vc vs14 .128 480 0 \n"
"vc vs15 .128 496 0 \n"
"vc vs16 .128 512 0 \n"
"vc vs17 .128 528 0 \n"
"vc vs18 .128 544 0 \n"
"vc vs19 .128 560 0 \n"
"vc vs20 .128 576 0 \n"
"vc vs21 .128 592 0 \n"
"vc vs22 .128 608 0 \n"
"vc vs23 .128 624 0 \n"
"vc vs24 .128 640 0 \n"
"vc vs25 .128 656 0 \n"
"vc vs26 .128 672 0 \n"
"vc vs27 .128 688 0 \n"
"vc vs28 .128 704 0 \n"
"vc vs29 .128 720 0 \n"
"vc vs30 .128 736 0 \n"
"vc vs31 .128 752 0 \n"
"vc vs32 .128 768 0 \n"
"vc vs33 .128 784 0 \n"
"vc vs34 .128 800 0 \n"
"vc vs35 .128 816 0 \n"
"vc vs36 .128 832 0 \n"
"vc vs37 .128 848 0 \n"
"vc vs38 .128 864 0 \n"
"vc vs39 .128 880 0 \n"
"vc vs40 .128 896 0 \n"
"vc vs41 .128 912 0 \n"
"vc vs42 .128 928 0 \n"
"vc vs43 .128 944 0 \n"
"vc vs44 .128 960 0 \n"
"vc vs45 .128 976 0 \n"
"vc vs46 .128 992 0 \n"
"vc vs47 .128 1008 0 \n"
"vc vs48 .128 1024 0 \n"
"vc vs49 .128 1040 0 \n"
"vc vs50 .128 1056 0 \n"
"vc vs51 .128 1072 0 \n"
"vc vs52 .128 1088 0 \n"
"vc vs53 .128 1104 0 \n"
"vc vs54 .128 1120 0 \n"
"vc vs55 .128 1136 0 \n"
"vc vs56 .128 1152 0 \n"
"vc vs57 .128 1168 0 \n"
"vc vs58 .128 1184 0 \n"
"vc vs59 .128 1200 0 \n"
"vc vs60 .128 1216 0 \n"
"vc vs61 .128 1232 0 \n"
"vc vs62 .128 1248 0 \n"
"vc vs63 .128 1264 0 \n"
"fpu f0 .64 1280 0 \n"
"fpu f1 .64 1288 0 \n"
"fpu f2 .64 1296 0 \n"
"fpu f3 .64 1304 0 \n"
"fpu f4 .64 1312 0 \n"
"fpu f5 .64 1320 0 \n"
"fpu f6 .64 1328 0 \n"
"fpu f7 .64 1336 0 \n"
"fpu f8 .64 1344 0 \n"
"fpu f9 .64 1352 0 \n"
"fpu f10 .64 1360 0 \n"
"fpu f11 .64 1368 0 \n"
"fpu f12 .64 1376 0 \n"
"fpu f13 .64 1384 0 \n"
"fpu f14 .64 1392 0 \n"
"fpu f15 .64 1400 0 \n"
"fpu f16 .64 1408 0 \n"
"fpu f17 .64 1416 0 \n"
"fpu f18 .64 1424 0 \n"
"fpu f19 .64 1432 0 \n"
"fpu f20 .64 1440 0 \n"
"fpu f21 .64 1448 0 \n"
"fpu f22 .64 1456 0 \n"
"fpu f23 .64 1464 0 \n"
"fpu f24 .64 1472 0 \n"
"fpu f25 .64 1480 0 \n"
"fpu f26 .64 1488 0 \n"
"fpu f27 .64 1496 0 \n"
"fpu f28 .64 1504 0 \n"
"fpu f29 .64 1512 0 \n"
"fpu f30 .64 1520 0 \n"
"fpu f31 .64 1528 0 \n"
"vc v0 .128 1536 0 \n"
"vc v1 .128 1552 0 \n"
"vc v2 .128 1568 0 \n"
"vc v3 .128 1584 0 \n"
"vc v4 .128 1600 0 \n"
"vc v5 .128 1616 0 \n"
"vc v6 .128 1632 0 \n"
"vc v7 .128 1648 0 \n"
"vc v8 .128 1664 0 \n"
"vc v9 .128 1680 0 \n"
"vc v10 .128 1696 0 \n"
"vc v11 .128 1712 0 \n"
"vc v12 .128 1728 0 \n"
"vc v13 .128 1744 0 \n"
"vc v14 .128 1760 0 \n"
"vc v15 .128 1776 0 \n"
"vc v16 .128 1792 0 \n"
"vc v17 .128 1808 0 \n"
"vc v18 .128 1824 0 \n"
"vc v19 .128 1840 0 \n"
"vc v20 .128 1856 0 \n"
"vc v21 .128 1872 0 \n"
"vc v22 .128 1888 0 \n"
"vc v23 .128 1904 0 \n"
"vc v24 .128 1920 0 \n"
"vc v25 .128 1936 0 \n"
"vc v26 .128 1952 0 \n"
"vc v27 .128 1968 0 \n"
"vc v28 .128 1984 0 \n"
"vc v29 .128 2000 0 \n"
"vc v30 .128 2016 0 \n"
"vc v31 .128 2032 0 \n"
"ctr xer .64 2048 0 # Fixed-Point Exception Register\n"
"vcc vrsave .32 2056 0 # VR Save Register\n"
"ctr fpscr .64 2060 0 # Floating-Point Status and Control Register\n"
"vcc vscr .32 2068 0 # Vector Status and Control Register\n"
"ctr cr .32 2072 0 # Condition Register\n"
"ctr lr .32 2076 0 # Link Register\n"
"ctr ctr .32 2084 0 # Count Register\n"
"ctr tar .32 2092 0 # Target Address Register\n"
"ctr ppr .64 2100 0 # Process Priority Register\n"
"ctr dscr .64 2108 0 # Data Stream Control Register\n"
"ctr bescr .64 2116 0 # Branch Event Status and Control Register\n"
"ctr ebbhr .64 2124 0 # Event-Based Branch Handler Register\n"
"ctr ebbrr .64 2132 0 # Event-Based Branch Return Register\n"
"ctr lpcr .64 2140 0 # Logical Partitioning Control Register\n"
"ctr hrmor .64 2148 0 # Hypervisor Real Mode Offset Register\n"
"ctr lpidr .32 2156 0 # Logical Partition Identification Regiser\n"
"ctr pcr .64 2160 0 # Processor Compatibility Register\n"
"ctr tir .64 2168 0 # Thread Identification Register\n"
"ctr urmor .64 2176 0 # Ultravisor Real Mode Offset Register\n"
"ctr smfctrl .64 2184 0 # Secure Memory Facility Control Register\n"
"ctr msr .64 2192 0 # Machine State Register\n"
"ctr pvr .32 2200 0 # Processor Version Register\n"
"ctr pir .32 2204 0 # Processor Version Register\n"
"ctr pidr .32 2208 0 # Processor Identification Register\n"
"ctr ctrl .32 2212 0 # Control Register\n"
"ctr pspb .32 2216 0 # Problem State Priority Boost Register\n"
"ctr rpr .64 2220 0 # Relative Priority Register\n"
"ctr hashkey .64 2228 0 # Hash Key Register\n"
"ctr hashpkey .64 2236 0 # Hash Privileged Key Register\n"
"ctr sprg0 .64 2244 0 # Software-use SPR 0\n"
"ctr sprg1 .64 2252 0 # Software-use SPR 1\n"
"ctr sprg2 .64 2260 0 # Software-use SPR 2\n"
"ctr sprg3 .64 2268 0 # Software-use SPR 3\n"
"ctr hsprg0 .64 2276 0 # Hypervisor Software-use SPR 0\n"
"ctr hsprg1 .64 2284 0 # Hypervisor Software-use SPR 1\n"
"ctr usprg0 .64 2292 0 # Ultravisor Software-use SPR 0\n"
"ctr usprg1 .64 2300 0 # Ultravisor Software-use SPR 1\n"
"ctr srr0 .64 2308 0 # Machine Status Save/Restore Register 0\n"
"ctr srr1 .64 2316 0 # Machine Status Save/Restore Register 1\n"
"ctr hsrr0 .64 2324 0 # Hypervisor Machine Status Save/Restore Register 0\n"
"ctr hsrr1 .64 2332 0 # Hypervisor Machine Status Save/Restore Register 1\n"
"ctr usrr0 .64 2340 0 # Hypervisor Machine Status Save/Restore Register 0\n"
"ctr usrr1 .64 2348 0 # Ultravisor Machine Status Save/Restore Register 1\n"
"ctr asdr .64 2356 0 # Access Segment Descriptor Register\n"
"ctr dar .64 2364 0 # Data Address Register\n"
"ctr hdar .64 2372 0 # Hypervisor Data Address Register\n"
"ctr dsisr .32 2380 0 # Data Storage Interrupt Status Register\n"
"ctr hdsisr .32 2384 0 # Hypervisor Data Storage Interrupt Status Register\n"
"ctr heir .64 2388 0 # Hypervisor Emulation Instruction Register\n"
"ctr hmer .64 2396 0 # Hypervisor Maintenance Exception Register\n"
"ctr hmeer .64 2404 0 # Hypervisor Maintenance Exception Enable Register\n"
"ctr fscr .64 2412 0 # Facility Status and Control Register\n"
"ctr hfscr .64 2420 0 # Hypervisor Facility Status and Control Register\n"
"ctr purr .64 2428 0 # Process Utilization of Resources Register\n"
"ctr spurr .64 2436 0 # Scaled Process Utilization of Resources Register\n"
"ctr dexcr .64 2444 0 # Dynamic Execution Control Register\n"
"ctr hdexcr .64 2452 0 # Hypervisor Dynamic Execution Control Register\n"
"ctr udexcr .64 2460 0 # Ultravisor Dynamic Execution Control Register\n"
"ctr cfar .64 2468 0 # Come-From Address Register\n"
"ctr mmcr0 .64 2476 0 # Monitor Mode Control Register 0\n"
"ctr mmcr1 .64 2484 0 # Monitor Mode Control Register 1\n"
"ctr mmcr2 .64 2492 0 # Monitor Mode Control Register 2\n"
"ctr mmcra .64 2500 0 # Monitor Mode Control Register A\n"
"ctr siar .64 2508 0 # Sampled Instruction Address Register\n"
"ctr sdar .64 2516 0 # Sampled Data Address Register\n"
"ctr sier .64 2524 0 # Sampled Instruction Event Register\n"
"ctr sier2 .64 2532 0 # Sampled Instruction Event Register 2\n"
"ctr sier3 .64 2540 0 # Sampled Instruction Event Register 3\n"
"ctr mmcr3 .64 2548 0 # Monitor Mode Control Register 2\n"
"ctr dpdes .64 2556 0 # Directed Privileged Doorbell Exception State Register\n"
"ctr pc .64 2564 0 # Programm Counter\n"
"ctr cr0 .4 2572 0 # Condition Register Field 0\n"
"ctr cr1 .4 2573 0 # Condition Register Field 1\n"
"ctr cr2 .4 2574 0 # Condition Register Field 2\n"
"ctr cr3 .4 2575 0 # Condition Register Field 3\n"
"ctr cr4 .4 2576 0 # Condition Register Field 4\n"
"ctr cr5 .4 2577 0 # Condition Register Field 5\n"
"ctr cr6 .4 2578 0 # Condition Register Field 6\n"
"ctr cr7 .4 2579 0 # Condition Register Field 7\n"
"ctr ppr32 .32 2580 0 # Process Priority Register 32-bit\n"
"flg so .1 2584 0 # Summary Overflow\n"
"flg ov .1 2585 0 # Overflow\n"
"flg ca .1 2586 0 # Carry\n";
return strdup(p);
}
return strdup(p);
}
static int analop_vle(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) {
@ -638,7 +954,9 @@ static int analop(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, in
n = cs_disasm(handle, (const ut8 *)buf, len, addr, 1, &insn);
if (n < 1) {
op->type = RZ_ANALYSIS_OP_TYPE_ILL;
op->il_op = rz_il_op_new_empty();
} else {
op->il_op = rz_ppc_cs_get_il_op(handle, insn, mode);
if (mask & RZ_ANALYSIS_OP_MASK_DISASM) {
op->mnemonic = strdup(insn->mnemonic);
}
@ -1314,6 +1632,13 @@ static RzList *analysis_preludes(RzAnalysis *analysis) {
return l;
}
static RzAnalysisILConfig *il_config(RzAnalysis *analysis) {
if (analysis->bits == 64) {
return rz_ppc_cs_64_il_config(analysis->big_endian);
}
return rz_ppc_cs_32_il_config(analysis->big_endian);
}
RzAnalysisPlugin rz_analysis_plugin_ppc_cs = {
.name = "ppc",
.desc = "Capstone PowerPC analysis",
@ -1325,6 +1650,7 @@ RzAnalysisPlugin rz_analysis_plugin_ppc_cs = {
.preludes = analysis_preludes,
.op = &analop,
.get_reg_profile = &get_reg_profile,
.il_config = il_config,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -685,7 +685,7 @@ RZ_API RZ_OWN RzILOpEffect *rz_il_op_new_blk(RZ_NONNULL const char *label, RZ_NO
/**
* \brief op structure for `repeat` (bool -> data eff -> data eff)
*
* repeat c data repeats data effects until the condition c holds.
* repeat c data repeats data effects until the condition c evaluates to false.
*/
RZ_API RZ_OWN RzILOpEffect *rz_il_op_new_repeat(RZ_NONNULL RzILOpBool *condition, RZ_NONNULL RzILOpEffect *data_eff) {
rz_return_val_if_fail(condition && data_eff, NULL);

View file

@ -108,8 +108,9 @@ RZ_API RzILRegBinding *rz_il_reg_binding_derive(RZ_NONNULL RzReg *reg) {
RzRegItem *prev = NULL;
rz_list_foreach (items, iter, item) {
if (prev && prev->offset + prev->size > item->offset) {
// overlap where one reg is not fully contained in another.
// this is not supported yet.
RZ_LOG_WARN("Could not bind register \"%s\"\n"
"\t It is not fully contained in another but overlaps with one.\n",
item->name);
continue;
}
if (pc && !strcmp(item->name, pc)) {

View file

@ -27,7 +27,7 @@ static void rz_il_set(RzILVM *vm, const char *var_name, bool is_local, RZ_OWN Rz
bool rz_il_handler_empty(RzILVM *vm, RzILOpEffect *op) {
rz_return_val_if_fail(vm && op, false);
RZ_LOG_WARN("Encountered an empty instruction at %s", rz_bv_as_string(vm->pc))
RZ_LOG_INFO("Encountered an empty instruction at %s\n", rz_bv_as_string(vm->pc))
return true;
}

View file

@ -37,11 +37,14 @@
#define ITE(c, t, f) rz_il_op_new_ite(c, t, f)
#define UN(l, val) rz_il_op_new_bitv_from_ut64(l, val)
#define U8(val) UN(8, val)
#define U16(val) UN(16, val)
#define U32(val) UN(32, val)
#define U64(val) UN(64, val)
#define UN(l, val) rz_il_op_new_bitv_from_ut64(l, val)
#define U8(val) UN(8, val)
#define U16(val) UN(16, val)
#define U32(val) UN(32, val)
#define U48(val) UN(48, val)
#define U64(val) UN(64, val)
#define CAST(l, f, v) rz_il_op_new_cast(l, f, v)
#define BOOL_TO_BV(b, l) ITE(b, UN(l, 1), UN(l, 0))
#define SN(l, val) rz_il_op_new_bitv_from_st64(l, val)
#define S8(val) SN(8, val)
@ -66,6 +69,8 @@
#define MUL(x, y) rz_il_op_new_mul(x, y)
#define DIV(x, y) rz_il_op_new_div(x, y)
#define SDIV(x, y) rz_il_op_new_sdiv(x, y)
#define MOD(x, y) rz_il_op_new_mod(x, y)
#define SMOD(x, y) rz_il_op_new_smod(x, y)
#define SHIFTL(f, v, dist) rz_il_op_new_shiftl(f, v, dist)
#define SHIFTR(f, v, dist) rz_il_op_new_shiftr(f, v, dist)
#define SHIFTL0(v, dist) SHIFTL(IL_FALSE, v, dist)
@ -111,6 +116,7 @@
#define SEQ7(e0, e1, e2, e3, e4, e5, e6) rz_il_op_new_seqn(7, e0, e1, e2, e3, e4, e5, e6)
#define SEQ8(e0, e1, e2, e3, e4, e5, e6, e7) rz_il_op_new_seqn(8, e0, e1, e2, e3, e4, e5, e6, e7)
#define SEQ9(e0, e1, e2, e3, e4, e5, e6, e7, e8) rz_il_op_new_seqn(9, e0, e1, e2, e3, e4, e5, e6, e7, e8)
#define SEQN(n, ...) rz_il_op_new_seqn(n, __VA_ARGS__)
#define EMPTY() rz_il_op_new_empty()
#define NOP() rz_il_op_new_nop()

View file

@ -9,7 +9,10 @@
#undef U8
#undef U16
#undef U32
#undef U48
#undef U64
#undef CAST
#undef BOOL_TO_BV
#undef SN
#undef S8
@ -28,6 +31,8 @@
#undef MUL
#undef DIV
#undef SDIV
#undef MOD
#undef SMOD
#undef SHIFTL
#undef SHIFTR
#undef SHIFTL0
@ -74,6 +79,7 @@
#undef SEQ7
#undef SEQ8
#undef SEQ9
#undef SEQN
#undef EMPTY
#undef NOP
@ -82,4 +88,6 @@
#undef JMP
#undef GOTO
#undef NOT_IMPLEMENTED
#undef RZ_IL_OPBUILDER_BEGIN_H

View file

@ -452,6 +452,7 @@ RZ_API RZ_OWN RzILOpBool *rz_il_op_new_bool_inv(RZ_NONNULL RzILOpBool *x);
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv(RZ_NONNULL RzBitVector *value);
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv_from_ut64(ut32 length, ut64 number);
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv_from_st64(ut32 length, st64 number);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_bitv_max(ut32 length);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_msb(RZ_NONNULL RzILOpPure *val);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_lsb(RZ_NONNULL RzILOpPure *val);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_is_zero(RZ_NONNULL RzILOpPure *bv);

View file

@ -229,6 +229,21 @@ RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value) {
case 8:
rz_write_ble8(src, (ut8)(value & UT8_MAX));
break;
case 4: {
// Example: 4bit Register is located at bit 1 of a byte.
// Example byte = 0b101xxxx1
// 'xxxx' are the bits where the new 'value' is set.
ut8 *buf = reg->regset[item->arena].arena->bytes + (item->offset / 8);
ut8 reg_byte = buf[0];
// Number of bits we have to shift the bits of the new value so they align with the 'xxxx' (in example: 1).
ut8 shift = item->offset % 8;
ut8 mask_xxxx = 0xf << shift;
ut8 xxxx = (value & 0xf) << shift;
ut8 new_val = (reg_byte & ~mask_xxxx) | xxxx;
rz_mem_copybits(buf, &new_val, 8); // Write byte back.
return true;
}
case 1:
if (value) {
ut8 *buf = arena->bytes + (item->offset / 8);

View file

@ -187,6 +187,7 @@ RZ_API ut32 rz_bv_copy(RZ_NONNULL const RzBitVector *src, RZ_NONNULL RzBitVector
rz_return_val_if_fail(src && dst, 0);
if (dst->len != src->len) {
rz_warn_if_reached();
return 0;
} else if (dst->len <= 64) {
dst->bits.small_u = src->bits.small_u;
@ -546,6 +547,7 @@ RZ_API bool rz_bv_rshift_fill(RZ_NONNULL RzBitVector *bv, ut32 size, bool fill_b
RZ_API RZ_OWN RzBitVector *rz_bv_and(RZ_NONNULL RzBitVector *x, RZ_NONNULL RzBitVector *y) {
rz_return_val_if_fail(x && y, NULL);
if (x->len != y->len) {
rz_warn_if_reached();
return NULL;
}
@ -573,6 +575,7 @@ RZ_API RZ_OWN RzBitVector *rz_bv_and(RZ_NONNULL RzBitVector *x, RZ_NONNULL RzBit
RZ_API RZ_OWN RzBitVector *rz_bv_or(RZ_NONNULL RzBitVector *x, RZ_NONNULL RzBitVector *y) {
rz_return_val_if_fail(x && y, NULL);
if (x->len != y->len) {
rz_warn_if_reached();
return NULL;
}
@ -600,6 +603,7 @@ RZ_API RZ_OWN RzBitVector *rz_bv_or(RZ_NONNULL RzBitVector *x, RZ_NONNULL RzBitV
RZ_API RZ_OWN RzBitVector *rz_bv_xor(RZ_NONNULL RzBitVector *x, RZ_NONNULL RzBitVector *y) {
rz_return_val_if_fail(x && y, NULL);
if (x->len != y->len) {
rz_warn_if_reached();
return NULL;
}

View file

@ -155,8 +155,6 @@ FILE=bins/abi_bins/elf/platforms/powerpc-linux-gnu-symexec-guess
ARGS=-A
CMDS=ar
EXPECT=<<EOF
srr0 = 0x00000000
srr1 = 0x00000000
r0 = 0x00000000
r1 = 0x00000000
r2 = 0x00000000
@ -189,35 +187,9 @@ r28 = 0x00000000
r29 = 0x00000000
r30 = 0x00000000
r31 = 0x00000000
lr = 0x00000000
ctr = 0x00000000
msr = 0x00000000
pc = 0x00000000
cr = 0x00000000
xer = 0x00000000
mq = 0x00000000
fpscr = 0x00000000
vrsave = 0x00000000
pvr = 0x00000000
dccr = 0x00000000
iccr = 0x00000000
dear = 0x00000000
hid0 = 0x00000000
hid1 = 0x00000000
hid2 = 0x00000000
hid3 = 0x00000000
hid4 = 0x00000000
hid5 = 0x00000000
hid6 = 0x00000000
ibat0 = 0x00000000
ibat1 = 0x00000000
ibat2 = 0x00000000
ibat3 = 0x00000000
dbat0 = 0x00000000
dbat1 = 0x00000000
dbat2 = 0x00000000
dbat3 = 0x00000000
mask = 0x00000000
so = 0x00000000
ov = 0x00000000
ca = 0x00000000
EOF
RUN
@ -226,8 +198,6 @@ FILE=bins/abi_bins/elf/platforms/powerpc32-linux-gnu-echo
ARGS=-A
CMDS=ar
EXPECT=<<EOF
srr0 = 0x00000000
srr1 = 0x00000000
r0 = 0x00000000
r1 = 0x00000000
r2 = 0x00000000
@ -260,35 +230,9 @@ r28 = 0x00000000
r29 = 0x00000000
r30 = 0x00000000
r31 = 0x00000000
lr = 0x00000000
ctr = 0x00000000
msr = 0x00000000
pc = 0x00000000
cr = 0x00000000
xer = 0x00000000
mq = 0x00000000
fpscr = 0x00000000
vrsave = 0x00000000
pvr = 0x00000000
dccr = 0x00000000
iccr = 0x00000000
dear = 0x00000000
hid0 = 0x00000000
hid1 = 0x00000000
hid2 = 0x00000000
hid3 = 0x00000000
hid4 = 0x00000000
hid5 = 0x00000000
hid6 = 0x00000000
ibat0 = 0x00000000
ibat1 = 0x00000000
ibat2 = 0x00000000
ibat3 = 0x00000000
dbat0 = 0x00000000
dbat1 = 0x00000000
dbat2 = 0x00000000
dbat3 = 0x00000000
mask = 0x00000000
so = 0x00000000
ov = 0x00000000
ca = 0x00000000
EOF
RUN

View file

@ -550,6 +550,135 @@ EXPECT=<<EOF
"mnemonic": "stwu",
"mask": "ffffffff",
"esil": "r1,-16,r1,+,=[4],-16,r1,+=",
"rzil": {
"opcode": "seq",
"x": {
"opcode": "storew",
"mem": 0,
"key": {
"opcode": "+",
"x": {
"opcode": "var",
"value": "r1"
},
"y": {
"opcode": "let",
"dst": "v",
"exp": {
"opcode": "bitv",
"bits": "0xfff0",
"len": 16
},
"body": {
"opcode": "ite",
"condition": {
"opcode": "msb",
"bv": {
"opcode": "var",
"value": "v"
}
},
"x": {
"opcode": "cast",
"value": {
"opcode": "var",
"value": "v"
},
"length": 64,
"fill": {
"opcode": "msb",
"bv": {
"opcode": "var",
"value": "v"
}
}
},
"y": {
"opcode": "cast",
"value": {
"opcode": "var",
"value": "v"
},
"length": 64,
"fill": {
"opcode": "bool",
"value": false
}
}
}
}
},
"value": {
"opcode": "cast",
"value": {
"opcode": "var",
"value": "r1"
},
"length": 32,
"fill": {
"opcode": "bool",
"value": false
}
}
},
"y": {
"opcode": "set",
"dst": "r1",
"src": {
"opcode": "+",
"x": {
"opcode": "var",
"value": "r1"
},
"y": {
"opcode": "let",
"dst": "v",
"exp": {
"opcode": "bitv",
"bits": "0xfff0",
"len": 16
},
"body": {
"opcode": "ite",
"condition": {
"opcode": "msb",
"bv": {
"opcode": "var",
"value": "v"
}
},
"x": {
"opcode": "cast",
"value": {
"opcode": "var",
"value": "v"
},
"length": 64,
"fill": {
"opcode": "msb",
"bv": {
"opcode": "var",
"value": "v"
}
}
},
"y": {
"opcode": "cast",
"value": {
"opcode": "var",
"value": "v"
},
"length": 64,
"fill": {
"opcode": "bool",
"value": false
}
}
}
}
}
}
},
"sign": false,
"prefix": 0,
"id": 594,

253
test/db/asm/ppc_64 Normal file
View file

@ -0,0 +1,253 @@
dE "addi r0, r26, 4" 381a0004 0x0 (seq (set a (var r26)) (set b (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty (set r0 (+ (var a) (var b))) empty empty empty)
dE "add r0, r1, r2" 7c011214 0x4 (seq (set a (var r1)) (set b (var r2)) empty (set r0 (+ (var a) (var b))) empty empty empty)
dE "addic r0, r1, 1" 30010001 0x8 (seq (set a (var r1)) (set b (let v (bv 16 0x1) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty (set r0 (+ (var a) (var b))) (set ca (msb (+ (cast 65 false (var a)) (cast 65 false (var b))))) empty empty)
dE "addis r0, r26, 1" 3c1a0001 0xc (seq (set a (var r26)) (set b (let v (append (bv 16 0x1) (bv 16 0x0)) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty (set r0 (+ (var a) (var b))) empty empty empty)
dE "addme r0, r2" 7c0201d4 0x10 (seq (set a (var r2)) (set b (ite (var ca) (bv 64 0x1) (bv 64 0x0))) (set c (bv 64 0xffffffffffffffff)) (set r0 (+ (var a) (+ (var b) (var c)))) (set ca (let r1 (+ (cast 65 false (var b)) (cast 65 false (var c))) (|| (msb (var r1)) (msb (+ (cast 65 false (var a)) (var r1)))))) empty empty)
dE "addze r0, r2" 7c020194 0x14 (seq (set a (var r2)) (set b (ite (var ca) (bv 64 0x1) (bv 64 0x0))) empty (set r0 (+ (var a) (var b))) (set ca (msb (+ (cast 65 false (var a)) (cast 65 false (var b))))) empty empty)
dE "adde r0, r2, r1" 7c020914 0x18 (seq (set a (var r2)) (set b (var r1)) (set c (ite (var ca) (bv 64 0x1) (bv 64 0x0))) (set r0 (+ (var a) (+ (var b) (var c)))) (set ca (let r1 (+ (cast 65 false (var b)) (cast 65 false (var c))) (|| (msb (var r1)) (msb (+ (cast 65 false (var a)) (var r1)))))) empty empty)
dE "addc r0, r2, r1" 7c020814 0x1c (seq (set a (var r2)) (set b (var r1)) empty (set r0 (+ (var a) (var b))) (set ca (msb (+ (cast 65 false (var a)) (cast 65 false (var b))))) empty empty)
dE "subf r0, r1, r2" 7c011050 0x20 (seq (set a (+ (~ (var r1)) (bv 64 0x1))) (set b (var r2)) empty (set r0 (+ (var a) (var b))) empty empty empty)
dE "subfc r0, r1, r2" 7c011010 0x24 (seq (set a (+ (~ (var r1)) (bv 64 0x1))) (set b (var r2)) empty (set r0 (+ (var a) (var b))) (set ca (msb (+ (cast 65 false (var a)) (cast 65 false (var b))))) empty empty)
dE "subfic r0, r2, 1" 20020001 0x28 (seq (set a (~ (var r2))) (set b (let v (bv 16 0x1) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (set c (bv 64 0x1)) (set r0 (+ (var a) (+ (var b) (var c)))) (set ca (let r1 (+ (cast 65 false (var b)) (cast 65 false (var c))) (|| (msb (var r1)) (msb (+ (cast 65 false (var a)) (var r1)))))) empty empty)
dE "subfe r0, r1, r2" 7c011110 0x2c (seq (set a (~ (var r1))) (set b (var r2)) (set c (ite (var ca) (bv 64 0x1) (bv 64 0x0))) (set r0 (+ (var a) (+ (var b) (var c)))) (set ca (let r1 (+ (cast 65 false (var b)) (cast 65 false (var c))) (|| (msb (var r1)) (msb (+ (cast 65 false (var a)) (var r1)))))) empty empty)
dE "subfme r0, r2" 7c0201d0 0x30 (seq (set a (~ (var r2))) (set b (ite (var ca) (bv 64 0x1) (bv 64 0x0))) (set c (bv 64 0xffffffffffffffff)) (set r0 (+ (var a) (+ (var b) (var c)))) (set ca (let r1 (+ (cast 65 false (var b)) (cast 65 false (var c))) (|| (msb (var r1)) (msb (+ (cast 65 false (var a)) (var r1)))))) empty empty)
dE "subfze r0, r2" 7c020190 0x34 (seq (set a (~ (var r2))) (set b (ite (var ca) (bv 64 0x1) (bv 64 0x0))) empty (set r0 (+ (var a) (var b))) (set ca (msb (+ (cast 65 false (var a)) (cast 65 false (var b))))) empty empty)
dE "neg r1, r3" 7c2300d0 0x38 (seq (set a (~ (var r3))) (set b (bv 64 0x1)) empty (set r1 (+ (var a) (var b))) empty empty empty)
dE "dcbz r1, r0" 7c0107ec 0x3c (seq (storew 0 (& (+ (var r1) (var r0)) (<< (bv 64 0xffffffffffffffff) (bv 8 0x7) false)) (bv 1024 0x0)) empty)
dE "stb r0, 4(r26)" 981a0004 0x40 (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 8 false (var r0))) empty)
dE "sth r0, 4(r26)" b01a0004 0x44 (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 16 false (var r0))) empty)
dE "stw r0, 4(r26)" 901a0004 0x48 (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 32 false (var r0))) empty)
dE "std r0, 4(r26)" f81a0004 0x4c (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 64 false (var r0))) empty)
dE "stbx r0, r26, r1" 7c1a09ae 0x50 (seq (storew 0 (+ (var r26) (var r1)) (cast 8 false (var r0))) empty)
dE "sthx r0, r26, r1" 7c1a0b2e 0x54 (seq (storew 0 (+ (var r26) (var r1)) (cast 16 false (var r0))) empty)
dE "stwx r0, r26, r1" 7c1a092e 0x58 (seq (storew 0 (+ (var r26) (var r1)) (cast 32 false (var r0))) empty)
dE "stdx r0, r26, r1" 7c1a092a 0x5c (seq (storew 0 (+ (var r26) (var r1)) (cast 64 false (var r0))) empty)
dE "stbu r0, 4(r26)" 9c1a0004 0x60 (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 8 false (var r0))) (set r26 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v)))))))
dE "sthu r0, 4(r26)" b41a0004 0x64 (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 16 false (var r0))) (set r26 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v)))))))
dE "stwu r0, 4(r26)" 941a0004 0x68 (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 32 false (var r0))) (set r26 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v)))))))
dE "stdu r0, 4(r26)" f81a0005 0x6c (seq (storew 0 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (cast 64 false (var r0))) (set r26 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v)))))))
dE "stbux r0, r26, r1" 7c1a09ee 0x70 (seq (storew 0 (+ (var r26) (var r1)) (cast 8 false (var r0))) (set r26 (+ (var r26) (var r1))))
dE "sthux r0, r26, r1" 7c1a0b6e 0x74 (seq (storew 0 (+ (var r26) (var r1)) (cast 16 false (var r0))) (set r26 (+ (var r26) (var r1))))
dE "stwux r0, r26, r1" 7c1a096e 0x78 (seq (storew 0 (+ (var r26) (var r1)) (cast 32 false (var r0))) (set r26 (+ (var r26) (var r1))))
dE "stdux r0, r26, r1" 7c1a096a 0x7c (seq (storew 0 (+ (var r26) (var r1)) (cast 64 false (var r0))) (set r26 (+ (var r26) (var r1))))
dE "stbcix r0, r26, r1" 7c1a0faa 0x80 (seq (storew 0 (+ (var r26) (var r1)) (cast 8 false (var r0))) empty)
dE "sthcix r0, r26, r1" 7c1a0f6a 0x84 (seq (storew 0 (+ (var r26) (var r1)) (cast 16 false (var r0))) empty)
dE "stwcix r0, r26, r1" 7c1a0f2a 0x88 (seq (storew 0 (+ (var r26) (var r1)) (cast 32 false (var r0))) empty)
dE "stdcix r0, r26, r1" 7c1a0fea 0x8c (seq (storew 0 (+ (var r26) (var r1)) (cast 64 false (var r0))) empty)
dE "li r0, 1" 38000001 0x90 (seq (set r0 (let v (bv 16 0x1) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty)
dE "lis r0, 1" 3c000001 0x94 (seq (set r0 (let v (append (bv 16 0x1) (bv 16 0x0)) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty)
dE "addi r0, r26, 8" 381a0008 0x98 (seq (set a (var r26)) (set b (let v (bv 16 0x8) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty (set r0 (+ (var a) (var b))) empty empty empty)
dE "lbz r0, 4(r26)" 881a0004 0x9c (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 8 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lbzx r0, r26, r1" 7c1a08ae 0xa0 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 8 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lbzu r0, 8(r26)" 8c1a0008 0xa4 (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x8) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 8 (var ea)) (cast 64 false (var loadw))))) (set r26 (+ (var r26) (let v (bv 16 0x8) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v)))))))
dE "lbzux r0, r26, r1" 7c1a08ee 0xa8 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 8 (var ea)) (cast 64 false (var loadw))))) (set r26 (+ (var r26) (var r1))))
dE "lbzcix r0, r26, r1" 7c1a0eaa 0xac (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 8 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lha r0, 4(r26)" a81a0004 0xb0 (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 16 (var ea)) (let v (var loadw) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))))) empty)
dE "lhz r0, 4(r26)" a01a0004 0xb4 (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 16 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lhzx r0, r26, r1" 7c1a0a2e 0xb8 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 16 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lhzu r0, 8(r26)" a41a0008 0xbc (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x8) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 16 (var ea)) (cast 64 false (var loadw))))) (set r26 (+ (var r26) (let v (bv 16 0x8) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v)))))))
dE "lhzux r0, r26, r1" 7c1a0a6e 0xc0 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 16 (var ea)) (cast 64 false (var loadw))))) (set r26 (+ (var r26) (var r1))))
dE "lhax r0, r26, r1" 7c1a0aae 0xc4 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 16 (var ea)) (let v (var loadw) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))))) empty)
dE "lhaux r0, r26, r1" 7c1a0aee 0xc8 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 16 (var ea)) (let v (var loadw) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))))) (set r26 (+ (var r26) (var r1))))
dE "lhzcix r0, r26, r1" 7c1a0e6a 0xcc (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 16 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lwa r0, 4(r26)" e81a0006 0xd0 (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 32 (var ea)) (let v (var loadw) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))))) empty)
dE "lwz r0, 4(r26)" 801a0004 0xd4 (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 32 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lwzx r0, r26, r1" 7c1a082e 0xd8 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 32 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lwax r0, r26, r1" 7c1a0aaa 0xdc (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 32 (var ea)) (let v (var loadw) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))))) empty)
dE "lwaux r0, r26, r1" 7c1a0aea 0xe0 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 32 (var ea)) (let v (var loadw) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))))) (set r26 (+ (var r26) (var r1))))
dE "lwzcix r0, r26, r1" 7c1a0e2a 0xe4 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 32 (var ea)) (cast 64 false (var loadw))))) empty)
dE "ld r0, 4(r26)" e81a0004 0xe8 (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 64 (var ea)) (cast 64 false (var loadw))))) empty)
dE "ldx r0, r26, r1" 7c1a082a 0xec (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 64 (var ea)) (cast 64 false (var loadw))))) empty)
dE "ldu r0, 4(r26)" e81a0005 0xf0 (seq (set r0 (let ea (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 64 (var ea)) (cast 64 false (var loadw))))) (set r26 (+ (var r26) (let v (bv 16 0x4) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v)))))))
dE "ldux r0, r26, r1" 7c1a086a 0xf4 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 64 (var ea)) (cast 64 false (var loadw))))) (set r26 (+ (var r26) (var r1))))
dE "ldcix r0, r26, r1" 7c1a0eea 0xf8 (seq (set r0 (let ea (+ (var r26) (var r1)) (let loadw (loadw 0 64 (var ea)) (cast 64 false (var loadw))))) empty)
dE "lhbrx r0, r26, r1" 7c1a0e2c 0xfc (seq (set r0 (cast 64 false (let ea (+ (var r26) (var r1)) (append (loadw 0 8 (+ (var ea) (bv 64 0x0))) (loadw 0 8 (+ (var ea) (bv 64 0x1))))))) empty)
dE "lwbrx r0, r26, r1" 7c1a0c2c 0x100 (seq (set r0 (cast 64 false (let ea (+ (var r26) (var r1)) (append (loadw 0 8 (+ (var ea) (bv 64 0x0))) (append (loadw 0 8 (+ (var ea) (bv 64 0x1))) (append (loadw 0 8 (+ (var ea) (bv 64 0x2))) (loadw 0 8 (+ (var ea) (bv 64 0x3))))))))) empty)
dE "ldbrx r0, r26, r1" 7c1a0c28 0x104 (seq (set r0 (cast 64 false (let ea (+ (var r26) (var r1)) (append (loadw 0 8 (+ (var ea) (bv 64 0x0))) (append (loadw 0 8 (+ (var ea) (bv 64 0x1))) (append (loadw 0 8 (+ (var ea) (bv 64 0x2))) (append (loadw 0 8 (+ (var ea) (bv 64 0x3))) (append (loadw 0 8 (+ (var ea) (bv 64 0x4))) (append (loadw 0 8 (+ (var ea) (bv 64 0x5))) (append (loadw 0 8 (+ (var ea) (bv 64 0x6))) (loadw 0 8 (+ (var ea) (bv 64 0x7))))))))))))) empty)
d "lhbrx r0, r26, r1" 2c0e1a7c 0xfc (seq (set r0 (cast 64 false (let ea (+ (var r26) (var r1)) (append (loadw 0 8 (+ (var ea) (bv 64 0x1))) (loadw 0 8 (+ (var ea) (bv 64 0x0))))))) empty)
d "lwbrx r0, r26, r1" 2c0c1a7c 0x100 (seq (set r0 (cast 64 false (let ea (+ (var r26) (var r1)) (append (loadw 0 8 (+ (var ea) (bv 64 0x3))) (append (loadw 0 8 (+ (var ea) (bv 64 0x2))) (append (loadw 0 8 (+ (var ea) (bv 64 0x1))) (loadw 0 8 (+ (var ea) (bv 64 0x0))))))))) empty)
d "ldbrx r0, r26, r1" 280c1a7c 0x104 (seq (set r0 (cast 64 false (let ea (+ (var r26) (var r1)) (append (loadw 0 8 (+ (var ea) (bv 64 0x7))) (append (loadw 0 8 (+ (var ea) (bv 64 0x6))) (append (loadw 0 8 (+ (var ea) (bv 64 0x5))) (append (loadw 0 8 (+ (var ea) (bv 64 0x4))) (append (loadw 0 8 (+ (var ea) (bv 64 0x3))) (append (loadw 0 8 (+ (var ea) (bv 64 0x2))) (append (loadw 0 8 (+ (var ea) (bv 64 0x1))) (loadw 0 8 (+ (var ea) (bv 64 0x0))))))))))))) empty)
dE "and r0, r1, r2" 7c201038 0x108 (seq (set res (& (var r1) (var r2))) (set r0 (var res)) empty)
dE "andc r0, r1, r2" 7c201078 0x10c (seq (set res (& (var r1) (~ (var r2)))) (set r0 (var res)) empty)
dE "andi. r0, r2, 4" 70400004 0x110 (seq (set res (& (var r2) (cast 64 false (bv 16 0x4)))) (set r0 (var res)) (set l (var res)) (set r (bv 64 0x0)) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (sle (var l) (var r)) (! (== (var l) (var r)))) (set cr0 (append (bv 3 0x4) (var so_flag))) (branch (! (sle (var l) (var r))) (set cr0 (append (bv 3 0x2) (var so_flag))) (set cr0 (append (bv 3 0x1) (var so_flag))))))
dE "andis. r26, r0, 4" 741a0004 0x114 (seq (set res (& (var r0) (cast 64 false (append (bv 16 0x4) (bv 16 0x0))))) (set r26 (var res)) (set l (var res)) (set r (bv 64 0x0)) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (sle (var l) (var r)) (! (== (var l) (var r)))) (set cr0 (append (bv 3 0x4) (var so_flag))) (branch (! (sle (var l) (var r))) (set cr0 (append (bv 3 0x2) (var so_flag))) (set cr0 (append (bv 3 0x1) (var so_flag))))))
dE "mr r5, r20" 7e85a378 0x118 (seq (set res (| (var r20) (var r20))) (set r5 (var res)) empty)
dE "or r0, r26, r1" 7f400b78 0x11c (seq (set res (| (var r26) (var r1))) (set r0 (var res)) empty)
dE "orc r0, r1, r2" 7c201338 0x120 (seq (set res (| (var r1) (~ (var r2)))) (set r0 (var res)) empty)
dE "ori r0, r26, 4" 63400004 0x124 (seq (set res (| (var r26) (cast 64 false (bv 16 0x4)))) (set r0 (var res)) empty)
dE "oris r0, r2, 4" 64400004 0x128 (seq (set res (| (var r2) (cast 64 false (append (bv 16 0x4) (bv 16 0x0))))) (set r0 (var res)) empty)
dE "xor r0, r1, r2" 7c201278 0x12c (seq (set res (^ (var r1) (var r2))) (set r0 (var res)) empty)
dE "xori r0, r26, 4" 6b400004 0x130 (seq (set res (^ (var r26) (cast 64 false (bv 16 0x4)))) (set r0 (var res)) empty)
dE "xoris r0, r2, 4" 6c400004 0x134 (seq (set res (^ (var r2) (cast 64 false (append (bv 16 0x4) (bv 16 0x0))))) (set r0 (var res)) empty)
dE "nand r0, r1, r2" 7c2013b8 0x138 (seq (set res (~ (& (var r1) (var r2)))) (set r0 (var res)) empty)
dE "nor r0, r1, r2" 7c2010f8 0x13c (seq (set res (~ (| (var r1) (var r2)))) (set r0 (var res)) empty)
dE "cmpb r0, r0, r1" 7c000bf8 0x140 (seq (set res (bv 64 0x0)) (set n (bv 8 0x0)) (set bitmask_n_n7 (~ (| (>> (bv 64 0x0) (* (bv 8 0x8) (var n)) true) (<< (bv 64 0x0) (- (bv 8 0x3f) (+ (* (bv 8 0x8) (var n)) (bv 8 0x7))) true)))) (repeat (&& (ule (var n) (bv 8 0x8)) (! (== (var n) (bv 8 0x8)))) (seq (branch (== (& (var bitmask_n_n7) (var r0)) (& (var bitmask_n_n7) (var r1))) (set res (| (var res) (& (bv 64 0xffffffffffffffff) (var bitmask_n_n7)))) empty) (set n (+ (var n) (bv 8 0x1))) (set bitmask_n_n7 (~ (| (>> (bv 64 0x0) (* (bv 8 0x8) (var n)) true) (<< (bv 64 0x0) (- (bv 8 0x3f) (+ (* (bv 8 0x8) (var n)) (bv 8 0x7))) true)))))) (set r0 (var res)))
dE "eqv r0, r1, r6" 7c203238 0x144 (seq (set res (^ (var r1) (~ (var r6)))) (set r0 (var res)) empty)
dE "extsb r0, r4" 7c800774 0x148 (seq (set res (cast 64 (msb (cast 8 false (var r4))) (cast 8 false (var r4)))) (set r0 (var res)) empty)
dE "extsh r0, r4" 7c800734 0x14c (seq (set res (cast 64 (msb (cast 16 false (var r4))) (cast 16 false (var r4)))) (set r0 (var res)) empty)
dE "extsw r0, r4" 7c8007b4 0x150 (seq (set res (cast 64 (msb (cast 32 false (var r4))) (cast 32 false (var r4)))) (set r0 (var res)) empty)
dE "cntlzd r0, r1" 7c200074 0x154 (seq (set m (bv 64 0x0)) (set n (bv 64 0x0)) (repeat (&& (&& (ule (var n) (bv 64 0x40)) (! (== (var n) (bv 64 0x40)))) (! (! (is_zero (& (var r1) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var n) false)))))) (set n (+ (var n) (bv 64 0x1)))) (set r0 (- (var n) (var m))))
dE "cntlzd r0, r1" 7c200074 0x158 (seq (set m (bv 64 0x0)) (set n (bv 64 0x0)) (repeat (&& (&& (ule (var n) (bv 64 0x40)) (! (== (var n) (bv 64 0x40)))) (! (! (is_zero (& (var r1) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var n) false)))))) (set n (+ (var n) (bv 64 0x1)))) (set r0 (- (var n) (var m))))
dE "cmpw cr3, r0, r1" 7d800800 0x15c (seq (set l (cast 64 (msb (cast 32 false (var r0))) (cast 32 false (var r0)))) (set r (cast 64 (msb (cast 32 false (var r1))) (cast 32 false (var r1)))) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (sle (var l) (var r)) (! (== (var l) (var r)))) (set cr3 (append (bv 3 0x4) (var so_flag))) (branch (! (sle (var l) (var r))) (set cr3 (append (bv 3 0x2) (var so_flag))) (set cr3 (append (bv 3 0x1) (var so_flag))))))
dE "cmpd cr5, r0, r1" 7ea00800 0x160 (seq (set l (var r0)) (set r (var r1)) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (sle (var l) (var r)) (! (== (var l) (var r)))) (set cr5 (append (bv 3 0x4) (var so_flag))) (branch (! (sle (var l) (var r))) (set cr5 (append (bv 3 0x2) (var so_flag))) (set cr5 (append (bv 3 0x1) (var so_flag))))))
dE "cmpwi cr2, r0, 0xffff" 2d00ffff 0x164 (seq (set l (cast 64 (msb (cast 32 false (var r0))) (cast 32 false (var r0)))) (set r (cast 64 (msb (bv 16 0xffff)) (bv 16 0xffff))) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (sle (var l) (var r)) (! (== (var l) (var r)))) (set cr2 (append (bv 3 0x4) (var so_flag))) (branch (! (sle (var l) (var r))) (set cr2 (append (bv 3 0x2) (var so_flag))) (set cr2 (append (bv 3 0x1) (var so_flag))))))
dE "cmpdi cr3, r0, 1" 2da00001 0x168 (seq (set l (var r0)) (set r (let v (bv 16 0x1) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (sle (var l) (var r)) (! (== (var l) (var r)))) (set cr3 (append (bv 3 0x4) (var so_flag))) (branch (! (sle (var l) (var r))) (set cr3 (append (bv 3 0x2) (var so_flag))) (set cr3 (append (bv 3 0x1) (var so_flag))))))
dE "cmplw cr4, r0, r1" 7e000840 0x16c (seq (set l (cast 64 (msb (cast 32 false (var r0))) (cast 32 false (var r0)))) (set r (cast 64 (msb (cast 32 false (var r1))) (cast 32 false (var r1)))) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (ule (var l) (var r)) (! (== (var l) (var r)))) (set cr4 (append (bv 3 0x4) (var so_flag))) (branch (! (ule (var l) (var r))) (set cr4 (append (bv 3 0x2) (var so_flag))) (set cr4 (append (bv 3 0x1) (var so_flag))))))
dE "cmpld cr5, r0, r1" 7ea00840 0x170 (seq (set l (var r0)) (set r (var r1)) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (ule (var l) (var r)) (! (== (var l) (var r)))) (set cr5 (append (bv 3 0x4) (var so_flag))) (branch (! (ule (var l) (var r))) (set cr5 (append (bv 3 0x2) (var so_flag))) (set cr5 (append (bv 3 0x1) (var so_flag))))))
dE "cmplwi cr6, r0, 0" 2b000000 0x174 (seq (set l (cast 64 (msb (cast 32 false (var r0))) (cast 32 false (var r0)))) (set r (cast 64 false (bv 16 0x0))) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (ule (var l) (var r)) (! (== (var l) (var r)))) (set cr6 (append (bv 3 0x4) (var so_flag))) (branch (! (ule (var l) (var r))) (set cr6 (append (bv 3 0x2) (var so_flag))) (set cr6 (append (bv 3 0x1) (var so_flag))))))
dE "cmpldi cr7, r0, 1" 2ba00001 0x178 (seq (set l (var r0)) (set r (append (bv 48 0x0) (bv 16 0x1))) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (ule (var l) (var r)) (! (== (var l) (var r)))) (set cr7 (append (bv 3 0x4) (var so_flag))) (branch (! (ule (var l) (var r))) (set cr7 (append (bv 3 0x2) (var so_flag))) (set cr7 (append (bv 3 0x1) (var so_flag))))))
dE "b 0x180" 48000004 0x17c (seq (set CIA (bv 64 0x17c)) empty empty (set NIA (bv 64 0x180)) (jmp (var NIA)))
dE "ba 0x4" 48000006 0x180 (seq (set CIA (bv 64 0x180)) empty empty (set NIA (bv 64 0x4)) (jmp (var NIA)))
dE "bgectr" 4c800420 0x184 (seq (set CIA (bv 64 0x184)) empty empty (set NIA (ite (let bo (bv 5 0x4) (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x8)))) (! (! (is_zero (& (bv 5 0x8) (var bo)))))))) (& (bv 64 0xfffffffffffffffc) (var ctr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bgectrl" 4c800421 0x188 (seq (set CIA (bv 64 0x188)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (let bo (bv 5 0x4) (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x8)))) (! (! (is_zero (& (bv 5 0x8) (var bo)))))))) (& (bv 64 0xfffffffffffffffc) (var ctr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bge 0x190" 40800004 0x18c (seq (set CIA (bv 64 0x18c)) empty empty (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x8)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (bv 64 0x190) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "ble 0x194" 40810004 0x190 (seq (set CIA (bv 64 0x190)) empty empty (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x4)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (bv 64 0x194) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bgel 0x198" 40800005 0x194 (seq (set CIA (bv 64 0x194)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x8)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (bv 64 0x198) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bgelr" 4c800020 0x198 (seq (set CIA (bv 64 0x198)) empty empty (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x8)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (& (bv 64 0xfffffffffffffffc) (var lr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bgelrl" 4c800021 0x19c (seq (set CIA (bv 64 0x19c)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x8)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (& (bv 64 0xfffffffffffffffc) (var lr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bctr" 4e800420 0x1a0 (seq (set CIA (bv 64 0x1a0)) empty empty (set NIA (& (bv 64 0xfffffffffffffffc) (var ctr))) (jmp (var NIA)))
dE "bctrl" 4e800421 0x1a4 (seq (set CIA (bv 64 0x1a4)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (& (bv 64 0xfffffffffffffffc) (var ctr))) (jmp (var NIA)))
d "bne cr5" 00009640 0x1a4 (seq (set CIA (bv 64 0x1a4)) empty empty (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr5) (bv 4 0x2)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (bv 64 0x7) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnz 0x1ac" 42000004 0x1a8 (seq (set CIA (bv 64 0x1a8)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (! (is_zero (var ctr))) (bv 64 0x1ac) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnza 0x4" 42000006 0x1ac (seq (set CIA (bv 64 0x1ac)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (! (is_zero (var ctr))) (bv 64 0x4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzl 0x1b4" 42000005 0x1b0 (seq (set CIA (bv 64 0x1b0)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (! (is_zero (var ctr))) (bv 64 0x1b4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzla 0x4" 42000007 0x1b4 (seq (set CIA (bv 64 0x1b4)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (! (is_zero (var ctr))) (bv 64 0x4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzlr" 4e000020 0x1b8 (seq (set CIA (bv 64 0x1b8)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (! (is_zero (var ctr))) (& (bv 64 0xfffffffffffffffc) (var lr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzlrl" 4e000021 0x1bc (seq (set CIA (bv 64 0x1bc)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (! (is_zero (var ctr))) (& (bv 64 0xfffffffffffffffc) (var lr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdz 0x1c4" 42400004 0x1c0 (seq (set CIA (bv 64 0x1c0)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (is_zero (var ctr)) (bv 64 0x1c4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdza 0x4" 42400006 0x1c4 (seq (set CIA (bv 64 0x1c4)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (is_zero (var ctr)) (bv 64 0x4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzl 0x1cc" 42400005 0x1c8 (seq (set CIA (bv 64 0x1c8)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (is_zero (var ctr)) (bv 64 0x1cc) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzla 0x4" 42400007 0x1cc (seq (set CIA (bv 64 0x1cc)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (is_zero (var ctr)) (bv 64 0x4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzlr" 4e400020 0x1d0 (seq (set CIA (bv 64 0x1d0)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (is_zero (var ctr)) (& (bv 64 0xfffffffffffffffc) (var lr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzlrl" 4e400021 0x1d4 (seq (set CIA (bv 64 0x1d4)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (is_zero (var ctr)) (& (bv 64 0xfffffffffffffffc) (var lr)) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bl 0x1dc" 48000005 0x1d8 (seq (set CIA (bv 64 0x1d8)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (bv 64 0x1dc)) (jmp (var NIA)))
dE "bla 0x4" 48000007 0x1dc (seq (set CIA (bv 64 0x1dc)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (bv 64 0x4)) (jmp (var NIA)))
dE "blr" 4e800020 0x1e0 (seq (set CIA (bv 64 0x1e0)) empty empty (set NIA (& (bv 64 0xfffffffffffffffc) (var lr))) (jmp (var NIA)))
dE "blrl" 4e800021 0x1e4 (seq (set CIA (bv 64 0x1e4)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (& (bv 64 0xfffffffffffffffc) (var lr))) (jmp (var NIA)))
dE "bnsa 0x18" 4083001a 0x1e8 (seq (set CIA (bv 64 0x1e8)) empty empty (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr0) (bv 4 0x1)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (bv 64 0x18) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bgela cr1, 0x18" 4084001b 0x1ec (seq (set CIA (bv 64 0x1ec)) empty (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (let bo (bv 5 0x4) (&& (|| (! (is_zero (& (bv 5 0x10) (var bo)))) (^^ (! (is_zero (& (var cr1) (bv 4 0x8)))) (! (! (is_zero (& (bv 5 0x8) (var bo))))))) (|| (! (is_zero (& (bv 5 0x4) (var bo)))) (^^ (! (is_zero (var ctr))) (! (is_zero (& (bv 5 0x2) (var bo)))))))) (bv 64 0x18) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzt 4*cr1+lt, 0x81d4" 41047fe4 0x1f0 (seq (set CIA (bv 64 0x1f0)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (! (is_zero (var ctr))) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x81d4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnztl 4*cr1+lt, 0x81d8" 41047fe5 0x1f4 (seq (set CIA (bv 64 0x1f4)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (! (is_zero (var ctr))) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x81d8) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzta 4*cr1+lt, 0x7fe4" 41047fe6 0x1f8 (seq (set CIA (bv 64 0x1f8)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (! (is_zero (var ctr))) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnztla 4*cr1+lt, 0x7fe4" 41047fe7 0x1fc (seq (set CIA (bv 64 0x1fc)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (! (is_zero (var ctr))) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzf 4*cr1+lt, 0x81e4" 40047fe4 0x200 (seq (set CIA (bv 64 0x200)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (! (is_zero (var ctr))) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x81e4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzfl 4*cr1+lt, 0x81e8" 40047fe5 0x204 (seq (set CIA (bv 64 0x204)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (! (is_zero (var ctr))) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x81e8) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzfa 4*cr1+lt, 0x7fe4" 40047fe6 0x208 (seq (set CIA (bv 64 0x208)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (! (is_zero (var ctr))) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdnzfla 4*cr1+lt, 0x7fe4" 40047fe7 0x20c (seq (set CIA (bv 64 0x20c)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (! (is_zero (var ctr))) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzt 4*cr1+lt, 0x81f4" 41447fe4 0x210 (seq (set CIA (bv 64 0x210)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (is_zero (var ctr)) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x81f4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzta 4*cr1+lt, 0x7fe4" 41447fe6 0x214 (seq (set CIA (bv 64 0x214)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (is_zero (var ctr)) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdztl 4*cr1+lt, 0x81fc" 41447fe5 0x218 (seq (set CIA (bv 64 0x218)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (is_zero (var ctr)) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x81fc) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdztla 4*cr1+lt, 0x7fe4" 41447fe7 0x21c (seq (set CIA (bv 64 0x21c)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (is_zero (var ctr)) (! (is_zero (& (var cr1) (bv 4 0x1))))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzf 4*cr1+lt, 0x8204" 40447fe4 0x220 (seq (set CIA (bv 64 0x220)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (is_zero (var ctr)) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x8204) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzfa 4*cr1+lt, 0x7fe4" 40447fe6 0x224 (seq (set CIA (bv 64 0x224)) (set ctr (- (var ctr) (bv 64 0x1))) empty (set NIA (ite (&& (is_zero (var ctr)) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzfl 4*cr1+lt, 0x820c" 40447fe5 0x228 (seq (set CIA (bv 64 0x228)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (is_zero (var ctr)) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x820c) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "bdzfla 4*cr1+lt, 0x7fe4" 40447fe7 0x22c (seq (set CIA (bv 64 0x22c)) (set ctr (- (var ctr) (bv 64 0x1))) (set lr (+ (var CIA) (bv 64 0x4))) (set NIA (ite (&& (is_zero (var ctr)) (is_zero (& (var cr1) (bv 4 0x1)))) (bv 64 0x7fe4) (+ (var CIA) (bv 64 0x4)))) (jmp (var NIA)))
dE "nop" 60000000 0x230 nop
dE "xnop" 68000000 0x234 nop
dEB "mtocrf 4, r4" 7c904120 0x238 (seq (set val (>> (var r4) (bv 8 0x18) false)) (set cr6 (cast 4 false (var val))))
dEB "isel r10,0,r23,14" 7d40bb9e 0x23c ()
dE "mtctr r28" 7f8903a6 0x240 (set ctr (cast 64 false (var r28)))
dE "mfctr r28" 7f8902a6 0x244 (set r28 (cast 64 false (var ctr)))
dE "mtlr r28" 7f8803a6 0x248 (set lr (cast 64 false (var r28)))
dE "mflr r28" 7f8802a6 0x24c (set r28 (cast 64 false (var lr)))
dE "mtxer r28" 7f8103a6 0x250 (seq (set v (& (~ (| (>> (bv 64 0x0) (bv 8 0x20) true) (<< (bv 64 0x0) (- (bv 8 0x3f) (bv 8 0x22)) true))) (cast 64 false (var r28)))) (set xer (var v)) (set so (! (is_zero (& (var v) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (bv 8 0x20) false))))) (set ov (! (is_zero (& (var v) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (bv 8 0x21) false))))) (set ca (! (is_zero (& (var v) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (bv 8 0x22) false))))))
dE "mfxer r0" 7c0102a6 0x254 (seq (set val (| (| (<< (cast 64 false (ite (var so) (bv 1 0x1) (bv 1 0x0))) (bv 8 0x1f) false) (<< (cast 64 false (ite (var ov) (bv 1 0x1) (bv 1 0x0))) (bv 8 0x1e) false)) (<< (cast 64 false (ite (var ca) (bv 1 0x1) (bv 1 0x0))) (bv 8 0x1d) false))) (set r0 (cast 64 false (var val))))
dE "mfcr r10" 7d400026 0x258 (seq (set cr (| (cast 32 false (var cr7)) (| (<< (cast 32 false (var cr6)) (bv 8 0x4) false) (| (<< (cast 32 false (var cr5)) (bv 8 0x8) false) (| (<< (cast 32 false (var cr4)) (bv 8 0xc) false) (| (<< (cast 32 false (var cr3)) (bv 8 0x10) false) (| (<< (cast 32 false (var cr2)) (bv 8 0x14) false) (| (<< (cast 32 false (var cr1)) (bv 8 0x18) false) (<< (cast 32 false (var cr0)) (bv 8 0x1c) false))))))))) (set r10 (cast 64 false (var cr))))
dE "mfctr r10" 7d4902a6 0x25c (set r10 (cast 64 false (var ctr)))
dEB "mffs f3" fc60048e 0x260 ()
dE "mflr r10" 7d4802a6 0x264 (set r10 (cast 64 false (var lr)))
dE "mfmsr r10" 7d4000a6 0x268 (set r10 (cast 64 false (var msr)))
dEB "mfocrf r10, 1" 7d501026 0x26c (seq (set val (<< (cast 64 false (var cr6)) (bv 8 0x18) false)) (set r10 (cast 64 false (var val))))
dEB "mfspr r10,2" 7d4202a6 0x270 ()
dEB "mftb r10" 7d4c42a6 0x274 ()
dEB "mfvscr v2" 10400604 0x278 ()
dEB "mtocrf 1, r12" 7d901120 0x27c (seq (set val (>> (var r12) (bv 8 0x18) false)) (set cr6 (cast 4 false (var val))))
dE "mtctr r10" 7d4903a6 0x280 (set ctr (cast 64 false (var r10)))
dEB "mtfsb0 2" fc40008c 0x284 ()
dEB "mtfsb1 1" fc20004c 0x288 ()
dEB "mtfsf 3,f1" fc060d8e 0x28c ()
dEB "mtfsfi 4,4" fe00410c 0x290 ()
dE "mtlr r10" 7d4803a6 0x294 (set lr (cast 64 false (var r10)))
dEB "mtmsr r10" 7d400124 0x298 ()
dEB "mtmsrd r10" 7d400164 0x29c ()
dEB "mtocrf 1, r2" 7c501120 0x2a0 (seq (set val (>> (var r2) (bv 8 0x18) false)) (set cr6 (cast 4 false (var val))))
dEB "mtspr 15,r1" 7c2f03a6 0x2a4 ()
dEB "mtvscr v1" 10000e44 0x2a8 ()
dEB "mfxer r10" 7d4102a6 0x2ac (seq (set val (| (| (<< (cast 64 false (ite (var so) (bv 1 0x1) (bv 1 0x0))) (bv 8 0x1f) false) (<< (cast 64 false (ite (var ov) (bv 1 0x1) (bv 1 0x0))) (bv 8 0x1e) false)) (<< (cast 64 false (ite (var ca) (bv 1 0x1) (bv 1 0x0))) (bv 8 0x1d) false))) (set r10 (cast 64 false (var val))))
dEB "mfrtcu r10" 7d4402a6 0x2b0 ()
dEB "mfrtcl r10" 7d4502a6 0x2b4 ()
dEB "mfdscr r10" 7d5102a6 0x2b8 ()
dEB "mfdsisr r10" 7d5202a6 0x2bc ()
dEB "mfdar r10" 7d5302a6 0x2c0 ()
dEB "mfcfar r10" 7d5c02a6 0x2c4 ()
dEB "mfamr r10" 7d5d02a6 0x2c8 ()
dEB "mfdbatu r10,2" 7d5c82a6 0x2cc ()
dEB "mfdbatl r10,1" 7d5b82a6 0x2d0 ()
dEB "mfibatu r10,3" 7d5682a6 0x2d4 ()
dEB "mfibatl r1,1" 7c3382a6 0x2d8 ()
dEB "mfasr r10" 7d5842a6 0x2dc ()
dEB "mfpvr r10" 7d5f42a6 0x2e0 ()
dEB "mftbu r10" 7d4d42a6 0x2e4 ()
dE "mtxer r10" 7d4103a6 0x2e8 (seq (set v (& (~ (| (>> (bv 64 0x0) (bv 8 0x20) true) (<< (bv 64 0x0) (- (bv 8 0x3f) (bv 8 0x22)) true))) (cast 64 false (var r10)))) (set xer (var v)) (set so (! (is_zero (& (var v) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (bv 8 0x20) false))))) (set ov (! (is_zero (& (var v) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (bv 8 0x21) false))))) (set ca (! (is_zero (& (var v) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (bv 8 0x22) false))))))
dEB "mtdscr r10" 7d5103a6 0x2ec ()
dEB "mtdsisr r10" 7d5203a6 0x2f0 ()
dEB "mtdar r10" 7d5303a6 0x2f4 ()
dEB "mtcfar r10" 7d5c03a6 0x2f8 ()
dEB "mtamr r10" 7d5d03a6 0x2fc ()
dEB "mttbl r10" 7d5c43a6 0x300 ()
dEB "mttbu r10" 7d5d43a6 0x304 ()
dEB "mtdbatu 3,r4" 7c9e83a6 0x308 ()
dEB "mtdbatl 3,r4" 7c9f83a6 0x30c ()
dEB "mtibatu 3,r4" 7c9683a6 0x310 ()
dEB "mtibatl 3,r4" 7c9783a6 0x314 ()
dE "sld r10, r20, r4" 7e8a2036 0x318 (seq empty empty (set result (<< (var r20) (& (bv 64 0x3f) (var r4)) false)) (set r10 (var result)) empty)
dE "srd r10, r20, r4" 7e8a2436 0x31c (seq empty empty (set result (>> (var r20) (& (bv 64 0x3f) (var r4)) false)) (set r10 (var result)) empty)
dE "slw r10, r20, r4" 7e8a2030 0x320 (seq empty empty (set result (append (bv 32 0x0) (<< (cast 32 false (var r20)) (var r4) false))) (set r10 (var result)) empty)
dE "srw r10, r20, r4" 7e8a2430 0x324 (seq empty empty (set result (append (bv 32 0x0) (>> (cast 32 false (var r20)) (var r4) false))) (set r10 (var result)) empty)
dE "srad r10, r20, r4" 7e8a2634 0x328 (seq empty (set ca (ite (&& (msb (var r20)) (! (is_zero (smod (var r20) (cast 64 false (<< (bv 64 0x1) (cast 6 false (& (var r4) (bv 64 0x3f))) false)))))) true false)) (set result (>> (var r20) (cast 6 false (& (var r4) (bv 64 0x3f))) (msb (var r20)))) (set r10 (var result)) empty)
dE "sradi r10, r20, 4" 7e8a2674 0x32c (seq empty (set ca (ite (&& (msb (var r20)) (! (is_zero (smod (var r20) (cast 64 false (<< (bv 64 0x1) (bv 8 0x4) false)))))) true false)) (set result (>> (var r20) (bv 8 0x4) (msb (var r20)))) (set r10 (var result)) empty)
dE "lis r22, 0" 3ec00000 0x330 (seq (set r22 (let v (append (bv 16 0x0) (bv 16 0x0)) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty)
dE "addi r22, r22, 0" 3ad60000 0x334 (seq (set a (var r22)) (set b (let v (bv 16 0x0) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) empty (set r22 (+ (var a) (var b))) empty empty empty)
dE "ld r22, 0(r22)" ead60000 0x338 (seq (set r22 (let ea (+ (var r22) (let v (bv 16 0x0) (ite (msb (var v)) (cast 64 (msb (var v)) (var v)) (cast 64 false (var v))))) (let loadw (loadw 0 64 (var ea)) (cast 64 false (var loadw))))) empty)
dE "sraw r10, r22, r4" 7eca2630 0x33c (seq empty (set ca (ite (&& (msb (cast 32 (msb (var r22)) (var r22))) (! (is_zero (smod (cast 32 false (var r22)) (cast 32 false (<< (bv 64 0x1) (cast 6 false (& (var r4) (bv 64 0x3f))) false)))))) true false)) (set result (cast 64 (msb (>> (cast 32 false (var r22)) (cast 6 false (& (var r4) (bv 64 0x3f))) (msb (cast 32 false (var r22))))) (>> (cast 32 false (var r22)) (cast 6 false (& (var r4) (bv 64 0x3f))) (msb (cast 32 false (var r22)))))) (set r10 (var result)) empty)
dE "srawi r10, r22, 4" 7eca2670 0x340 (seq empty (set ca (ite (&& (msb (cast 32 (msb (var r22)) (var r22))) (! (is_zero (smod (cast 32 false (var r22)) (cast 32 false (<< (bv 64 0x1) (bv 8 0x4) false)))))) true false)) (set result (cast 64 (msb (>> (cast 32 false (var r22)) (bv 8 0x4) (msb (cast 32 false (var r22))))) (>> (cast 32 false (var r22)) (bv 8 0x4) (msb (cast 32 false (var r22)))))) (set r10 (var result)) empty)
dE "slwi r10, r20, 0x10" 568a801e 0x344 (seq empty empty (set result (& (<< (var r20) (& (bv 64 0x3f) (bv 64 0x10)) false) (bv 64 0xffffffff))) (set r10 (var result)) empty)
dE "srwi r10, r20, 0x10" 568a843e 0x348 (seq empty empty (set result (& (>> (& (var r20) (bv 64 0xffffffff)) (& (bv 64 0x3f) (bv 64 0x10)) false) (bv 64 0xffffffff))) (set r10 (var result)) empty)
dE "rlwimi r10, r20, 8, 5, 5" 528a414a 0x34c (seq (set mstart (bv 8 0x25)) (set mstop (bv 8 0x25)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (| (& (let rotl32_x (cast 32 false (var r20)) (let rotl32_y (bv 8 0x8) (let rotl64_x (append (var rotl32_x) (var rotl32_x)) (let rotl64_y (var rotl32_y) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))))) (var mask)) (& (var r10) (~ (var mask))))) (set r10 (var result)) empty)
dE "rldicl r10, r20, 4, 0x10" 7a8a2400 0x350 (seq (set mstart (bv 8 0x10)) (set mstop (bv 8 0x3f)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl64_x (var r20) (let rotl64_y (& (bv 8 0x3f) (bv 8 0x4)) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))) (var mask))) (set r10 (var result)) empty)
dE "rldimi r10, r20, 4, 8" 7a8a220c 0x354 (seq (set mstart (bv 8 0x8)) (set mstop (bv 8 0x3b)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (| (& (let rotl64_x (var r20) (let rotl64_y (& (bv 8 0x3f) (bv 8 0x4)) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))) (var mask)) (& (var r10) (~ (var mask))))) (set r10 (var result)) empty)
dE "rotld r10, r20, r4" 7a8a2010 0x358 (seq empty empty (set result (let rotl64_x (var r20) (let rotl64_y (& (bv 8 0x3f) (cast 8 false (var r4))) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false))))) (set r10 (var result)) empty)
dE "rotlw r10, r20, r4" 5e8a203e 0x35c (seq (set mstart (bv 8 0x20)) (set mstop (bv 8 0x3f)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl32_x (cast 32 false (var r20)) (let rotl32_y (cast 6 false (& (var r4) (bv 64 0x1f))) (let rotl64_x (append (var rotl32_x) (var rotl32_x)) (let rotl64_y (var rotl32_y) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))))) (var mask))) (set r10 (var result)) empty)
dE "rotlwi r10, r2, 4" 544a203e 0x360 (seq (set mstart (bv 8 0x20)) (set mstop (bv 8 0x3f)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl32_x (cast 32 false (var r2)) (let rotl32_y (bv 8 0x4) (let rotl64_x (append (var rotl32_x) (var rotl32_x)) (let rotl64_y (var rotl32_y) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))))) (var mask))) (set r10 (var result)) empty)
dE "clrlwi r10, r20, 0xc" 568a033e 0x364 (seq (set mstart (bv 8 0x2c)) (set mstop (bv 8 0x3f)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (var r20) (var mask))) (set r10 (var result)) empty)
dE "clrldi. r10, r20, 0x3c" 7a8a0721 0x368 (seq (set mstart (bv 8 0x3c)) (set mstop (bv 8 0x3f)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (var r20) (var mask))) (set r10 (var result)) (set l (var result)) (set r (bv 64 0x0)) (set so_flag (ite (var so) (bv 1 0x1) (bv 1 0x0))) (branch (&& (sle (var l) (var r)) (! (== (var l) (var r)))) (set cr0 (append (bv 3 0x4) (var so_flag))) (branch (! (sle (var l) (var r))) (set cr0 (append (bv 3 0x2) (var so_flag))) (set cr0 (append (bv 3 0x1) (var so_flag))))))
dE "rldcl r10, r20, r4, 0x10" 7a8a2410 0x36c (seq (set mstart (bv 8 0x10)) (set mstop (bv 8 0x3f)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl64_x (var r20) (let rotl64_y (& (bv 8 0x3f) (cast 8 false (var r4))) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))) (var mask))) (set r10 (var result)) empty)
dE "rldcr r10, r20, r4, 0x10" 7a8a2412 0x370 (seq (set mstart (bv 8 0x0)) (set mstop (bv 8 0x10)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl64_x (var r20) (let rotl64_y (& (bv 8 0x3f) (cast 8 false (var r4))) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))) (var mask))) (set r10 (var result)) empty)
dE "rldicr r10, r20, 4, 0x10" 7a8a2404 0x374 (seq (set mstart (bv 8 0x0)) (set mstop (bv 8 0x10)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl64_x (var r20) (let rotl64_y (& (bv 8 0x3f) (bv 8 0x4)) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))) (var mask))) (set r10 (var result)) empty)
dE "rlwinm r10, r20, 4, 0x1b, 0x1b" 568a26f6 0x378 (seq (set mstart (bv 8 0x3b)) (set mstop (bv 8 0x3b)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl32_x (cast 32 false (var r20)) (let rotl32_y (bv 8 0x4) (let rotl64_x (append (var rotl32_x) (var rotl32_x)) (let rotl64_y (var rotl32_y) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))))) (var mask))) (set r10 (var result)) empty)
dE "rlwnm r10, r20, r4, 0x1b, 0x1b" 5e8a26f6 0x37c (seq (set mstart (bv 8 0x3b)) (set mstop (bv 8 0x3b)) (set m (bv 64 0x0)) (repeat (! (== (var mstart) (var mstop))) (seq (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstart) false))) (set mstart (smod (+ (var mstart) (bv 8 0x1)) (bv 8 0x40))))) (set m (| (var m) (>> (>> (bv 64 0x0) (bv 8 0x1) true) (var mstop) false))) (set mask (cast 64 false (var m))) empty (set result (& (let rotl32_x (cast 32 false (var r20)) (let rotl32_y (cast 6 false (& (var r4) (bv 64 0x1f))) (let rotl64_x (append (var rotl32_x) (var rotl32_x)) (let rotl64_y (var rotl32_y) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false)))))) (var mask))) (set r10 (var result)) empty)
dE "rotldi r10, r20, 4" 7a8a2000 0x380 (seq empty empty (set result (let rotl64_x (var r20) (let rotl64_y (& (bv 8 0x3f) (bv 8 0x4)) (| (<< (var rotl64_x) (var rotl64_y) false) (>> (var rotl64_x) (- (bv 8 0x40) (cast 8 false (var rotl64_y))) false))))) (set r10 (var result)) empty)
dE "divd r4, r6, r7" 7c863bd2 0x384 (seq (set r4 (cast 64 false (sdiv (cast 128 (msb (var r6)) (var r6)) (cast 128 (msb (var r7)) (var r7))))) empty)
dE "divdu r4, r6, r7" 7c863b92 0x388 (seq (set r4 (cast 64 false (div (cast 128 false (var r6)) (cast 128 false (var r7))))) empty)
dE "divw r4, r6, r7" 7c863bd6 0x38c (seq (set r4 (cast 64 false (sdiv (cast 64 (msb (cast 32 false (var r6))) (cast 32 false (var r6))) (cast 64 (msb (cast 32 false (var r7))) (cast 32 false (var r7)))))) empty)
dE "divwu r4, r6, r7" 7c863b96 0x390 (seq (set r4 (cast 64 false (div (cast 64 false (cast 32 (msb (var r6)) (var r6))) (cast 64 false (cast 32 (msb (var r7)) (var r7)))))) empty)
dE "mulhd r4, r6, r7" 7c863892 0x394 (seq (set r4 (cast 64 false (>> (* (cast 128 (msb (var r6)) (var r6)) (cast 128 (msb (var r7)) (var r7))) (bv 8 0x40) false))) empty)
dE "mulhdu r4, r6, r7" 7c863812 0x398 (seq (set r4 (cast 64 false (>> (* (cast 128 false (var r6)) (cast 128 false (var r7))) (bv 8 0x40) false))) empty)
dE "mulhw r4, r6, r7" 7c863896 0x39c (seq (set r4 (cast 64 false (>> (* (cast 64 (msb (cast 32 false (var r6))) (cast 32 false (var r6))) (cast 64 (msb (cast 32 false (var r7))) (cast 32 false (var r7)))) (bv 8 0x20) false))) empty)
dE "mulhwu r4, r6, r7" 7c863816 0x3a0 (seq (set r4 (cast 64 false (>> (* (cast 64 false (cast 32 (msb (var r6)) (var r6))) (cast 64 false (cast 32 (msb (var r7)) (var r7)))) (bv 8 0x20) false))) empty)
dE "mulld r4, r6, r7" 7c8639d2 0x3a4 (seq (set r4 (cast 64 false (* (cast 128 (msb (var r6)) (var r6)) (cast 128 (msb (var r7)) (var r7))))) empty)
dE "mulli r4, r6, 7" 1c860007 0x3a8 (seq (set r4 (cast 64 false (* (cast 128 (msb (var r6)) (var r6)) (cast 128 (msb (bv 16 0x7)) (bv 16 0x7))))) empty)
dE "mullw r4, r6, r7" 7c8639d6 0x3ac (seq (set r4 (cast 64 false (* (cast 64 (msb (cast 32 false (var r6))) (cast 32 false (var r6))) (cast 64 (msb (cast 32 false (var r7))) (cast 32 false (var r7)))))) empty)
dEB "creqv 4*cr3+so,4*cr1+lt,4*cr1+so" 4de43a42 0x3b0 ()
dEB "crxor 4*cr3+so,4*cr1+lt,4*cr1+so" 4de43982 0x3b4 ()
dEB "crand 4*cr3+so,4*cr1+lt,4*cr1+so" 4de43a02 0x3b8 ()
dEB "crandc 4*cr3+so,4*cr1+lt,4*cr1+so" 4de43902 0x3bc ()
dEB "crnand 4*cr3+so,4*cr1+lt,4*cr1+so" 4de439c2 0x3c0 ()
dEB "crnor 4*cr3+so,4*cr1+lt,4*cr1+so" 4de43842 0x3c4 ()
dEB "cror 4*cr3+so,4*cr1+lt,4*cr1+so" 4de43b82 0x3c8 ()
dEB "crorc 4*cr3+so,4*cr1+lt,4*cr1+so" 4de43b42 0x3cc ()
dEB "crset 4*cr3+so" 4def7a42 0x3d0 ()
dEB "crnot 4*cr3+so,4*cr1+lt" 4de42042 0x3d4 ()
dEB "crmove 4*cr3+so,4*cr1+lt" 4de42382 0x3d8 ()
dEB "crclr 4*cr3+so" 4def7982 0x3dc ()
dE "mcrf cr4, cr3" 4e0c0000 0x3e0 (set cr4 (var cr3))

View file

@ -1009,3 +1009,26 @@ EXPECT=<<EOF
0x00000000 8 rbx
EOF
RUN
NAME=ar 4 bit register
FILE==
CMDS=<<EOF
e asm.arch=ppc
e analysis.arch=ppc
ar cr0
ar cr0 = 15
ar cr0
ar cr1
ar cr1 = 15
ar cr1
ar cr1 = 7
ar cr1
EOF
EXPECT=<<EOF
cr0 = 0x00000000
cr0 = 0x0000000f
cr1 = 0x00000000
cr1 = 0x0000000f
cr1 = 0x00000007
EOF
RUN

View file

@ -108,7 +108,6 @@ EXPECT=<<EOF
;-- section..text:
;-- .text:
;-- _start:
;-- pc:
0x10000308 mr r9, r1 ; start.S:62
0x1000030c rlwinm r1, r1, 0, 0, 0x1b ; start.S:64
0x10000310 li r0, 0 ; start.S:69

46
test/db/rzil/ppc32 Normal file
View file

@ -0,0 +1,46 @@
NAME=emulateme-big-endian
FILE=bins/elf/ppc/emulateme-ppc32be
TIMEOUT=30
CMDS=<<EOF
s sym.decrypt
ps @ obj.seckrit
aezi
o malloc://0x1000 0x400000
o malloc://0x10 0x500000
e io.cache=1
e cfg.bigendian=1
w AnyColourYouLike @ 0x500000
ar r1=0x400000
ar r3=0x500000
aezsu 0x0010057c
ps @ obj.seckrit
EOF
EXPECT=<<EOF
QSMwX\x14Q_El\x17\x7fnx\x7f\x1c
Hello from RzIL!
EOF
EXPECT_ERR=
RUN
NAME=emulateme-little-endian
FILE=bins/elf/ppc/emulateme-ppc32le
TIMEOUT=30
CMDS=<<EOF
s sym.decrypt
ps @ obj.seckrit
aezi
o malloc://0x1000 0x400000
o malloc://0x10 0x500000
e io.cache=1
w AnyColourYouLike @ 0x500000
ar r1=0x400000
ar r3=0x500000
aezsu 0x00100504
ps @ obj.seckrit
EOF
EXPECT=<<EOF
QSMwX\x14Q_El\x17\x7fnx\x7f\x1c
Hello from RzIL!
EOF
EXPECT_ERR=
RUN

619
test/db/rzil/ppc64 Normal file
View file

@ -0,0 +1,619 @@
NAME=ppc add instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
af
s sym.add_insns
aezi
aezse 16~var_write
EOF
EXPECT=<<EOF
var_write(name: r23, old: 0x0, new: 0x1)
var_write(name: r2, old: 0x0, new: 0x2)
var_write(name: r3, old: 0x0, new: 0x3)
var_write(name: r4, old: 0x0, new: 0x4)
var_write(name: cr0, old: 0x0, new: 0x4)
var_write(name: r10, old: 0x0, new: 0xffffffffffffffff)
var_write(name: r0, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x0, new: 0x1)
var_write(name: cr0, old: 0x4, new: 0x2)
var_write(name: r11, old: 0x0, new: 0xffffffffffff0000)
var_write(name: r11, old: 0xffffffffffff0000, new: 0xffffffffffffffff)
var_write(name: r12, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x2, new: 0x2)
var_write(name: r13, old: 0x0, new: 0x2)
var_write(name: ca, old: 0x1, new: 0x0)
var_write(name: cr0, old: 0x2, new: 0x4)
var_write(name: r12, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x0, new: 0x1)
var_write(name: cr0, old: 0x4, new: 0x2)
var_write(name: r16, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x2, new: 0x2)
var_write(name: r12, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x2, new: 0x2)
var_write(name: r17, old: 0x0, new: 0x1)
var_write(name: ca, old: 0x1, new: 0x0)
var_write(name: cr0, old: 0x2, new: 0x4)
var_write(name: r17, old: 0x1, new: 0xffffffffffffffff)
var_write(name: ca, old: 0x0, new: 0x0)
var_write(name: cr0, old: 0x4, new: 0x8)
var_write(name: r17, old: 0xffffffffffffffff, new: 0x1)
EOF
RUN
NAME=ppc sub instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
af
s sym.sub_insns
aezi
aezse 18~var_write
EOF
EXPECT=<<EOF
var_write(name: r0, old: 0x0, new: 0x0)
var_write(name: r23, old: 0x0, new: 0x1)
var_write(name: r2, old: 0x0, new: 0x2)
var_write(name: r3, old: 0x0, new: 0x3)
var_write(name: r23, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x0, new: 0x4)
var_write(name: r0, old: 0x0, new: 0x0)
var_write(name: cr0, old: 0x4, new: 0x2)
var_write(name: r11, old: 0x0, new: 0xffffffffffffffff)
var_write(name: cr0, old: 0x2, new: 0x8)
var_write(name: r11, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
var_write(name: ca, old: 0x0, new: 0x0)
var_write(name: cr0, old: 0x8, new: 0x8)
var_write(name: r0, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x0, new: 0x1)
var_write(name: cr0, old: 0x8, new: 0x2)
var_write(name: r11, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
var_write(name: ca, old: 0x1, new: 0x0)
var_write(name: r0, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x0, new: 0x1)
var_write(name: r11, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
var_write(name: ca, old: 0x1, new: 0x0)
var_write(name: cr0, old: 0x2, new: 0x8)
var_write(name: r12, old: 0x0, new: 0xfffffffffffffffe)
var_write(name: ca, old: 0x0, new: 0x0)
var_write(name: cr0, old: 0x8, new: 0x8)
var_write(name: r13, old: 0x0, new: 0xfffffffffffffffd)
var_write(name: ca, old: 0x0, new: 0x1)
var_write(name: cr0, old: 0x8, new: 0x8)
var_write(name: r12, old: 0xfffffffffffffffe, new: 0xfffffffffffffffe)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x8, new: 0x8)
var_write(name: r11, old: 0xffffffffffffffff, new: 0x0)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x8, new: 0x2)
var_write(name: r0, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x2, new: 0x2)
var_write(name: r10, old: 0x0, new: 0x0)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x2, new: 0x2)
EOF
RUN
NAME=ppc store instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
e io.cache=true
wc-*
s sym.store_insns
aezi
aezse 15~mem_write
aezse 4~var_write
EOF
EXPECT=<<EOF
mem_write(addr: 0x1e2010, old: 0x0, new: 0xff)
mem_write(addr: 0x1e2020, old: 0x0, new: 0xffff)
mem_write(addr: 0x1e2030, old: 0x0, new: 0xffffffff)
mem_write(addr: 0x1e2040, old: 0x0, new: 0xffffffffffffffff)
mem_write(addr: 0x1e2010, old: 0xff, new: 0xff)
mem_write(addr: 0x1e2020, old: 0xffff, new: 0xffff)
mem_write(addr: 0x1e2030, old: 0xffffffff, new: 0xffffffff)
mem_write(addr: 0x1e2040, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
var_write(name: r21, old: 0x1e2010, new: 0x1e2010)
var_write(name: r21, old: 0x1e2010, new: 0x1e2020)
var_write(name: r21, old: 0x1e2020, new: 0x1e2030)
var_write(name: r21, old: 0x1e2030, new: 0x1e2040)
EOF
RUN
NAME=ppc load instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
e io.cache=true
wc-*
s sym.test_loads
aezi
aezse 16~var_write
aezs 2
aezse 3~var_write
EOF
EXPECT=<<EOF
var_write(name: r30, old: 0x0, new: 0x0)
var_write(name: lr, old: 0x0, new: 0x100a44)
var_write(name: r4, old: 0x0, new: 0x4)
var_write(name: r11, old: 0x0, new: 0xffffffffffffffff)
var_write(name: r12, old: 0x0, new: 0x10)
var_write(name: r13, old: 0x0, new: 0x20)
var_write(name: r14, old: 0x0, new: 0x30)
var_write(name: r21, old: 0x0, new: 0x1e0000)
var_write(name: r21, old: 0x1e0000, new: 0x1e2010)
var_write(name: r21, old: 0x1e2010, new: 0x1e2020)
var_write(name: r21, old: 0x1e2020, new: 0x1e2030)
var_write(name: r21, old: 0x1e2030, new: 0x1e2040)
EOF
RUN
NAME=ppc logical instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.logical_insns
aezi
aezs 1 # backup lr
aezse 17~var_write
# EXTS tests
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
# Count zeros tests
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 2~var_write
aezs 5
aezse 1~var_write
aezse 2~var_write
# eqv tests
aezse 2~var_write
EOF
EXPECT=<<EOF
var_write(name: r0, old: 0x0, new: 0x0)
var_write(name: r23, old: 0x0, new: 0x1)
var_write(name: r11, old: 0x0, new: 0xffffffffffffffff)
var_write(name: r21, old: 0x0, new: 0x1)
var_write(name: r12, old: 0x0, new: 0xfffffffffffffffe)
var_write(name: r23, old: 0x1, new: 0x1)
var_write(name: cr0, old: 0x0, new: 0x4)
var_write(name: r19, old: 0x0, new: 0xffff0000)
var_write(name: cr0, old: 0x4, new: 0x4)
var_write(name: r23, old: 0x1, new: 0x1)
var_write(name: r12, old: 0xfffffffffffffffe, new: 0xfffffffffffffffe)
var_write(name: r5, old: 0x0, new: 0x5555)
var_write(name: r5, old: 0x5555, new: 0x55550000)
var_write(name: r5, old: 0x55550000, new: 0xffffffffaaaaffff)
var_write(name: r5, old: 0xffffffffaaaaffff, new: 0xffffffffaaaa3333)
var_write(name: r5, old: 0xffffffffaaaa3333, new: 0xffffffff66663333)
var_write(name: r12, old: 0xfffffffffffffffe, new: 0xfffffffffffffffe)
var_write(name: r12, old: 0xfffffffffffffffe, new: 0xfffffffffffffffe)
var_write(name: r20, old: 0x0, new: 0xffffffff66663333)
var_write(name: r10, old: 0x0, new: 0xffffffffffffff80)
var_write(name: r10, old: 0xffffffffffffff80, new: 0x7f)
var_write(name: r10, old: 0x7f, new: 0xffffffffffff8000)
var_write(name: r10, old: 0xffffffffffff8000, new: 0x7fff)
var_write(name: r10, old: 0x7fff, new: 0xffffffff80000000)
var_write(name: r10, old: 0xffffffff80000000, new: 0x7fffffff)
var_write(name: r13, old: 0x0, new: 0x40)
var_write(name: r13, old: 0x40, new: 0x0)
var_write(name: r13, old: 0x0, new: 0x20)
var_write(name: r13, old: 0x20, new: 0x0)
var_write(name: r13, old: 0x0, new: 0x20)
var_write(name: r11, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
var_write(name: r19, old: 0xffff0000, new: 0xfffffffffffffffe)
var_write(name: lr, old: 0x100c20, new: 0x0)
EOF
RUN
NAME=ppc compare instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.compare_insns
aezi
aezs 2
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezs 5
aezse 1~var_write
aezse 4~var_write
aezs 4
aezse 1~var_write
aezs 1
aezse 1~var_write
EOF
EXPECT=<<EOF
var_write(name: cr0, old: 0x0, new: 0x8)
var_write(name: cr0, old: 0x8, new: 0x8)
var_write(name: cr1, old: 0x0, new: 0x4)
var_write(name: cr1, old: 0x4, new: 0x4)
var_write(name: cr2, old: 0x0, new: 0x8)
var_write(name: cr2, old: 0x8, new: 0x8)
var_write(name: cr3, old: 0x0, new: 0x2)
var_write(name: cr3, old: 0x2, new: 0x2)
var_write(name: cr4, old: 0x0, new: 0x4)
var_write(name: cr5, old: 0x0, new: 0x8)
var_write(name: cr6, old: 0x0, new: 0x8)
var_write(name: cr7, old: 0x0, new: 0x8)
var_write(name: r9, old: 0x0, new: 0xffffffffffffffff)
var_write(name: r9, old: 0xffffffffffffffff, new: 0xff00)
EOF
RUN
NAME=ppc shift instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.shift_insns
aezi
aezs 4
aezse 6~var_write
aezs 3
aezse 4~var_write
EOF
EXPECT=<<EOF
var_write(name: r10, old: 0x0, new: 0xedcba98765432100)
var_write(name: r10, old: 0xedcba98765432100, new: 0xfedcba987654321)
var_write(name: r10, old: 0xfedcba987654321, new: 0x65432100)
var_write(name: r10, old: 0x65432100, new: 0x7654321)
var_write(name: ca, old: 0x0, new: 0x0)
var_write(name: r10, old: 0x7654321, new: 0xffedcba987654321)
var_write(name: ca, old: 0x0, new: 0x0)
var_write(name: r10, old: 0xffedcba987654321, new: 0xffedcba987654321)
var_write(name: ca, old: 0x0, new: 0x1)
var_write(name: r10, old: 0xffedcba987654321, new: 0xfffffffff89abcde)
var_write(name: ca, old: 0x1, new: 0x1)
var_write(name: r10, old: 0xfffffffff89abcde, new: 0xfffffffff89abcde)
var_write(name: r10, old: 0xfffffffff89abcde, new: 0x32100000)
var_write(name: r10, old: 0x32100000, new: 0x7654)
EOF
RUN
NAME=ppc rotate instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.rotate_insns
aezi
aezs 4
aezse 16~var_write
EOF
EXPECT=<<EOF
var_write(name: r10, old: 0x0, new: 0x4320000)
var_write(name: r10, old: 0x4320000, new: 0x5432107654321076)
var_write(name: r10, old: 0x5432107654321076, new: 0x0)
var_write(name: r10, old: 0x0, new: 0x5432107650001076)
var_write(name: r10, old: 0x5432107650001076, new: 0x0)
var_write(name: r10, old: 0x0, new: 0x4000000)
var_write(name: r10, old: 0x4000000, new: 0xa9876543210f)
var_write(name: r10, old: 0xa9876543210f, new: 0x0)
var_write(name: r10, old: 0x0, new: 0xcba98765432100)
var_write(name: r10, old: 0xcba98765432100, new: 0xedcba9876543210f)
var_write(name: r10, old: 0xedcba9876543210f, new: 0x65432107)
var_write(name: r10, old: 0x65432107, new: 0xcba9876543210)
var_write(name: r10, old: 0xcba9876543210, new: 0x43210)
var_write(name: r10, old: 0x43210, new: 0x7edcba9876543210)
var_write(name: cr0, old: 0x0, new: 0x4)
var_write(name: r10, old: 0x7edcba9876543210, new: 0xfedcba9876543210)
var_write(name: cr0, old: 0x4, new: 0x8)
var_write(name: r10, old: 0xfedcba9876543210, new: 0x0)
var_write(name: cr0, old: 0x8, new: 0x2)
EOF
RUN
NAME=ppc CR logical instructions
FILE=bins/elf/ppc/ppc64le_uplifted
BROKEN=1
ARGS=-appc
CMDS=<<EOF
s sym.cr_logical_insns
aezi
aezs 3
aezse 5~var_write
aezs
aezse 2~var_write
EOF
EXPECT=<<EOF
EOF
RUN
NAME=ppc div and mul instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.div_mul_insns
aezi
aezs 1
aezs 4 # -1 into r11
aezs 5 # max into r28
aezse 1~var_write
aezs 5 # max into r28
aezse 2~var_write
# High words/double words
aezs 5 # min into r27
aezse 1~var_write
aezs 5 # min into r27
aezs 5 # max into r28
aezse 1~var_write
aezs 6 # r2 = 2 & max into r28
aezse 1~var_write
aezs 5 # max into r28
aezse 1~var_write
aezs 5 # max d into r28
aezs 4 # minus into r11
aezse 1~var_write
aezse 1~var_write
aezs 5 # max w into r28
aezs 4 # minus into r11
aezse 1~var_write
aezse 1~var_write
EOF
EXPECT=<<EOF
var_write(name: r19, old: 0x0, new: 0xffffffff80000001)
var_write(name: r19, old: 0xffffffff80000001, new: 0x8000000000000001)
var_write(name: r19, old: 0x8000000000000001, new: 0x8000000000000001)
var_write(name: r19, old: 0x8000000000000001, new: 0xc000000000000000)
var_write(name: r19, old: 0xc000000000000000, new: 0xc0000000)
var_write(name: r19, old: 0xc0000000, new: 0x1)
var_write(name: r19, old: 0x1, new: 0x1)
var_write(name: r19, old: 0x1, new: 0x8000000000000001)
var_write(name: r19, old: 0x8000000000000001, new: 0x0)
var_write(name: r19, old: 0x0, new: 0xffffffff80000001)
var_write(name: r19, old: 0xffffffff80000001, new: 0x0)
EOF
RUN
NAME=ppc branch instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.branch_insns
aezi
aezs 1
aezse 48
EOF
EXPECT=<<EOF
pc_write(old: 0x10095c, new: 0x100960)
var_write(name: r23, old: 0x0, new: 0x1)
pc_write(old: 0x100960, new: 0x100964)
var_write(name: r20, old: 0x0, new: 0x0)
pc_write(old: 0x100964, new: 0x100968)
var_write(name: lr, old: 0x0, new: 0x100968)
pc_write(old: 0x100968, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x100968)
pc_write(old: 0x100968, new: 0x10096c)
var_write(name: r20, old: 0x0, new: 0x100000)
pc_write(old: 0x10096c, new: 0x100970)
var_write(name: r20, old: 0x100000, new: 0x100954)
pc_write(old: 0x100970, new: 0x100974)
var_write(name: ctr, old: 0x0, new: 0x100954)
pc_write(old: 0x100974, new: 0x100978)
var_write(name: lr, old: 0x100968, new: 0x100978)
pc_write(old: 0x100978, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x100978)
pc_write(old: 0x100978, new: 0x10097c)
var_write(name: ctr, old: 0x100954, new: 0x100953)
var_write(name: lr, old: 0x100978, new: 0x10097c)
pc_write(old: 0x10097c, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x10097c)
pc_write(old: 0x10097c, new: 0x100980)
var_write(name: ctr, old: 0x100953, new: 0x1)
pc_write(old: 0x100980, new: 0x100984)
var_write(name: ctr, old: 0x1, new: 0x0)
var_write(name: lr, old: 0x10097c, new: 0x100984)
pc_write(old: 0x100984, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x100984)
pc_write(old: 0x100984, new: 0x100988)
var_write(name: lr, old: 0x100984, new: 0x100988)
pc_write(old: 0x100988, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x100988)
pc_write(old: 0x100988, new: 0x10098c)
var_write(name: cr0, old: 0x0, new: 0x2)
pc_write(old: 0x10098c, new: 0x100990)
var_write(name: lr, old: 0x100988, new: 0x100990)
pc_write(old: 0x100990, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x100990)
pc_write(old: 0x100990, new: 0x100994)
var_write(name: ctr, old: 0x0, new: 0x100954)
pc_write(old: 0x100994, new: 0x100998)
var_write(name: r10, old: 0x0, new: 0xfff0000)
pc_write(old: 0x100998, new: 0x10099c)
var_write(name: r10, old: 0xfff0000, new: 0xfff0ff0)
pc_write(old: 0x10099c, new: 0x1009a0)
var_write(name: cr7, old: 0x0, new: 0x0)
var_write(name: cr6, old: 0x0, new: 0xf)
var_write(name: cr5, old: 0x0, new: 0xf)
var_write(name: cr4, old: 0x0, new: 0x0)
var_write(name: cr3, old: 0x0, new: 0xf)
var_write(name: cr2, old: 0x0, new: 0xf)
var_write(name: cr1, old: 0x0, new: 0xf)
var_write(name: cr0, old: 0x2, new: 0x0)
pc_write(old: 0x1009a0, new: 0x1009a4)
var_write(name: ctr, old: 0x100954, new: 0x100953)
var_write(name: lr, old: 0x100990, new: 0x1009a4)
pc_write(old: 0x1009a4, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x1009a4)
pc_write(old: 0x1009a4, new: 0x1009a8)
var_write(name: r10, old: 0xfff0ff0, new: 0x1000)
pc_write(old: 0x1009a8, new: 0x1009ac)
var_write(name: cr6, old: 0xf, new: 0x0)
pc_write(old: 0x1009ac, new: 0x1009b0)
var_write(name: ctr, old: 0x100953, new: 0x100952)
var_write(name: lr, old: 0x1009a4, new: 0x1009b0)
pc_write(old: 0x1009b0, new: 0x1009b0)
pc_write(old: 0x1009b0, new: 0x1009b4)
var_write(name: ctr, old: 0x100952, new: 0x1)
pc_write(old: 0x1009b4, new: 0x1009b8)
var_write(name: cr6, old: 0x0, new: 0x0)
pc_write(old: 0x1009b8, new: 0x1009bc)
var_write(name: ctr, old: 0x1, new: 0x0)
var_write(name: lr, old: 0x1009b0, new: 0x1009bc)
pc_write(old: 0x1009bc, new: 0x1009bc)
pc_write(old: 0x1009bc, new: 0x1009c0)
var_write(name: ctr, old: 0x0, new: 0x1)
pc_write(old: 0x1009c0, new: 0x1009c4)
var_write(name: r10, old: 0x1000, new: 0x0)
pc_write(old: 0x1009c4, new: 0x1009c8)
var_write(name: r10, old: 0x0, new: 0x10000000)
pc_write(old: 0x1009c8, new: 0x1009cc)
var_write(name: cr6, old: 0x0, new: 0x0)
pc_write(old: 0x1009cc, new: 0x1009d0)
var_write(name: ctr, old: 0x1, new: 0x0)
var_write(name: lr, old: 0x1009bc, new: 0x1009d0)
pc_write(old: 0x1009d0, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x1009d0)
pc_write(old: 0x1009d0, new: 0x1009d4)
var_write(name: ctr, old: 0x0, new: 0x0)
pc_write(old: 0x1009d4, new: 0x1009d8)
var_write(name: ctr, old: 0x0, new: 0xffffffffffffffff)
var_write(name: lr, old: 0x1009d0, new: 0x1009d8)
pc_write(old: 0x1009d8, new: 0x1009d8)
pc_write(old: 0x1009d8, new: 0x1009dc)
var_write(name: ctr, old: 0xffffffffffffffff, new: 0x1)
pc_write(old: 0x1009dc, new: 0x1009e0)
var_write(name: r3, old: 0x0, new: 0x3)
pc_write(old: 0x1009e0, new: 0x1009e4)
var_write(name: cr6, old: 0x0, new: 0x0)
pc_write(old: 0x1009e4, new: 0x1009e8)
var_write(name: ctr, old: 0x1, new: 0x0)
var_write(name: lr, old: 0x1009d8, new: 0x1009e8)
pc_write(old: 0x1009e8, new: 0x1009e8)
pc_write(old: 0x1009e8, new: 0x1009ec)
var_write(name: lr, old: 0x1009e8, new: 0x1009ec)
pc_write(old: 0x1009ec, new: 0x100954)
pc_write(old: 0x100954, new: 0x100958)
pc_write(old: 0x100958, new: 0x1009ec)
pc_write(old: 0x1009ec, new: 0x1009f0)
var_write(name: lr, old: 0x1009ec, new: 0x0)
pc_write(old: 0x1009f0, new: 0x1009f4)
pc_write(old: 0x1009f4, new: 0x0)
EOF
BROKEN=1
RUN
NAME=ppc special instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.special_insns
aezi
aezse 2 # nop, xnor
aezs 3
aezse 2 # isel
EOF
EXPECT=<<EOF
EOF
BROKEN=1
RUN
NAME=ppc move to from spr instructions
FILE=bins/elf/ppc/ppc64le_uplifted
ARGS=-appc
CMDS=<<EOF
s sym.read_set_spr
aezi
aezs 1
aezs 5
aezse 4~var_write
aezs 5 # max into r28
aezse 1~var_write
EOF
EXPECT=<<EOF
var_write(name: ctr, old: 0x0, new: 0xffffffffffffffff)
var_write(name: r28, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
var_write(name: lr, old: 0x100a1c, new: 0xffffffffffffffff)
var_write(name: r28, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
var_write(name: xer, old: 0x0, new: 0xe0000000)
var_write(name: so, old: 0x0, new: 0x1)
var_write(name: ov, old: 0x0, new: 0x1)
var_write(name: ca, old: 0x0, new: 0x1)
EOF
RUN
NAME=emulateme-big-endian
FILE=bins/elf/ppc/emulateme-ppc64be
TIMEOUT=30
CMDS=<<EOF
s sym.decrypt
ps @ obj.seckrit
aezi
o malloc://0x1000 0x400000
o malloc://0x10 0x500000
e io.cache=1
e cfg.bigendian=1
w AnyColourYouLike @ 0x500000
ar r1=0x400000
ar r3=0x500000
aezsu 0x001005a8
ps @ obj.seckrit
EOF
EXPECT=<<EOF
QSMwX\x14Q_El\x17\x7fnx\x7f\x1c
Hello from RzIL!
EOF
EXPECT_ERR=
RUN
NAME=emulateme-little-endian
FILE=bins/elf/ppc/emulateme-ppc64le
TIMEOUT=30
CMDS=<<EOF
s sym.decrypt
ps @ obj.seckrit
aezi
o malloc://0x1000 0x400000
o malloc://0x10 0x500000
e io.cache=1
w AnyColourYouLike @ 0x500000
ar r1=0x400000
ar r3=0x500000
aezsu 0x001007f8
ps @ obj.seckrit
EOF
EXPECT=<<EOF
QSMwX\x14Q_El\x17\x7fnx\x7f\x1c
Hello from RzIL!
EOF
EXPECT_ERR=
RUN