mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-02-12 09:58:42 +00:00
Handle reserved values of the 'at' bits of BO fields. (#2168)
This commit is contained in:
parent
4e496d77f1
commit
123beeee4a
@ -582,51 +582,6 @@ void PPC_set_detail_op_imm(MCInst *MI, unsigned OpNum, int64_t Imm)
|
||||
PPC_inc_op_count(MI);
|
||||
}
|
||||
|
||||
/// Returns the predicate wihtout branch hint information.
|
||||
ppc_pred PPC_get_no_hint_pred(unsigned Code)
|
||||
{
|
||||
switch (Code) {
|
||||
default:
|
||||
assert(0 && "Invalid predicate code");
|
||||
case PPC_PRED_LT:
|
||||
case PPC_PRED_LT_MINUS:
|
||||
case PPC_PRED_LT_PLUS:
|
||||
return PPC_PRED_LT;
|
||||
case PPC_PRED_LE:
|
||||
case PPC_PRED_LE_MINUS:
|
||||
case PPC_PRED_LE_PLUS:
|
||||
return PPC_PRED_LE;
|
||||
case PPC_PRED_EQ:
|
||||
case PPC_PRED_EQ_MINUS:
|
||||
case PPC_PRED_EQ_PLUS:
|
||||
return PPC_PRED_EQ;
|
||||
case PPC_PRED_GE:
|
||||
case PPC_PRED_GE_MINUS:
|
||||
case PPC_PRED_GE_PLUS:
|
||||
return PPC_PRED_GE;
|
||||
case PPC_PRED_GT:
|
||||
case PPC_PRED_GT_MINUS:
|
||||
case PPC_PRED_GT_PLUS:
|
||||
return PPC_PRED_GT;
|
||||
case PPC_PRED_NE:
|
||||
case PPC_PRED_NE_MINUS:
|
||||
case PPC_PRED_NE_PLUS:
|
||||
return PPC_PRED_NE;
|
||||
case PPC_PRED_UN:
|
||||
case PPC_PRED_UN_MINUS:
|
||||
case PPC_PRED_UN_PLUS:
|
||||
return PPC_PRED_UN;
|
||||
case PPC_PRED_NU:
|
||||
case PPC_PRED_NU_MINUS:
|
||||
case PPC_PRED_NU_PLUS:
|
||||
return PPC_PRED_NU;
|
||||
case PPC_PRED_BIT_SET:
|
||||
case PPC_PRED_BIT_UNSET:
|
||||
assert(0 && "Invalid use of bit predicate code");
|
||||
}
|
||||
return PPC_PRED_INVALID;
|
||||
}
|
||||
|
||||
void PPC_set_mem_access(MCInst *MI, bool status)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
|
@ -68,7 +68,6 @@ void PPC_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Val,
|
||||
|
||||
void PPC_setup_op(cs_ppc_op *op);
|
||||
|
||||
ppc_pred PPC_get_no_hint_pred(unsigned Code);
|
||||
void PPC_check_updates_cr0(MCInst *MI);
|
||||
void PPC_set_instr_map_data(MCInst *MI, const uint8_t *Bytes, size_t BytesLen);
|
||||
|
||||
|
@ -31,8 +31,18 @@ PPC_PRED_GT_PLUS = (1<<5)|15
|
||||
PPC_PRED_NE_PLUS = (2<<5)|7
|
||||
PPC_PRED_UN_PLUS = (3<<5)|15
|
||||
PPC_PRED_NU_PLUS = (3<<5)|7
|
||||
PPC_PRED_NZ_PLUS = (0<<5)|17
|
||||
PPC_PRED_Z_PLUS = (0<<5)|19
|
||||
PPC_PRED_NZ_PLUS = (0<<5)|25
|
||||
PPC_PRED_Z_PLUS = (0<<5)|27
|
||||
PPC_PRED_LT_RESERVED = (0<<5)|13
|
||||
PPC_PRED_LE_RESERVED = (1<<5)|5
|
||||
PPC_PRED_EQ_RESERVED = (2<<5)|13
|
||||
PPC_PRED_GE_RESERVED = (0<<5)|5
|
||||
PPC_PRED_GT_RESERVED = (1<<5)|13
|
||||
PPC_PRED_NE_RESERVED = (2<<5)|5
|
||||
PPC_PRED_UN_RESERVED = (3<<5)|13
|
||||
PPC_PRED_NU_RESERVED = (3<<5)|5
|
||||
PPC_PRED_NZ_RESERVED = (0<<5)|17
|
||||
PPC_PRED_Z_RESERVED = (0<<5)|19
|
||||
PPC_PRED_SPE = PPC_PRED_GT
|
||||
PPC_PRED_BIT_SET = 1024
|
||||
PPC_PRED_BIT_UNSET = 1025
|
||||
|
@ -15,42 +15,52 @@ static const char* get_pred_name(ppc_pred pred)
|
||||
case PPC_PRED_LT:
|
||||
case PPC_PRED_LT_MINUS:
|
||||
case PPC_PRED_LT_PLUS:
|
||||
case PPC_PRED_LT_RESERVED:
|
||||
return ("lt");
|
||||
case PPC_PRED_LE:
|
||||
case PPC_PRED_LE_MINUS:
|
||||
case PPC_PRED_LE_PLUS:
|
||||
case PPC_PRED_LE_RESERVED:
|
||||
return ("le");
|
||||
case PPC_PRED_EQ:
|
||||
case PPC_PRED_EQ_MINUS:
|
||||
case PPC_PRED_EQ_PLUS:
|
||||
case PPC_PRED_EQ_RESERVED:
|
||||
return ("eq");
|
||||
case PPC_PRED_GE:
|
||||
case PPC_PRED_GE_MINUS:
|
||||
case PPC_PRED_GE_PLUS:
|
||||
case PPC_PRED_GE_RESERVED:
|
||||
return ("ge");
|
||||
case PPC_PRED_GT:
|
||||
case PPC_PRED_GT_MINUS:
|
||||
case PPC_PRED_GT_PLUS:
|
||||
case PPC_PRED_GT_RESERVED:
|
||||
return ("gt");
|
||||
case PPC_PRED_NE:
|
||||
case PPC_PRED_NE_MINUS:
|
||||
case PPC_PRED_NE_PLUS:
|
||||
case PPC_PRED_NE_RESERVED:
|
||||
return ("ne");
|
||||
case PPC_PRED_UN: // PPC_PRED_SO
|
||||
case PPC_PRED_UN_MINUS:
|
||||
case PPC_PRED_UN_PLUS:
|
||||
case PPC_PRED_UN_RESERVED:
|
||||
return ("so/un");
|
||||
case PPC_PRED_NU: // PPC_PRED_NS
|
||||
case PPC_PRED_NU_MINUS:
|
||||
case PPC_PRED_NU_PLUS:
|
||||
case PPC_PRED_NU_RESERVED:
|
||||
return ("ns/nu");
|
||||
case PPC_PRED_NZ:
|
||||
case PPC_PRED_NZ_MINUS:
|
||||
case PPC_PRED_NZ_PLUS:
|
||||
case PPC_PRED_NZ_RESERVED:
|
||||
return ("nz");
|
||||
case PPC_PRED_Z:
|
||||
case PPC_PRED_Z_MINUS:
|
||||
case PPC_PRED_Z_PLUS:
|
||||
case PPC_PRED_Z_RESERVED:
|
||||
return ("z");
|
||||
case PPC_PRED_BIT_SET:
|
||||
return "bit-set";
|
||||
@ -59,6 +69,21 @@ static const char* get_pred_name(ppc_pred pred)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *get_pred_hint(ppc_br_hint at) {
|
||||
switch (at) {
|
||||
default:
|
||||
return "invalid";
|
||||
case PPC_BR_NOT_GIVEN:
|
||||
return "not-given";
|
||||
case PPC_BR_TAKEN:
|
||||
return "likely-taken";
|
||||
case PPC_BR_NOT_TAKEN:
|
||||
return "likely-not-taken";
|
||||
case PPC_BR_RESERVED:
|
||||
return "reserved";
|
||||
}
|
||||
}
|
||||
|
||||
void print_insn_detail_ppc(csh handle, cs_insn *ins)
|
||||
{
|
||||
cs_ppc *ppc;
|
||||
@ -125,7 +150,7 @@ void print_insn_detail_ppc(csh handle, cs_insn *ins)
|
||||
if (ppc->bc.pred_ctr != PPC_PRED_INVALID)
|
||||
printf("\t\tpred CTR: %s\n", get_pred_name(ppc->bc.pred_ctr));
|
||||
if (ppc->bc.hint != PPC_BH_INVALID)
|
||||
printf("\t\thint: %u\n", ppc->bc.hint);
|
||||
printf("\t\thint: %s\n", get_pred_hint(ppc->bc.hint));
|
||||
}
|
||||
|
||||
if (ppc->bc.hint != PPC_BR_NOT_GIVEN)
|
||||
|
@ -8,6 +8,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include "cs_operand.h"
|
||||
#include "platform.h"
|
||||
|
||||
@ -89,8 +90,19 @@ typedef enum ppc_pred {
|
||||
PPC_PRED_NE_PLUS = (2 << 5) | 7,
|
||||
PPC_PRED_UN_PLUS = (3 << 5) | 15,
|
||||
PPC_PRED_NU_PLUS = (3 << 5) | 7,
|
||||
PPC_PRED_NZ_PLUS = (0 << 5) | 17,
|
||||
PPC_PRED_Z_PLUS = (0 << 5) | 19,
|
||||
PPC_PRED_NZ_PLUS = (0 << 5) | 25,
|
||||
PPC_PRED_Z_PLUS = (0 << 5) | 27,
|
||||
// Reserved
|
||||
PPC_PRED_LT_RESERVED = (0 << 5) | 13,
|
||||
PPC_PRED_LE_RESERVED = (1 << 5) | 5,
|
||||
PPC_PRED_EQ_RESERVED = (2 << 5) | 13,
|
||||
PPC_PRED_GE_RESERVED = (0 << 5) | 5,
|
||||
PPC_PRED_GT_RESERVED = (1 << 5) | 13,
|
||||
PPC_PRED_NE_RESERVED = (2 << 5) | 5,
|
||||
PPC_PRED_UN_RESERVED = (3 << 5) | 13,
|
||||
PPC_PRED_NU_RESERVED = (3 << 5) | 5,
|
||||
PPC_PRED_NZ_RESERVED = (0 << 5) | 17,
|
||||
PPC_PRED_Z_RESERVED = (0 << 5) | 19,
|
||||
|
||||
// SPE scalar compare instructions always set the GT bit.
|
||||
PPC_PRED_SPE = PPC_PRED_GT,
|
||||
@ -141,6 +153,71 @@ typedef enum {
|
||||
PPC_BH_RESERVED,
|
||||
} ppc_bh;
|
||||
|
||||
|
||||
/// Returns the predicate wihtout branch hint information.
|
||||
inline static ppc_pred PPC_get_no_hint_pred(ppc_pred Code)
|
||||
{
|
||||
switch (Code) {
|
||||
default:
|
||||
return PPC_PRED_INVALID;
|
||||
case PPC_PRED_LT:
|
||||
case PPC_PRED_LT_MINUS:
|
||||
case PPC_PRED_LT_PLUS:
|
||||
case PPC_PRED_LT_RESERVED:
|
||||
return PPC_PRED_LT;
|
||||
case PPC_PRED_LE:
|
||||
case PPC_PRED_LE_MINUS:
|
||||
case PPC_PRED_LE_PLUS:
|
||||
case PPC_PRED_LE_RESERVED:
|
||||
return PPC_PRED_LE;
|
||||
case PPC_PRED_EQ:
|
||||
case PPC_PRED_EQ_MINUS:
|
||||
case PPC_PRED_EQ_PLUS:
|
||||
case PPC_PRED_EQ_RESERVED:
|
||||
return PPC_PRED_EQ;
|
||||
case PPC_PRED_GE:
|
||||
case PPC_PRED_GE_MINUS:
|
||||
case PPC_PRED_GE_PLUS:
|
||||
case PPC_PRED_GE_RESERVED:
|
||||
return PPC_PRED_GE;
|
||||
case PPC_PRED_GT:
|
||||
case PPC_PRED_GT_MINUS:
|
||||
case PPC_PRED_GT_PLUS:
|
||||
case PPC_PRED_GT_RESERVED:
|
||||
return PPC_PRED_GT;
|
||||
case PPC_PRED_NE:
|
||||
case PPC_PRED_NE_MINUS:
|
||||
case PPC_PRED_NE_PLUS:
|
||||
case PPC_PRED_NE_RESERVED:
|
||||
return PPC_PRED_NE;
|
||||
case PPC_PRED_UN:
|
||||
case PPC_PRED_UN_MINUS:
|
||||
case PPC_PRED_UN_PLUS:
|
||||
case PPC_PRED_UN_RESERVED:
|
||||
return PPC_PRED_UN;
|
||||
case PPC_PRED_NU:
|
||||
case PPC_PRED_NU_MINUS:
|
||||
case PPC_PRED_NU_PLUS:
|
||||
case PPC_PRED_NU_RESERVED:
|
||||
return PPC_PRED_NU;
|
||||
case PPC_PRED_NZ:
|
||||
case PPC_PRED_NZ_MINUS:
|
||||
case PPC_PRED_NZ_PLUS:
|
||||
case PPC_PRED_NZ_RESERVED:
|
||||
return PPC_PRED_NZ;
|
||||
case PPC_PRED_Z:
|
||||
case PPC_PRED_Z_MINUS:
|
||||
case PPC_PRED_Z_PLUS:
|
||||
case PPC_PRED_Z_RESERVED:
|
||||
return PPC_PRED_Z;
|
||||
case PPC_PRED_BIT_SET:
|
||||
return PPC_PRED_BIT_SET;
|
||||
case PPC_PRED_BIT_UNSET:
|
||||
return PPC_PRED_BIT_UNSET;
|
||||
}
|
||||
return PPC_PRED_INVALID;
|
||||
}
|
||||
|
||||
/// Returns the hint encoded in the BO bits a and t.
|
||||
static inline ppc_br_hint PPC_get_hint(uint8_t bo)
|
||||
{
|
||||
@ -158,6 +235,7 @@ static inline ppc_br_hint PPC_get_hint(uint8_t bo)
|
||||
/// Returns the branch predicate encoded in the BO and BI field.
|
||||
/// If get_cr_pred = true the CR-bit predicate is returned (LE, GE, EQ...).
|
||||
/// Otherwise the CTR predicate (NZ, Z)
|
||||
/// The branch hint does not include the hint of the 'at' bits.
|
||||
///
|
||||
/// It returns PPC_PRED_INVALID if the CR predicate is requested, but no
|
||||
/// CR predicate is encoded in BI and BO. Same for the CTR predicate.
|
||||
@ -176,11 +254,11 @@ static inline ppc_pred PPC_get_branch_pred(uint8_t bi, uint8_t bo,
|
||||
// The CTR condition without the CR-bit condition.
|
||||
unsigned ctr_bo_cond = (bo | PPC_BO_TEST_CR) & ~PPC_BO_CR_CMP;
|
||||
if (get_cr_pred)
|
||||
return (ppc_pred)(((bi % 4) << 5) | cr_bo_cond);
|
||||
return (ppc_pred)ctr_bo_cond; // BI is ignored
|
||||
return PPC_get_no_hint_pred((ppc_pred)(((bi % 4) << 5) | cr_bo_cond));
|
||||
return PPC_get_no_hint_pred((ppc_pred)ctr_bo_cond); // BI is ignored
|
||||
}
|
||||
// BO doesn't need any separation
|
||||
return (ppc_pred)(((bi % 4) << 5) | bo);
|
||||
return PPC_get_no_hint_pred((ppc_pred)(((bi % 4) << 5) | bo));
|
||||
}
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
|
Loading…
x
Reference in New Issue
Block a user