From 6ca3afba0a1896d9273b3a7035fc342565f5ebff Mon Sep 17 00:00:00 2001 From: R33v0LT Date: Fri, 22 Mar 2024 18:57:55 +0300 Subject: [PATCH] clang-format hppa files --- MathExtras.h | 9 +- arch/HPPA/HPPAConstants.h | 122 +- arch/HPPA/HPPADisassembler.c | 7395 ++++++++++++++++---------------- arch/HPPA/HPPAInstPrinter.c | 115 +- arch/HPPA/HPPAInstPrinter.h | 9 +- arch/HPPA/HPPAMapping.c | 78 +- cstool/cstool_hppa.c | 107 +- include/capstone/hppa.h | 919 ++-- suite/cstest/src/hppa_detail.c | 51 +- tests/test_hppa.c | 77 +- 10 files changed, 4461 insertions(+), 4421 deletions(-) diff --git a/MathExtras.h b/MathExtras.h index e89b17344e..9e58e07664 100644 --- a/MathExtras.h +++ b/MathExtras.h @@ -432,8 +432,7 @@ static inline int64_t SignExtend64(uint64_t X, unsigned B) { /// \brief Removes the rightmost bit of x and extends the field to the left with that /// bit to form a 64-bit quantity. The field is of size len -static inline int64_t LowSignExtend64(uint64_t x, unsigned len) -{ +static inline int64_t LowSignExtend64(uint64_t x, unsigned len) { return (x >> 1) - ((x & 1) << (len - 1)); } @@ -475,11 +474,13 @@ static inline unsigned int countLeadingZeros(int x) } /// \brief Get specified field from 32-bit instruction. Returns bits from the segment [from, to] -static inline uint32_t get_insn_field(uint32_t insn, uint8_t from, uint8_t to) { +static inline uint32_t get_insn_field(uint32_t insn, uint8_t from, uint8_t to) +{ return insn >> (31 - to) & ((1 << (to - from + 1)) - 1); } /// \brief Get specified bit from 32-bit instruction -static inline uint32_t get_insn_bit(uint32_t insn, uint8_t bit) { +static inline uint32_t get_insn_bit(uint32_t insn, uint8_t bit) +{ return get_insn_field(insn, bit, bit); } diff --git a/arch/HPPA/HPPAConstants.h b/arch/HPPA/HPPAConstants.h index fd88331d13..d2ebb61b79 100644 --- a/arch/HPPA/HPPAConstants.h +++ b/arch/HPPA/HPPAConstants.h @@ -6,69 +6,69 @@ #ifndef CS_HPPA_CONSTANTS_H #define CS_HPPA_CONSTANTS_H -#define HPPA_OP_TYPE(byte) (byte) >> 2 -#define MODE_IS_HPPA_20(mode) (((mode) & CS_MODE_HPPA_20) != 0) +#define HPPA_OP_TYPE(byte) (byte) >> 2 +#define MODE_IS_HPPA_20(mode) (((mode)&CS_MODE_HPPA_20) != 0) #define MODE_IS_HPPA_20W(mode) (((mode) & (1 << 3)) != 0) ///> HPPA opcode types -#define HPPA_OP_TYPE_SYSOP 0x00 -#define HPPA_OP_TYPE_MEMMGMT 0x01 -#define HPPA_OP_TYPE_ALU 0x02 -#define HPPA_OP_TYPE_IDXMEM 0x03 -#define HPPA_OP_TYPE_SPOP 0x04 -#define HPPA_OP_TYPE_DIAG 0x05 -#define HPPA_OP_TYPE_FMPYADD 0x06 -#define HPPA_OP_TYPE_LDIL 0x08 -#define HPPA_OP_TYPE_COPRW 0x09 -#define HPPA_OP_TYPE_ADDIL 0x0a -#define HPPA_OP_TYPE_COPRDW 0x0b -#define HPPA_OP_TYPE_COPR 0x0c -#define HPPA_OP_TYPE_LDO 0x0d -#define HPPA_OP_TYPE_FLOAT 0x0e -#define HPPA_OP_TYPE_PRDSPEC 0x0f -#define HPPA_OP_TYPE_LDB 0x10 -#define HPPA_OP_TYPE_LDH 0x11 -#define HPPA_OP_TYPE_LDW 0x12 -#define HPPA_OP_TYPE_LDWM 0x13 -#define HPPA_OP_TYPE_LOADDW 0x14 -#define HPPA_OP_TYPE_FLDW 0x16 -#define HPPA_OP_TYPE_LOADW 0x17 -#define HPPA_OP_TYPE_STB 0x18 -#define HPPA_OP_TYPE_STH 0x19 -#define HPPA_OP_TYPE_STW 0x1a -#define HPPA_OP_TYPE_STWM 0x1b -#define HPPA_OP_TYPE_STOREDW 0x1c -#define HPPA_OP_TYPE_FSTW 0x1e -#define HPPA_OP_TYPE_STOREW 0x1f -#define HPPA_OP_TYPE_CMPBT 0x20 -#define HPPA_OP_TYPE_CMPIBT 0x21 -#define HPPA_OP_TYPE_CMPBF 0x22 -#define HPPA_OP_TYPE_CMPIBF 0x23 -#define HPPA_OP_TYPE_CMPICLR 0x24 -#define HPPA_OP_TYPE_SUBI 0x25 -#define HPPA_OP_TYPE_FMPYSUB 0x26 -#define HPPA_OP_TYPE_CMPBDWT 0x27 -#define HPPA_OP_TYPE_ADDBT 0x28 -#define HPPA_OP_TYPE_ADDIBT 0x29 -#define HPPA_OP_TYPE_ADDBF 0x2a -#define HPPA_OP_TYPE_ADDIBF 0x2b -#define HPPA_OP_TYPE_ADDIT 0x2c -#define HPPA_OP_TYPE_ADDI 0x2d -#define HPPA_OP_TYPE_FPFUSED 0x2e -#define HPPA_OP_TYPE_CMPBDWF 0x2f -#define HPPA_OP_TYPE_BBS 0x30 -#define HPPA_OP_TYPE_BB 0x31 -#define HPPA_OP_TYPE_MOVB 0x32 -#define HPPA_OP_TYPE_MOVIB 0x33 -#define HPPA_OP_TYPE_SHEXDEP0 0x34 -#define HPPA_OP_TYPE_SHEXDEP1 0x35 -#define HPPA_OP_TYPE_SHEXDEP2 0x36 -#define HPPA_OP_TYPE_BE 0x38 -#define HPPA_OP_TYPE_BLE 0x39 -#define HPPA_OP_TYPE_BRANCH 0x3a -#define HPPA_OP_TYPE_CMPIBDW 0x3b -#define HPPA_OP_TYPE_SHEXDEP3 0x3c -#define HPPA_OP_TYPE_SHEXDEP4 0x3d -#define HPPA_OP_TYPE_MULTMED 0x3e +#define HPPA_OP_TYPE_SYSOP 0x00 +#define HPPA_OP_TYPE_MEMMGMT 0x01 +#define HPPA_OP_TYPE_ALU 0x02 +#define HPPA_OP_TYPE_IDXMEM 0x03 +#define HPPA_OP_TYPE_SPOP 0x04 +#define HPPA_OP_TYPE_DIAG 0x05 +#define HPPA_OP_TYPE_FMPYADD 0x06 +#define HPPA_OP_TYPE_LDIL 0x08 +#define HPPA_OP_TYPE_COPRW 0x09 +#define HPPA_OP_TYPE_ADDIL 0x0a +#define HPPA_OP_TYPE_COPRDW 0x0b +#define HPPA_OP_TYPE_COPR 0x0c +#define HPPA_OP_TYPE_LDO 0x0d +#define HPPA_OP_TYPE_FLOAT 0x0e +#define HPPA_OP_TYPE_PRDSPEC 0x0f +#define HPPA_OP_TYPE_LDB 0x10 +#define HPPA_OP_TYPE_LDH 0x11 +#define HPPA_OP_TYPE_LDW 0x12 +#define HPPA_OP_TYPE_LDWM 0x13 +#define HPPA_OP_TYPE_LOADDW 0x14 +#define HPPA_OP_TYPE_FLDW 0x16 +#define HPPA_OP_TYPE_LOADW 0x17 +#define HPPA_OP_TYPE_STB 0x18 +#define HPPA_OP_TYPE_STH 0x19 +#define HPPA_OP_TYPE_STW 0x1a +#define HPPA_OP_TYPE_STWM 0x1b +#define HPPA_OP_TYPE_STOREDW 0x1c +#define HPPA_OP_TYPE_FSTW 0x1e +#define HPPA_OP_TYPE_STOREW 0x1f +#define HPPA_OP_TYPE_CMPBT 0x20 +#define HPPA_OP_TYPE_CMPIBT 0x21 +#define HPPA_OP_TYPE_CMPBF 0x22 +#define HPPA_OP_TYPE_CMPIBF 0x23 +#define HPPA_OP_TYPE_CMPICLR 0x24 +#define HPPA_OP_TYPE_SUBI 0x25 +#define HPPA_OP_TYPE_FMPYSUB 0x26 +#define HPPA_OP_TYPE_CMPBDWT 0x27 +#define HPPA_OP_TYPE_ADDBT 0x28 +#define HPPA_OP_TYPE_ADDIBT 0x29 +#define HPPA_OP_TYPE_ADDBF 0x2a +#define HPPA_OP_TYPE_ADDIBF 0x2b +#define HPPA_OP_TYPE_ADDIT 0x2c +#define HPPA_OP_TYPE_ADDI 0x2d +#define HPPA_OP_TYPE_FPFUSED 0x2e +#define HPPA_OP_TYPE_CMPBDWF 0x2f +#define HPPA_OP_TYPE_BBS 0x30 +#define HPPA_OP_TYPE_BB 0x31 +#define HPPA_OP_TYPE_MOVB 0x32 +#define HPPA_OP_TYPE_MOVIB 0x33 +#define HPPA_OP_TYPE_SHEXDEP0 0x34 +#define HPPA_OP_TYPE_SHEXDEP1 0x35 +#define HPPA_OP_TYPE_SHEXDEP2 0x36 +#define HPPA_OP_TYPE_BE 0x38 +#define HPPA_OP_TYPE_BLE 0x39 +#define HPPA_OP_TYPE_BRANCH 0x3a +#define HPPA_OP_TYPE_CMPIBDW 0x3b +#define HPPA_OP_TYPE_SHEXDEP3 0x3c +#define HPPA_OP_TYPE_SHEXDEP4 0x3d +#define HPPA_OP_TYPE_MULTMED 0x3e #endif // CS_HPPA_CONSTANTS_H \ No newline at end of file diff --git a/arch/HPPA/HPPADisassembler.c b/arch/HPPA/HPPADisassembler.c index ad650c04b2..2e0af53b17 100644 --- a/arch/HPPA/HPPADisassembler.c +++ b/arch/HPPA/HPPADisassembler.c @@ -13,106 +13,88 @@ #include "../../MathExtras.h" #include "../../utils.h" -#define CMPLT_HAS_MODIFY_BIT(CMPLT) (((CMPLT) & 1) == 1) +#define CMPLT_HAS_MODIFY_BIT(CMPLT) (((CMPLT)&1) == 1) #define HPPA_EXT_REF(MI) (&MI->hppa_ext) -static const char *const compare_cond_names[] = -{ - "", "=", "<", "<=", "<<", "<<=", "sv", "od", - "tr", "<>", ">=", ">", ">>=", ">>", "nsv", "ev" -}; -static const char *const compare_cond_64_names[] = -{ - "*", "*=", "*<", "*<=", "*<<", "*<<=", "*sv", "*od", - "*tr", "*<>", "*>=", "*>", "*>>=", "*>>", "*nsv", "*ev" -}; -static const char *const cmpib_cond_64_names[] = -{ - "*<<", "*=", "*<", "*<=", "*>>=", "*<>", "*>=", "*>" -}; -static const char *const add_cond_names[] = -{ - "", "=", "<", "<=", "nuv", "znv", "sv", "od", - "tr", "<>", ">=", ">", "uv", "vnz", "nsv", "ev" +static const char *const compare_cond_names[] = { + "", "=", "<", "<=", "<<", "<<=", "sv", "od", + "tr", "<>", ">=", ">", ">>=", ">>", "nsv", "ev" }; -static const char *const add_cond_64_names[] = -{ - "*", "*=", "*<", "*<=", "*nuv", "*znv", "*sv", "*od", - "*tr", "*<>", "*>=", "*>", "*uv", "*vnz", "*nsv", "*ev" +static const char *const compare_cond_64_names[] = { + "*", "*=", "*<", "*<=", "*<<", "*<<=", "*sv", "*od", + "*tr", "*<>", "*>=", "*>", "*>>=", "*>>", "*nsv", "*ev" }; -static const char *const wide_add_cond_names[] = -{ - "*", "=", "<", "<=", "nuv", "*=", "*<", "*<=", - "tr", "<>", ">=", ">", "uv", "*<>", "*>=", "*>" +static const char *const cmpib_cond_64_names[] = { "*<<", "*=", "*<", "*<=", + "*>>=", "*<>", "*>=", "*>" }; +static const char *const add_cond_names[] = { + "", "=", "<", "<=", "nuv", "znv", "sv", "od", + "tr", "<>", ">=", ">", "uv", "vnz", "nsv", "ev" }; -static const char *const logical_cond_names[] = -{ - "", "=", "<", "<=", "", "", "", "od", - "tr", "<>", ">=", ">", "", "", "", "ev"}; -static const char *const logical_cond_64_names[] = -{ - "*", "*=", "*<", "*<=", "", "", "", "*od", - "*tr", "*<>", "*>=", "*>", "", "", "", "*ev"}; -static const char *const unit_cond_names[] = -{ - "", "swz", "sbz", "shz", "sdc", "swc", "sbc", "shc", - "tr", "nwz", "nbz", "nhz", "ndc", "nwc", "nbc", "nhc" +static const char *const add_cond_64_names[] = { + "*", "*=", "*<", "*<=", "*nuv", "*znv", "*sv", "*od", + "*tr", "*<>", "*>=", "*>", "*uv", "*vnz", "*nsv", "*ev" }; -static const char *const unit_cond_64_names[] = -{ - "*", "*swz", "*sbz", "*shz", "*sdc", "*swc", "*sbc", "*shc", - "*tr", "*nwz", "*nbz", "*nhz", "*ndc", "*nwc", "*nbc", "*nhc" +static const char *const wide_add_cond_names[] = { + "*", "=", "<", "<=", "nuv", "*=", "*<", "*<=", + "tr", "<>", ">=", ">", "uv", "*<>", "*>=", "*>" }; -static const char *const shift_cond_names[] = -{ - "", "=", "<", "od", "tr", "<>", ">=", "ev" +static const char *const logical_cond_names[] = { + "", "=", "<", "<=", "", "", "", "od", + "tr", "<>", ">=", ">", "", "", "", "ev" }; -static const char *const shift_cond_64_names[] = -{ - "*", "*=", "*<", "*od", "*tr", "*<>", "*>=", "*ev" +static const char *const logical_cond_64_names[] = { + "*", "*=", "*<", "*<=", "", "", "", "*od", + "*tr", "*<>", "*>=", "*>", "", "", "", "*ev" }; -static const char *const index_compl_names[] = {"", "m", "s", "sm"}; -static const char *const short_ldst_compl_names[] = {"", "ma", "", "mb"}; -static const char *const short_bytes_compl_names[] = -{ - "", "b,m", "e", "e,m" +static const char *const unit_cond_names[] = { "", "swz", "sbz", "shz", + "sdc", "swc", "sbc", "shc", + "tr", "nwz", "nbz", "nhz", + "ndc", "nwc", "nbc", "nhc" }; +static const char *const unit_cond_64_names[] = { + "*", "*swz", "*sbz", "*shz", "*sdc", "*swc", "*sbc", "*shc", + "*tr", "*nwz", "*nbz", "*nhz", "*ndc", "*nwc", "*nbc", "*nhc" }; -static const char *const float_format_names[] = {"sgl", "dbl", "", "quad"}; -static const char *const float_cond_names[] = -{ - "", "acc", "rej", "", "", "acc8", "rej8", "", - "", "acc6", "", "", "", "acc4", "", "", - "", "acc2", "", "", "", "", "", "", - "", "", "", "", "", "", "", "" +static const char *const shift_cond_names[] = { "", "=", "<", "od", + "tr", "<>", ">=", "ev" }; +static const char *const shift_cond_64_names[] = { "*", "*=", "*<", "*od", + "*tr", "*<>", "*>=", "*ev" }; +static const char *const index_compl_names[] = { "", "m", "s", "sm" }; +static const char *const short_ldst_compl_names[] = { "", "ma", "", "mb" }; +static const char *const short_bytes_compl_names[] = { "", "b,m", "e", "e,m" }; +static const char *const float_format_names[] = { "sgl", "dbl", "", "quad" }; +static const char *const float_cond_names[] = { + "", "acc", "rej", "", "", "acc8", "rej8", "", "", "acc6", "", + "", "", "acc4", "", "", "", "acc2", "", "", "", "", + "", "", "", "", "", "", "", "", "", "" }; -static const char *const fcnv_fixed_names[] = {"w", "dw", "", "qw"}; -static const char *const fcnv_ufixed_names[] = {"uw", "udw", "", "uqw"}; -static const char *const float_comp_names[] = -{ - "false?", "false", "?", "!<=>", "=", "=t", "?=", "!<>", - "!?>=", "<", "?<", "!>=", "!?>", "<=", "?<=", "!>", - "!?<=", ">", "?>", "!<=", "!?<", ">=", "?>=", "!<", - "!?=", "<>", "!=", "!=t", "!?", "<=>", "true?", "true" +static const char *const fcnv_fixed_names[] = { "w", "dw", "", "qw" }; +static const char *const fcnv_ufixed_names[] = { "uw", "udw", "", "uqw" }; +static const char *const float_comp_names[] = { + "false?", "false", "?", "!<=>", "=", "=t", "?=", "!<>", + "!?>=", "<", "?<", "!>=", "!?>", "<=", "?<=", "!>", + "!?<=", ">", "?>", "!<=", "!?<", ">=", "?>=", "!<", + "!?=", "<>", "!=", "!=t", "!?", "<=>", "true?", "true" }; -static const char *const signed_unsigned_names[] = {"u", "s"}; -static const char *const saturation_names[] = {"us", "ss", "", ""}; +static const char *const signed_unsigned_names[] = { "u", "s" }; +static const char *const saturation_names[] = { "us", "ss", "", "" }; static const char *const add_compl_names[] = { "", "", "l", "tsv" }; -#define CREATE_GR_REG(MI, gr) MCOperand_CreateReg0(MI, gr + HPPA_REG_GR0) -#define CREATE_SR_REG(MI, sr) MCOperand_CreateReg0(MI, sr + HPPA_REG_SR0) -#define CREATE_CR_REG(MI, cr) MCOperand_CreateReg0(MI, cr + HPPA_REG_CR0) -#define CREATE_FPR_REG(MI, fpr) MCOperand_CreateReg0(MI, fpr + HPPA_REG_FPR0) -#define CREATE_FPE_REG(MI, fpe) MCOperand_CreateReg0(MI, fpe + HPPA_REG_FPE0) -#define CREATE_SP_FPR_REG(MI, fpr) MCOperand_CreateReg0(MI, fpr + HPPA_REG_SP_FPR0) +#define CREATE_GR_REG(MI, gr) MCOperand_CreateReg0(MI, gr + HPPA_REG_GR0) +#define CREATE_SR_REG(MI, sr) MCOperand_CreateReg0(MI, sr + HPPA_REG_SR0) +#define CREATE_CR_REG(MI, cr) MCOperand_CreateReg0(MI, cr + HPPA_REG_CR0) +#define CREATE_FPR_REG(MI, fpr) MCOperand_CreateReg0(MI, fpr + HPPA_REG_FPR0) +#define CREATE_FPE_REG(MI, fpe) MCOperand_CreateReg0(MI, fpe + HPPA_REG_FPE0) +#define CREATE_SP_FPR_REG(MI, fpr) \ + MCOperand_CreateReg0(MI, fpr + HPPA_REG_SP_FPR0) -static void create_float_reg_spec(MCInst *MI, uint32_t reg, uint32_t fpe_flag) { - if (fpe_flag == 1) { - CREATE_FPE_REG(MI, reg); - } - else { - CREATE_FPR_REG(MI, reg); - } +static void create_float_reg_spec(MCInst *MI, uint32_t reg, uint32_t fpe_flag) +{ + if (fpe_flag == 1) { + CREATE_FPE_REG(MI, reg); + } else { + CREATE_FPR_REG(MI, reg); + } } /* Get at various relevant fields of an instruction word. */ @@ -130,83 +112,83 @@ static void create_float_reg_spec(MCInst *MI, uint32_t reg, uint32_t fpe_flag) { /* Extract a 3-bit space register number from a be, ble, mtsp or mfsp. */ static int extract_3(unsigned word) { - return get_insn_field(word, 18, 18) << 2 | get_insn_field(word, 16, 17); + return get_insn_field(word, 18, 18) << 2 | get_insn_field(word, 16, 17); } static int extract_5_load(unsigned word) { - return LowSignExtend64(word >> 16 & MASK_5, 5); + return LowSignExtend64(word >> 16 & MASK_5, 5); } /* Extract the immediate field from a st{bhw}s instruction. */ static int extract_5_store(unsigned word) { - return LowSignExtend64(word & MASK_5, 5); + return LowSignExtend64(word & MASK_5, 5); } /* Extract an 11 bit immediate field. */ static int extract_11(unsigned word) { - return LowSignExtend64(word & MASK_11, 11); + return LowSignExtend64(word & MASK_11, 11); } /* Extract a 14 bit immediate field. */ static int extract_14(unsigned word) { - return LowSignExtend64(word & MASK_14, 14); + return LowSignExtend64(word & MASK_14, 14); } /* Extract a 16 bit immediate field. */ static int extract_16(unsigned word, bool wide) { - int m15, m0, m1; + int m15, m0, m1; - m0 = get_insn_bit(word, 16); - m1 = get_insn_bit(word, 17); - m15 = get_insn_bit(word, 31); - word = (word >> 1) & 0x1fff; - if (wide) { - word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13); - } - else { - word = word | (m15 << 15) | (m15 << 14) | (m15 << 13); - } - return SignExtend32(word, 16); + m0 = get_insn_bit(word, 16); + m1 = get_insn_bit(word, 17); + m15 = get_insn_bit(word, 31); + word = (word >> 1) & 0x1fff; + if (wide) { + word = word | (m15 << 15) | ((m15 ^ m0) << 14) | + ((m15 ^ m1) << 13); + } else { + word = word | (m15 << 15) | (m15 << 14) | (m15 << 13); + } + return SignExtend32(word, 16); } /* Extract a 21 bit constant. */ static int extract_21(unsigned word) { - int val; - - word &= MASK_21; - word <<= 11; - val = get_insn_field(word, 20, 20); - val <<= 11; - val |= get_insn_field(word, 9, 19); - val <<= 2; - val |= get_insn_field(word, 5, 6); - val <<= 5; - val |= get_insn_field(word, 0, 4); - val <<= 2; - val |= get_insn_field(word, 7, 8); - return SignExtend32(val, 21) << 11; + int val; + + word &= MASK_21; + word <<= 11; + val = get_insn_field(word, 20, 20); + val <<= 11; + val |= get_insn_field(word, 9, 19); + val <<= 2; + val |= get_insn_field(word, 5, 6); + val <<= 5; + val |= get_insn_field(word, 0, 4); + val <<= 2; + val |= get_insn_field(word, 7, 8); + return SignExtend32(val, 21) << 11; } /* Extract a 12 bit constant from branch instructions. */ static int extract_12(unsigned word) { - return SignExtend32(get_insn_field(word, 19, 28) | - get_insn_field(word, 29, 29) << 10 | - (word & 0x1) << 11, - 12) - << 2; + return SignExtend32(get_insn_field(word, 19, 28) | + get_insn_field(word, 29, 29) << 10 | + (word & 0x1) << 11, + 12) + << 2; } /* Extract a 17 bit constant from branch instructions, returning the @@ -214,3588 +196,3635 @@ static int extract_12(unsigned word) static int extract_17(unsigned word) { - return SignExtend32(get_insn_field(word, 19, 28) | - get_insn_field(word, 29, 29) << 10 | - get_insn_field(word, 11, 15) << 11 | - (word & 0x1) << 16, - 17) - << 2; + return SignExtend32(get_insn_field(word, 19, 28) | + get_insn_field(word, 29, 29) << 10 | + get_insn_field(word, 11, 15) << 11 | + (word & 0x1) << 16, + 17) + << 2; } static int extract_22(unsigned word) { - return SignExtend32(get_insn_field(word, 19, 28) | - get_insn_field(word, 29, 29) << 10 | - get_insn_field(word, 11, 15) << 11 | - get_insn_field(word, 6, 10) << 16 | - (word & 0x1) << 21, - 22) - << 2; + return SignExtend32(get_insn_field(word, 19, 28) | + get_insn_field(word, 29, 29) << 10 | + get_insn_field(word, 11, 15) << 11 | + get_insn_field(word, 6, 10) << 16 | + (word & 0x1) << 21, + 22) + << 2; } static void push_str_modifier(hppa_ext *hppa, const char *modifier) { - if (strcmp(modifier, "")) { - hppa_modifier *mod = &hppa->modifiers[hppa->mod_num++]; - assert(hppa->mod_num <= HPPA_MAX_MODIFIERS_LEN); - mod->type = HPPA_MOD_STR; - assert(strlen(modifier) <= HPPA_STR_MODIFIER_LEN); - strcpy(mod->str_mod, modifier); - } + if (strcmp(modifier, "")) { + hppa_modifier *mod = &hppa->modifiers[hppa->mod_num++]; + assert(hppa->mod_num <= HPPA_MAX_MODIFIERS_LEN); + mod->type = HPPA_MOD_STR; + assert(strlen(modifier) <= HPPA_STR_MODIFIER_LEN); + strcpy(mod->str_mod, modifier); + } } static void push_int_modifier(hppa_ext *hppa, uint64_t modifier) { - hppa_modifier *mod = &hppa->modifiers[hppa->mod_num++]; - assert(hppa->mod_num <= HPPA_MAX_MODIFIERS_LEN); - mod->type = HPPA_MOD_INT; - mod->int_mod = modifier; -} - -static void fill_sysop_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext8 = get_insn_field(insn, 19, 26); - uint32_t ext5 = get_insn_field(insn, 11, 15); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (ext8) { - case 0xa5: - MCInst_setOpcode(MI, HPPA_INS_MFIA); - return; - case 0xc6: - MCInst_setOpcode(MI, HPPA_INS_MTSARCM); - return; - case 0x65: - push_str_modifier(HPPA_EXT_REF(MI), "r"); - // fallthrough - case 0x60: - MCInst_setOpcode(MI, HPPA_INS_RFI); - return; - } - } - - switch (ext8) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_BREAK); - break; - case 0x20: - if (ext5 == 0x00) { - MCInst_setOpcode(MI, HPPA_INS_SYNC); - } - else if (ext5 == 0x10) { - MCInst_setOpcode(MI, HPPA_INS_SYNCDMA); - } - break; - case 0x60: - MCInst_setOpcode(MI, HPPA_INS_RFI); - break; - case 0x65: - MCInst_setOpcode(MI, HPPA_INS_RFIR); - break; - case 0x6b: - MCInst_setOpcode(MI, HPPA_INS_SSM); - break; - case 0x73: - MCInst_setOpcode(MI, HPPA_INS_RSM); - break; - case 0xc3: - MCInst_setOpcode(MI, HPPA_INS_MTSM); - break; - case 0x85: - MCInst_setOpcode(MI, HPPA_INS_LDSID); - break; - case 0xc1: - MCInst_setOpcode(MI, HPPA_INS_MTSP); - break; - case 0x25: - MCInst_setOpcode(MI, HPPA_INS_MFSP); - break; - case 0xc2: - MCInst_setOpcode(MI, HPPA_INS_MTCTL); - break; - case 0x45: - MCInst_setOpcode(MI, HPPA_INS_MFCTL); - if (get_insn_bit(insn, 17) == 1 && MODE_IS_HPPA_20(MI->csh->mode)) { - push_str_modifier(HPPA_EXT_REF(MI), "w"); - } - break; - } -} - -static bool decode_sysop(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext8 = get_insn_field(insn, 19, 26); - uint32_t ext5 = get_insn_field(insn, 11, 15); - uint32_t r1 = get_insn_field(insn, 6, 10); - uint32_t r2 = get_insn_field(insn, 11, 15); - uint32_t t = get_insn_field(insn, 27, 31); - uint32_t s = extract_3(insn); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (ext8) { - case 0xa5: - if (ext5 != 0) { - return false; - } - CREATE_GR_REG(MI, t); - return true; - case 0xc6: - CREATE_GR_REG(MI, r2); - return true; - } - } - - switch (ext8) { - case 0x00: - MCOperand_CreateImm0(MI, t); - MCOperand_CreateImm0(MI, get_insn_field(insn, 6, 18)); - return true; - case 0x20: - if (ext5 != 0x00 && ext5 != 0x10) { - return false; - } - // fallthrough - case 0x60: - case 0x65: - return true; - case 0x6b: - case 0x73: - MCOperand_CreateImm0(MI, get_insn_field(insn, 9, 15)); - CREATE_GR_REG(MI, t); - return true; - case 0xc3: - CREATE_GR_REG(MI, r2); - return true; - case 0x85: - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, r1); - CREATE_GR_REG(MI, t); - return true; - case 0xc1: - CREATE_GR_REG(MI, r2); - CREATE_SR_REG(MI, s); - return true; - case 0x25: - if (ext5 != 0) { - return false; - } - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, t); - return true; - case 0xc2: - CREATE_GR_REG(MI, r2); - CREATE_CR_REG(MI, r1); - return true; - case 0x45: - if (ext5 != 0) { - return false; - } - if (get_insn_bit(insn, 17) == 1 && MODE_IS_HPPA_20(ud->mode) && - r1 != 11) { - return false; - } - CREATE_CR_REG(MI, r1); - CREATE_GR_REG(MI, t); - return true; - default: - return false; - } -} - -static void fill_memmgmt_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 19, 25); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (ext) { - case 0x20: - MCInst_setOpcode(MI, HPPA_INS_IITLBT); - return; - case 0x18: - MCInst_setOpcode(MI, HPPA_INS_PITLB); - push_str_modifier(HPPA_EXT_REF(MI), "l"); - return; - case 0x60: - MCInst_setOpcode(MI, HPPA_INS_IDTLBT); - return; - case 0x58: - MCInst_setOpcode(MI, HPPA_INS_PDTLB); - push_str_modifier(HPPA_EXT_REF(MI), "l"); - return; - case 0x4f: - MCInst_setOpcode(MI, HPPA_INS_FIC); - return; - case 0x46: - if (get_insn_bit(insn, 18) == 0) { - MCInst_setOpcode(MI, HPPA_INS_PROBE); - } - else { - MCInst_setOpcode(MI, HPPA_INS_PROBEI); - }; - push_str_modifier(HPPA_EXT_REF(MI), "r"); - return; - case 0x47: - if (get_insn_bit(insn, 18) == 0) { - MCInst_setOpcode(MI, HPPA_INS_PROBE); - } - else { - MCInst_setOpcode(MI, HPPA_INS_PROBEI); - }; - push_str_modifier(HPPA_EXT_REF(MI), "w"); - return; - } - } - - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_IITLBP); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_IITLBA); - break; - case 0x08: - MCInst_setOpcode(MI, HPPA_INS_PITLB); - break; - case 0x09: - MCInst_setOpcode(MI, HPPA_INS_PITLBE); - break; - case 0x0a: - MCInst_setOpcode(MI, HPPA_INS_FIC); - break; - case 0x0b: - MCInst_setOpcode(MI, HPPA_INS_FICE); - break; - case 0x40: - MCInst_setOpcode(MI, HPPA_INS_IDTLBP); - break; - case 0x41: - MCInst_setOpcode(MI, HPPA_INS_IDTLBA); - break; - case 0x48: - MCInst_setOpcode(MI, HPPA_INS_PDTLB); - break; - case 0x49: - MCInst_setOpcode(MI, HPPA_INS_PDTLBE); - break; - case 0x4a: - MCInst_setOpcode(MI, HPPA_INS_FDC); - break; - case 0x4b: - MCInst_setOpcode(MI, HPPA_INS_FDCE); - break; - case 0x4e: - MCInst_setOpcode(MI, HPPA_INS_PDC); - break; - case 0x46: - if (get_insn_bit(insn, 18) == 0) { - MCInst_setOpcode(MI, HPPA_INS_PROBER); - } - else { - MCInst_setOpcode(MI, HPPA_INS_PROBERI); - }; - break; - case 0x47: - if (get_insn_bit(insn, 18) == 0) { - MCInst_setOpcode(MI, HPPA_INS_PROBEW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_PROBEWI); - }; - break; - case 0x4d: - MCInst_setOpcode(MI, HPPA_INS_LPA); - break; - case 0x4c: - MCInst_setOpcode(MI, HPPA_INS_LCI); - break; - } -} - -static void fill_memmgmt_mods(uint32_t insn, hppa_ext* hppa_ext, cs_mode mode) { - uint8_t cmplt = get_insn_bit(insn, 26); - uint32_t ext = get_insn_field(insn, 19, 25); - if (MODE_IS_HPPA_20(mode)) { - switch (ext) { - case 0x18: - case 0x58: - case 0x4f: - goto success; - default: - break; - } - } - - switch (ext) { - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4e: - case 0x4d: - break; - default: - return; - } + hppa_modifier *mod = &hppa->modifiers[hppa->mod_num++]; + assert(hppa->mod_num <= HPPA_MAX_MODIFIERS_LEN); + mod->type = HPPA_MOD_INT; + mod->int_mod = modifier; +} + +static void fill_sysop_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext8 = get_insn_field(insn, 19, 26); + uint32_t ext5 = get_insn_field(insn, 11, 15); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (ext8) { + case 0xa5: + MCInst_setOpcode(MI, HPPA_INS_MFIA); + return; + case 0xc6: + MCInst_setOpcode(MI, HPPA_INS_MTSARCM); + return; + case 0x65: + push_str_modifier(HPPA_EXT_REF(MI), "r"); + // fallthrough + case 0x60: + MCInst_setOpcode(MI, HPPA_INS_RFI); + return; + } + } + + switch (ext8) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_BREAK); + break; + case 0x20: + if (ext5 == 0x00) { + MCInst_setOpcode(MI, HPPA_INS_SYNC); + } else if (ext5 == 0x10) { + MCInst_setOpcode(MI, HPPA_INS_SYNCDMA); + } + break; + case 0x60: + MCInst_setOpcode(MI, HPPA_INS_RFI); + break; + case 0x65: + MCInst_setOpcode(MI, HPPA_INS_RFIR); + break; + case 0x6b: + MCInst_setOpcode(MI, HPPA_INS_SSM); + break; + case 0x73: + MCInst_setOpcode(MI, HPPA_INS_RSM); + break; + case 0xc3: + MCInst_setOpcode(MI, HPPA_INS_MTSM); + break; + case 0x85: + MCInst_setOpcode(MI, HPPA_INS_LDSID); + break; + case 0xc1: + MCInst_setOpcode(MI, HPPA_INS_MTSP); + break; + case 0x25: + MCInst_setOpcode(MI, HPPA_INS_MFSP); + break; + case 0xc2: + MCInst_setOpcode(MI, HPPA_INS_MTCTL); + break; + case 0x45: + MCInst_setOpcode(MI, HPPA_INS_MFCTL); + if (get_insn_bit(insn, 17) == 1 && + MODE_IS_HPPA_20(MI->csh->mode)) { + push_str_modifier(HPPA_EXT_REF(MI), "w"); + } + break; + } +} + +static bool decode_sysop(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext8 = get_insn_field(insn, 19, 26); + uint32_t ext5 = get_insn_field(insn, 11, 15); + uint32_t r1 = get_insn_field(insn, 6, 10); + uint32_t r2 = get_insn_field(insn, 11, 15); + uint32_t t = get_insn_field(insn, 27, 31); + uint32_t s = extract_3(insn); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (ext8) { + case 0xa5: + if (ext5 != 0) { + return false; + } + CREATE_GR_REG(MI, t); + return true; + case 0xc6: + CREATE_GR_REG(MI, r2); + return true; + } + } + + switch (ext8) { + case 0x00: + MCOperand_CreateImm0(MI, t); + MCOperand_CreateImm0(MI, get_insn_field(insn, 6, 18)); + return true; + case 0x20: + if (ext5 != 0x00 && ext5 != 0x10) { + return false; + } + // fallthrough + case 0x60: + case 0x65: + return true; + case 0x6b: + case 0x73: + MCOperand_CreateImm0(MI, get_insn_field(insn, 9, 15)); + CREATE_GR_REG(MI, t); + return true; + case 0xc3: + CREATE_GR_REG(MI, r2); + return true; + case 0x85: + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, r1); + CREATE_GR_REG(MI, t); + return true; + case 0xc1: + CREATE_GR_REG(MI, r2); + CREATE_SR_REG(MI, s); + return true; + case 0x25: + if (ext5 != 0) { + return false; + } + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, t); + return true; + case 0xc2: + CREATE_GR_REG(MI, r2); + CREATE_CR_REG(MI, r1); + return true; + case 0x45: + if (ext5 != 0) { + return false; + } + if (get_insn_bit(insn, 17) == 1 && MODE_IS_HPPA_20(ud->mode) && + r1 != 11) { + return false; + } + CREATE_CR_REG(MI, r1); + CREATE_GR_REG(MI, t); + return true; + default: + return false; + } +} + +static void fill_memmgmt_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 19, 25); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (ext) { + case 0x20: + MCInst_setOpcode(MI, HPPA_INS_IITLBT); + return; + case 0x18: + MCInst_setOpcode(MI, HPPA_INS_PITLB); + push_str_modifier(HPPA_EXT_REF(MI), "l"); + return; + case 0x60: + MCInst_setOpcode(MI, HPPA_INS_IDTLBT); + return; + case 0x58: + MCInst_setOpcode(MI, HPPA_INS_PDTLB); + push_str_modifier(HPPA_EXT_REF(MI), "l"); + return; + case 0x4f: + MCInst_setOpcode(MI, HPPA_INS_FIC); + return; + case 0x46: + if (get_insn_bit(insn, 18) == 0) { + MCInst_setOpcode(MI, HPPA_INS_PROBE); + } else { + MCInst_setOpcode(MI, HPPA_INS_PROBEI); + }; + push_str_modifier(HPPA_EXT_REF(MI), "r"); + return; + case 0x47: + if (get_insn_bit(insn, 18) == 0) { + MCInst_setOpcode(MI, HPPA_INS_PROBE); + } else { + MCInst_setOpcode(MI, HPPA_INS_PROBEI); + }; + push_str_modifier(HPPA_EXT_REF(MI), "w"); + return; + } + } + + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_IITLBP); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_IITLBA); + break; + case 0x08: + MCInst_setOpcode(MI, HPPA_INS_PITLB); + break; + case 0x09: + MCInst_setOpcode(MI, HPPA_INS_PITLBE); + break; + case 0x0a: + MCInst_setOpcode(MI, HPPA_INS_FIC); + break; + case 0x0b: + MCInst_setOpcode(MI, HPPA_INS_FICE); + break; + case 0x40: + MCInst_setOpcode(MI, HPPA_INS_IDTLBP); + break; + case 0x41: + MCInst_setOpcode(MI, HPPA_INS_IDTLBA); + break; + case 0x48: + MCInst_setOpcode(MI, HPPA_INS_PDTLB); + break; + case 0x49: + MCInst_setOpcode(MI, HPPA_INS_PDTLBE); + break; + case 0x4a: + MCInst_setOpcode(MI, HPPA_INS_FDC); + break; + case 0x4b: + MCInst_setOpcode(MI, HPPA_INS_FDCE); + break; + case 0x4e: + MCInst_setOpcode(MI, HPPA_INS_PDC); + break; + case 0x46: + if (get_insn_bit(insn, 18) == 0) { + MCInst_setOpcode(MI, HPPA_INS_PROBER); + } else { + MCInst_setOpcode(MI, HPPA_INS_PROBERI); + }; + break; + case 0x47: + if (get_insn_bit(insn, 18) == 0) { + MCInst_setOpcode(MI, HPPA_INS_PROBEW); + } else { + MCInst_setOpcode(MI, HPPA_INS_PROBEWI); + }; + break; + case 0x4d: + MCInst_setOpcode(MI, HPPA_INS_LPA); + break; + case 0x4c: + MCInst_setOpcode(MI, HPPA_INS_LCI); + break; + } +} + +static void fill_memmgmt_mods(uint32_t insn, hppa_ext *hppa_ext, cs_mode mode) +{ + uint8_t cmplt = get_insn_bit(insn, 26); + uint32_t ext = get_insn_field(insn, 19, 25); + if (MODE_IS_HPPA_20(mode)) { + switch (ext) { + case 0x18: + case 0x58: + case 0x4f: + goto success; + default: + break; + } + } + + switch (ext) { + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4e: + case 0x4d: + break; + default: + return; + } success: - if (CMPLT_HAS_MODIFY_BIT(cmplt)) { - hppa_ext->b_writeble = true; - } - push_str_modifier(hppa_ext, index_compl_names[cmplt]); -} - -static bool decode_memmgmt(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 19, 25); - uint32_t b = get_insn_field(insn, 6, 10); - uint32_t r = get_insn_field(insn, 11, 15); - uint32_t s3 = extract_3(insn); - uint32_t s2 = get_insn_field(insn, 16, 17); - uint32_t t = get_insn_field(insn, 27, 31); - if (ext > 0x20 && get_insn_bit(insn, 18) == 1 && - (ext != 0x46 && ext != 0x47)) { - if (MODE_IS_HPPA_20(ud->mode)) { - if (ext != 0x4a) { - return false; - } - } - else { - return false; - } - } - if (MODE_IS_HPPA_20(ud->mode)) { - switch (ext) { - case 0x20: - case 0x60: - CREATE_GR_REG(MI, r); - CREATE_GR_REG(MI, b); - goto success; - case 0x58: - case 0x4f: - CREATE_GR_REG(MI, r); - CREATE_SR_REG(MI, s2); - CREATE_GR_REG(MI, b); - goto success; - case 0x18: - CREATE_GR_REG(MI, r); - CREATE_SR_REG(MI, s3); - CREATE_GR_REG(MI, b); - goto success; - case 0x4a: - if (get_insn_bit(insn, 18) == 1) { - MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); - } - else { - CREATE_GR_REG(MI, r); - } - CREATE_SR_REG(MI, s2); - CREATE_GR_REG(MI, b); - goto success; - default: - break; - } - } - - switch (ext) { - case 0x00: - case 0x01: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - CREATE_GR_REG(MI, r); - CREATE_SR_REG(MI, s3); - CREATE_GR_REG(MI, b); - break; - case 0x40: - case 0x41: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4e: - CREATE_GR_REG(MI, r); - CREATE_SR_REG(MI, s2); - CREATE_GR_REG(MI, b); - break; - case 0x46: - case 0x47: - CREATE_SR_REG(MI, s2); - CREATE_GR_REG(MI, b); - if (get_insn_bit(insn, 18) == 0) { - CREATE_GR_REG(MI, r); - } - else { - MCOperand_CreateImm0(MI, r); - } - CREATE_GR_REG(MI, t); - break; - case 0x4d: - case 0x4c: - CREATE_GR_REG(MI, r); - CREATE_SR_REG(MI, s2); - CREATE_GR_REG(MI, b); - CREATE_GR_REG(MI, t); - break; - default: - return false; - } + if (CMPLT_HAS_MODIFY_BIT(cmplt)) { + hppa_ext->b_writeble = true; + } + push_str_modifier(hppa_ext, index_compl_names[cmplt]); +} + +static bool decode_memmgmt(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 19, 25); + uint32_t b = get_insn_field(insn, 6, 10); + uint32_t r = get_insn_field(insn, 11, 15); + uint32_t s3 = extract_3(insn); + uint32_t s2 = get_insn_field(insn, 16, 17); + uint32_t t = get_insn_field(insn, 27, 31); + if (ext > 0x20 && get_insn_bit(insn, 18) == 1 && + (ext != 0x46 && ext != 0x47)) { + if (MODE_IS_HPPA_20(ud->mode)) { + if (ext != 0x4a) { + return false; + } + } else { + return false; + } + } + if (MODE_IS_HPPA_20(ud->mode)) { + switch (ext) { + case 0x20: + case 0x60: + CREATE_GR_REG(MI, r); + CREATE_GR_REG(MI, b); + goto success; + case 0x58: + case 0x4f: + CREATE_GR_REG(MI, r); + CREATE_SR_REG(MI, s2); + CREATE_GR_REG(MI, b); + goto success; + case 0x18: + CREATE_GR_REG(MI, r); + CREATE_SR_REG(MI, s3); + CREATE_GR_REG(MI, b); + goto success; + case 0x4a: + if (get_insn_bit(insn, 18) == 1) { + MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); + } else { + CREATE_GR_REG(MI, r); + } + CREATE_SR_REG(MI, s2); + CREATE_GR_REG(MI, b); + goto success; + default: + break; + } + } + + switch (ext) { + case 0x00: + case 0x01: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + CREATE_GR_REG(MI, r); + CREATE_SR_REG(MI, s3); + CREATE_GR_REG(MI, b); + break; + case 0x40: + case 0x41: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4e: + CREATE_GR_REG(MI, r); + CREATE_SR_REG(MI, s2); + CREATE_GR_REG(MI, b); + break; + case 0x46: + case 0x47: + CREATE_SR_REG(MI, s2); + CREATE_GR_REG(MI, b); + if (get_insn_bit(insn, 18) == 0) { + CREATE_GR_REG(MI, r); + } else { + MCOperand_CreateImm0(MI, r); + } + CREATE_GR_REG(MI, t); + break; + case 0x4d: + case 0x4c: + CREATE_GR_REG(MI, r); + CREATE_SR_REG(MI, s2); + CREATE_GR_REG(MI, b); + CREATE_GR_REG(MI, t); + break; + default: + return false; + } success: - fill_memmgmt_mods(insn, HPPA_EXT_REF(MI), MI->csh->mode); - return true; -} - -static void fill_alu_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 20, 25); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (ext) { - case 0x28: - case 0x38: - case 0x1c: - case 0x3c: - MCInst_setOpcode(MI, HPPA_INS_ADD); - return; - case 0x19: - case 0x29: - case 0x39: - case 0x1a: - case 0x2a: - case 0x3a: - case 0x1b: - case 0x2b: - case 0x3b: - MCInst_setOpcode(MI, HPPA_INS_SHLADD); - return; - case 0x30: - case 0x13: - case 0x33: - case 0x14: - case 0x34: - MCInst_setOpcode(MI, HPPA_INS_SUB); - return; - case 0x22: - MCInst_setOpcode(MI, HPPA_INS_CMPCLR); - return; - case 0x27: - MCInst_setOpcode(MI, HPPA_INS_UADDCM); - return; - case 0x2f: - MCInst_setOpcode(MI, HPPA_INS_DCOR); - return; - case 0x0f: - case 0x0d: - case 0x0c: - MCInst_setOpcode(MI, HPPA_INS_HADD); - return; - case 0x07: - case 0x05: - case 0x04: - MCInst_setOpcode(MI, HPPA_INS_HSUB); - return; - case 0x0b: - MCInst_setOpcode(MI, HPPA_INS_HAVG); - return; - case 0x1d: - case 0x1e: - case 0x1f: - MCInst_setOpcode(MI, HPPA_INS_HSHLADD); - return; - case 0x15: - case 0x16: - case 0x17: - MCInst_setOpcode(MI, HPPA_INS_HSHRADD); - return; - default: - break; - } - } - - switch (ext) { - case 0x18: - MCInst_setOpcode(MI, HPPA_INS_ADD); - break; - case 0x38: - MCInst_setOpcode(MI, HPPA_INS_ADDO); - break; - case 0x1c: - MCInst_setOpcode(MI, HPPA_INS_ADDC); - break; - case 0x3c: - MCInst_setOpcode(MI, HPPA_INS_ADDCO); - break; - case 0x19: - MCInst_setOpcode(MI, HPPA_INS_SH1ADD); - break; - case 0x39: - MCInst_setOpcode(MI, HPPA_INS_SH1ADDO); - break; - case 0x1a: - MCInst_setOpcode(MI, HPPA_INS_SH2ADD); - break; - case 0x3a: - MCInst_setOpcode(MI, HPPA_INS_SH2ADDO); - break; - case 0x1b: - MCInst_setOpcode(MI, HPPA_INS_SH3ADD); - break; - case 0x3b: - MCInst_setOpcode(MI, HPPA_INS_SH3ADDO); - break; - case 0x10: - MCInst_setOpcode(MI, HPPA_INS_SUB); - break; - case 0x30: - MCInst_setOpcode(MI, HPPA_INS_SUBO); - break; - case 0x13: - MCInst_setOpcode(MI, HPPA_INS_SUBT); - break; - case 0x33: - MCInst_setOpcode(MI, HPPA_INS_SUBTO); - break; - case 0x14: - MCInst_setOpcode(MI, HPPA_INS_SUBB); - break; - case 0x34: - MCInst_setOpcode(MI, HPPA_INS_SUBBO); - break; - case 0x11: - MCInst_setOpcode(MI, HPPA_INS_DS); - break; - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_ANDCM); - break; - case 0x08: - MCInst_setOpcode(MI, HPPA_INS_AND); - break; - case 0x09: - MCInst_setOpcode(MI, HPPA_INS_OR); - break; - case 0x0a: - MCInst_setOpcode(MI, HPPA_INS_XOR); - break; - case 0x0e: - MCInst_setOpcode(MI, HPPA_INS_UXOR); - break; - case 0x22: - MCInst_setOpcode(MI, HPPA_INS_COMCLR); - break; - case 0x26: - MCInst_setOpcode(MI, HPPA_INS_UADDCM); - break; - case 0x27: - MCInst_setOpcode(MI, HPPA_INS_UADDCMT); - break; - case 0x28: - MCInst_setOpcode(MI, HPPA_INS_ADDL); - break; - case 0x29: - MCInst_setOpcode(MI, HPPA_INS_SH1ADDL); - break; - case 0x2a: - MCInst_setOpcode(MI, HPPA_INS_SH2ADDL); - break; - case 0x2b: - MCInst_setOpcode(MI, HPPA_INS_SH3ADDL); - break; - case 0x2e: - MCInst_setOpcode(MI, HPPA_INS_DCOR); - break; - case 0x2f: - MCInst_setOpcode(MI, HPPA_INS_IDCOR); - break; - default: - break; - } -} - -static void fill_alu_mods(uint32_t insn, hppa_ext* hppa_ext, cs_mode mode) { - uint32_t cond = (get_insn_field(insn, 19, 19) << 3) | get_insn_field(insn, 16, 18); - uint32_t ext = get_insn_field(insn, 20, 25); - if (MODE_IS_HPPA_20(mode)) { - uint32_t e1 = get_insn_field(insn, 20, 21); - uint32_t e2 = get_insn_bit(insn, 23); - uint32_t e3 = get_insn_field(insn, 24, 25); - uint32_t d = get_insn_bit(insn, 26); - switch (ext) { - case 0x18: - case 0x28: - case 0x38: - case 0x1c: - case 0x3c: - if (e2 == 1) { - if (d == 1) { - push_str_modifier(hppa_ext, "dc"); - } - else { - push_str_modifier(hppa_ext, "c"); - } - } - // fallthrough - case 0x19: - case 0x29: - case 0x39: - case 0x1a: - case 0x2a: - case 0x3a: - case 0x1b: - case 0x2b: - case 0x3b: - push_str_modifier(hppa_ext, add_compl_names[e1]); - if (d == 1) { - push_str_modifier(hppa_ext, add_cond_64_names[cond]); - } - else { - push_str_modifier(hppa_ext, add_cond_names[cond]); - } - return; - case 0x10: - case 0x30: - case 0x13: - case 0x33: - case 0x14: - case 0x34: - if (e2 == 1) { - if (d == 1) { - push_str_modifier(hppa_ext, "db"); - } - else { - push_str_modifier(hppa_ext, "b"); - } - } - if (e1 == 3) { - push_str_modifier(hppa_ext, "tsv"); - } - if (e3 == 3) { - push_str_modifier(hppa_ext, "tc"); - } - case 0x22: - if (d == 1) { - push_str_modifier(hppa_ext, compare_cond_64_names[cond]); - } - else { - push_str_modifier(hppa_ext, compare_cond_names[cond]); - } - return; - case 0x00: - case 0x08: - case 0x09: - case 0x0a: - if (d == 1) { - push_str_modifier(hppa_ext, logical_cond_64_names[cond]); - } - else { - push_str_modifier(hppa_ext, logical_cond_names[cond]); - } - return; - case 0x27: - push_str_modifier(hppa_ext, "tc"); - goto unit_cond; - case 0x2f: - push_str_modifier(hppa_ext, "i"); - // fallthough - case 0x26: - case 0x0e: - case 0x2e: - unit_cond: - if (d == 1) { - push_str_modifier(hppa_ext, unit_cond_64_names[cond]); - } - else { - push_str_modifier(hppa_ext, unit_cond_names[cond]); - } - return; - case 0x0d: - case 0x0c: - case 0x05: - case 0x04: - push_str_modifier(hppa_ext, saturation_names[e3]); - return; - default: - break; - } - } - - switch (ext) { - case 0x18: - case 0x38: - case 0x1c: - case 0x3c: - case 0x19: - case 0x39: - case 0x1a: - case 0x3a: - case 0x3b: - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: - push_str_modifier(hppa_ext, add_cond_names[cond]); - break; - case 0x10: - case 0x30: - case 0x13: - case 0x33: - case 0x14: - case 0x34: - case 0x11: - case 0x22: - push_str_modifier(hppa_ext, compare_cond_names[cond]); - break; - case 0x00: - case 0x08: - case 0x09: - case 0x0a: - push_str_modifier(hppa_ext, logical_cond_names[cond]); - break; - case 0x0e: - case 0x26: - case 0x27: - case 0x2e: - case 0x2f: - push_str_modifier(hppa_ext, unit_cond_names[cond]); - break; - default: - break; - } -} - -static bool decode_alu(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 20, 25); - uint32_t r1 = get_insn_field(insn, 11, 15); - uint32_t r2 = get_insn_field(insn, 6, 10); - uint32_t t = get_insn_field(insn, 27, 31); - if (MODE_IS_HPPA_20(ud->mode)) { - switch (ext) { - case 0x19: - case 0x29: - case 0x39: - case 0x1a: - case 0x2a: - case 0x3a: - case 0x1b: - case 0x2b: - case 0x3b: - case 0x1d: - case 0x1e: - case 0x1f: - case 0x15: - case 0x16: - case 0x17: - case 0x0f: - case 0x0d: - case 0x0c: - case 0x07: - case 0x05: - case 0x04: - case 0x0b: - CREATE_GR_REG(MI, r1); - if (ext > 0x10) { - MCOperand_CreateImm0(MI, get_insn_field(insn, 24, 25)); - } - CREATE_GR_REG(MI, r2); - CREATE_GR_REG(MI, t); - goto success; - default: - break; - } - } - switch (ext) { - case 0x18: - case 0x38: - case 0x1c: - case 0x3c: - case 0x19: - case 0x39: - case 0x1a: - case 0x3a: - case 0x1b: - case 0x3b: - case 0x10: - case 0x30: - case 0x13: - case 0x33: - case 0x14: - case 0x34: - case 0x11: - case 0x00: - case 0x08: - case 0x09: - case 0x0a: - case 0x0e: - case 0x22: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: - CREATE_GR_REG(MI, r1); - case 0x2e: - case 0x2f: - CREATE_GR_REG(MI, r2); - CREATE_GR_REG(MI, t); - break; - default: - return false; - } + fill_memmgmt_mods(insn, HPPA_EXT_REF(MI), MI->csh->mode); + return true; +} + +static void fill_alu_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 20, 25); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (ext) { + case 0x28: + case 0x38: + case 0x1c: + case 0x3c: + MCInst_setOpcode(MI, HPPA_INS_ADD); + return; + case 0x19: + case 0x29: + case 0x39: + case 0x1a: + case 0x2a: + case 0x3a: + case 0x1b: + case 0x2b: + case 0x3b: + MCInst_setOpcode(MI, HPPA_INS_SHLADD); + return; + case 0x30: + case 0x13: + case 0x33: + case 0x14: + case 0x34: + MCInst_setOpcode(MI, HPPA_INS_SUB); + return; + case 0x22: + MCInst_setOpcode(MI, HPPA_INS_CMPCLR); + return; + case 0x27: + MCInst_setOpcode(MI, HPPA_INS_UADDCM); + return; + case 0x2f: + MCInst_setOpcode(MI, HPPA_INS_DCOR); + return; + case 0x0f: + case 0x0d: + case 0x0c: + MCInst_setOpcode(MI, HPPA_INS_HADD); + return; + case 0x07: + case 0x05: + case 0x04: + MCInst_setOpcode(MI, HPPA_INS_HSUB); + return; + case 0x0b: + MCInst_setOpcode(MI, HPPA_INS_HAVG); + return; + case 0x1d: + case 0x1e: + case 0x1f: + MCInst_setOpcode(MI, HPPA_INS_HSHLADD); + return; + case 0x15: + case 0x16: + case 0x17: + MCInst_setOpcode(MI, HPPA_INS_HSHRADD); + return; + default: + break; + } + } + + switch (ext) { + case 0x18: + MCInst_setOpcode(MI, HPPA_INS_ADD); + break; + case 0x38: + MCInst_setOpcode(MI, HPPA_INS_ADDO); + break; + case 0x1c: + MCInst_setOpcode(MI, HPPA_INS_ADDC); + break; + case 0x3c: + MCInst_setOpcode(MI, HPPA_INS_ADDCO); + break; + case 0x19: + MCInst_setOpcode(MI, HPPA_INS_SH1ADD); + break; + case 0x39: + MCInst_setOpcode(MI, HPPA_INS_SH1ADDO); + break; + case 0x1a: + MCInst_setOpcode(MI, HPPA_INS_SH2ADD); + break; + case 0x3a: + MCInst_setOpcode(MI, HPPA_INS_SH2ADDO); + break; + case 0x1b: + MCInst_setOpcode(MI, HPPA_INS_SH3ADD); + break; + case 0x3b: + MCInst_setOpcode(MI, HPPA_INS_SH3ADDO); + break; + case 0x10: + MCInst_setOpcode(MI, HPPA_INS_SUB); + break; + case 0x30: + MCInst_setOpcode(MI, HPPA_INS_SUBO); + break; + case 0x13: + MCInst_setOpcode(MI, HPPA_INS_SUBT); + break; + case 0x33: + MCInst_setOpcode(MI, HPPA_INS_SUBTO); + break; + case 0x14: + MCInst_setOpcode(MI, HPPA_INS_SUBB); + break; + case 0x34: + MCInst_setOpcode(MI, HPPA_INS_SUBBO); + break; + case 0x11: + MCInst_setOpcode(MI, HPPA_INS_DS); + break; + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_ANDCM); + break; + case 0x08: + MCInst_setOpcode(MI, HPPA_INS_AND); + break; + case 0x09: + MCInst_setOpcode(MI, HPPA_INS_OR); + break; + case 0x0a: + MCInst_setOpcode(MI, HPPA_INS_XOR); + break; + case 0x0e: + MCInst_setOpcode(MI, HPPA_INS_UXOR); + break; + case 0x22: + MCInst_setOpcode(MI, HPPA_INS_COMCLR); + break; + case 0x26: + MCInst_setOpcode(MI, HPPA_INS_UADDCM); + break; + case 0x27: + MCInst_setOpcode(MI, HPPA_INS_UADDCMT); + break; + case 0x28: + MCInst_setOpcode(MI, HPPA_INS_ADDL); + break; + case 0x29: + MCInst_setOpcode(MI, HPPA_INS_SH1ADDL); + break; + case 0x2a: + MCInst_setOpcode(MI, HPPA_INS_SH2ADDL); + break; + case 0x2b: + MCInst_setOpcode(MI, HPPA_INS_SH3ADDL); + break; + case 0x2e: + MCInst_setOpcode(MI, HPPA_INS_DCOR); + break; + case 0x2f: + MCInst_setOpcode(MI, HPPA_INS_IDCOR); + break; + default: + break; + } +} + +static void fill_alu_mods(uint32_t insn, hppa_ext *hppa_ext, cs_mode mode) +{ + uint32_t cond = (get_insn_field(insn, 19, 19) << 3) | + get_insn_field(insn, 16, 18); + uint32_t ext = get_insn_field(insn, 20, 25); + if (MODE_IS_HPPA_20(mode)) { + uint32_t e1 = get_insn_field(insn, 20, 21); + uint32_t e2 = get_insn_bit(insn, 23); + uint32_t e3 = get_insn_field(insn, 24, 25); + uint32_t d = get_insn_bit(insn, 26); + switch (ext) { + case 0x18: + case 0x28: + case 0x38: + case 0x1c: + case 0x3c: + if (e2 == 1) { + if (d == 1) { + push_str_modifier(hppa_ext, "dc"); + } else { + push_str_modifier(hppa_ext, "c"); + } + } + // fallthrough + case 0x19: + case 0x29: + case 0x39: + case 0x1a: + case 0x2a: + case 0x3a: + case 0x1b: + case 0x2b: + case 0x3b: + push_str_modifier(hppa_ext, add_compl_names[e1]); + if (d == 1) { + push_str_modifier(hppa_ext, + add_cond_64_names[cond]); + } else { + push_str_modifier(hppa_ext, + add_cond_names[cond]); + } + return; + case 0x10: + case 0x30: + case 0x13: + case 0x33: + case 0x14: + case 0x34: + if (e2 == 1) { + if (d == 1) { + push_str_modifier(hppa_ext, "db"); + } else { + push_str_modifier(hppa_ext, "b"); + } + } + if (e1 == 3) { + push_str_modifier(hppa_ext, "tsv"); + } + if (e3 == 3) { + push_str_modifier(hppa_ext, "tc"); + } + case 0x22: + if (d == 1) { + push_str_modifier(hppa_ext, + compare_cond_64_names[cond]); + } else { + push_str_modifier(hppa_ext, + compare_cond_names[cond]); + } + return; + case 0x00: + case 0x08: + case 0x09: + case 0x0a: + if (d == 1) { + push_str_modifier(hppa_ext, + logical_cond_64_names[cond]); + } else { + push_str_modifier(hppa_ext, + logical_cond_names[cond]); + } + return; + case 0x27: + push_str_modifier(hppa_ext, "tc"); + goto unit_cond; + case 0x2f: + push_str_modifier(hppa_ext, "i"); + // fallthough + case 0x26: + case 0x0e: + case 0x2e: +unit_cond: + if (d == 1) { + push_str_modifier(hppa_ext, + unit_cond_64_names[cond]); + } else { + push_str_modifier(hppa_ext, + unit_cond_names[cond]); + } + return; + case 0x0d: + case 0x0c: + case 0x05: + case 0x04: + push_str_modifier(hppa_ext, saturation_names[e3]); + return; + default: + break; + } + } + + switch (ext) { + case 0x18: + case 0x38: + case 0x1c: + case 0x3c: + case 0x19: + case 0x39: + case 0x1a: + case 0x3a: + case 0x3b: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + push_str_modifier(hppa_ext, add_cond_names[cond]); + break; + case 0x10: + case 0x30: + case 0x13: + case 0x33: + case 0x14: + case 0x34: + case 0x11: + case 0x22: + push_str_modifier(hppa_ext, compare_cond_names[cond]); + break; + case 0x00: + case 0x08: + case 0x09: + case 0x0a: + push_str_modifier(hppa_ext, logical_cond_names[cond]); + break; + case 0x0e: + case 0x26: + case 0x27: + case 0x2e: + case 0x2f: + push_str_modifier(hppa_ext, unit_cond_names[cond]); + break; + default: + break; + } +} + +static bool decode_alu(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 20, 25); + uint32_t r1 = get_insn_field(insn, 11, 15); + uint32_t r2 = get_insn_field(insn, 6, 10); + uint32_t t = get_insn_field(insn, 27, 31); + if (MODE_IS_HPPA_20(ud->mode)) { + switch (ext) { + case 0x19: + case 0x29: + case 0x39: + case 0x1a: + case 0x2a: + case 0x3a: + case 0x1b: + case 0x2b: + case 0x3b: + case 0x1d: + case 0x1e: + case 0x1f: + case 0x15: + case 0x16: + case 0x17: + case 0x0f: + case 0x0d: + case 0x0c: + case 0x07: + case 0x05: + case 0x04: + case 0x0b: + CREATE_GR_REG(MI, r1); + if (ext > 0x10) { + MCOperand_CreateImm0( + MI, get_insn_field(insn, 24, 25)); + } + CREATE_GR_REG(MI, r2); + CREATE_GR_REG(MI, t); + goto success; + default: + break; + } + } + switch (ext) { + case 0x18: + case 0x38: + case 0x1c: + case 0x3c: + case 0x19: + case 0x39: + case 0x1a: + case 0x3a: + case 0x1b: + case 0x3b: + case 0x10: + case 0x30: + case 0x13: + case 0x33: + case 0x14: + case 0x34: + case 0x11: + case 0x00: + case 0x08: + case 0x09: + case 0x0a: + case 0x0e: + case 0x22: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + CREATE_GR_REG(MI, r1); + case 0x2e: + case 0x2f: + CREATE_GR_REG(MI, r2); + CREATE_GR_REG(MI, t); + break; + default: + return false; + } success: - fill_alu_mods(insn, HPPA_EXT_REF(MI), MI->csh->mode); - return true; -} - -static void fill_idxmem_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 22, 25); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_LDB); - return; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_LDH); - return; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_LDW); - return; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_LDD); - return; - case 0x04: - MCInst_setOpcode(MI, HPPA_INS_LDDA); - return; - case 0x05: - MCInst_setOpcode(MI, HPPA_INS_LDCD); - return; - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_LDWA); - return; - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_LDCW); - return; - default: - break; - } - if (get_insn_bit(insn, 19) == 1) { - switch (ext) { - case 0x08: - MCInst_setOpcode(MI, HPPA_INS_STB); - return; - case 0x09: - MCInst_setOpcode(MI, HPPA_INS_STH); - return; - case 0x0a: - MCInst_setOpcode(MI, HPPA_INS_STW); - return; - case 0x0b: - MCInst_setOpcode(MI, HPPA_INS_STD); - return; - case 0x0c: - MCInst_setOpcode(MI, HPPA_INS_STBY); - return; - case 0x0d: - MCInst_setOpcode(MI, HPPA_INS_STDBY); - return; - case 0x0e: - MCInst_setOpcode(MI, HPPA_INS_STWA); - return; - case 0x0f: - MCInst_setOpcode(MI, HPPA_INS_STDA); - return; - default: - break; - } - } - } - if (get_insn_bit(insn, 19) == 0) { - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_LDBX); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_LDHX); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_LDWX); - break; - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_LDCWX); - break; - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_LDWAX); - break; - default: - break; - } - } - else { - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_LDBS); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_LDHS); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_LDWS); - break; - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_LDCWS); - break; - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_LDWAS); - break; - case 0x08: - MCInst_setOpcode(MI, HPPA_INS_STBS); - break; - case 0x09: - MCInst_setOpcode(MI, HPPA_INS_STHS); - break; - case 0x0a: - MCInst_setOpcode(MI, HPPA_INS_STWS); - break; - case 0x0c: - MCInst_setOpcode(MI, HPPA_INS_STBYS); - break; - case 0x0e: - MCInst_setOpcode(MI, HPPA_INS_STWAS); - break; - default: - break; - } - } -} - -static void fill_idxmem_mods(uint32_t insn, hppa_ext* hppa_ext, cs_mode mode, uint32_t im5) { - uint32_t cmplt = (get_insn_bit(insn, 18) << 1) | get_insn_bit(insn, 26); - uint32_t cc = get_insn_field(insn, 20, 21); - uint32_t ext = get_insn_field(insn, 22, 25); - if (CMPLT_HAS_MODIFY_BIT(cmplt)) { - hppa_ext->b_writeble = true; - } - if (get_insn_bit(insn, 19) == 0) { - switch (ext) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x06: - push_str_modifier(hppa_ext, index_compl_names[cmplt]); - if (cc == 2) { - push_str_modifier(hppa_ext, "sl"); - } - break; - case 0x05: - case 0x07: - push_str_modifier(hppa_ext, index_compl_names[cmplt]); - if (cc == 1) { - push_str_modifier(hppa_ext, "co"); - } - break; - default: - break; - } - } - else { - switch (ext) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x06: - if (cmplt == 1 && im5 == 0) { - push_str_modifier(hppa_ext, "o"); - } - else { - push_str_modifier(hppa_ext, short_ldst_compl_names[cmplt]); - } - if (cc == 2) { - push_str_modifier(hppa_ext, "sl"); - } - break; - case 0x05: - case 0x07: - if (cmplt == 1 && im5 == 0) { - push_str_modifier(hppa_ext, "o"); - } - else { - push_str_modifier(hppa_ext, short_ldst_compl_names[cmplt]); - } - if (cc == 1) { - push_str_modifier(hppa_ext, "co"); - } - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0e: - case 0x0f: - if (cmplt == 1 && im5 == 0) { - push_str_modifier(hppa_ext, "o"); - } - else { - push_str_modifier(hppa_ext, short_ldst_compl_names[cmplt]); - } - if (cc == 1) { - push_str_modifier(hppa_ext, "bc"); - } - else if (cc == 2) { - push_str_modifier(hppa_ext, "sl"); - } - break; - case 0x0c: - case 0x0d: - push_str_modifier(hppa_ext, short_bytes_compl_names[cmplt]); - if (cc == 1) { - push_str_modifier(hppa_ext, "bc"); - } - else if (cc == 2) { - push_str_modifier(hppa_ext, "sl"); - } - break; - default: - break; - } - } -} - -static bool decode_idxmem(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 22, 25); - uint32_t im5; - uint32_t r = get_insn_field(insn, 11, 15); - uint32_t b = get_insn_field(insn, 6, 10); - uint32_t t = get_insn_field(insn, 27, 31); - uint32_t s = get_insn_field(insn, 16, 17); - if (MODE_IS_HPPA_20(ud->mode)) { - if (get_insn_bit(insn, 19) == 0) { - switch (ext) { - case 0x03: - case 0x05: - case 0x04: - CREATE_GR_REG(MI, r); - if (ext != 0x04) { - CREATE_SR_REG(MI, s); - } - CREATE_GR_REG(MI, b); - CREATE_GR_REG(MI, t); - fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, -1); - return true; - default: - break; - } - } - else { - switch (ext) { - case 0x03: - case 0x05: - case 0x04: - im5 = extract_5_load(insn); - MCOperand_CreateImm0(MI, im5); - if (ext != 0x04) { - CREATE_SR_REG(MI, s); - } - CREATE_GR_REG(MI, b); - CREATE_GR_REG(MI, t); - fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, im5); - return true; - case 0x0b: - case 0x0d: - case 0x0f: - im5 = extract_5_store(insn); - CREATE_GR_REG(MI, r); - MCOperand_CreateImm0(MI, im5); - if (ext != 0x0f) { - CREATE_SR_REG(MI, s); - } - CREATE_GR_REG(MI, b); - fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, im5); - return true; - default: - break; - } - } - } - if (get_insn_bit(insn, 19) == 0) { - switch (ext) { - case 0x00: - case 0x01: - case 0x02: - case 0x07: - case 0x06: - CREATE_GR_REG(MI, r); - if (ext != 0x06) { - CREATE_SR_REG(MI, s); - } - CREATE_GR_REG(MI, b); - CREATE_GR_REG(MI, t); - break; - default: - return false; - } - fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, -1); - return true; - } - else { - switch (ext) { - case 0x00: - case 0x01: - case 0x02: - case 0x07: - case 0x06: - im5 = extract_5_load(insn); - MCOperand_CreateImm0(MI, im5); - if (ext != 0x06) { - CREATE_SR_REG(MI, s); - } - CREATE_GR_REG(MI, b); - CREATE_GR_REG(MI, t); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0c: - case 0x0e: - im5 = extract_5_store(insn); - CREATE_GR_REG(MI, r); - MCOperand_CreateImm0(MI, im5); - if (ext != 0x0e) { - CREATE_SR_REG(MI, s); - } - CREATE_GR_REG(MI, b); - break; - default: - return false; - } - if (MODE_IS_HPPA_20(ud->mode)) { - fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, im5); - } - else { - fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, -1); - } - return true; - } -} - -static void fill_ldst_dw_insn_name(MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t ext = get_insn_bit(insn, 30); - if (opcode == 0x14) { - if (ext == 0) { - MCInst_setOpcode(MI, HPPA_INS_LDD); - } else { - MCInst_setOpcode(MI, HPPA_INS_FLDD); - } - } - else { - if (ext == 0) { - MCInst_setOpcode(MI, HPPA_INS_STD); - } else { - MCInst_setOpcode(MI, HPPA_INS_FSTD); - } - } -} - -static void fill_ldst_dw_mods(uint32_t insn, hppa_ext* hppa_ext, uint32_t im) { - uint32_t cmplt = (get_insn_bit(insn, 29) << 1) | get_insn_bit(insn, 28); - if (cmplt == 1 && im == 0) { - push_str_modifier(hppa_ext, "o"); - } - else { - push_str_modifier(hppa_ext, short_ldst_compl_names[cmplt]); - } -} - -static bool decode_ldst_dw(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t im = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); - im &= ~7; - uint32_t ext = get_insn_bit(insn, 30); - uint32_t r = get_insn_field(insn, 11, 15); - uint32_t b = get_insn_field(insn, 6, 10); - uint32_t s = get_insn_field(insn, 16, 17); - if (opcode == HPPA_OP_TYPE_LOADDW) { - MCOperand_CreateImm0(MI, im); - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, b); - if (ext == 0) { - CREATE_GR_REG(MI, r); - } - else { - CREATE_FPR_REG(MI, r); - } - } - else { - if (ext == 0) { - CREATE_GR_REG(MI, r); - } - else { - CREATE_FPR_REG(MI, r); - } - MCOperand_CreateImm0(MI, im); - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, b); - } - fill_ldst_dw_mods(insn, HPPA_EXT_REF(MI), im); - return true; -} - -static void fill_ldst_w_insn_name(MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t ext = get_insn_bit(insn, 29); - if (opcode == 0x17) { - if (ext == 0) { - MCInst_setOpcode(MI, HPPA_INS_FLDW); - } else { - MCInst_setOpcode(MI, HPPA_INS_LDW); - } - } - else { - if (ext == 0) { - MCInst_setOpcode(MI, HPPA_INS_FSTW); - } else { - MCInst_setOpcode(MI, HPPA_INS_STW); - } - } -} - -static void fill_ldst_w_mods(uint32_t insn, hppa_ext* hppa_ext, uint32_t im) { - if (im >= 0) { - push_str_modifier(hppa_ext, "mb"); - } else { - push_str_modifier(hppa_ext, "ma"); - } -} - -static bool decode_ldst_w(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t ext = get_insn_bit(insn, 29); - uint32_t im = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); - im &= ~3; - uint32_t r = get_insn_field(insn, 11, 15); - uint32_t b = get_insn_field(insn, 6, 10); - uint32_t s = get_insn_field(insn, 16, 17); - if (opcode == 0x17) { - MCOperand_CreateImm0(MI, im); - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, b); - if (ext == 1) { - CREATE_GR_REG(MI, r); - } - else { - CREATE_FPR_REG(MI, r); - } - } - else { - if (ext == 1) { - CREATE_GR_REG(MI, r); - } - else { - CREATE_FPR_REG(MI, r); - } - MCOperand_CreateImm0(MI, im); - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, b); - } - if (ext == 1) { - fill_ldst_w_mods(insn, HPPA_EXT_REF(MI), im); - } - return true; -} - -static void fill_arith_imm_insn_name(MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (opcode) { - case 0x2d: - case 0x2c: - MCInst_setOpcode(MI, HPPA_INS_ADDI); - return; - case 0x25: - MCInst_setOpcode(MI, HPPA_INS_SUBI); - return; - default: - break; - } - } - if (get_insn_bit(insn, 20) == 0) { - switch (opcode) { - case 0x2d: - MCInst_setOpcode(MI, HPPA_INS_ADDI); - break; - case 0x2c: - MCInst_setOpcode(MI, HPPA_INS_ADDIT); - break; - case 0x25: - MCInst_setOpcode(MI, HPPA_INS_SUBI); - break; - default: - break; - } - } - else { - switch (opcode) { - case 0x2d: - MCInst_setOpcode(MI, HPPA_INS_ADDIO); - break; - case 0x2c: - MCInst_setOpcode(MI, HPPA_INS_ADDITO); - break; - case 0x25: - MCInst_setOpcode(MI, HPPA_INS_SUBIO); - break; - default: - break; - } - } - -} - -static void fill_arith_imm_insn_mods(uint32_t insn, hppa_ext* hppa_ext, cs_mode mode) { - uint32_t opcode = insn >> 26; - uint32_t cond = (get_insn_bit(insn, 19) << 3) | get_insn_field(insn, 16, 18); - uint32_t cmplt = get_insn_bit(insn, 20); - if (MODE_IS_HPPA_20(mode)) { - if (cmplt == 1) { - push_str_modifier(hppa_ext, "tsv"); - } - if (opcode == 0x2c) { - push_str_modifier(hppa_ext, "tc"); - } - } - switch (opcode) { - case 0x2d: - case 0x2c: - push_str_modifier(hppa_ext, add_cond_names[cond]); - break; - case 0x25: - push_str_modifier(hppa_ext, compare_cond_names[cond]); - break; - default: - break; - } -} - -static bool decode_arith_imm(const cs_struct *ud, MCInst *MI, uint32_t insn) { - MCOperand_CreateImm0(MI, extract_11(insn)); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); - fill_arith_imm_insn_mods(insn, HPPA_EXT_REF(MI), ud->mode); - return true; -} - -static void fill_shexdep0_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 19, 21); - uint32_t d = get_insn_bit(insn, 22); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (ext) { - case 0x01: - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_SHRPD); - return; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_SHRPW); - return; - case 0x06: - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_EXTRW); - return; - case 0x00: - if (d == 0) { - MCInst_setOpcode(MI, HPPA_INS_SHRPW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_SHRPD); - } - return; - case 0x04: - case 0x05: - if (d == 0) { - MCInst_setOpcode(MI, HPPA_INS_EXTRW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_EXTRD); - } - return; - default: - break; - } - } - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_VSHD); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_SHD); - break; - case 0x04: - MCInst_setOpcode(MI, HPPA_INS_VEXTRU); - break; - case 0x05: - MCInst_setOpcode(MI, HPPA_INS_VEXTRS); - break; - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_EXTRU); - break; - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_EXTRS); - break; - default: - break; - } -} - -static void fill_shexdep0_mods(uint32_t insn, hppa_ext* hppa_ext, cs_mode mode) { - uint32_t cond = get_insn_field(insn, 16, 18); - uint32_t ext = get_insn_field(insn, 19, 21); - uint32_t d = get_insn_bit(insn, 22); - - if (ext >= 0x04 && MODE_IS_HPPA_20(mode)) { - push_str_modifier(hppa_ext, signed_unsigned_names[ext & 1]); - } - - if (MODE_IS_HPPA_20(mode)) { - switch (ext) { - case 0x00: - case 0x04: - case 0x05: - if (d == 0) { - break; - } - // fallthrough - case 0x01: - case 0x03: - push_str_modifier(hppa_ext, shift_cond_64_names[cond]); - return; - default: - break; - } - } - push_str_modifier(hppa_ext, shift_cond_names[cond]); -} - -static bool decode_shexdep0(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 19, 21); - uint32_t cp = get_insn_bit(insn, 20); - uint32_t cpos = get_insn_field(insn, 22, 26); - uint32_t sa = 63 - ((cp << 5) | cpos); - uint32_t r1 = get_insn_field(insn, 11, 15); - uint32_t r2 = get_insn_field(insn, 6, 10); - uint32_t clen_t = get_insn_field(insn, 27, 31); - if (MODE_IS_HPPA_20(ud->mode)) { - switch (ext) { - case 0x01: - case 0x00: - case 0x03: - case 0x02: - CREATE_GR_REG(MI, r1); - CREATE_GR_REG(MI, r2); - if (ext <= 0x01) { - CREATE_CR_REG(MI, 11); - HPPA_EXT_REF(MI)->is_alternative = true; - } - else { - MCOperand_CreateImm0(MI, sa); - } - CREATE_GR_REG(MI, clen_t); - break; - case 0x06: - case 0x07: - case 0x04: - case 0x05: - CREATE_GR_REG(MI, r2); - if (ext >= 0x06) { - MCOperand_CreateImm0(MI, cpos); - } - else { - CREATE_CR_REG(MI, 11); - HPPA_EXT_REF(MI)->is_alternative = true; - } - MCOperand_CreateImm0(MI, 32 - clen_t); - CREATE_GR_REG(MI, r1); - break; - default: - return false; - } - } - else { - switch (ext) { - case 0x00: - case 0x02: - CREATE_GR_REG(MI, r1); - CREATE_GR_REG(MI, r2); - if (ext == 0x02) { - MCOperand_CreateImm0(MI, 31 - cpos); - } - CREATE_GR_REG(MI, clen_t); - break; - case 0x04: - case 0x05: - case 0x06: - case 0x07: - CREATE_GR_REG(MI, r2); - if (ext >= 0x06) { - MCOperand_CreateImm0(MI, cpos); - } - MCOperand_CreateImm0(MI, 32 - clen_t); - CREATE_GR_REG(MI, r1); - break; - default: - return false; - } - } - fill_shexdep0_mods(insn, HPPA_EXT_REF(MI), ud->mode); - return true; -} - -static void fill_shexdep1_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 19, 21); - uint32_t d = get_insn_bit(insn, 22); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (ext) { - case 0x02: - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_DEPW); - break; - case 0x06: - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_DEPWI); - break; - case 0x00: - case 0x01: - if (d == 0) { - MCInst_setOpcode(MI, HPPA_INS_DEPW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_DEPD); - } - break; - case 0x04: - case 0x05: - if (d == 0) { - MCInst_setOpcode(MI, HPPA_INS_DEPWI); - } - else { - MCInst_setOpcode(MI, HPPA_INS_DEPDI); - } - break; - default: - break; - } - } - else { - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_ZVDEP); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_VDEP); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_ZDEP); - break; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_DEP); - break; - case 0x04: - MCInst_setOpcode(MI, HPPA_INS_ZVDEPI); - break; - case 0x05: - MCInst_setOpcode(MI, HPPA_INS_VDEPI); - break; - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_ZDEPI); - break; - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_DEPI); - break; - default: - break; - } - } -} - -static void fill_shexdep1_mods(uint32_t insn, hppa_ext* hppa_ext, cs_mode mode) { - uint32_t cond = get_insn_field(insn, 16, 18); - uint32_t cmplt = get_insn_bit(insn, 21); - uint32_t ext = get_insn_field(insn, 19, 21); - if (MODE_IS_HPPA_20(mode)) { - if (cmplt == 0) { - push_str_modifier(hppa_ext, "z"); - } - switch (ext) { - case 0x00: - case 0x01: - case 0x04: - case 0x05: - push_str_modifier(hppa_ext, shift_cond_64_names[cond]); - return; - default: - break; - } - } - push_str_modifier(hppa_ext, shift_cond_names[cond]); -} - -static bool decode_shexdep1(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 19, 21); - uint32_t cl = get_insn_bit(insn, 23); - uint32_t clen = get_insn_field(insn, 27, 31); - uint32_t len = (cl + 1) * 32 - clen; - uint32_t r = get_insn_field(insn, 11, 15); - uint32_t t = get_insn_field(insn, 6, 10); - uint32_t cpos = get_insn_field(insn, 22, 26); - if (MODE_IS_HPPA_20(ud->mode)) { - switch (ext) { - case 0x02: - case 0x03: - case 0x06: - case 0x07: - if (ext >= 0x06) { - MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); - } - else { - CREATE_GR_REG(MI, r); - } - MCOperand_CreateImm0(MI, 31 - cpos); - MCOperand_CreateImm0(MI, 32 - clen); - CREATE_GR_REG(MI, t); - break; - case 0x00: - case 0x01: - case 0x04: - case 0x05: - if (ext >= 0x04) { - MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); - } - else { - CREATE_GR_REG(MI, r); - } - CREATE_CR_REG(MI, 11); - HPPA_EXT_REF(MI)->is_alternative = true; - MCOperand_CreateImm0(MI, len); - CREATE_GR_REG(MI, t); - break; - default: - break; - } - } - else { - switch (ext) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - CREATE_GR_REG(MI, r); - if (ext >= 0x02) { - MCOperand_CreateImm0(MI, 31 - cpos); - } - MCOperand_CreateImm0(MI, 32 - clen); - CREATE_GR_REG(MI, t); - break; - case 0x04: - case 0x05: - case 0x06: - case 0x07: - MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); - if (ext >= 0x06) { - MCOperand_CreateImm0(MI, 31 - cpos); - } - MCOperand_CreateImm0(MI, 32 - clen); - CREATE_GR_REG(MI, t); - break; - default: - break; - } - } - fill_shexdep1_mods(insn, HPPA_EXT_REF(MI), ud->mode); - return true; -} - -static void fill_shexdep2_mods(uint32_t insn, hppa_ext* hppa_ext) { - uint32_t cmplt = get_insn_bit(insn, 21); - uint32_t cond = get_insn_field(insn, 16, 18); - push_str_modifier(hppa_ext, signed_unsigned_names[cmplt]); - push_str_modifier(hppa_ext, shift_cond_64_names[cond]); -} - -static bool decode_shexdep2(MCInst *MI, uint32_t insn) { - uint32_t pos = (get_insn_bit(insn, 20) << 5) | get_insn_field(insn, 22, 26); - uint32_t cl = get_insn_bit(insn, 19); - uint32_t clen = get_insn_field(insn, 27, 31); - uint32_t len = (cl + 1) * 32 - clen; - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - MCOperand_CreateImm0(MI, pos); - MCOperand_CreateImm0(MI, len); - CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); - fill_shexdep2_mods(insn, HPPA_EXT_REF(MI)); - return true; -} - -static void fill_shexdep3_mods(uint32_t insn, hppa_ext* hppa_ext) { - uint32_t cmplt = get_insn_bit(insn, 21); - uint32_t cond = get_insn_field(insn, 16, 18); - if (cmplt == 0) { - push_str_modifier(hppa_ext, "z"); - } - push_str_modifier(hppa_ext, shift_cond_64_names[cond]); -} - -static bool decode_shexdep3(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - if (opcode == HPPA_OP_TYPE_SHEXDEP3) { - MCInst_setOpcode(MI, HPPA_INS_DEPD); - } - else { - MCInst_setOpcode(MI, HPPA_INS_DEPDI); - } - uint32_t pos = 63 - ((get_insn_bit(insn, 20) << 5) | get_insn_field(insn, 22, 26)); - uint32_t cl = get_insn_bit(insn, 19); - uint32_t clen = get_insn_field(insn, 27, 31); - uint32_t len = (cl + 1) * 32 - clen; - if (opcode == HPPA_OP_TYPE_SHEXDEP3) { - CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); - } - else { - MCOperand_CreateImm0(MI, LowSignExtend64(get_insn_field(insn, 11, 15), 5)); - } - MCOperand_CreateImm0(MI, pos); - MCOperand_CreateImm0(MI, len); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - fill_shexdep3_mods(insn, HPPA_EXT_REF(MI)); - return true; -} - -static void fill_multmed_insn_name(MCInst *MI, uint32_t insn) { - uint32_t bit_16 = get_insn_bit(insn, 16); - uint32_t ext = (get_insn_field(insn, 17, 18) << 2) | get_insn_field(insn, 20, 21); - if (bit_16 == 0) { - MCInst_setOpcode(MI, HPPA_INS_PERMH); - return; - } - switch (ext) { - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_HSHL); - break; - case 0x0a: - case 0x0b: - MCInst_setOpcode(MI, HPPA_INS_HSHR); - break; - case 0x00: - case 0x08: - MCInst_setOpcode(MI, HPPA_INS_MIXW); - break; - case 0x01: - case 0x09: - MCInst_setOpcode(MI, HPPA_INS_MIXH); - break; - default: - break; - } -} - -static void fill_multmed_mods(uint32_t insn, hppa_ext* hppa_ext) { - uint32_t bit_16 = get_insn_bit(insn, 16); - uint32_t ext = (get_insn_field(insn, 17, 18) << 2) | get_insn_field(insn, 20, 21); - uint32_t eb = get_insn_field(insn, 20, 21); - uint32_t ea = get_insn_field(insn, 17, 18); - if (bit_16 == 0) { - char c[5]; - snprintf(c, sizeof(c), "%d%d%d%d", - get_insn_field(insn, 17, 18), get_insn_field(insn, 20, 21), - get_insn_field(insn, 22, 23), get_insn_field(insn, 24, 25)); - push_str_modifier(hppa_ext, c); - return; - } - switch (ext) { - case 0x0a: - case 0x0b: - if (eb >= 2) { - push_str_modifier(hppa_ext, signed_unsigned_names[eb-2]); - } - break; - case 0x00: - case 0x08: - case 0x01: - case 0x09: - if (ea == 2) { - push_str_modifier(hppa_ext, "l"); - } - else if (ea == 0) { - push_str_modifier(hppa_ext, "r"); - } - break; - default: - break; - } -} - -static bool decode_multmed(MCInst *MI, uint32_t insn) { - uint32_t bit_16 = get_insn_bit(insn, 16); - uint32_t ext = (get_insn_field(insn, 17, 18) << 2) | get_insn_field(insn, 20, 21); - uint32_t r1 = get_insn_field(insn, 11, 15); - uint32_t r2 = get_insn_field(insn, 6, 10); - uint32_t t = get_insn_field(insn, 27, 31); - uint32_t sa = get_insn_field(insn, 22, 25); - if (bit_16 == 0) { - CREATE_GR_REG(MI, r2); - CREATE_GR_REG(MI, t); - goto success; - } - switch (ext) { - case 0x02: - case 0x0a: - case 0x0b: - if (ext >= 0x0a) { - CREATE_GR_REG(MI, r2); - } - else { - CREATE_GR_REG(MI, r1); - } - MCOperand_CreateImm0(MI, sa); - CREATE_GR_REG(MI, t); - break; - case 0x00: - case 0x08: - case 0x01: - case 0x09: - CREATE_GR_REG(MI, r1); - CREATE_GR_REG(MI, r2); - CREATE_GR_REG(MI, t); - break; - default: - return false; - } + fill_alu_mods(insn, HPPA_EXT_REF(MI), MI->csh->mode); + return true; +} + +static void fill_idxmem_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 22, 25); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_LDB); + return; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_LDH); + return; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_LDW); + return; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_LDD); + return; + case 0x04: + MCInst_setOpcode(MI, HPPA_INS_LDDA); + return; + case 0x05: + MCInst_setOpcode(MI, HPPA_INS_LDCD); + return; + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_LDWA); + return; + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_LDCW); + return; + default: + break; + } + if (get_insn_bit(insn, 19) == 1) { + switch (ext) { + case 0x08: + MCInst_setOpcode(MI, HPPA_INS_STB); + return; + case 0x09: + MCInst_setOpcode(MI, HPPA_INS_STH); + return; + case 0x0a: + MCInst_setOpcode(MI, HPPA_INS_STW); + return; + case 0x0b: + MCInst_setOpcode(MI, HPPA_INS_STD); + return; + case 0x0c: + MCInst_setOpcode(MI, HPPA_INS_STBY); + return; + case 0x0d: + MCInst_setOpcode(MI, HPPA_INS_STDBY); + return; + case 0x0e: + MCInst_setOpcode(MI, HPPA_INS_STWA); + return; + case 0x0f: + MCInst_setOpcode(MI, HPPA_INS_STDA); + return; + default: + break; + } + } + } + if (get_insn_bit(insn, 19) == 0) { + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_LDBX); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_LDHX); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_LDWX); + break; + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_LDCWX); + break; + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_LDWAX); + break; + default: + break; + } + } else { + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_LDBS); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_LDHS); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_LDWS); + break; + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_LDCWS); + break; + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_LDWAS); + break; + case 0x08: + MCInst_setOpcode(MI, HPPA_INS_STBS); + break; + case 0x09: + MCInst_setOpcode(MI, HPPA_INS_STHS); + break; + case 0x0a: + MCInst_setOpcode(MI, HPPA_INS_STWS); + break; + case 0x0c: + MCInst_setOpcode(MI, HPPA_INS_STBYS); + break; + case 0x0e: + MCInst_setOpcode(MI, HPPA_INS_STWAS); + break; + default: + break; + } + } +} + +static void fill_idxmem_mods(uint32_t insn, hppa_ext *hppa_ext, cs_mode mode, + uint32_t im5) +{ + uint32_t cmplt = (get_insn_bit(insn, 18) << 1) | get_insn_bit(insn, 26); + uint32_t cc = get_insn_field(insn, 20, 21); + uint32_t ext = get_insn_field(insn, 22, 25); + if (CMPLT_HAS_MODIFY_BIT(cmplt)) { + hppa_ext->b_writeble = true; + } + if (get_insn_bit(insn, 19) == 0) { + switch (ext) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x06: + push_str_modifier(hppa_ext, index_compl_names[cmplt]); + if (cc == 2) { + push_str_modifier(hppa_ext, "sl"); + } + break; + case 0x05: + case 0x07: + push_str_modifier(hppa_ext, index_compl_names[cmplt]); + if (cc == 1) { + push_str_modifier(hppa_ext, "co"); + } + break; + default: + break; + } + } else { + switch (ext) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x06: + if (cmplt == 1 && im5 == 0) { + push_str_modifier(hppa_ext, "o"); + } else { + push_str_modifier( + hppa_ext, + short_ldst_compl_names[cmplt]); + } + if (cc == 2) { + push_str_modifier(hppa_ext, "sl"); + } + break; + case 0x05: + case 0x07: + if (cmplt == 1 && im5 == 0) { + push_str_modifier(hppa_ext, "o"); + } else { + push_str_modifier( + hppa_ext, + short_ldst_compl_names[cmplt]); + } + if (cc == 1) { + push_str_modifier(hppa_ext, "co"); + } + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0e: + case 0x0f: + if (cmplt == 1 && im5 == 0) { + push_str_modifier(hppa_ext, "o"); + } else { + push_str_modifier( + hppa_ext, + short_ldst_compl_names[cmplt]); + } + if (cc == 1) { + push_str_modifier(hppa_ext, "bc"); + } else if (cc == 2) { + push_str_modifier(hppa_ext, "sl"); + } + break; + case 0x0c: + case 0x0d: + push_str_modifier(hppa_ext, + short_bytes_compl_names[cmplt]); + if (cc == 1) { + push_str_modifier(hppa_ext, "bc"); + } else if (cc == 2) { + push_str_modifier(hppa_ext, "sl"); + } + break; + default: + break; + } + } +} + +static bool decode_idxmem(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 22, 25); + uint32_t im5; + uint32_t r = get_insn_field(insn, 11, 15); + uint32_t b = get_insn_field(insn, 6, 10); + uint32_t t = get_insn_field(insn, 27, 31); + uint32_t s = get_insn_field(insn, 16, 17); + if (MODE_IS_HPPA_20(ud->mode)) { + if (get_insn_bit(insn, 19) == 0) { + switch (ext) { + case 0x03: + case 0x05: + case 0x04: + CREATE_GR_REG(MI, r); + if (ext != 0x04) { + CREATE_SR_REG(MI, s); + } + CREATE_GR_REG(MI, b); + CREATE_GR_REG(MI, t); + fill_idxmem_mods(insn, HPPA_EXT_REF(MI), + ud->mode, -1); + return true; + default: + break; + } + } else { + switch (ext) { + case 0x03: + case 0x05: + case 0x04: + im5 = extract_5_load(insn); + MCOperand_CreateImm0(MI, im5); + if (ext != 0x04) { + CREATE_SR_REG(MI, s); + } + CREATE_GR_REG(MI, b); + CREATE_GR_REG(MI, t); + fill_idxmem_mods(insn, HPPA_EXT_REF(MI), + ud->mode, im5); + return true; + case 0x0b: + case 0x0d: + case 0x0f: + im5 = extract_5_store(insn); + CREATE_GR_REG(MI, r); + MCOperand_CreateImm0(MI, im5); + if (ext != 0x0f) { + CREATE_SR_REG(MI, s); + } + CREATE_GR_REG(MI, b); + fill_idxmem_mods(insn, HPPA_EXT_REF(MI), + ud->mode, im5); + return true; + default: + break; + } + } + } + if (get_insn_bit(insn, 19) == 0) { + switch (ext) { + case 0x00: + case 0x01: + case 0x02: + case 0x07: + case 0x06: + CREATE_GR_REG(MI, r); + if (ext != 0x06) { + CREATE_SR_REG(MI, s); + } + CREATE_GR_REG(MI, b); + CREATE_GR_REG(MI, t); + break; + default: + return false; + } + fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, -1); + return true; + } else { + switch (ext) { + case 0x00: + case 0x01: + case 0x02: + case 0x07: + case 0x06: + im5 = extract_5_load(insn); + MCOperand_CreateImm0(MI, im5); + if (ext != 0x06) { + CREATE_SR_REG(MI, s); + } + CREATE_GR_REG(MI, b); + CREATE_GR_REG(MI, t); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0c: + case 0x0e: + im5 = extract_5_store(insn); + CREATE_GR_REG(MI, r); + MCOperand_CreateImm0(MI, im5); + if (ext != 0x0e) { + CREATE_SR_REG(MI, s); + } + CREATE_GR_REG(MI, b); + break; + default: + return false; + } + if (MODE_IS_HPPA_20(ud->mode)) { + fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, im5); + } else { + fill_idxmem_mods(insn, HPPA_EXT_REF(MI), ud->mode, -1); + } + return true; + } +} + +static void fill_ldst_dw_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t ext = get_insn_bit(insn, 30); + if (opcode == 0x14) { + if (ext == 0) { + MCInst_setOpcode(MI, HPPA_INS_LDD); + } else { + MCInst_setOpcode(MI, HPPA_INS_FLDD); + } + } else { + if (ext == 0) { + MCInst_setOpcode(MI, HPPA_INS_STD); + } else { + MCInst_setOpcode(MI, HPPA_INS_FSTD); + } + } +} + +static void fill_ldst_dw_mods(uint32_t insn, hppa_ext *hppa_ext, uint32_t im) +{ + uint32_t cmplt = (get_insn_bit(insn, 29) << 1) | get_insn_bit(insn, 28); + if (cmplt == 1 && im == 0) { + push_str_modifier(hppa_ext, "o"); + } else { + push_str_modifier(hppa_ext, short_ldst_compl_names[cmplt]); + } +} + +static bool decode_ldst_dw(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t im = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); + im &= ~7; + uint32_t ext = get_insn_bit(insn, 30); + uint32_t r = get_insn_field(insn, 11, 15); + uint32_t b = get_insn_field(insn, 6, 10); + uint32_t s = get_insn_field(insn, 16, 17); + if (opcode == HPPA_OP_TYPE_LOADDW) { + MCOperand_CreateImm0(MI, im); + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, b); + if (ext == 0) { + CREATE_GR_REG(MI, r); + } else { + CREATE_FPR_REG(MI, r); + } + } else { + if (ext == 0) { + CREATE_GR_REG(MI, r); + } else { + CREATE_FPR_REG(MI, r); + } + MCOperand_CreateImm0(MI, im); + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, b); + } + fill_ldst_dw_mods(insn, HPPA_EXT_REF(MI), im); + return true; +} + +static void fill_ldst_w_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t ext = get_insn_bit(insn, 29); + if (opcode == 0x17) { + if (ext == 0) { + MCInst_setOpcode(MI, HPPA_INS_FLDW); + } else { + MCInst_setOpcode(MI, HPPA_INS_LDW); + } + } else { + if (ext == 0) { + MCInst_setOpcode(MI, HPPA_INS_FSTW); + } else { + MCInst_setOpcode(MI, HPPA_INS_STW); + } + } +} + +static void fill_ldst_w_mods(uint32_t insn, hppa_ext *hppa_ext, uint32_t im) +{ + if (im >= 0) { + push_str_modifier(hppa_ext, "mb"); + } else { + push_str_modifier(hppa_ext, "ma"); + } +} + +static bool decode_ldst_w(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t ext = get_insn_bit(insn, 29); + uint32_t im = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); + im &= ~3; + uint32_t r = get_insn_field(insn, 11, 15); + uint32_t b = get_insn_field(insn, 6, 10); + uint32_t s = get_insn_field(insn, 16, 17); + if (opcode == 0x17) { + MCOperand_CreateImm0(MI, im); + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, b); + if (ext == 1) { + CREATE_GR_REG(MI, r); + } else { + CREATE_FPR_REG(MI, r); + } + } else { + if (ext == 1) { + CREATE_GR_REG(MI, r); + } else { + CREATE_FPR_REG(MI, r); + } + MCOperand_CreateImm0(MI, im); + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, b); + } + if (ext == 1) { + fill_ldst_w_mods(insn, HPPA_EXT_REF(MI), im); + } + return true; +} + +static void fill_arith_imm_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (opcode) { + case 0x2d: + case 0x2c: + MCInst_setOpcode(MI, HPPA_INS_ADDI); + return; + case 0x25: + MCInst_setOpcode(MI, HPPA_INS_SUBI); + return; + default: + break; + } + } + if (get_insn_bit(insn, 20) == 0) { + switch (opcode) { + case 0x2d: + MCInst_setOpcode(MI, HPPA_INS_ADDI); + break; + case 0x2c: + MCInst_setOpcode(MI, HPPA_INS_ADDIT); + break; + case 0x25: + MCInst_setOpcode(MI, HPPA_INS_SUBI); + break; + default: + break; + } + } else { + switch (opcode) { + case 0x2d: + MCInst_setOpcode(MI, HPPA_INS_ADDIO); + break; + case 0x2c: + MCInst_setOpcode(MI, HPPA_INS_ADDITO); + break; + case 0x25: + MCInst_setOpcode(MI, HPPA_INS_SUBIO); + break; + default: + break; + } + } +} + +static void fill_arith_imm_insn_mods(uint32_t insn, hppa_ext *hppa_ext, + cs_mode mode) +{ + uint32_t opcode = insn >> 26; + uint32_t cond = (get_insn_bit(insn, 19) << 3) | + get_insn_field(insn, 16, 18); + uint32_t cmplt = get_insn_bit(insn, 20); + if (MODE_IS_HPPA_20(mode)) { + if (cmplt == 1) { + push_str_modifier(hppa_ext, "tsv"); + } + if (opcode == 0x2c) { + push_str_modifier(hppa_ext, "tc"); + } + } + switch (opcode) { + case 0x2d: + case 0x2c: + push_str_modifier(hppa_ext, add_cond_names[cond]); + break; + case 0x25: + push_str_modifier(hppa_ext, compare_cond_names[cond]); + break; + default: + break; + } +} + +static bool decode_arith_imm(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + MCOperand_CreateImm0(MI, extract_11(insn)); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); + fill_arith_imm_insn_mods(insn, HPPA_EXT_REF(MI), ud->mode); + return true; +} + +static void fill_shexdep0_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 19, 21); + uint32_t d = get_insn_bit(insn, 22); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (ext) { + case 0x01: + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_SHRPD); + return; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_SHRPW); + return; + case 0x06: + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_EXTRW); + return; + case 0x00: + if (d == 0) { + MCInst_setOpcode(MI, HPPA_INS_SHRPW); + } else { + MCInst_setOpcode(MI, HPPA_INS_SHRPD); + } + return; + case 0x04: + case 0x05: + if (d == 0) { + MCInst_setOpcode(MI, HPPA_INS_EXTRW); + } else { + MCInst_setOpcode(MI, HPPA_INS_EXTRD); + } + return; + default: + break; + } + } + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_VSHD); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_SHD); + break; + case 0x04: + MCInst_setOpcode(MI, HPPA_INS_VEXTRU); + break; + case 0x05: + MCInst_setOpcode(MI, HPPA_INS_VEXTRS); + break; + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_EXTRU); + break; + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_EXTRS); + break; + default: + break; + } +} + +static void fill_shexdep0_mods(uint32_t insn, hppa_ext *hppa_ext, cs_mode mode) +{ + uint32_t cond = get_insn_field(insn, 16, 18); + uint32_t ext = get_insn_field(insn, 19, 21); + uint32_t d = get_insn_bit(insn, 22); + + if (ext >= 0x04 && MODE_IS_HPPA_20(mode)) { + push_str_modifier(hppa_ext, signed_unsigned_names[ext & 1]); + } + + if (MODE_IS_HPPA_20(mode)) { + switch (ext) { + case 0x00: + case 0x04: + case 0x05: + if (d == 0) { + break; + } + // fallthrough + case 0x01: + case 0x03: + push_str_modifier(hppa_ext, shift_cond_64_names[cond]); + return; + default: + break; + } + } + push_str_modifier(hppa_ext, shift_cond_names[cond]); +} + +static bool decode_shexdep0(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 19, 21); + uint32_t cp = get_insn_bit(insn, 20); + uint32_t cpos = get_insn_field(insn, 22, 26); + uint32_t sa = 63 - ((cp << 5) | cpos); + uint32_t r1 = get_insn_field(insn, 11, 15); + uint32_t r2 = get_insn_field(insn, 6, 10); + uint32_t clen_t = get_insn_field(insn, 27, 31); + if (MODE_IS_HPPA_20(ud->mode)) { + switch (ext) { + case 0x01: + case 0x00: + case 0x03: + case 0x02: + CREATE_GR_REG(MI, r1); + CREATE_GR_REG(MI, r2); + if (ext <= 0x01) { + CREATE_CR_REG(MI, 11); + HPPA_EXT_REF(MI)->is_alternative = true; + } else { + MCOperand_CreateImm0(MI, sa); + } + CREATE_GR_REG(MI, clen_t); + break; + case 0x06: + case 0x07: + case 0x04: + case 0x05: + CREATE_GR_REG(MI, r2); + if (ext >= 0x06) { + MCOperand_CreateImm0(MI, cpos); + } else { + CREATE_CR_REG(MI, 11); + HPPA_EXT_REF(MI)->is_alternative = true; + } + MCOperand_CreateImm0(MI, 32 - clen_t); + CREATE_GR_REG(MI, r1); + break; + default: + return false; + } + } else { + switch (ext) { + case 0x00: + case 0x02: + CREATE_GR_REG(MI, r1); + CREATE_GR_REG(MI, r2); + if (ext == 0x02) { + MCOperand_CreateImm0(MI, 31 - cpos); + } + CREATE_GR_REG(MI, clen_t); + break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + CREATE_GR_REG(MI, r2); + if (ext >= 0x06) { + MCOperand_CreateImm0(MI, cpos); + } + MCOperand_CreateImm0(MI, 32 - clen_t); + CREATE_GR_REG(MI, r1); + break; + default: + return false; + } + } + fill_shexdep0_mods(insn, HPPA_EXT_REF(MI), ud->mode); + return true; +} + +static void fill_shexdep1_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 19, 21); + uint32_t d = get_insn_bit(insn, 22); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (ext) { + case 0x02: + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_DEPW); + break; + case 0x06: + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_DEPWI); + break; + case 0x00: + case 0x01: + if (d == 0) { + MCInst_setOpcode(MI, HPPA_INS_DEPW); + } else { + MCInst_setOpcode(MI, HPPA_INS_DEPD); + } + break; + case 0x04: + case 0x05: + if (d == 0) { + MCInst_setOpcode(MI, HPPA_INS_DEPWI); + } else { + MCInst_setOpcode(MI, HPPA_INS_DEPDI); + } + break; + default: + break; + } + } else { + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_ZVDEP); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_VDEP); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_ZDEP); + break; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_DEP); + break; + case 0x04: + MCInst_setOpcode(MI, HPPA_INS_ZVDEPI); + break; + case 0x05: + MCInst_setOpcode(MI, HPPA_INS_VDEPI); + break; + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_ZDEPI); + break; + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_DEPI); + break; + default: + break; + } + } +} + +static void fill_shexdep1_mods(uint32_t insn, hppa_ext *hppa_ext, cs_mode mode) +{ + uint32_t cond = get_insn_field(insn, 16, 18); + uint32_t cmplt = get_insn_bit(insn, 21); + uint32_t ext = get_insn_field(insn, 19, 21); + if (MODE_IS_HPPA_20(mode)) { + if (cmplt == 0) { + push_str_modifier(hppa_ext, "z"); + } + switch (ext) { + case 0x00: + case 0x01: + case 0x04: + case 0x05: + push_str_modifier(hppa_ext, shift_cond_64_names[cond]); + return; + default: + break; + } + } + push_str_modifier(hppa_ext, shift_cond_names[cond]); +} + +static bool decode_shexdep1(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 19, 21); + uint32_t cl = get_insn_bit(insn, 23); + uint32_t clen = get_insn_field(insn, 27, 31); + uint32_t len = (cl + 1) * 32 - clen; + uint32_t r = get_insn_field(insn, 11, 15); + uint32_t t = get_insn_field(insn, 6, 10); + uint32_t cpos = get_insn_field(insn, 22, 26); + if (MODE_IS_HPPA_20(ud->mode)) { + switch (ext) { + case 0x02: + case 0x03: + case 0x06: + case 0x07: + if (ext >= 0x06) { + MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); + } else { + CREATE_GR_REG(MI, r); + } + MCOperand_CreateImm0(MI, 31 - cpos); + MCOperand_CreateImm0(MI, 32 - clen); + CREATE_GR_REG(MI, t); + break; + case 0x00: + case 0x01: + case 0x04: + case 0x05: + if (ext >= 0x04) { + MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); + } else { + CREATE_GR_REG(MI, r); + } + CREATE_CR_REG(MI, 11); + HPPA_EXT_REF(MI)->is_alternative = true; + MCOperand_CreateImm0(MI, len); + CREATE_GR_REG(MI, t); + break; + default: + break; + } + } else { + switch (ext) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + CREATE_GR_REG(MI, r); + if (ext >= 0x02) { + MCOperand_CreateImm0(MI, 31 - cpos); + } + MCOperand_CreateImm0(MI, 32 - clen); + CREATE_GR_REG(MI, t); + break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + MCOperand_CreateImm0(MI, LowSignExtend64(r, 5)); + if (ext >= 0x06) { + MCOperand_CreateImm0(MI, 31 - cpos); + } + MCOperand_CreateImm0(MI, 32 - clen); + CREATE_GR_REG(MI, t); + break; + default: + break; + } + } + fill_shexdep1_mods(insn, HPPA_EXT_REF(MI), ud->mode); + return true; +} + +static void fill_shexdep2_mods(uint32_t insn, hppa_ext *hppa_ext) +{ + uint32_t cmplt = get_insn_bit(insn, 21); + uint32_t cond = get_insn_field(insn, 16, 18); + push_str_modifier(hppa_ext, signed_unsigned_names[cmplt]); + push_str_modifier(hppa_ext, shift_cond_64_names[cond]); +} + +static bool decode_shexdep2(MCInst *MI, uint32_t insn) +{ + uint32_t pos = (get_insn_bit(insn, 20) << 5) | + get_insn_field(insn, 22, 26); + uint32_t cl = get_insn_bit(insn, 19); + uint32_t clen = get_insn_field(insn, 27, 31); + uint32_t len = (cl + 1) * 32 - clen; + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + MCOperand_CreateImm0(MI, pos); + MCOperand_CreateImm0(MI, len); + CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); + fill_shexdep2_mods(insn, HPPA_EXT_REF(MI)); + return true; +} + +static void fill_shexdep3_mods(uint32_t insn, hppa_ext *hppa_ext) +{ + uint32_t cmplt = get_insn_bit(insn, 21); + uint32_t cond = get_insn_field(insn, 16, 18); + if (cmplt == 0) { + push_str_modifier(hppa_ext, "z"); + } + push_str_modifier(hppa_ext, shift_cond_64_names[cond]); +} + +static bool decode_shexdep3(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + if (opcode == HPPA_OP_TYPE_SHEXDEP3) { + MCInst_setOpcode(MI, HPPA_INS_DEPD); + } else { + MCInst_setOpcode(MI, HPPA_INS_DEPDI); + } + uint32_t pos = 63 - ((get_insn_bit(insn, 20) << 5) | + get_insn_field(insn, 22, 26)); + uint32_t cl = get_insn_bit(insn, 19); + uint32_t clen = get_insn_field(insn, 27, 31); + uint32_t len = (cl + 1) * 32 - clen; + if (opcode == HPPA_OP_TYPE_SHEXDEP3) { + CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); + } else { + MCOperand_CreateImm0( + MI, LowSignExtend64(get_insn_field(insn, 11, 15), 5)); + } + MCOperand_CreateImm0(MI, pos); + MCOperand_CreateImm0(MI, len); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + fill_shexdep3_mods(insn, HPPA_EXT_REF(MI)); + return true; +} + +static void fill_multmed_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t bit_16 = get_insn_bit(insn, 16); + uint32_t ext = (get_insn_field(insn, 17, 18) << 2) | + get_insn_field(insn, 20, 21); + if (bit_16 == 0) { + MCInst_setOpcode(MI, HPPA_INS_PERMH); + return; + } + switch (ext) { + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_HSHL); + break; + case 0x0a: + case 0x0b: + MCInst_setOpcode(MI, HPPA_INS_HSHR); + break; + case 0x00: + case 0x08: + MCInst_setOpcode(MI, HPPA_INS_MIXW); + break; + case 0x01: + case 0x09: + MCInst_setOpcode(MI, HPPA_INS_MIXH); + break; + default: + break; + } +} + +static void fill_multmed_mods(uint32_t insn, hppa_ext *hppa_ext) +{ + uint32_t bit_16 = get_insn_bit(insn, 16); + uint32_t ext = (get_insn_field(insn, 17, 18) << 2) | + get_insn_field(insn, 20, 21); + uint32_t eb = get_insn_field(insn, 20, 21); + uint32_t ea = get_insn_field(insn, 17, 18); + if (bit_16 == 0) { + char c[5]; + snprintf(c, sizeof(c), "%d%d%d%d", get_insn_field(insn, 17, 18), + get_insn_field(insn, 20, 21), + get_insn_field(insn, 22, 23), + get_insn_field(insn, 24, 25)); + push_str_modifier(hppa_ext, c); + return; + } + switch (ext) { + case 0x0a: + case 0x0b: + if (eb >= 2) { + push_str_modifier(hppa_ext, + signed_unsigned_names[eb - 2]); + } + break; + case 0x00: + case 0x08: + case 0x01: + case 0x09: + if (ea == 2) { + push_str_modifier(hppa_ext, "l"); + } else if (ea == 0) { + push_str_modifier(hppa_ext, "r"); + } + break; + default: + break; + } +} + +static bool decode_multmed(MCInst *MI, uint32_t insn) +{ + uint32_t bit_16 = get_insn_bit(insn, 16); + uint32_t ext = (get_insn_field(insn, 17, 18) << 2) | + get_insn_field(insn, 20, 21); + uint32_t r1 = get_insn_field(insn, 11, 15); + uint32_t r2 = get_insn_field(insn, 6, 10); + uint32_t t = get_insn_field(insn, 27, 31); + uint32_t sa = get_insn_field(insn, 22, 25); + if (bit_16 == 0) { + CREATE_GR_REG(MI, r2); + CREATE_GR_REG(MI, t); + goto success; + } + switch (ext) { + case 0x02: + case 0x0a: + case 0x0b: + if (ext >= 0x0a) { + CREATE_GR_REG(MI, r2); + } else { + CREATE_GR_REG(MI, r1); + } + MCOperand_CreateImm0(MI, sa); + CREATE_GR_REG(MI, t); + break; + case 0x00: + case 0x08: + case 0x01: + case 0x09: + CREATE_GR_REG(MI, r1); + CREATE_GR_REG(MI, r2); + CREATE_GR_REG(MI, t); + break; + default: + return false; + } success: - fill_multmed_mods(insn, HPPA_EXT_REF(MI)); - return true; -} - -static void fill_branch_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 16, 18); - uint32_t bit_19 = get_insn_bit(insn, 19); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - if (insn == 0xe8004005) { - MCInst_setOpcode(MI, HPPA_INS_CLRBTS); - return; - } - else if (insn == 0xe8004001) { - MCInst_setOpcode(MI, HPPA_INS_PUSHNOM); - return; - } - - switch (ext) { - case 0x00: - case 0x01: - case 0x04: - case 0x05: - MCInst_setOpcode(MI, HPPA_INS_B); - return; - case 0x06: - if (bit_19 == 0) { - MCInst_setOpcode(MI, HPPA_INS_BV); - } - else { - MCInst_setOpcode(MI, HPPA_INS_BVE); - } - return; - case 0x07: - if (bit_19 == 1) { - MCInst_setOpcode(MI, HPPA_INS_BVE); - } - return; - case 0x02: - if (get_insn_field(insn, 19, 29) == 0 && get_insn_bit(insn, 31) == 0) { - MCInst_setOpcode(MI, HPPA_INS_BLR); - return; - } - if (get_insn_field(insn, 19, 31) == 1) { - MCInst_setOpcode(MI, HPPA_INS_PUSHBTS); - return; - } - if (bit_19 == 0 && get_insn_field(insn, 29, 31) == 0x5) { - MCInst_setOpcode(MI, HPPA_INS_POPBTS); - return; - } - return; - default: - return; - } - } - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_BL); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_GATE); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_BLR); - break; - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_BV); - break; - default: - break; - } -} - -static void fill_branch_mods(uint32_t insn, hppa_ext* hppa_ext, cs_mode mode) { - uint32_t ext = get_insn_field(insn, 16, 18); - uint32_t n = get_insn_bit(insn, 30); - uint32_t p = get_insn_bit(insn, 31); - if (MODE_IS_HPPA_20(mode)) { - switch (ext) { - case 0x00: - case 0x05: - push_str_modifier(hppa_ext, "l"); - // fallthrough - case 0x02: - break; - case 0x01: - push_str_modifier(hppa_ext, "gate"); - break; - case 0x04: - push_str_modifier(hppa_ext, "l"); - push_str_modifier(hppa_ext, "push"); - break; - case 0x06: - case 0x07: - if (get_insn_bit(insn, 19) == 0) { - break; - } - if (ext == 7) { - push_str_modifier(hppa_ext, "l"); - hppa_ext->is_alternative = true; - if (p == 1) { - push_str_modifier(hppa_ext, "push"); - } - } - else { - if (p == 1) { - push_str_modifier(hppa_ext, "pop"); - } - } - break; - default: - return; - } - } - if (n == 1) { - push_str_modifier(hppa_ext, "n"); - } -} - -static bool decode_branch(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 16, 18); - uint32_t t = get_insn_field(insn, 6, 10); - uint32_t i = get_insn_field(insn, 20, 28); - uint32_t r = get_insn_field(insn, 11, 15); - uint32_t bit_19 = get_insn_bit(insn, 19); - if (MODE_IS_HPPA_20(ud->mode)) { - if (insn == 0xe8004005 || insn == 0xe8004001) { - return true; - } - - switch (ext) { - case 0x01: - case 0x00: - MCOperand_CreateImm0(MI, extract_17(insn)); - CREATE_GR_REG(MI, t); - break; - case 0x04: - case 0x05: - MCOperand_CreateImm0(MI, extract_22(insn)); - CREATE_GR_REG(MI, t); - break; - case 0x02: - if (bit_19 == 1) { - return false; - } - if (get_insn_field(insn, 20, 31) == 1 && t == 0) { - CREATE_GR_REG(MI, r); - break; - } - if (r == 0 && t == 0 && get_insn_field(insn, 29, 31) == 0x5) { - MCOperand_CreateImm0(MI, i); - break; - } - if (get_insn_bit(insn, 31) == 0 && get_insn_field(insn, 19, 29) == 0) { - CREATE_GR_REG(MI, r); - CREATE_GR_REG(MI, t); - break; - } - return false; - case 0x06: - if (bit_19 == 0) { - CREATE_GR_REG(MI, r); - } - CREATE_GR_REG(MI, t); - break; - case 0x07: - if (bit_19 == 1) { - CREATE_GR_REG(MI, t); - CREATE_GR_REG(MI, 2); - break; - } - default: - return false; - } - fill_branch_mods(insn, HPPA_EXT_REF(MI), ud->mode); - return true; - } - else { - switch (ext) { - case 0x00: - case 0x01: - MCOperand_CreateImm0(MI, extract_17(insn)); - CREATE_GR_REG(MI, t); - break; - case 0x02: - case 0x06: - CREATE_GR_REG(MI, r); - CREATE_GR_REG(MI, t); - break; - default: - return false; - } - fill_branch_mods(insn, HPPA_EXT_REF(MI), ud->mode); - return true; - } -} - -static void fill_corpdw_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = (get_insn_field(insn, 19, 19) << 1) | get_insn_field(insn, 22, 22); - uint32_t opcode = insn >> 26; - uint32_t uid = get_insn_field(insn, 23, 25); - if (MODE_IS_HPPA_20(MI->csh->mode)) { - if (opcode == 0x09) { - switch (ext) { - case 0x00: - case 0x02: - if (uid <= 0x01) { - MCInst_setOpcode(MI, HPPA_INS_FLDW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_CLDW); - } - return; - case 0x01: - case 0x03: - if (uid <= 0x01) { - MCInst_setOpcode(MI, HPPA_INS_FSTW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_CSTW); - } - return; - default: - break; - } - } - else { - switch (ext) { - case 0x00: - case 0x02: - if (uid == 0x00) { - MCInst_setOpcode(MI, HPPA_INS_FLDD); - } - else { - MCInst_setOpcode(MI, HPPA_INS_CLDD); - } - return; - case 0x01: - case 0x03: - if (uid == 0x00) { - MCInst_setOpcode(MI, HPPA_INS_FSTD); - } - else { - MCInst_setOpcode(MI, HPPA_INS_CSTD); - } - return; - default: - break; - } - } - } - if (opcode == 0x09) { - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_CLDWX); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_CSTWX); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_CLDWS); - break; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_CSTWS); - break; - default: - break; - } - } - else { - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_CLDDX); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_CSTDX); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_CLDDS); - break; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_CSTDS); - break; - default: - break; - } - } -} - -static inline bool coprdw_has_uid_mod(uint32_t opcode, uint32_t uid) { - return !((opcode == HPPA_OP_TYPE_COPRW && uid <= 0x01) || - (opcode == HPPA_OP_TYPE_COPRDW && uid == 0x00)); -} - -static void fill_corpdw_mods(uint32_t insn, uint32_t im, hppa_ext* hppa_ext, cs_mode mode) { - uint32_t uid = get_insn_field(insn, 23, 25); - uint32_t cmplt = (get_insn_bit(insn, 18) << 1) | get_insn_bit(insn, 26); - uint32_t cc = get_insn_field(insn, 20, 21); - uint32_t ext = (get_insn_bit(insn, 19) << 1) | get_insn_bit(insn, 22); - uint32_t opcode = insn >> 26; - - if (coprdw_has_uid_mod(opcode, uid)) { - push_int_modifier(hppa_ext, uid); - } - if (CMPLT_HAS_MODIFY_BIT(cmplt)) { - hppa_ext->b_writeble = true; - } - - switch (ext) { - case 0x00: - case 0x01: - push_str_modifier(hppa_ext, index_compl_names[cmplt]); - break; - case 0x02: - case 0x03: - if (MODE_IS_HPPA_20(mode)) { - if (cmplt == 1 && im == 0) { - push_str_modifier(hppa_ext, "o"); - break; - } - } - push_str_modifier(hppa_ext, short_ldst_compl_names[cmplt]); - break; - default: - break; - } - if ((ext & 1) == 1 && cc == 1) { - push_str_modifier(hppa_ext, "bc"); - } - if (cc == 2) { - push_str_modifier(hppa_ext, "sl"); - } -} - -static bool decode_corpdw(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = (get_insn_bit(insn, 19) << 1) | get_insn_bit(insn, 22); - uint32_t x = get_insn_field(insn, 11, 15); - uint32_t b = get_insn_field(insn, 6, 10); - uint32_t s = get_insn_field(insn, 16, 17); - uint32_t t = get_insn_field(insn, 27, 31); - uint32_t opcode = MCInst_getOpcode(MI); - switch (ext) { - case 0x00: - case 0x02: - if (ext == 0x02) { - x = LowSignExtend64(x, 5); - MCOperand_CreateImm0(MI, x); - } - else { - CREATE_GR_REG(MI, x); - } - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, b); - if (opcode == HPPA_INS_FLDW || opcode == HPPA_INS_FLDD) { - CREATE_FPR_REG(MI, t); - } - else { - CREATE_GR_REG(MI, t); - } - break; - case 0x01: - case 0x03: - if (opcode == HPPA_INS_FSTW || opcode == HPPA_INS_FSTD) { - CREATE_FPR_REG(MI, t); - } - else { - CREATE_GR_REG(MI, t); - } - if (ext == 0x03) { - x = LowSignExtend64(x, 5); - MCOperand_CreateImm0(MI, x); - } - else { - CREATE_GR_REG(MI, x); - } - CREATE_SR_REG(MI, s); - CREATE_GR_REG(MI, b); - break; - default: - break; - } - fill_corpdw_mods(insn, x, HPPA_EXT_REF(MI), ud->mode); - return true; -} - -static void fill_spop_insn_name(MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 21, 22); - switch (ext) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_SPOP0); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_SPOP1); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_SPOP2); - break; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_SPOP3); - break; - default: - break; - } -} - -static void fill_spop_mods(uint32_t insn, uint32_t ext, hppa_ext* hppa_ext) { - uint32_t sfu = get_insn_field(insn, 23, 25); - uint32_t n = get_insn_field(insn, 26, 26); - uint32_t sop; - - push_int_modifier(hppa_ext, sfu); - switch (ext) { - case 0x00: - sop = (get_insn_field(insn, 6, 20) << 5) | get_insn_field(insn, 27, 31); - break; - case 0x01: - sop = get_insn_field(insn, 6, 20); - break; - case 0x02: - sop = (get_insn_field(insn, 11, 20) << 5) | get_insn_field(insn, 27, 31); - break; - case 0x03: - sop = (get_insn_field(insn, 16, 20) << 5) | get_insn_field(insn, 27, 31); - break; - default: - break; - } - push_int_modifier(hppa_ext, sop); - if (n == 1) { - push_str_modifier(hppa_ext, "n"); - } -} - -static bool decode_spop(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t ext = get_insn_field(insn, 21, 22); - uint32_t r2 = get_insn_field(insn, 11, 15); - uint32_t r1 = get_insn_field(insn, 6, 10); - uint32_t t = get_insn_field(insn, 27, 31); - switch (ext) { - case 0x00: - break; - case 0x01: - CREATE_GR_REG(MI, t); - break; - case 0x02: - CREATE_GR_REG(MI, r1); - break; - case 0x03: - CREATE_GR_REG(MI, r2); - CREATE_GR_REG(MI, r1); - break; - default: - return false; - } - fill_spop_mods(insn, ext, HPPA_EXT_REF(MI)); - return true; -} - -static void fill_copr_insn_name(MCInst *MI, uint32_t insn) { - uint32_t class = get_insn_field(insn, 21, 22); - uint32_t uid = get_insn_field(insn, 23, 25); - uint32_t subop; - if (MODE_IS_HPPA_20(MI->csh->mode)) { - if (uid == 0) { - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_FID); - return; - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_FNEG); - return; - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_FNEGABS); - return; - default: - break; - } - } - else if (class == 1) { - subop = get_insn_field(insn, 14, 16); - if (subop != 4) { - MCInst_setOpcode(MI, HPPA_INS_FCNV); - return; - } - } - else if (class == 2) { - if (get_insn_bit(insn, 26) == 0) { - MCInst_setOpcode(MI, HPPA_INS_FCMP); - } - else { - MCInst_setOpcode(MI, HPPA_INS_FTEST); - } - return; - } - } - } - - if (uid == 0) { - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_COPR); - return; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_FCPY); - return; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_FABS); - return; - case 0x04: - MCInst_setOpcode(MI, HPPA_INS_FSQRT); - return; - case 0x05: - MCInst_setOpcode(MI, HPPA_INS_FRND); - return; - default: - break; - } - } - else if (class == 1) { - subop = get_insn_field(insn, 15, 16); - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_FCNVFF); - return; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_FCNVXF); - return; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_FCNVFX); - return; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_FCNVFXT); - return; - default: - break; - } - } - else if (class == 2) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_FCMP); - return; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_FTEST); - return; - default: - break; - } - } - else if (class == 3) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_FADD); - return; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_FSUB); - return; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_FMPY); - return; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_FDIV); - return; - default: - break; - } - } - } - else if (uid == 2) { - subop = get_insn_field(insn, 18, 22); - switch (subop) { - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_PMDIS); - return; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_PMENB); - return; - default: - break; - } - } - MCInst_setOpcode(MI, HPPA_INS_COPR); -} - -static void fill_copr_mods(uint32_t insn, uint32_t uid, uint32_t class, - hppa_ext* hppa_ext, uint32_t subop, cs_mode mode) { - uint32_t n = get_insn_field(insn, 26, 26); - uint32_t sf = get_insn_field(insn, 19, 20); - uint32_t df = get_insn_field(insn, 17, 18); - if (MODE_IS_HPPA_20(mode)) { - if (uid == 0) { - if (class == 0) { - switch (subop) { - case 0x00: - return; - default: - break; - } - } - else if (class == 1) { - switch (subop) { - case 0x00: - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - return; - case 0x01: - push_str_modifier(hppa_ext, fcnv_fixed_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - return; - case 0x03: - push_str_modifier(hppa_ext, "t"); - // fallthrough - case 0x02: - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, fcnv_fixed_names[df]); - return; - case 0x05: - push_str_modifier(hppa_ext, fcnv_ufixed_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - return; - case 0x07: - push_str_modifier(hppa_ext, "t"); - // fallthrough - case 0x06: - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, fcnv_ufixed_names[df]); - return; - default: - break; - } - } - } - } - - if (uid == 0) { - if (class == 0) { - switch (subop) { - case 0x00: - push_int_modifier(hppa_ext, 0); - push_int_modifier(hppa_ext, 0); - if (n == 1) { - push_str_modifier(hppa_ext, "n"); - } - break; - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - push_str_modifier(hppa_ext, float_format_names[sf]); - break; - default: - break; - } - } - else if (class == 1) { - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - } - else if (class == 2) { - uint32_t cond = get_insn_field(insn, 27, 31); - if (n == 1 && subop == 1) { - push_str_modifier(hppa_ext, float_cond_names[cond]); - } - if (n == 0) { - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, float_comp_names[cond]); - } - } - else if (class == 3) { - push_str_modifier(hppa_ext, float_format_names[sf]); - } - } - else if (uid == 2) { - if (n == 1) { - push_str_modifier(hppa_ext, "n"); - } - } - else { - uint32_t uid = get_insn_field(insn, 23, 25); - uint32_t sop = (get_insn_field(insn, 6, 22) << 5) | get_insn_field(insn, 27, 31); - push_int_modifier(hppa_ext, uid); - push_int_modifier(hppa_ext, sop); - if (n == 1) { - push_str_modifier(hppa_ext, "n"); - } - } -} - -static bool decode_copr(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t class = get_insn_field(insn, 21, 22); - uint32_t uid = get_insn_field(insn, 23, 25); - uint32_t subop; - uint32_t r1 = get_insn_field(insn, 6, 10); - uint32_t r2 = get_insn_field(insn, 11, 15); - uint32_t t = get_insn_field(insn, 27, 31); - if (MODE_IS_HPPA_20(ud->mode)) { - if (uid == 0) { - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - if (subop == 0x01) { - return false; - } - if (subop >= 0x02) { - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, t); - } - } - else if (class == 1) { - subop = get_insn_field(insn, 14, 16); - if (subop == 0x04) { - return false; - } - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, t); - } - else if (class == 2) { - uint32_t n = get_insn_bit(insn, 26); - subop = get_insn_field(insn, 16, 18); - if (n == 0) { - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, r2); - if (subop != 0) { - MCOperand_CreateImm0(MI, subop - 1); - HPPA_EXT_REF(MI)->is_alternative = true; - } - } - else { - if (subop != 1) { - MCOperand_CreateImm0(MI, (subop ^ 1) - 1); - HPPA_EXT_REF(MI)->is_alternative = true; - } - } - } - else if (class == 3) { - subop = get_insn_field(insn, 16, 18); - if (subop >= 4) { - return false; - } - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, r2); - CREATE_FPR_REG(MI, t); - } - fill_copr_mods(insn, uid, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - } - } - if (uid == 0) { - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x02: - case 0x03: - case 0x04: - case 0x05: - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, t); - // fallthough - case 0x00: - break; - default: - return false; - } - } - else if (class == 1) { - subop = get_insn_field(insn, 15, 16); - switch (subop) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, t); - break; - default: - return false; - } - } - else if (class == 2) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, r2); - // fallthough - case 0x01: - break; - default: - return false; - } - } - else if (class == 3) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - CREATE_FPR_REG(MI, r1); - CREATE_FPR_REG(MI, r2); - CREATE_FPR_REG(MI, t); - break; - default: - return false; - } - } - fill_copr_mods(insn, uid, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - } - else if (uid == 2) { - subop = get_insn_field(insn, 18, 22); - switch (subop) { - case 0x01: - case 0x03: - break; - default: - return false; - } - } - fill_copr_mods(insn, uid, class, HPPA_EXT_REF(MI), -1, ud->mode); - return true; -} - -static void fill_float_insn_name(MCInst *MI, uint32_t insn) { - uint32_t class = get_insn_field(insn, 21, 22); - uint32_t subop; - if (MODE_IS_HPPA_20(MI->csh->mode)) { - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x06: - MCInst_setOpcode(MI, HPPA_INS_FNEG); - return; - case 0x07: - MCInst_setOpcode(MI, HPPA_INS_FNEGABS); - return; - default: - break; - } - } - else if (class == 1) { - subop = get_insn_field(insn, 14, 16); - if (subop == 0x04) { - return; - } - MCInst_setOpcode(MI, HPPA_INS_FCNV); - return; - } - else if (class == 2) { - MCInst_setOpcode(MI, HPPA_INS_FCMP); - return; - } - } - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_FCPY); - break; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_FABS); - break; - case 0x04: - MCInst_setOpcode(MI, HPPA_INS_FSQRT); - break; - case 0x05: - MCInst_setOpcode(MI, HPPA_INS_FRND); - break; - default: - break; - } - } - else if (class == 1) { - subop = get_insn_field(insn, 15, 16); - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_FCNVFF); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_FCNVXF); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_FCNVFX); - break; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_FCNVFXT); - break; - default: - break; - } - } - else if (class == 2) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_FCMP); - break; - } - } - else if (class == 3) { - subop = get_insn_field(insn, 16, 18); - uint32_t fixed = get_insn_field(insn, 23, 23); - if (fixed == 0) { - switch (subop) { - case 0x00: - MCInst_setOpcode(MI, HPPA_INS_FADD); - break; - case 0x01: - MCInst_setOpcode(MI, HPPA_INS_FSUB); - break; - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_FMPY); - break; - case 0x03: - MCInst_setOpcode(MI, HPPA_INS_FDIV); - break; - default: - break; - } - } - else { - switch (subop) { - case 0x02: - MCInst_setOpcode(MI, HPPA_INS_XMPYU); - break; - default: - break; - } - } - } -} - -static void fill_float_mods(uint32_t insn, uint32_t class, - hppa_ext* hppa_ext, uint32_t subop, - cs_mode mode) { - uint32_t sf = get_insn_field(insn, 19, 20); - uint32_t df = get_insn_field(insn, 17, 18); - - if (MODE_IS_HPPA_20(mode)) { - if (class == 1) { - switch (subop) { - case 0x00: - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - return; - case 0x01: - push_str_modifier(hppa_ext, fcnv_fixed_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - return; - case 0x03: - push_str_modifier(hppa_ext, "t"); - // fallthough - case 0x02: - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, fcnv_fixed_names[df]); - return; - case 0x05: - push_str_modifier(hppa_ext, fcnv_ufixed_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - return; - case 0x07: - push_str_modifier(hppa_ext, "t"); - // fallthrough - case 0x06: - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, fcnv_ufixed_names[df]); - return; - default: - return; - } - } - } - - if (class == 0) { - uint32_t fmt = get_insn_field(insn, 19, 20); - push_str_modifier(hppa_ext, float_format_names[fmt]); - } - else if (class == 1) { - push_str_modifier(hppa_ext, float_format_names[sf]); - push_str_modifier(hppa_ext, float_format_names[df]); - } - else if (class == 2) { - uint32_t fmt = get_insn_field(insn, 20, 20); - uint32_t cond = get_insn_field(insn, 27, 31); - push_str_modifier(hppa_ext, float_format_names[fmt]); - push_str_modifier(hppa_ext, float_cond_names[cond]); - } - else if (class == 3) { - if (get_insn_field(insn, 23, 23) == 0) { - uint32_t fmt = get_insn_field(insn, 20, 20); - push_str_modifier(hppa_ext, float_format_names[fmt]); - } - } -} - -static bool decode_float(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t class = get_insn_field(insn, 21, 22); - uint32_t subop; - uint32_t r1 = get_insn_field(insn, 6, 10); - uint32_t r1_fpe = get_insn_bit(insn, 24); - uint32_t r2 = get_insn_field(insn, 11, 15); - uint32_t r2_fpe = get_insn_bit(insn, 19); - uint32_t t = get_insn_field(insn, 27, 31); - uint32_t t_fpe = get_insn_bit(insn, 25); - if (MODE_IS_HPPA_20(ud->mode)) { - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - if (subop >= 0x02) { - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, t, t_fpe); - fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - } - } - else if (class == 1) { - subop = get_insn_field(insn, 14, 16); - if (subop == 0x04) { - return false; - } - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, t, t_fpe); - fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - } - else if (class == 2) { - subop = get_insn_field(insn, 16, 18); - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, r2, r2_fpe); - if (subop != 0) { - MCOperand_CreateImm0(MI, subop - 1); - } - fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - } - } - if (class == 0) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x02: - case 0x03: - case 0x04: - case 0x05: - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, t, t_fpe); - fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - default: - return false; - } - } - else if (class == 1) { - subop = get_insn_field(insn, 15, 16); - if (subop <= 0x03) { - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, t, t_fpe); - fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - } - } - else if (class == 2) { - subop = get_insn_field(insn, 16, 18); - switch (subop) { - case 0x00: - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, r2, r2_fpe); - fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - default: - return false; - } - } - else if (class == 3) { - subop = get_insn_field(insn, 16, 18); - uint32_t fixed = get_insn_field(insn, 23, 23); - if ((fixed == 0 && subop <= 0x03) || - (fixed == 1 && subop == 0x02)) { - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, r2, r2_fpe); - create_float_reg_spec(MI, t, t_fpe); - fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, ud->mode); - return true; - } - return false; - } - return false; -} - -static void fill_fpfused_insn_name(MCInst *MI, uint32_t insn) { - uint32_t subop = get_insn_bit(insn, 26); - if (subop == 0x00) { - MCInst_setOpcode(MI, HPPA_INS_FMPYFADD); - } - else { - MCInst_setOpcode(MI, HPPA_INS_FMPYNFADD); - } -} - -static void fill_fpfused_mods(uint32_t insn, hppa_ext* hppa_ext) { - uint32_t fmt = get_insn_bit(insn, 20); - push_str_modifier(hppa_ext, float_format_names[fmt]); -} - -static bool decode_fpfused(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t r1 = get_insn_field(insn, 6, 10); - uint32_t r1_fpe = get_insn_bit(insn, 24); - uint32_t r2 = get_insn_field(insn, 11, 15); - uint32_t r2_fpe = get_insn_bit(insn, 19); - uint32_t ra = (get_insn_field(insn, 16, 18) << 2) | get_insn_field(insn, 21, 22); - uint32_t ra_fpe = get_insn_bit(insn, 23); - uint32_t t = get_insn_field(insn, 27, 31); - uint32_t t_fpe = get_insn_bit(insn, 25); - create_float_reg_spec(MI, r1, r1_fpe); - create_float_reg_spec(MI, r2, r2_fpe); - create_float_reg_spec(MI, ra, ra_fpe); - create_float_reg_spec(MI, t, t_fpe); - fill_fpfused_mods(insn, HPPA_EXT_REF(MI)); - return true; -} - -static void fill_action_and_branch_insn_name(MCInst *MI, uint32_t opcode) { - if (MODE_IS_HPPA_20(MI->csh->mode)) { - switch (opcode) { - case HPPA_OP_TYPE_CMPBT: - case HPPA_OP_TYPE_CMPBF: - case HPPA_OP_TYPE_CMPBDWT: - case HPPA_OP_TYPE_CMPBDWF: - MCInst_setOpcode(MI, HPPA_INS_CMPB); - return; - case HPPA_OP_TYPE_CMPIBT: - case HPPA_OP_TYPE_CMPIBF: - case HPPA_OP_TYPE_CMPIBDW: - MCInst_setOpcode(MI, HPPA_INS_CMPIB); - return; - case HPPA_OP_TYPE_ADDBT: - case HPPA_OP_TYPE_ADDBF: - MCInst_setOpcode(MI, HPPA_INS_ADDB); - return; - case HPPA_OP_TYPE_ADDIBT: - case HPPA_OP_TYPE_ADDIBF: - MCInst_setOpcode(MI, HPPA_INS_ADDIB); - return; - case HPPA_OP_TYPE_BBS: - MCInst_setOpcode(MI, HPPA_INS_BB); - return; - default: - break; - } - } - switch (opcode) { - case HPPA_OP_TYPE_CMPBT: - MCInst_setOpcode(MI, HPPA_INS_COMBT); - break; - case HPPA_OP_TYPE_CMPBF: - MCInst_setOpcode(MI, HPPA_INS_COMBF); - break; - case HPPA_OP_TYPE_CMPIBT: - MCInst_setOpcode(MI, HPPA_INS_COMIBT); - break; - case HPPA_OP_TYPE_CMPIBF: - MCInst_setOpcode(MI, HPPA_INS_COMIBF); - break; - case HPPA_OP_TYPE_ADDBT: - MCInst_setOpcode(MI, HPPA_INS_ADDBT); - break; - case HPPA_OP_TYPE_ADDBF: - MCInst_setOpcode(MI, HPPA_INS_ADDBF); - break; - case HPPA_OP_TYPE_ADDIBT: - MCInst_setOpcode(MI, HPPA_INS_ADDIBT); - break; - case HPPA_OP_TYPE_ADDIBF: - MCInst_setOpcode(MI, HPPA_INS_ADDIBF); - break; - case HPPA_OP_TYPE_MOVB: - MCInst_setOpcode(MI, HPPA_INS_MOVB); - break; - case HPPA_OP_TYPE_MOVIB: - MCInst_setOpcode(MI, HPPA_INS_MOVIB); - break; - case HPPA_OP_TYPE_BBS: - MCInst_setOpcode(MI, HPPA_INS_BVB); - break; - case HPPA_OP_TYPE_BB: - MCInst_setOpcode(MI, HPPA_INS_BB); - break; - default: - break; - } -} - -static void fill_action_and_branch_mods(uint32_t insn, uint32_t opcode, hppa_ext* hppa_ext, cs_mode mode) { - uint32_t cond = get_insn_field(insn, 16, 18); - uint32_t n = get_insn_bit(insn, 30); - uint32_t d = get_insn_bit(insn, 18); - - if (MODE_IS_HPPA_20(mode)) { - switch (opcode) { - case HPPA_OP_TYPE_CMPBT: - case HPPA_OP_TYPE_CMPIBT: - push_str_modifier(hppa_ext, compare_cond_names[cond]); - break; - case HPPA_OP_TYPE_CMPBF: - case HPPA_OP_TYPE_CMPIBF: - push_str_modifier(hppa_ext, compare_cond_names[cond+8]); - break; - case HPPA_OP_TYPE_CMPBDWT: - push_str_modifier(hppa_ext, compare_cond_64_names[cond]); - break; - case HPPA_OP_TYPE_CMPBDWF: - push_str_modifier(hppa_ext, compare_cond_64_names[cond+8]); - break; - case HPPA_OP_TYPE_CMPIBDW: - push_str_modifier(hppa_ext, cmpib_cond_64_names[cond]); - break; - case HPPA_OP_TYPE_ADDBT: - case HPPA_OP_TYPE_ADDIBT: - if (MODE_IS_HPPA_20W(mode)) { - push_str_modifier(hppa_ext, wide_add_cond_names[cond]); - } - else { - push_str_modifier(hppa_ext, add_cond_names[cond]); - } - break; - case HPPA_OP_TYPE_ADDBF: - case HPPA_OP_TYPE_ADDIBF: - if (MODE_IS_HPPA_20W(mode)) { - push_str_modifier(hppa_ext, wide_add_cond_names[cond+8]); - } - else { - push_str_modifier(hppa_ext, add_cond_names[cond+8]); - } - break; - case HPPA_OP_TYPE_BBS: - case HPPA_OP_TYPE_BB: - if (d == 0) { - push_str_modifier(hppa_ext, shift_cond_names[cond]); - } - else { - push_str_modifier(hppa_ext, shift_cond_64_names[cond]); - } - break; - case HPPA_OP_TYPE_MOVB: - case HPPA_OP_TYPE_MOVIB: - push_str_modifier(hppa_ext, shift_cond_names[cond]); - break; - default: - break; - } - if (n == 1) { - push_str_modifier(hppa_ext, "n"); - } - return; - } - switch (opcode) { - case HPPA_OP_TYPE_CMPBT: - case HPPA_OP_TYPE_CMPBF: - case HPPA_OP_TYPE_CMPIBT: - case HPPA_OP_TYPE_CMPIBF: - push_str_modifier(hppa_ext, compare_cond_names[cond]); - break; - case HPPA_OP_TYPE_ADDBT: - case HPPA_OP_TYPE_ADDBF: - case HPPA_OP_TYPE_ADDIBT: - case HPPA_OP_TYPE_ADDIBF: - push_str_modifier(hppa_ext, add_cond_names[cond]); - break; - case HPPA_OP_TYPE_MOVB: - case HPPA_OP_TYPE_MOVIB: - case HPPA_OP_TYPE_BBS: - case HPPA_OP_TYPE_BB: - push_str_modifier(hppa_ext, shift_cond_names[cond]); - break; - default: - break; - } - if (n == 1) { - push_str_modifier(hppa_ext, "n"); - } -} - -static bool fill_action_and_branch(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t r1 = get_insn_field(insn, 6, 10); - uint32_t r2 = get_insn_field(insn, 11, 15); - if (MODE_IS_HPPA_20(ud->mode)) { - switch (opcode) { - case HPPA_OP_TYPE_CMPBT: - case HPPA_OP_TYPE_CMPBF: - case HPPA_OP_TYPE_CMPBDWT: - case HPPA_OP_TYPE_CMPBDWF: - case HPPA_OP_TYPE_ADDBT: - case HPPA_OP_TYPE_ADDBF: - case HPPA_OP_TYPE_MOVB: - CREATE_GR_REG(MI, r2); - CREATE_GR_REG(MI, r1); - MCOperand_CreateImm0(MI, extract_12(insn)); - break; - case HPPA_OP_TYPE_CMPIBT: - case HPPA_OP_TYPE_CMPIBF: - case HPPA_OP_TYPE_CMPIBDW: - case HPPA_OP_TYPE_ADDIBT: - case HPPA_OP_TYPE_ADDIBF: - case HPPA_OP_TYPE_MOVIB: - MCOperand_CreateImm0(MI, LowSignExtend64(r2, 5)); - CREATE_GR_REG(MI, r1); - MCOperand_CreateImm0(MI, extract_12(insn)); - break; - case HPPA_OP_TYPE_BBS: - case HPPA_OP_TYPE_BB: - CREATE_GR_REG(MI, r2); - if ((opcode & 1) == 1) { - MCOperand_CreateImm0(MI, r1); - } - else { - CREATE_CR_REG(MI, 11); - } - MCOperand_CreateImm0(MI, extract_12(insn)); - break; - default: - return false; - } - fill_action_and_branch_mods(insn, opcode, HPPA_EXT_REF(MI), ud->mode); - return true; - } - if ((opcode & 1) == 0 || opcode == HPPA_OP_TYPE_BB) { - CREATE_GR_REG(MI, r2); - } - else { - MCOperand_CreateImm0(MI, LowSignExtend64(r2, 5)); - } - if (opcode == HPPA_OP_TYPE_BB) { - MCOperand_CreateImm0(MI, r1); - } - else if (opcode != HPPA_OP_TYPE_BBS) { - CREATE_GR_REG(MI, r1); - } - MCOperand_CreateImm0(MI, extract_12(insn)); - fill_action_and_branch_mods(insn, opcode, HPPA_EXT_REF(MI), ud->mode); - return true; -} - -static void fill_load_insn_name(MCInst *MI, uint32_t opcode) { - switch (opcode) { - case HPPA_OP_TYPE_LDB: - MCInst_setOpcode(MI, HPPA_INS_LDB); - break; - case HPPA_OP_TYPE_LDH: - MCInst_setOpcode(MI, HPPA_INS_LDH); - break; - case HPPA_OP_TYPE_LDW: - MCInst_setOpcode(MI, HPPA_INS_LDW); - break; - case HPPA_OP_TYPE_LDWM: - if (MODE_IS_HPPA_20(MI->csh->mode)) { - MCInst_setOpcode(MI, HPPA_INS_LDW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_LDWM); - } - break; - default: - break; - } -} - -static void fill_store_insn_name(MCInst *MI, uint32_t opcode) { - switch (opcode) { - case HPPA_OP_TYPE_STB: - MCInst_setOpcode(MI, HPPA_INS_STB); - break; - case HPPA_OP_TYPE_STH: - MCInst_setOpcode(MI, HPPA_INS_STH); - break; - case HPPA_OP_TYPE_STW: - MCInst_setOpcode(MI, HPPA_INS_STW); - break; - case HPPA_OP_TYPE_STWM: - if (MODE_IS_HPPA_20(MI->csh->mode)) { - MCInst_setOpcode(MI, HPPA_INS_STW); - } - else { - MCInst_setOpcode(MI, HPPA_INS_STWM); - } - break; - default: - break; - } -} - -static bool decode_cmpclr(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t cond = (get_insn_bit(insn, 19) << 3) | get_insn_field(insn, 16, 18); - uint32_t d = get_insn_bit(insn, 20); - if (MODE_IS_HPPA_20(ud->mode)) { - MCInst_setOpcode(MI, HPPA_INS_CMPICLR); - } - else { - MCInst_setOpcode(MI, HPPA_INS_COMICLR); - } - - MCOperand_CreateImm0(MI, LowSignExtend64(get_insn_field(insn, 21, 31), 11)); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); - - if (d == 0) { - push_str_modifier(HPPA_EXT_REF(MI), compare_cond_names[cond]); - } - else { - push_str_modifier(HPPA_EXT_REF(MI), compare_cond_64_names[cond]); - } - return true; -} - -static bool decode_be(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t n = get_insn_bit(insn, 30); - bool mode = MODE_IS_HPPA_20(ud->mode); - if (opcode == HPPA_OP_TYPE_BLE) { - if (!mode) { - MCInst_setOpcode(MI, HPPA_INS_BLE); - } - else { - MCInst_setOpcode(MI, HPPA_INS_BE); - push_str_modifier(HPPA_EXT_REF(MI), "l"); - HPPA_EXT_REF(MI)->is_alternative = true; - } - } - else { - MCInst_setOpcode(MI, HPPA_INS_BE); - } - - MCOperand_CreateImm0(MI, extract_17(insn)); - CREATE_SR_REG(MI, extract_3(insn)); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - if (opcode == HPPA_OP_TYPE_BLE && mode) { - CREATE_SR_REG(MI, 0); - CREATE_GR_REG(MI, 31); - } - if (n == 1) { - push_str_modifier(HPPA_EXT_REF(MI), "n"); - } - return true; -} - -static bool decode_float_ldst(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t a = get_insn_bit(insn, 29); - uint32_t disp = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); - disp &= ~3; - - if (opcode == HPPA_OP_TYPE_FLDW) { - MCInst_setOpcode(MI, HPPA_INS_FLDW); - MCOperand_CreateImm0(MI, disp); - CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - CREATE_FPR_REG(MI, get_insn_field(insn, 11, 15)); - } - else { - MCInst_setOpcode(MI, HPPA_INS_FSTW); - CREATE_FPR_REG(MI, get_insn_field(insn, 11, 15)); - MCOperand_CreateImm0(MI, disp); - CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - } - - if (a == 0) { - push_str_modifier(HPPA_EXT_REF(MI), "ma"); - } - else { - push_str_modifier(HPPA_EXT_REF(MI), "mb"); - } - return true; -} - -static bool decode_fmpy(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - uint32_t rm1 = get_insn_field(insn, 6, 10); - uint32_t rm2 = get_insn_field(insn, 11, 15); - uint32_t ta = get_insn_field(insn, 16, 20); - uint32_t ra = get_insn_field(insn, 21, 25); - uint32_t tm = get_insn_field(insn, 27, 31); - uint32_t fmt = get_insn_field(insn, 26, 26); - - if (opcode == HPPA_OP_TYPE_FMPYADD) { - MCInst_setOpcode(MI, HPPA_INS_FMPYADD); - } - else { - MCInst_setOpcode(MI, HPPA_INS_FMPYSUB); - } - - if (fmt == 0) { - push_str_modifier(HPPA_EXT_REF(MI), "dbl"); - CREATE_FPR_REG(MI, rm1); - CREATE_FPR_REG(MI, rm2); - CREATE_FPR_REG(MI, tm); - CREATE_FPR_REG(MI, ra); - CREATE_FPR_REG(MI, ta); - } - else { - push_str_modifier(HPPA_EXT_REF(MI), "sgl"); - CREATE_SP_FPR_REG(MI, rm1); - CREATE_SP_FPR_REG(MI, rm2); - CREATE_SP_FPR_REG(MI, tm); - CREATE_SP_FPR_REG(MI, ra); - CREATE_SP_FPR_REG(MI, ta); - } - - return true; -} - -static bool decode_load(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - if (MODE_IS_HPPA_20(ud->mode)) { - uint32_t d = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); - if (opcode == HPPA_OP_TYPE_LDWM) { - if (d < 0) { - push_str_modifier(HPPA_EXT_REF(MI), "mb"); - } - else { - push_str_modifier(HPPA_EXT_REF(MI), "ma"); - } - } - MCOperand_CreateImm0(MI, d); - } - else { - MCOperand_CreateImm0(MI, extract_14(insn)); - } - CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); - return true; -} - -static bool decode_store(const cs_struct *ud, MCInst *MI, uint32_t insn) { - uint32_t opcode = insn >> 26; - CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); - if (MODE_IS_HPPA_20(ud->mode)) { - uint32_t d = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); - if (opcode == HPPA_OP_TYPE_STWM) { - if (d < 0) { - push_str_modifier(HPPA_EXT_REF(MI), "mb"); - } - else { - push_str_modifier(HPPA_EXT_REF(MI), "ma"); - } - } - MCOperand_CreateImm0(MI, d); - } - else { - MCOperand_CreateImm0(MI, extract_14(insn)); - } - CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); - CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); - return true; -} - -static bool getInstruction(const cs_struct *ud, const uint8_t *code, size_t code_len, - MCInst *MI) -{ - if (code_len < 4) - return false; - - MCInst_clear(MI); - - uint32_t full_insn = readBytes32(MI, code); - uint8_t opcode = full_insn >> 26; - - if (MODE_IS_HPPA_20(ud->mode)) { - switch (opcode) { - case HPPA_OP_TYPE_LOADDW: - case HPPA_OP_TYPE_STOREDW: - fill_ldst_dw_insn_name(MI, full_insn); - return decode_ldst_dw(ud, MI, full_insn); - case HPPA_OP_TYPE_LOADW: - case HPPA_OP_TYPE_STOREW: - fill_ldst_w_insn_name(MI, full_insn); - return decode_ldst_w(ud, MI, full_insn); - case HPPA_OP_TYPE_SHEXDEP2: - MCInst_setOpcode(MI, HPPA_INS_EXTRD); - return decode_shexdep2(MI, full_insn); - case HPPA_OP_TYPE_SHEXDEP3: - case HPPA_OP_TYPE_SHEXDEP4: - return decode_shexdep3(ud, MI, full_insn); - case HPPA_OP_TYPE_MULTMED: - fill_multmed_insn_name(MI, full_insn); - return decode_multmed(MI, full_insn); - case HPPA_OP_TYPE_FPFUSED: - fill_fpfused_insn_name(MI, full_insn); - return decode_fpfused(ud, MI, full_insn); - case HPPA_OP_TYPE_FLDW: - case HPPA_OP_TYPE_FSTW: - return decode_float_ldst(ud, MI, full_insn); - case HPPA_OP_TYPE_CMPBDWT: - case HPPA_OP_TYPE_CMPBDWF: - case HPPA_OP_TYPE_CMPIBDW: - fill_action_and_branch_insn_name(MI, opcode); - return fill_action_and_branch(ud, MI, full_insn); - default: - break; - } - } - - switch (opcode) { - case HPPA_OP_TYPE_SYSOP: - fill_sysop_insn_name(MI, full_insn); - return decode_sysop(ud, MI, full_insn); - case HPPA_OP_TYPE_MEMMGMT: - fill_memmgmt_insn_name(MI, full_insn); - return decode_memmgmt(ud, MI, full_insn); - case HPPA_OP_TYPE_ALU: - fill_alu_insn_name(MI, full_insn); - return decode_alu(ud, MI, full_insn); - case HPPA_OP_TYPE_IDXMEM: - fill_idxmem_insn_name(MI, full_insn); - return decode_idxmem(ud, MI, full_insn); - case HPPA_OP_TYPE_ADDIT: - case HPPA_OP_TYPE_ADDI: - case HPPA_OP_TYPE_SUBI: - fill_arith_imm_insn_name(MI, full_insn); - return decode_arith_imm(ud, MI, full_insn); - case HPPA_OP_TYPE_SHEXDEP0: - fill_shexdep0_insn_name(MI, full_insn); - return decode_shexdep0(ud, MI, full_insn); - case HPPA_OP_TYPE_SHEXDEP1: - fill_shexdep1_insn_name(MI, full_insn); - return decode_shexdep1(ud, MI, full_insn); - case HPPA_OP_TYPE_BRANCH: - fill_branch_insn_name(MI, full_insn); - return decode_branch(ud, MI, full_insn); - case HPPA_OP_TYPE_COPRW: - case HPPA_OP_TYPE_COPRDW: - fill_corpdw_insn_name(MI, full_insn); - return decode_corpdw(ud, MI, full_insn); - case HPPA_OP_TYPE_SPOP: - fill_spop_insn_name(MI, full_insn); - return decode_spop(ud, MI, full_insn); - case HPPA_OP_TYPE_COPR: - fill_copr_insn_name(MI, full_insn); - return decode_copr(ud, MI, full_insn); - case HPPA_OP_TYPE_FLOAT: - fill_float_insn_name(MI, full_insn); - return decode_float(ud, MI, full_insn); - case HPPA_OP_TYPE_DIAG: - MCInst_setOpcode(MI, HPPA_INS_DIAG); - MCOperand_CreateImm0(MI, get_insn_field(full_insn, 6, 31)); - return true; - case HPPA_OP_TYPE_FMPYADD: - case HPPA_OP_TYPE_FMPYSUB: - return decode_fmpy(ud, MI, full_insn); - case HPPA_OP_TYPE_LDIL: - case HPPA_OP_TYPE_ADDIL: - if (opcode == HPPA_OP_TYPE_LDIL) { - MCInst_setOpcode(MI, HPPA_INS_LDIL); - } - else { - MCInst_setOpcode(MI, HPPA_INS_ADDIL); - } - MCOperand_CreateImm0(MI, extract_21(full_insn)); - CREATE_GR_REG(MI, get_insn_field(full_insn, 6, 10)); - return true; - case HPPA_OP_TYPE_LDO: - MCInst_setOpcode(MI, HPPA_INS_LDO); - if (MODE_IS_HPPA_20(ud->mode)) { - MCOperand_CreateImm0(MI, extract_16(full_insn, MODE_IS_HPPA_20W(ud->mode))); - } - else { - MCOperand_CreateImm0(MI, extract_14(full_insn)); - } - CREATE_GR_REG(MI, get_insn_field(full_insn, 6, 10)); - CREATE_GR_REG(MI, get_insn_field(full_insn, 11, 15)); - return true; - case HPPA_OP_TYPE_LDB: - case HPPA_OP_TYPE_LDH: - case HPPA_OP_TYPE_LDW: - case HPPA_OP_TYPE_LDWM: - fill_load_insn_name(MI, opcode); - return decode_load(ud, MI, full_insn); - case HPPA_OP_TYPE_STB: - case HPPA_OP_TYPE_STH: - case HPPA_OP_TYPE_STW: - case HPPA_OP_TYPE_STWM: - fill_store_insn_name(MI, opcode); - return decode_store(ud, MI, full_insn); - case HPPA_OP_TYPE_CMPBT: - case HPPA_OP_TYPE_CMPBF: - case HPPA_OP_TYPE_ADDBT: - case HPPA_OP_TYPE_ADDBF: - case HPPA_OP_TYPE_MOVB: - case HPPA_OP_TYPE_CMPIBT: - case HPPA_OP_TYPE_CMPIBF: - case HPPA_OP_TYPE_ADDIBT: - case HPPA_OP_TYPE_ADDIBF: - case HPPA_OP_TYPE_MOVIB: - case HPPA_OP_TYPE_BBS: - case HPPA_OP_TYPE_BB: - fill_action_and_branch_insn_name(MI, opcode); - return fill_action_and_branch(ud, MI, full_insn); - case HPPA_OP_TYPE_CMPICLR: - return decode_cmpclr(ud, MI, full_insn); - case HPPA_OP_TYPE_BE: - case HPPA_OP_TYPE_BLE: - return decode_be(ud, MI, full_insn); - default: - return false; - } -} - -void init_details(MCInst *MI) { - cs_detail *detail = get_detail(MI); - if (detail) { - memset(detail, 0, offsetof(cs_detail, hppa) + sizeof(cs_hppa)); - } + fill_multmed_mods(insn, HPPA_EXT_REF(MI)); + return true; +} + +static void fill_branch_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 16, 18); + uint32_t bit_19 = get_insn_bit(insn, 19); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + if (insn == 0xe8004005) { + MCInst_setOpcode(MI, HPPA_INS_CLRBTS); + return; + } else if (insn == 0xe8004001) { + MCInst_setOpcode(MI, HPPA_INS_PUSHNOM); + return; + } + + switch (ext) { + case 0x00: + case 0x01: + case 0x04: + case 0x05: + MCInst_setOpcode(MI, HPPA_INS_B); + return; + case 0x06: + if (bit_19 == 0) { + MCInst_setOpcode(MI, HPPA_INS_BV); + } else { + MCInst_setOpcode(MI, HPPA_INS_BVE); + } + return; + case 0x07: + if (bit_19 == 1) { + MCInst_setOpcode(MI, HPPA_INS_BVE); + } + return; + case 0x02: + if (get_insn_field(insn, 19, 29) == 0 && + get_insn_bit(insn, 31) == 0) { + MCInst_setOpcode(MI, HPPA_INS_BLR); + return; + } + if (get_insn_field(insn, 19, 31) == 1) { + MCInst_setOpcode(MI, HPPA_INS_PUSHBTS); + return; + } + if (bit_19 == 0 && + get_insn_field(insn, 29, 31) == 0x5) { + MCInst_setOpcode(MI, HPPA_INS_POPBTS); + return; + } + return; + default: + return; + } + } + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_BL); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_GATE); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_BLR); + break; + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_BV); + break; + default: + break; + } +} + +static void fill_branch_mods(uint32_t insn, hppa_ext *hppa_ext, cs_mode mode) +{ + uint32_t ext = get_insn_field(insn, 16, 18); + uint32_t n = get_insn_bit(insn, 30); + uint32_t p = get_insn_bit(insn, 31); + if (MODE_IS_HPPA_20(mode)) { + switch (ext) { + case 0x00: + case 0x05: + push_str_modifier(hppa_ext, "l"); + // fallthrough + case 0x02: + break; + case 0x01: + push_str_modifier(hppa_ext, "gate"); + break; + case 0x04: + push_str_modifier(hppa_ext, "l"); + push_str_modifier(hppa_ext, "push"); + break; + case 0x06: + case 0x07: + if (get_insn_bit(insn, 19) == 0) { + break; + } + if (ext == 7) { + push_str_modifier(hppa_ext, "l"); + hppa_ext->is_alternative = true; + if (p == 1) { + push_str_modifier(hppa_ext, "push"); + } + } else { + if (p == 1) { + push_str_modifier(hppa_ext, "pop"); + } + } + break; + default: + return; + } + } + if (n == 1) { + push_str_modifier(hppa_ext, "n"); + } +} + +static bool decode_branch(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 16, 18); + uint32_t t = get_insn_field(insn, 6, 10); + uint32_t i = get_insn_field(insn, 20, 28); + uint32_t r = get_insn_field(insn, 11, 15); + uint32_t bit_19 = get_insn_bit(insn, 19); + if (MODE_IS_HPPA_20(ud->mode)) { + if (insn == 0xe8004005 || insn == 0xe8004001) { + return true; + } + + switch (ext) { + case 0x01: + case 0x00: + MCOperand_CreateImm0(MI, extract_17(insn)); + CREATE_GR_REG(MI, t); + break; + case 0x04: + case 0x05: + MCOperand_CreateImm0(MI, extract_22(insn)); + CREATE_GR_REG(MI, t); + break; + case 0x02: + if (bit_19 == 1) { + return false; + } + if (get_insn_field(insn, 20, 31) == 1 && t == 0) { + CREATE_GR_REG(MI, r); + break; + } + if (r == 0 && t == 0 && + get_insn_field(insn, 29, 31) == 0x5) { + MCOperand_CreateImm0(MI, i); + break; + } + if (get_insn_bit(insn, 31) == 0 && + get_insn_field(insn, 19, 29) == 0) { + CREATE_GR_REG(MI, r); + CREATE_GR_REG(MI, t); + break; + } + return false; + case 0x06: + if (bit_19 == 0) { + CREATE_GR_REG(MI, r); + } + CREATE_GR_REG(MI, t); + break; + case 0x07: + if (bit_19 == 1) { + CREATE_GR_REG(MI, t); + CREATE_GR_REG(MI, 2); + break; + } + default: + return false; + } + fill_branch_mods(insn, HPPA_EXT_REF(MI), ud->mode); + return true; + } else { + switch (ext) { + case 0x00: + case 0x01: + MCOperand_CreateImm0(MI, extract_17(insn)); + CREATE_GR_REG(MI, t); + break; + case 0x02: + case 0x06: + CREATE_GR_REG(MI, r); + CREATE_GR_REG(MI, t); + break; + default: + return false; + } + fill_branch_mods(insn, HPPA_EXT_REF(MI), ud->mode); + return true; + } +} + +static void fill_corpdw_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = (get_insn_field(insn, 19, 19) << 1) | + get_insn_field(insn, 22, 22); + uint32_t opcode = insn >> 26; + uint32_t uid = get_insn_field(insn, 23, 25); + if (MODE_IS_HPPA_20(MI->csh->mode)) { + if (opcode == 0x09) { + switch (ext) { + case 0x00: + case 0x02: + if (uid <= 0x01) { + MCInst_setOpcode(MI, HPPA_INS_FLDW); + } else { + MCInst_setOpcode(MI, HPPA_INS_CLDW); + } + return; + case 0x01: + case 0x03: + if (uid <= 0x01) { + MCInst_setOpcode(MI, HPPA_INS_FSTW); + } else { + MCInst_setOpcode(MI, HPPA_INS_CSTW); + } + return; + default: + break; + } + } else { + switch (ext) { + case 0x00: + case 0x02: + if (uid == 0x00) { + MCInst_setOpcode(MI, HPPA_INS_FLDD); + } else { + MCInst_setOpcode(MI, HPPA_INS_CLDD); + } + return; + case 0x01: + case 0x03: + if (uid == 0x00) { + MCInst_setOpcode(MI, HPPA_INS_FSTD); + } else { + MCInst_setOpcode(MI, HPPA_INS_CSTD); + } + return; + default: + break; + } + } + } + if (opcode == 0x09) { + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_CLDWX); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_CSTWX); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_CLDWS); + break; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_CSTWS); + break; + default: + break; + } + } else { + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_CLDDX); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_CSTDX); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_CLDDS); + break; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_CSTDS); + break; + default: + break; + } + } +} + +static inline bool coprdw_has_uid_mod(uint32_t opcode, uint32_t uid) +{ + return !((opcode == HPPA_OP_TYPE_COPRW && uid <= 0x01) || + (opcode == HPPA_OP_TYPE_COPRDW && uid == 0x00)); +} + +static void fill_corpdw_mods(uint32_t insn, uint32_t im, hppa_ext *hppa_ext, + cs_mode mode) +{ + uint32_t uid = get_insn_field(insn, 23, 25); + uint32_t cmplt = (get_insn_bit(insn, 18) << 1) | get_insn_bit(insn, 26); + uint32_t cc = get_insn_field(insn, 20, 21); + uint32_t ext = (get_insn_bit(insn, 19) << 1) | get_insn_bit(insn, 22); + uint32_t opcode = insn >> 26; + + if (coprdw_has_uid_mod(opcode, uid)) { + push_int_modifier(hppa_ext, uid); + } + if (CMPLT_HAS_MODIFY_BIT(cmplt)) { + hppa_ext->b_writeble = true; + } + + switch (ext) { + case 0x00: + case 0x01: + push_str_modifier(hppa_ext, index_compl_names[cmplt]); + break; + case 0x02: + case 0x03: + if (MODE_IS_HPPA_20(mode)) { + if (cmplt == 1 && im == 0) { + push_str_modifier(hppa_ext, "o"); + break; + } + } + push_str_modifier(hppa_ext, short_ldst_compl_names[cmplt]); + break; + default: + break; + } + if ((ext & 1) == 1 && cc == 1) { + push_str_modifier(hppa_ext, "bc"); + } + if (cc == 2) { + push_str_modifier(hppa_ext, "sl"); + } +} + +static bool decode_corpdw(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = (get_insn_bit(insn, 19) << 1) | get_insn_bit(insn, 22); + uint32_t x = get_insn_field(insn, 11, 15); + uint32_t b = get_insn_field(insn, 6, 10); + uint32_t s = get_insn_field(insn, 16, 17); + uint32_t t = get_insn_field(insn, 27, 31); + uint32_t opcode = MCInst_getOpcode(MI); + switch (ext) { + case 0x00: + case 0x02: + if (ext == 0x02) { + x = LowSignExtend64(x, 5); + MCOperand_CreateImm0(MI, x); + } else { + CREATE_GR_REG(MI, x); + } + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, b); + if (opcode == HPPA_INS_FLDW || opcode == HPPA_INS_FLDD) { + CREATE_FPR_REG(MI, t); + } else { + CREATE_GR_REG(MI, t); + } + break; + case 0x01: + case 0x03: + if (opcode == HPPA_INS_FSTW || opcode == HPPA_INS_FSTD) { + CREATE_FPR_REG(MI, t); + } else { + CREATE_GR_REG(MI, t); + } + if (ext == 0x03) { + x = LowSignExtend64(x, 5); + MCOperand_CreateImm0(MI, x); + } else { + CREATE_GR_REG(MI, x); + } + CREATE_SR_REG(MI, s); + CREATE_GR_REG(MI, b); + break; + default: + break; + } + fill_corpdw_mods(insn, x, HPPA_EXT_REF(MI), ud->mode); + return true; +} + +static void fill_spop_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 21, 22); + switch (ext) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_SPOP0); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_SPOP1); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_SPOP2); + break; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_SPOP3); + break; + default: + break; + } +} + +static void fill_spop_mods(uint32_t insn, uint32_t ext, hppa_ext *hppa_ext) +{ + uint32_t sfu = get_insn_field(insn, 23, 25); + uint32_t n = get_insn_field(insn, 26, 26); + uint32_t sop; + + push_int_modifier(hppa_ext, sfu); + switch (ext) { + case 0x00: + sop = (get_insn_field(insn, 6, 20) << 5) | + get_insn_field(insn, 27, 31); + break; + case 0x01: + sop = get_insn_field(insn, 6, 20); + break; + case 0x02: + sop = (get_insn_field(insn, 11, 20) << 5) | + get_insn_field(insn, 27, 31); + break; + case 0x03: + sop = (get_insn_field(insn, 16, 20) << 5) | + get_insn_field(insn, 27, 31); + break; + default: + break; + } + push_int_modifier(hppa_ext, sop); + if (n == 1) { + push_str_modifier(hppa_ext, "n"); + } +} + +static bool decode_spop(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t ext = get_insn_field(insn, 21, 22); + uint32_t r2 = get_insn_field(insn, 11, 15); + uint32_t r1 = get_insn_field(insn, 6, 10); + uint32_t t = get_insn_field(insn, 27, 31); + switch (ext) { + case 0x00: + break; + case 0x01: + CREATE_GR_REG(MI, t); + break; + case 0x02: + CREATE_GR_REG(MI, r1); + break; + case 0x03: + CREATE_GR_REG(MI, r2); + CREATE_GR_REG(MI, r1); + break; + default: + return false; + } + fill_spop_mods(insn, ext, HPPA_EXT_REF(MI)); + return true; +} + +static void fill_copr_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t class = get_insn_field(insn, 21, 22); + uint32_t uid = get_insn_field(insn, 23, 25); + uint32_t subop; + if (MODE_IS_HPPA_20(MI->csh->mode)) { + if (uid == 0) { + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_FID); + return; + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_FNEG); + return; + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_FNEGABS); + return; + default: + break; + } + } else if (class == 1) { + subop = get_insn_field(insn, 14, 16); + if (subop != 4) { + MCInst_setOpcode(MI, HPPA_INS_FCNV); + return; + } + } else if (class == 2) { + if (get_insn_bit(insn, 26) == 0) { + MCInst_setOpcode(MI, HPPA_INS_FCMP); + } else { + MCInst_setOpcode(MI, HPPA_INS_FTEST); + } + return; + } + } + } + + if (uid == 0) { + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_COPR); + return; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_FCPY); + return; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_FABS); + return; + case 0x04: + MCInst_setOpcode(MI, HPPA_INS_FSQRT); + return; + case 0x05: + MCInst_setOpcode(MI, HPPA_INS_FRND); + return; + default: + break; + } + } else if (class == 1) { + subop = get_insn_field(insn, 15, 16); + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_FCNVFF); + return; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_FCNVXF); + return; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_FCNVFX); + return; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_FCNVFXT); + return; + default: + break; + } + } else if (class == 2) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_FCMP); + return; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_FTEST); + return; + default: + break; + } + } else if (class == 3) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_FADD); + return; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_FSUB); + return; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_FMPY); + return; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_FDIV); + return; + default: + break; + } + } + } else if (uid == 2) { + subop = get_insn_field(insn, 18, 22); + switch (subop) { + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_PMDIS); + return; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_PMENB); + return; + default: + break; + } + } + MCInst_setOpcode(MI, HPPA_INS_COPR); +} + +static void fill_copr_mods(uint32_t insn, uint32_t uid, uint32_t class, + hppa_ext *hppa_ext, uint32_t subop, cs_mode mode) +{ + uint32_t n = get_insn_field(insn, 26, 26); + uint32_t sf = get_insn_field(insn, 19, 20); + uint32_t df = get_insn_field(insn, 17, 18); + if (MODE_IS_HPPA_20(mode)) { + if (uid == 0) { + if (class == 0) { + switch (subop) { + case 0x00: + return; + default: + break; + } + } else if (class == 1) { + switch (subop) { + case 0x00: + push_str_modifier( + hppa_ext, + float_format_names[sf]); + push_str_modifier( + hppa_ext, + float_format_names[df]); + return; + case 0x01: + push_str_modifier(hppa_ext, + fcnv_fixed_names[sf]); + push_str_modifier( + hppa_ext, + float_format_names[df]); + return; + case 0x03: + push_str_modifier(hppa_ext, "t"); + // fallthrough + case 0x02: + push_str_modifier( + hppa_ext, + float_format_names[sf]); + push_str_modifier(hppa_ext, + fcnv_fixed_names[df]); + return; + case 0x05: + push_str_modifier( + hppa_ext, + fcnv_ufixed_names[sf]); + push_str_modifier( + hppa_ext, + float_format_names[df]); + return; + case 0x07: + push_str_modifier(hppa_ext, "t"); + // fallthrough + case 0x06: + push_str_modifier( + hppa_ext, + float_format_names[sf]); + push_str_modifier( + hppa_ext, + fcnv_ufixed_names[df]); + return; + default: + break; + } + } + } + } + + if (uid == 0) { + if (class == 0) { + switch (subop) { + case 0x00: + push_int_modifier(hppa_ext, 0); + push_int_modifier(hppa_ext, 0); + if (n == 1) { + push_str_modifier(hppa_ext, "n"); + } + break; + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + push_str_modifier(hppa_ext, + float_format_names[sf]); + break; + default: + break; + } + } else if (class == 1) { + push_str_modifier(hppa_ext, float_format_names[sf]); + push_str_modifier(hppa_ext, float_format_names[df]); + } else if (class == 2) { + uint32_t cond = get_insn_field(insn, 27, 31); + if (n == 1 && subop == 1) { + push_str_modifier(hppa_ext, + float_cond_names[cond]); + } + if (n == 0) { + push_str_modifier(hppa_ext, + float_format_names[sf]); + push_str_modifier(hppa_ext, + float_comp_names[cond]); + } + } else if (class == 3) { + push_str_modifier(hppa_ext, float_format_names[sf]); + } + } else if (uid == 2) { + if (n == 1) { + push_str_modifier(hppa_ext, "n"); + } + } else { + uint32_t uid = get_insn_field(insn, 23, 25); + uint32_t sop = (get_insn_field(insn, 6, 22) << 5) | + get_insn_field(insn, 27, 31); + push_int_modifier(hppa_ext, uid); + push_int_modifier(hppa_ext, sop); + if (n == 1) { + push_str_modifier(hppa_ext, "n"); + } + } +} + +static bool decode_copr(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t class = get_insn_field(insn, 21, 22); + uint32_t uid = get_insn_field(insn, 23, 25); + uint32_t subop; + uint32_t r1 = get_insn_field(insn, 6, 10); + uint32_t r2 = get_insn_field(insn, 11, 15); + uint32_t t = get_insn_field(insn, 27, 31); + if (MODE_IS_HPPA_20(ud->mode)) { + if (uid == 0) { + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + if (subop == 0x01) { + return false; + } + if (subop >= 0x02) { + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, t); + } + } else if (class == 1) { + subop = get_insn_field(insn, 14, 16); + if (subop == 0x04) { + return false; + } + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, t); + } else if (class == 2) { + uint32_t n = get_insn_bit(insn, 26); + subop = get_insn_field(insn, 16, 18); + if (n == 0) { + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, r2); + if (subop != 0) { + MCOperand_CreateImm0(MI, + subop - 1); + HPPA_EXT_REF(MI) + ->is_alternative = true; + } + } else { + if (subop != 1) { + MCOperand_CreateImm0( + MI, (subop ^ 1) - 1); + HPPA_EXT_REF(MI) + ->is_alternative = true; + } + } + } else if (class == 3) { + subop = get_insn_field(insn, 16, 18); + if (subop >= 4) { + return false; + } + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, r2); + CREATE_FPR_REG(MI, t); + } + fill_copr_mods(insn, uid, class, HPPA_EXT_REF(MI), + subop, ud->mode); + return true; + } + } + if (uid == 0) { + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x02: + case 0x03: + case 0x04: + case 0x05: + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, t); + // fallthough + case 0x00: + break; + default: + return false; + } + } else if (class == 1) { + subop = get_insn_field(insn, 15, 16); + switch (subop) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, t); + break; + default: + return false; + } + } else if (class == 2) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, r2); + // fallthough + case 0x01: + break; + default: + return false; + } + } else if (class == 3) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + CREATE_FPR_REG(MI, r1); + CREATE_FPR_REG(MI, r2); + CREATE_FPR_REG(MI, t); + break; + default: + return false; + } + } + fill_copr_mods(insn, uid, class, HPPA_EXT_REF(MI), subop, + ud->mode); + return true; + } else if (uid == 2) { + subop = get_insn_field(insn, 18, 22); + switch (subop) { + case 0x01: + case 0x03: + break; + default: + return false; + } + } + fill_copr_mods(insn, uid, class, HPPA_EXT_REF(MI), -1, ud->mode); + return true; +} + +static void fill_float_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t class = get_insn_field(insn, 21, 22); + uint32_t subop; + if (MODE_IS_HPPA_20(MI->csh->mode)) { + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x06: + MCInst_setOpcode(MI, HPPA_INS_FNEG); + return; + case 0x07: + MCInst_setOpcode(MI, HPPA_INS_FNEGABS); + return; + default: + break; + } + } else if (class == 1) { + subop = get_insn_field(insn, 14, 16); + if (subop == 0x04) { + return; + } + MCInst_setOpcode(MI, HPPA_INS_FCNV); + return; + } else if (class == 2) { + MCInst_setOpcode(MI, HPPA_INS_FCMP); + return; + } + } + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_FCPY); + break; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_FABS); + break; + case 0x04: + MCInst_setOpcode(MI, HPPA_INS_FSQRT); + break; + case 0x05: + MCInst_setOpcode(MI, HPPA_INS_FRND); + break; + default: + break; + } + } else if (class == 1) { + subop = get_insn_field(insn, 15, 16); + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_FCNVFF); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_FCNVXF); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_FCNVFX); + break; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_FCNVFXT); + break; + default: + break; + } + } else if (class == 2) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_FCMP); + break; + } + } else if (class == 3) { + subop = get_insn_field(insn, 16, 18); + uint32_t fixed = get_insn_field(insn, 23, 23); + if (fixed == 0) { + switch (subop) { + case 0x00: + MCInst_setOpcode(MI, HPPA_INS_FADD); + break; + case 0x01: + MCInst_setOpcode(MI, HPPA_INS_FSUB); + break; + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_FMPY); + break; + case 0x03: + MCInst_setOpcode(MI, HPPA_INS_FDIV); + break; + default: + break; + } + } else { + switch (subop) { + case 0x02: + MCInst_setOpcode(MI, HPPA_INS_XMPYU); + break; + default: + break; + } + } + } +} + +static void fill_float_mods(uint32_t insn, uint32_t class, hppa_ext *hppa_ext, + uint32_t subop, cs_mode mode) +{ + uint32_t sf = get_insn_field(insn, 19, 20); + uint32_t df = get_insn_field(insn, 17, 18); + + if (MODE_IS_HPPA_20(mode)) { + if (class == 1) { + switch (subop) { + case 0x00: + push_str_modifier(hppa_ext, + float_format_names[sf]); + push_str_modifier(hppa_ext, + float_format_names[df]); + return; + case 0x01: + push_str_modifier(hppa_ext, + fcnv_fixed_names[sf]); + push_str_modifier(hppa_ext, + float_format_names[df]); + return; + case 0x03: + push_str_modifier(hppa_ext, "t"); + // fallthough + case 0x02: + push_str_modifier(hppa_ext, + float_format_names[sf]); + push_str_modifier(hppa_ext, + fcnv_fixed_names[df]); + return; + case 0x05: + push_str_modifier(hppa_ext, + fcnv_ufixed_names[sf]); + push_str_modifier(hppa_ext, + float_format_names[df]); + return; + case 0x07: + push_str_modifier(hppa_ext, "t"); + // fallthrough + case 0x06: + push_str_modifier(hppa_ext, + float_format_names[sf]); + push_str_modifier(hppa_ext, + fcnv_ufixed_names[df]); + return; + default: + return; + } + } + } + + if (class == 0) { + uint32_t fmt = get_insn_field(insn, 19, 20); + push_str_modifier(hppa_ext, float_format_names[fmt]); + } else if (class == 1) { + push_str_modifier(hppa_ext, float_format_names[sf]); + push_str_modifier(hppa_ext, float_format_names[df]); + } else if (class == 2) { + uint32_t fmt = get_insn_field(insn, 20, 20); + uint32_t cond = get_insn_field(insn, 27, 31); + push_str_modifier(hppa_ext, float_format_names[fmt]); + push_str_modifier(hppa_ext, float_cond_names[cond]); + } else if (class == 3) { + if (get_insn_field(insn, 23, 23) == 0) { + uint32_t fmt = get_insn_field(insn, 20, 20); + push_str_modifier(hppa_ext, float_format_names[fmt]); + } + } +} + +static bool decode_float(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t class = get_insn_field(insn, 21, 22); + uint32_t subop; + uint32_t r1 = get_insn_field(insn, 6, 10); + uint32_t r1_fpe = get_insn_bit(insn, 24); + uint32_t r2 = get_insn_field(insn, 11, 15); + uint32_t r2_fpe = get_insn_bit(insn, 19); + uint32_t t = get_insn_field(insn, 27, 31); + uint32_t t_fpe = get_insn_bit(insn, 25); + if (MODE_IS_HPPA_20(ud->mode)) { + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + if (subop >= 0x02) { + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, t, t_fpe); + fill_float_mods(insn, class, HPPA_EXT_REF(MI), + subop, ud->mode); + return true; + } + } else if (class == 1) { + subop = get_insn_field(insn, 14, 16); + if (subop == 0x04) { + return false; + } + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, t, t_fpe); + fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, + ud->mode); + return true; + } else if (class == 2) { + subop = get_insn_field(insn, 16, 18); + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, r2, r2_fpe); + if (subop != 0) { + MCOperand_CreateImm0(MI, subop - 1); + } + fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, + ud->mode); + return true; + } + } + if (class == 0) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x02: + case 0x03: + case 0x04: + case 0x05: + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, t, t_fpe); + fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, + ud->mode); + return true; + default: + return false; + } + } else if (class == 1) { + subop = get_insn_field(insn, 15, 16); + if (subop <= 0x03) { + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, t, t_fpe); + fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, + ud->mode); + return true; + } + } else if (class == 2) { + subop = get_insn_field(insn, 16, 18); + switch (subop) { + case 0x00: + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, r2, r2_fpe); + fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, + ud->mode); + return true; + default: + return false; + } + } else if (class == 3) { + subop = get_insn_field(insn, 16, 18); + uint32_t fixed = get_insn_field(insn, 23, 23); + if ((fixed == 0 && subop <= 0x03) || + (fixed == 1 && subop == 0x02)) { + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, r2, r2_fpe); + create_float_reg_spec(MI, t, t_fpe); + fill_float_mods(insn, class, HPPA_EXT_REF(MI), subop, + ud->mode); + return true; + } + return false; + } + return false; +} + +static void fill_fpfused_insn_name(MCInst *MI, uint32_t insn) +{ + uint32_t subop = get_insn_bit(insn, 26); + if (subop == 0x00) { + MCInst_setOpcode(MI, HPPA_INS_FMPYFADD); + } else { + MCInst_setOpcode(MI, HPPA_INS_FMPYNFADD); + } +} + +static void fill_fpfused_mods(uint32_t insn, hppa_ext *hppa_ext) +{ + uint32_t fmt = get_insn_bit(insn, 20); + push_str_modifier(hppa_ext, float_format_names[fmt]); +} + +static bool decode_fpfused(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t r1 = get_insn_field(insn, 6, 10); + uint32_t r1_fpe = get_insn_bit(insn, 24); + uint32_t r2 = get_insn_field(insn, 11, 15); + uint32_t r2_fpe = get_insn_bit(insn, 19); + uint32_t ra = (get_insn_field(insn, 16, 18) << 2) | + get_insn_field(insn, 21, 22); + uint32_t ra_fpe = get_insn_bit(insn, 23); + uint32_t t = get_insn_field(insn, 27, 31); + uint32_t t_fpe = get_insn_bit(insn, 25); + create_float_reg_spec(MI, r1, r1_fpe); + create_float_reg_spec(MI, r2, r2_fpe); + create_float_reg_spec(MI, ra, ra_fpe); + create_float_reg_spec(MI, t, t_fpe); + fill_fpfused_mods(insn, HPPA_EXT_REF(MI)); + return true; +} + +static void fill_action_and_branch_insn_name(MCInst *MI, uint32_t opcode) +{ + if (MODE_IS_HPPA_20(MI->csh->mode)) { + switch (opcode) { + case HPPA_OP_TYPE_CMPBT: + case HPPA_OP_TYPE_CMPBF: + case HPPA_OP_TYPE_CMPBDWT: + case HPPA_OP_TYPE_CMPBDWF: + MCInst_setOpcode(MI, HPPA_INS_CMPB); + return; + case HPPA_OP_TYPE_CMPIBT: + case HPPA_OP_TYPE_CMPIBF: + case HPPA_OP_TYPE_CMPIBDW: + MCInst_setOpcode(MI, HPPA_INS_CMPIB); + return; + case HPPA_OP_TYPE_ADDBT: + case HPPA_OP_TYPE_ADDBF: + MCInst_setOpcode(MI, HPPA_INS_ADDB); + return; + case HPPA_OP_TYPE_ADDIBT: + case HPPA_OP_TYPE_ADDIBF: + MCInst_setOpcode(MI, HPPA_INS_ADDIB); + return; + case HPPA_OP_TYPE_BBS: + MCInst_setOpcode(MI, HPPA_INS_BB); + return; + default: + break; + } + } + switch (opcode) { + case HPPA_OP_TYPE_CMPBT: + MCInst_setOpcode(MI, HPPA_INS_COMBT); + break; + case HPPA_OP_TYPE_CMPBF: + MCInst_setOpcode(MI, HPPA_INS_COMBF); + break; + case HPPA_OP_TYPE_CMPIBT: + MCInst_setOpcode(MI, HPPA_INS_COMIBT); + break; + case HPPA_OP_TYPE_CMPIBF: + MCInst_setOpcode(MI, HPPA_INS_COMIBF); + break; + case HPPA_OP_TYPE_ADDBT: + MCInst_setOpcode(MI, HPPA_INS_ADDBT); + break; + case HPPA_OP_TYPE_ADDBF: + MCInst_setOpcode(MI, HPPA_INS_ADDBF); + break; + case HPPA_OP_TYPE_ADDIBT: + MCInst_setOpcode(MI, HPPA_INS_ADDIBT); + break; + case HPPA_OP_TYPE_ADDIBF: + MCInst_setOpcode(MI, HPPA_INS_ADDIBF); + break; + case HPPA_OP_TYPE_MOVB: + MCInst_setOpcode(MI, HPPA_INS_MOVB); + break; + case HPPA_OP_TYPE_MOVIB: + MCInst_setOpcode(MI, HPPA_INS_MOVIB); + break; + case HPPA_OP_TYPE_BBS: + MCInst_setOpcode(MI, HPPA_INS_BVB); + break; + case HPPA_OP_TYPE_BB: + MCInst_setOpcode(MI, HPPA_INS_BB); + break; + default: + break; + } +} + +static void fill_action_and_branch_mods(uint32_t insn, uint32_t opcode, + hppa_ext *hppa_ext, cs_mode mode) +{ + uint32_t cond = get_insn_field(insn, 16, 18); + uint32_t n = get_insn_bit(insn, 30); + uint32_t d = get_insn_bit(insn, 18); + + if (MODE_IS_HPPA_20(mode)) { + switch (opcode) { + case HPPA_OP_TYPE_CMPBT: + case HPPA_OP_TYPE_CMPIBT: + push_str_modifier(hppa_ext, compare_cond_names[cond]); + break; + case HPPA_OP_TYPE_CMPBF: + case HPPA_OP_TYPE_CMPIBF: + push_str_modifier(hppa_ext, + compare_cond_names[cond + 8]); + break; + case HPPA_OP_TYPE_CMPBDWT: + push_str_modifier(hppa_ext, + compare_cond_64_names[cond]); + break; + case HPPA_OP_TYPE_CMPBDWF: + push_str_modifier(hppa_ext, + compare_cond_64_names[cond + 8]); + break; + case HPPA_OP_TYPE_CMPIBDW: + push_str_modifier(hppa_ext, cmpib_cond_64_names[cond]); + break; + case HPPA_OP_TYPE_ADDBT: + case HPPA_OP_TYPE_ADDIBT: + if (MODE_IS_HPPA_20W(mode)) { + push_str_modifier(hppa_ext, + wide_add_cond_names[cond]); + } else { + push_str_modifier(hppa_ext, + add_cond_names[cond]); + } + break; + case HPPA_OP_TYPE_ADDBF: + case HPPA_OP_TYPE_ADDIBF: + if (MODE_IS_HPPA_20W(mode)) { + push_str_modifier( + hppa_ext, + wide_add_cond_names[cond + 8]); + } else { + push_str_modifier(hppa_ext, + add_cond_names[cond + 8]); + } + break; + case HPPA_OP_TYPE_BBS: + case HPPA_OP_TYPE_BB: + if (d == 0) { + push_str_modifier(hppa_ext, + shift_cond_names[cond]); + } else { + push_str_modifier(hppa_ext, + shift_cond_64_names[cond]); + } + break; + case HPPA_OP_TYPE_MOVB: + case HPPA_OP_TYPE_MOVIB: + push_str_modifier(hppa_ext, shift_cond_names[cond]); + break; + default: + break; + } + if (n == 1) { + push_str_modifier(hppa_ext, "n"); + } + return; + } + switch (opcode) { + case HPPA_OP_TYPE_CMPBT: + case HPPA_OP_TYPE_CMPBF: + case HPPA_OP_TYPE_CMPIBT: + case HPPA_OP_TYPE_CMPIBF: + push_str_modifier(hppa_ext, compare_cond_names[cond]); + break; + case HPPA_OP_TYPE_ADDBT: + case HPPA_OP_TYPE_ADDBF: + case HPPA_OP_TYPE_ADDIBT: + case HPPA_OP_TYPE_ADDIBF: + push_str_modifier(hppa_ext, add_cond_names[cond]); + break; + case HPPA_OP_TYPE_MOVB: + case HPPA_OP_TYPE_MOVIB: + case HPPA_OP_TYPE_BBS: + case HPPA_OP_TYPE_BB: + push_str_modifier(hppa_ext, shift_cond_names[cond]); + break; + default: + break; + } + if (n == 1) { + push_str_modifier(hppa_ext, "n"); + } +} + +static bool fill_action_and_branch(const cs_struct *ud, MCInst *MI, + uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t r1 = get_insn_field(insn, 6, 10); + uint32_t r2 = get_insn_field(insn, 11, 15); + if (MODE_IS_HPPA_20(ud->mode)) { + switch (opcode) { + case HPPA_OP_TYPE_CMPBT: + case HPPA_OP_TYPE_CMPBF: + case HPPA_OP_TYPE_CMPBDWT: + case HPPA_OP_TYPE_CMPBDWF: + case HPPA_OP_TYPE_ADDBT: + case HPPA_OP_TYPE_ADDBF: + case HPPA_OP_TYPE_MOVB: + CREATE_GR_REG(MI, r2); + CREATE_GR_REG(MI, r1); + MCOperand_CreateImm0(MI, extract_12(insn)); + break; + case HPPA_OP_TYPE_CMPIBT: + case HPPA_OP_TYPE_CMPIBF: + case HPPA_OP_TYPE_CMPIBDW: + case HPPA_OP_TYPE_ADDIBT: + case HPPA_OP_TYPE_ADDIBF: + case HPPA_OP_TYPE_MOVIB: + MCOperand_CreateImm0(MI, LowSignExtend64(r2, 5)); + CREATE_GR_REG(MI, r1); + MCOperand_CreateImm0(MI, extract_12(insn)); + break; + case HPPA_OP_TYPE_BBS: + case HPPA_OP_TYPE_BB: + CREATE_GR_REG(MI, r2); + if ((opcode & 1) == 1) { + MCOperand_CreateImm0(MI, r1); + } else { + CREATE_CR_REG(MI, 11); + } + MCOperand_CreateImm0(MI, extract_12(insn)); + break; + default: + return false; + } + fill_action_and_branch_mods(insn, opcode, HPPA_EXT_REF(MI), + ud->mode); + return true; + } + if ((opcode & 1) == 0 || opcode == HPPA_OP_TYPE_BB) { + CREATE_GR_REG(MI, r2); + } else { + MCOperand_CreateImm0(MI, LowSignExtend64(r2, 5)); + } + if (opcode == HPPA_OP_TYPE_BB) { + MCOperand_CreateImm0(MI, r1); + } else if (opcode != HPPA_OP_TYPE_BBS) { + CREATE_GR_REG(MI, r1); + } + MCOperand_CreateImm0(MI, extract_12(insn)); + fill_action_and_branch_mods(insn, opcode, HPPA_EXT_REF(MI), ud->mode); + return true; +} + +static void fill_load_insn_name(MCInst *MI, uint32_t opcode) +{ + switch (opcode) { + case HPPA_OP_TYPE_LDB: + MCInst_setOpcode(MI, HPPA_INS_LDB); + break; + case HPPA_OP_TYPE_LDH: + MCInst_setOpcode(MI, HPPA_INS_LDH); + break; + case HPPA_OP_TYPE_LDW: + MCInst_setOpcode(MI, HPPA_INS_LDW); + break; + case HPPA_OP_TYPE_LDWM: + if (MODE_IS_HPPA_20(MI->csh->mode)) { + MCInst_setOpcode(MI, HPPA_INS_LDW); + } else { + MCInst_setOpcode(MI, HPPA_INS_LDWM); + } + break; + default: + break; + } +} + +static void fill_store_insn_name(MCInst *MI, uint32_t opcode) +{ + switch (opcode) { + case HPPA_OP_TYPE_STB: + MCInst_setOpcode(MI, HPPA_INS_STB); + break; + case HPPA_OP_TYPE_STH: + MCInst_setOpcode(MI, HPPA_INS_STH); + break; + case HPPA_OP_TYPE_STW: + MCInst_setOpcode(MI, HPPA_INS_STW); + break; + case HPPA_OP_TYPE_STWM: + if (MODE_IS_HPPA_20(MI->csh->mode)) { + MCInst_setOpcode(MI, HPPA_INS_STW); + } else { + MCInst_setOpcode(MI, HPPA_INS_STWM); + } + break; + default: + break; + } +} + +static bool decode_cmpclr(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t cond = (get_insn_bit(insn, 19) << 3) | + get_insn_field(insn, 16, 18); + uint32_t d = get_insn_bit(insn, 20); + if (MODE_IS_HPPA_20(ud->mode)) { + MCInst_setOpcode(MI, HPPA_INS_CMPICLR); + } else { + MCInst_setOpcode(MI, HPPA_INS_COMICLR); + } + + MCOperand_CreateImm0(MI, + LowSignExtend64(get_insn_field(insn, 21, 31), 11)); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); + + if (d == 0) { + push_str_modifier(HPPA_EXT_REF(MI), compare_cond_names[cond]); + } else { + push_str_modifier(HPPA_EXT_REF(MI), + compare_cond_64_names[cond]); + } + return true; +} + +static bool decode_be(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t n = get_insn_bit(insn, 30); + bool mode = MODE_IS_HPPA_20(ud->mode); + if (opcode == HPPA_OP_TYPE_BLE) { + if (!mode) { + MCInst_setOpcode(MI, HPPA_INS_BLE); + } else { + MCInst_setOpcode(MI, HPPA_INS_BE); + push_str_modifier(HPPA_EXT_REF(MI), "l"); + HPPA_EXT_REF(MI)->is_alternative = true; + } + } else { + MCInst_setOpcode(MI, HPPA_INS_BE); + } + + MCOperand_CreateImm0(MI, extract_17(insn)); + CREATE_SR_REG(MI, extract_3(insn)); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + if (opcode == HPPA_OP_TYPE_BLE && mode) { + CREATE_SR_REG(MI, 0); + CREATE_GR_REG(MI, 31); + } + if (n == 1) { + push_str_modifier(HPPA_EXT_REF(MI), "n"); + } + return true; +} + +static bool decode_float_ldst(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t a = get_insn_bit(insn, 29); + uint32_t disp = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); + disp &= ~3; + + if (opcode == HPPA_OP_TYPE_FLDW) { + MCInst_setOpcode(MI, HPPA_INS_FLDW); + MCOperand_CreateImm0(MI, disp); + CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + CREATE_FPR_REG(MI, get_insn_field(insn, 11, 15)); + } else { + MCInst_setOpcode(MI, HPPA_INS_FSTW); + CREATE_FPR_REG(MI, get_insn_field(insn, 11, 15)); + MCOperand_CreateImm0(MI, disp); + CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + } + + if (a == 0) { + push_str_modifier(HPPA_EXT_REF(MI), "ma"); + } else { + push_str_modifier(HPPA_EXT_REF(MI), "mb"); + } + return true; +} + +static bool decode_fmpy(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + uint32_t rm1 = get_insn_field(insn, 6, 10); + uint32_t rm2 = get_insn_field(insn, 11, 15); + uint32_t ta = get_insn_field(insn, 16, 20); + uint32_t ra = get_insn_field(insn, 21, 25); + uint32_t tm = get_insn_field(insn, 27, 31); + uint32_t fmt = get_insn_field(insn, 26, 26); + + if (opcode == HPPA_OP_TYPE_FMPYADD) { + MCInst_setOpcode(MI, HPPA_INS_FMPYADD); + } else { + MCInst_setOpcode(MI, HPPA_INS_FMPYSUB); + } + + if (fmt == 0) { + push_str_modifier(HPPA_EXT_REF(MI), "dbl"); + CREATE_FPR_REG(MI, rm1); + CREATE_FPR_REG(MI, rm2); + CREATE_FPR_REG(MI, tm); + CREATE_FPR_REG(MI, ra); + CREATE_FPR_REG(MI, ta); + } else { + push_str_modifier(HPPA_EXT_REF(MI), "sgl"); + CREATE_SP_FPR_REG(MI, rm1); + CREATE_SP_FPR_REG(MI, rm2); + CREATE_SP_FPR_REG(MI, tm); + CREATE_SP_FPR_REG(MI, ra); + CREATE_SP_FPR_REG(MI, ta); + } + + return true; +} + +static bool decode_load(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + if (MODE_IS_HPPA_20(ud->mode)) { + uint32_t d = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); + if (opcode == HPPA_OP_TYPE_LDWM) { + if (d < 0) { + push_str_modifier(HPPA_EXT_REF(MI), "mb"); + } else { + push_str_modifier(HPPA_EXT_REF(MI), "ma"); + } + } + MCOperand_CreateImm0(MI, d); + } else { + MCOperand_CreateImm0(MI, extract_14(insn)); + } + CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); + return true; +} + +static bool decode_store(const cs_struct *ud, MCInst *MI, uint32_t insn) +{ + uint32_t opcode = insn >> 26; + CREATE_GR_REG(MI, get_insn_field(insn, 11, 15)); + if (MODE_IS_HPPA_20(ud->mode)) { + uint32_t d = extract_16(insn, MODE_IS_HPPA_20W(ud->mode)); + if (opcode == HPPA_OP_TYPE_STWM) { + if (d < 0) { + push_str_modifier(HPPA_EXT_REF(MI), "mb"); + } else { + push_str_modifier(HPPA_EXT_REF(MI), "ma"); + } + } + MCOperand_CreateImm0(MI, d); + } else { + MCOperand_CreateImm0(MI, extract_14(insn)); + } + CREATE_SR_REG(MI, get_insn_field(insn, 16, 17)); + CREATE_GR_REG(MI, get_insn_field(insn, 6, 10)); + return true; +} + +static bool getInstruction(const cs_struct *ud, const uint8_t *code, + size_t code_len, MCInst *MI) +{ + if (code_len < 4) + return false; + + MCInst_clear(MI); + + uint32_t full_insn = readBytes32(MI, code); + uint8_t opcode = full_insn >> 26; + + if (MODE_IS_HPPA_20(ud->mode)) { + switch (opcode) { + case HPPA_OP_TYPE_LOADDW: + case HPPA_OP_TYPE_STOREDW: + fill_ldst_dw_insn_name(MI, full_insn); + return decode_ldst_dw(ud, MI, full_insn); + case HPPA_OP_TYPE_LOADW: + case HPPA_OP_TYPE_STOREW: + fill_ldst_w_insn_name(MI, full_insn); + return decode_ldst_w(ud, MI, full_insn); + case HPPA_OP_TYPE_SHEXDEP2: + MCInst_setOpcode(MI, HPPA_INS_EXTRD); + return decode_shexdep2(MI, full_insn); + case HPPA_OP_TYPE_SHEXDEP3: + case HPPA_OP_TYPE_SHEXDEP4: + return decode_shexdep3(ud, MI, full_insn); + case HPPA_OP_TYPE_MULTMED: + fill_multmed_insn_name(MI, full_insn); + return decode_multmed(MI, full_insn); + case HPPA_OP_TYPE_FPFUSED: + fill_fpfused_insn_name(MI, full_insn); + return decode_fpfused(ud, MI, full_insn); + case HPPA_OP_TYPE_FLDW: + case HPPA_OP_TYPE_FSTW: + return decode_float_ldst(ud, MI, full_insn); + case HPPA_OP_TYPE_CMPBDWT: + case HPPA_OP_TYPE_CMPBDWF: + case HPPA_OP_TYPE_CMPIBDW: + fill_action_and_branch_insn_name(MI, opcode); + return fill_action_and_branch(ud, MI, full_insn); + default: + break; + } + } + + switch (opcode) { + case HPPA_OP_TYPE_SYSOP: + fill_sysop_insn_name(MI, full_insn); + return decode_sysop(ud, MI, full_insn); + case HPPA_OP_TYPE_MEMMGMT: + fill_memmgmt_insn_name(MI, full_insn); + return decode_memmgmt(ud, MI, full_insn); + case HPPA_OP_TYPE_ALU: + fill_alu_insn_name(MI, full_insn); + return decode_alu(ud, MI, full_insn); + case HPPA_OP_TYPE_IDXMEM: + fill_idxmem_insn_name(MI, full_insn); + return decode_idxmem(ud, MI, full_insn); + case HPPA_OP_TYPE_ADDIT: + case HPPA_OP_TYPE_ADDI: + case HPPA_OP_TYPE_SUBI: + fill_arith_imm_insn_name(MI, full_insn); + return decode_arith_imm(ud, MI, full_insn); + case HPPA_OP_TYPE_SHEXDEP0: + fill_shexdep0_insn_name(MI, full_insn); + return decode_shexdep0(ud, MI, full_insn); + case HPPA_OP_TYPE_SHEXDEP1: + fill_shexdep1_insn_name(MI, full_insn); + return decode_shexdep1(ud, MI, full_insn); + case HPPA_OP_TYPE_BRANCH: + fill_branch_insn_name(MI, full_insn); + return decode_branch(ud, MI, full_insn); + case HPPA_OP_TYPE_COPRW: + case HPPA_OP_TYPE_COPRDW: + fill_corpdw_insn_name(MI, full_insn); + return decode_corpdw(ud, MI, full_insn); + case HPPA_OP_TYPE_SPOP: + fill_spop_insn_name(MI, full_insn); + return decode_spop(ud, MI, full_insn); + case HPPA_OP_TYPE_COPR: + fill_copr_insn_name(MI, full_insn); + return decode_copr(ud, MI, full_insn); + case HPPA_OP_TYPE_FLOAT: + fill_float_insn_name(MI, full_insn); + return decode_float(ud, MI, full_insn); + case HPPA_OP_TYPE_DIAG: + MCInst_setOpcode(MI, HPPA_INS_DIAG); + MCOperand_CreateImm0(MI, get_insn_field(full_insn, 6, 31)); + return true; + case HPPA_OP_TYPE_FMPYADD: + case HPPA_OP_TYPE_FMPYSUB: + return decode_fmpy(ud, MI, full_insn); + case HPPA_OP_TYPE_LDIL: + case HPPA_OP_TYPE_ADDIL: + if (opcode == HPPA_OP_TYPE_LDIL) { + MCInst_setOpcode(MI, HPPA_INS_LDIL); + } else { + MCInst_setOpcode(MI, HPPA_INS_ADDIL); + } + MCOperand_CreateImm0(MI, extract_21(full_insn)); + CREATE_GR_REG(MI, get_insn_field(full_insn, 6, 10)); + return true; + case HPPA_OP_TYPE_LDO: + MCInst_setOpcode(MI, HPPA_INS_LDO); + if (MODE_IS_HPPA_20(ud->mode)) { + MCOperand_CreateImm0( + MI, extract_16(full_insn, + MODE_IS_HPPA_20W(ud->mode))); + } else { + MCOperand_CreateImm0(MI, extract_14(full_insn)); + } + CREATE_GR_REG(MI, get_insn_field(full_insn, 6, 10)); + CREATE_GR_REG(MI, get_insn_field(full_insn, 11, 15)); + return true; + case HPPA_OP_TYPE_LDB: + case HPPA_OP_TYPE_LDH: + case HPPA_OP_TYPE_LDW: + case HPPA_OP_TYPE_LDWM: + fill_load_insn_name(MI, opcode); + return decode_load(ud, MI, full_insn); + case HPPA_OP_TYPE_STB: + case HPPA_OP_TYPE_STH: + case HPPA_OP_TYPE_STW: + case HPPA_OP_TYPE_STWM: + fill_store_insn_name(MI, opcode); + return decode_store(ud, MI, full_insn); + case HPPA_OP_TYPE_CMPBT: + case HPPA_OP_TYPE_CMPBF: + case HPPA_OP_TYPE_ADDBT: + case HPPA_OP_TYPE_ADDBF: + case HPPA_OP_TYPE_MOVB: + case HPPA_OP_TYPE_CMPIBT: + case HPPA_OP_TYPE_CMPIBF: + case HPPA_OP_TYPE_ADDIBT: + case HPPA_OP_TYPE_ADDIBF: + case HPPA_OP_TYPE_MOVIB: + case HPPA_OP_TYPE_BBS: + case HPPA_OP_TYPE_BB: + fill_action_and_branch_insn_name(MI, opcode); + return fill_action_and_branch(ud, MI, full_insn); + case HPPA_OP_TYPE_CMPICLR: + return decode_cmpclr(ud, MI, full_insn); + case HPPA_OP_TYPE_BE: + case HPPA_OP_TYPE_BLE: + return decode_be(ud, MI, full_insn); + default: + return false; + } +} + +void init_details(MCInst *MI) +{ + cs_detail *detail = get_detail(MI); + if (detail) { + memset(detail, 0, offsetof(cs_detail, hppa) + sizeof(cs_hppa)); + } } bool HPPA_getInstruction(csh ud, const uint8_t *code, size_t code_len, - MCInst *instr, uint16_t *size, uint64_t address, - void *info) -{ - cs_struct *cs = (cs_struct *)ud; - init_details(instr); - if (!getInstruction(cs, code, code_len, instr)) { - *size = 0; - return false; - } - *size = 4; - return true; + MCInst *instr, uint16_t *size, uint64_t address, + void *info) +{ + cs_struct *cs = (cs_struct *)ud; + init_details(instr); + if (!getInstruction(cs, code, code_len, instr)) { + *size = 0; + return false; + } + *size = 4; + return true; } #endif \ No newline at end of file diff --git a/arch/HPPA/HPPAInstPrinter.c b/arch/HPPA/HPPAInstPrinter.c index 61fda90f59..56a2ff6385 100644 --- a/arch/HPPA/HPPAInstPrinter.c +++ b/arch/HPPA/HPPAInstPrinter.c @@ -10,8 +10,7 @@ #include "HPPAInstPrinter.h" #include "HPPAMapping.h" -static const struct pa_insn pa_insns[] = -{ +static const struct pa_insn pa_insns[] = { { HPPA_INS_LDI, HPPA_GRP_LONG_IMM }, { HPPA_INS_CMPIB, HPPA_GRP_BRANCH }, { HPPA_INS_COMIB, HPPA_GRP_BRANCH }, @@ -119,7 +118,7 @@ static const struct pa_insn pa_insns[] = { HPPA_INS_SH1ADDO, HPPA_GRP_COMPUTATION }, { HPPA_INS_SH2ADD, HPPA_GRP_COMPUTATION }, { HPPA_INS_SH2ADDL, HPPA_GRP_COMPUTATION }, - { HPPA_INS_SH2ADDO, HPPA_GRP_COMPUTATION}, + { HPPA_INS_SH2ADDO, HPPA_GRP_COMPUTATION }, { HPPA_INS_SH3ADD, HPPA_GRP_COMPUTATION }, { HPPA_INS_SH3ADDL, HPPA_GRP_COMPUTATION }, { HPPA_INS_SH3ADDO, HPPA_GRP_COMPUTATION }, @@ -139,8 +138,8 @@ static const struct pa_insn pa_insns[] = { HPPA_INS_SHD, HPPA_GRP_COMPUTATION }, { HPPA_INS_EXTRD, HPPA_GRP_COMPUTATION }, { HPPA_INS_EXTRW, HPPA_GRP_COMPUTATION }, - { HPPA_INS_VEXTRU, HPPA_GRP_COMPUTATION}, - { HPPA_INS_VEXTRS, HPPA_GRP_COMPUTATION}, + { HPPA_INS_VEXTRU, HPPA_GRP_COMPUTATION }, + { HPPA_INS_VEXTRS, HPPA_GRP_COMPUTATION }, { HPPA_INS_EXTRU, HPPA_GRP_COMPUTATION }, { HPPA_INS_EXTRS, HPPA_GRP_COMPUTATION }, { HPPA_INS_DEPD, HPPA_GRP_COMPUTATION }, @@ -300,7 +299,8 @@ static void set_op_target(cs_hppa *hppa, uint64_t val) op->imm = val; } -static void set_op_mem(cs_hppa *hppa, uint32_t base, uint32_t space, cs_ac_type base_access) +static void set_op_mem(cs_hppa *hppa, uint32_t base, uint32_t space, + cs_ac_type base_access) { cs_hppa_op *op = &hppa->operands[hppa->op_count++]; op->type = HPPA_OP_MEM; @@ -319,8 +319,7 @@ static void set_op_mem(cs_hppa *hppa, uint32_t base, uint32_t space, cs_ac_type x - [r] or [o] defined by the operand kind b - base register (may be writable in some cases) */ -static const struct pa_insn_fmt pa_formats[] = -{ +static const struct pa_insn_fmt pa_formats[] = { { HPPA_INS_LDI, "iW", false }, { HPPA_INS_CMPIB, "iRT", false }, @@ -590,8 +589,6 @@ static const struct pa_insn_fmt pa_formats[] = { HPPA_INS_RET, "", false }, }; - - static void print_operand(MCInst *MI, SStream *O, const cs_hppa_op *op) { switch (op->type) { @@ -601,10 +598,10 @@ static void print_operand(MCInst *MI, SStream *O, const cs_hppa_op *op) case HPPA_OP_REG: SStream_concat(O, HPPA_reg_name((csh)MI->csh, op->reg)); break; - case HPPA_OP_IMM: + case HPPA_OP_IMM: printInt32(O, op->imm); break; - case HPPA_OP_DISP: + case HPPA_OP_DISP: printInt32(O, op->imm); break; case HPPA_OP_IDX_REG: @@ -612,8 +609,10 @@ static void print_operand(MCInst *MI, SStream *O, const cs_hppa_op *op) break; case HPPA_OP_MEM: SStream_concat(O, "("); - if (op->mem.space != HPPA_OP_INVALID && op->mem.space != HPPA_REG_SR0) { - SStream_concat(O, HPPA_reg_name((csh)MI->csh, op->mem.space)); + if (op->mem.space != HPPA_OP_INVALID && + op->mem.space != HPPA_REG_SR0) { + SStream_concat(O, HPPA_reg_name((csh)MI->csh, + op->mem.space)); SStream_concat(O, ","); } SStream_concat(O, HPPA_reg_name((csh)MI->csh, op->mem.base)); @@ -637,9 +636,10 @@ static void fill_operands(MCInst *MI, cs_hppa *hppa) hppa_ext *hppa_ext = &MI->hppa_ext; uint32_t opcode = MCInst_getOpcode(MI); - for (int i = 0; i < NUMFMTS; ++i) { + for (int i = 0; i < NUMFMTS; ++i) { const struct pa_insn_fmt *pa_fmt = &pa_formats[i]; - if (opcode != pa_fmt->insn_id || hppa_ext->is_alternative != pa_fmt->is_alternative) { + if (opcode != pa_fmt->insn_id || + hppa_ext->is_alternative != pa_fmt->is_alternative) { continue; } const char *fmt = pa_fmt->format; @@ -648,33 +648,34 @@ static void fill_operands(MCInst *MI, cs_hppa *hppa) uint8_t space_reg_idx = 0; cs_ac_type base_access = CS_AC_INVALID; MCOperand *op = NULL; - while (*fmt) - { + while (*fmt) { op = MCInst_getOperand(MI, idx++); - switch (*fmt++) - { + switch (*fmt++) { case 'i': if (MCOperand_isReg(op)) { - set_op_reg(hppa, MCOperand_getReg(op), CS_AC_READ); - } - else { + set_op_reg(hppa, MCOperand_getReg(op), + CS_AC_READ); + } else { set_op_imm(hppa, MCOperand_getImm(op)); } break; case 'o': set_op_disp(hppa, MCOperand_getImm(op)); break; - + case 'R': - set_op_reg(hppa, MCOperand_getReg(op), CS_AC_READ); + set_op_reg(hppa, MCOperand_getReg(op), + CS_AC_READ); break; case 'W': - set_op_reg(hppa, MCOperand_getReg(op), CS_AC_WRITE); + set_op_reg(hppa, MCOperand_getReg(op), + CS_AC_WRITE); break; case 'w': - set_op_reg(hppa, MCOperand_getReg(op), CS_AC_READ_WRTE); + set_op_reg(hppa, MCOperand_getReg(op), + CS_AC_READ_WRTE); break; case 'r': @@ -687,9 +688,9 @@ static void fill_operands(MCInst *MI, cs_hppa *hppa) case 'x': if (MCOperand_isReg(op)) { - set_op_idx_reg(hppa, MCOperand_getReg(op)); - } - else { + set_op_idx_reg(hppa, + MCOperand_getReg(op)); + } else { set_op_disp(hppa, MCOperand_getImm(op)); } break; @@ -697,53 +698,59 @@ static void fill_operands(MCInst *MI, cs_hppa *hppa) case '(': while (*fmt != ')') { if (space_reg_idx > 0) { - op = MCInst_getOperand(MI, idx++); + op = MCInst_getOperand(MI, + idx++); } - assert(space_reg_idx < ARR_SIZE(space_regs)); - space_regs[space_reg_idx] = MCOperand_getReg(op); + assert(space_reg_idx < + ARR_SIZE(space_regs)); + space_regs[space_reg_idx] = + MCOperand_getReg(op); if (*fmt == 'R') { base_access = CS_AC_READ; } else if (*fmt == 'W') { base_access = CS_AC_WRITE; } else if (*fmt == 'b') { - base_access = CS_AC_READ; + base_access = CS_AC_READ; if (hppa_ext->b_writeble) - base_access |= CS_AC_WRITE; + base_access |= + CS_AC_WRITE; } fmt++; space_reg_idx++; } if (space_regs[1] == HPPA_REG_INVALID) - set_op_mem(hppa, space_regs[0], space_regs[1], base_access); - else - set_op_mem(hppa, space_regs[1], space_regs[0], base_access); + set_op_mem(hppa, space_regs[0], + space_regs[1], base_access); + else + set_op_mem(hppa, space_regs[1], + space_regs[0], base_access); fmt++; break; default: - printf("Unknown: %c\n", *(fmt-1)); + printf("Unknown: %c\n", *(fmt - 1)); break; } } break; - } - + } } -static void print_modifiers(MCInst *MI, SStream *O) +static void print_modifiers(MCInst *MI, SStream *O) { - hppa_ext *hppa_ext = &MI->hppa_ext; - for (uint8_t i = 0; i < hppa_ext->mod_num; ++i) { - SStream_concat(O, ","); - if (hppa_ext->modifiers[i].type == HPPA_MOD_STR) - SStream_concat(O, hppa_ext->modifiers[i].str_mod); - else - SStream_concat(O, "%d", hppa_ext->modifiers[i].int_mod); - } + hppa_ext *hppa_ext = &MI->hppa_ext; + for (uint8_t i = 0; i < hppa_ext->mod_num; ++i) { + SStream_concat(O, ","); + if (hppa_ext->modifiers[i].type == HPPA_MOD_STR) + SStream_concat(O, hppa_ext->modifiers[i].str_mod); + else + SStream_concat(O, "%d", hppa_ext->modifiers[i].int_mod); + } } -static void add_groups(MCInst *MI) { +static void add_groups(MCInst *MI) +{ unsigned int opcode = MCInst_getOpcode(MI); for (unsigned i = 0; i < ARR_SIZE(pa_insns); ++i) { if (pa_insns[i].insn != opcode) { @@ -805,14 +812,14 @@ void HPPA_printInst(MCInst *MI, SStream *O, void *Info) MCInst_setOpcodePub(MI, MCInst_getOpcode(MI)); SStream_concat(O, HPPA_insn_name((csh)MI->csh, MCInst_getOpcode(MI))); - print_modifiers(MI, O); + print_modifiers(MI, O); SStream_concat(O, " "); fill_operands(MI, &hppa); for (int i = 0; i < hppa.op_count; i++) { cs_hppa_op *op = &hppa.operands[i]; print_operand(MI, O, op); - if (op->type != HPPA_OP_IDX_REG && op->type != HPPA_OP_DISP && - i != hppa.op_count-1) { + if (op->type != HPPA_OP_IDX_REG && op->type != HPPA_OP_DISP && + i != hppa.op_count - 1) { SStream_concat(O, ","); } } diff --git a/arch/HPPA/HPPAInstPrinter.h b/arch/HPPA/HPPAInstPrinter.h index ac2990f72c..8bf1c673b1 100644 --- a/arch/HPPA/HPPAInstPrinter.h +++ b/arch/HPPA/HPPAInstPrinter.h @@ -10,15 +10,14 @@ #include "../../SStream.h" struct pa_insn { - hppa_insn insn; + hppa_insn insn; hppa_insn_group grp; }; -struct pa_insn_fmt -{ +struct pa_insn_fmt { hppa_insn insn_id; - const char *format; - bool is_alternative; ///< true if some completer affects the instruction format + const char *format; + bool is_alternative; ///< true if some completer affects the instruction format }; void HPPA_printInst(MCInst *MI, SStream *O, void *Info); diff --git a/arch/HPPA/HPPAMapping.c b/arch/HPPA/HPPAMapping.c index 54c8f6d9f0..75f03dc2d0 100644 --- a/arch/HPPA/HPPAMapping.c +++ b/arch/HPPA/HPPAMapping.c @@ -11,7 +11,6 @@ #include "../../Mapping.h" #include "../../utils.h" - #ifndef CAPSTONE_DIET static const name_map group_name_maps[] = { { HPPA_GRP_INVALID, NULL }, @@ -303,51 +302,42 @@ const char *HPPA_insn_name(csh handle, unsigned int id) /* Integer register names, indexed by the numbers which appear in the opcodes. */ -static const char *const reg_names[] = -{ - "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9", - "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", - "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1", - "sp", "r31" +static const char *const reg_names[] = { + "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "dp", "ret0", "ret1", "sp", "r31" }; /* Floating point register names, indexed by the numbers which appear in the opcodes. */ -static const char *const fp_reg_names[] = -{ - "fpsr", "fpe2", "fpe4", "fpe6", - "fr4", "fr5", "fr6", "fr7", "fr8", - "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", - "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", - "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31" +static const char *const fp_reg_names[] = { + "fpsr", "fpe2", "fpe4", "fpe6", "fr4", "fr5", "fr6", "fr7", + "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", + "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", + "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31" }; -static const char *const control_reg[] = -{ - "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", - "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4", - "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr", - "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3", - "tr4", "tr5", "tr6", "tr7" +static const char *const control_reg[] = { + "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", + "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4", "iva", "eiem", + "itmr", "pcsq", "pcoq", "iir", "isr", "ior", "ipsw", "eirr", + "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7" }; -static const char *const space_reg[] = -{ - "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7" -}; +static const char *const space_reg[] = { "sr0", "sr1", "sr2", "sr3", + "sr4", "sr5", "sr6", "sr7" }; static const char *const fpe_reg[] = { - "fpe1", "fpe3", "fpe5", "fpe7", - "fr4R", "fr5R", "fr6R", "fr7R", "fr8R", - "fr9R", "fr10R", "fr11R", "fr12R", "fr13R", "fr14R", "fr15R", - "fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R", - "fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R" + "fpe1", "fpe3", "fpe5", "fpe7", "fr4R", "fr5R", "fr6R", "fr7R", + "fr8R", "fr9R", "fr10R", "fr11R", "fr12R", "fr13R", "fr14R", "fr15R", + "fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R", + "fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R" }; static const char *const sp_fp_reg[] = { - "fr16L", "fr17L", "fr18L", "fr19L", - "fr20L", "fr21L", "fr22L", "fr23L", "fr24L", - "fr25L", "fr26L", "fr27L", "fr28L", "fr29L", "fr30L", "fr31L", + "fr16L", "fr17L", "fr18L", "fr19L", "fr20L", "fr21L", "fr22L", "fr23L", + "fr24L", "fr25L", "fr26L", "fr27L", "fr28L", "fr29L", "fr30L", "fr31L", "fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R", "fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R" }; @@ -357,16 +347,16 @@ const char *HPPA_reg_name(csh handle, unsigned int reg) #ifndef CAPSTONE_DIET if (reg >= HPPA_REG_GR0 && reg <= HPPA_REG_GR31) return reg_names[reg - HPPA_REG_GR0]; - else if (reg >= HPPA_REG_FPR0 && reg <= HPPA_REG_FPR31) - return fp_reg_names[reg - HPPA_REG_FPR0]; + else if (reg >= HPPA_REG_FPR0 && reg <= HPPA_REG_FPR31) + return fp_reg_names[reg - HPPA_REG_FPR0]; else if (reg >= HPPA_REG_SR0 && reg <= HPPA_REG_SR7) - return space_reg[reg - HPPA_REG_SR0]; - else if (reg >= HPPA_REG_CR0 && reg <= HPPA_REG_CR31) - return control_reg[reg - HPPA_REG_CR0]; + return space_reg[reg - HPPA_REG_SR0]; + else if (reg >= HPPA_REG_CR0 && reg <= HPPA_REG_CR31) + return control_reg[reg - HPPA_REG_CR0]; else if (reg >= HPPA_REG_FPE0 && reg <= HPPA_REG_FPE31) - return fpe_reg[reg - HPPA_REG_FPE0]; + return fpe_reg[reg - HPPA_REG_FPE0]; else if (reg >= HPPA_REG_SP_FPR0 && reg <= HPPA_REG_SP_FPR31) - return sp_fp_reg[reg - HPPA_REG_SP_FPR0]; + return sp_fp_reg[reg - HPPA_REG_SP_FPR0]; return NULL; #else return NULL; @@ -398,8 +388,7 @@ static void sort_and_uniq(cs_regs arr, uint8_t n, uint8_t *new_n) if (j != 0 && arr[iMin] == arr[j - 1]) { // duplicate ele found arr[iMin] = arr[n - 1]; --n; - } - else { + } else { tmp = arr[iMin]; arr[iMin] = arr[j]; arr[j] = tmp; @@ -419,8 +408,7 @@ void HPPA_reg_access(const cs_insn *insn, cs_regs regs_read, for (unsigned i = 0; i < hppa->op_count; ++i) { const cs_hppa_op *op = &(hppa->operands[i]); - switch (op->type) - { + switch (op->type) { case HPPA_OP_REG: case HPPA_OP_IDX_REG: if (op->access & CS_AC_READ) { @@ -431,7 +419,7 @@ void HPPA_reg_access(const cs_insn *insn, cs_regs regs_read, } break; case HPPA_OP_MEM: - if (op->mem.space != HPPA_OP_INVALID) + if (op->mem.space != HPPA_OP_INVALID) regs_read[read_count++] = op->mem.space; if (op->mem.base_access & CS_AC_READ) { regs_read[read_count++] = op->mem.base; diff --git a/cstool/cstool_hppa.c b/cstool/cstool_hppa.c index c5953b210a..f41b843180 100644 --- a/cstool/cstool_hppa.c +++ b/cstool/cstool_hppa.c @@ -11,65 +11,76 @@ void print_insn_detail_hppa(csh handle, cs_insn *ins) cs_regs regs_read, regs_write; uint8_t regs_read_count, regs_write_count; - if (ins->detail == NULL) - return; + if (ins->detail == NULL) + return; - hppa = &ins->detail->hppa; + hppa = &ins->detail->hppa; - printf("\top_count: %u\n", hppa->op_count); - for (unsigned i = 0; i < hppa->op_count; i++) { + printf("\top_count: %u\n", hppa->op_count); + for (unsigned i = 0; i < hppa->op_count; i++) { cs_hppa_op *op = &(hppa->operands[i]); - uint64_t target_addr; - switch (op->type) { - case HPPA_OP_REG: - printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); - break; - case HPPA_OP_IMM: - if (op->imm < 0) - printf("\t\toperands[%u].type: IMM = -0x%" PRIx64 "\n", i, -(op->imm)); - else - printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); - break; - case HPPA_OP_IDX_REG: - printf("\t\toperands[%u].type: IDX_REG = %s\n", i, cs_reg_name(handle, op->reg)); - break; - case HPPA_OP_DISP: - if (op->imm < 0) - printf("\t\toperands[%u].type: DISP = -0x%" PRIx64 "\n", i, -(op->imm)); - else - printf("\t\toperands[%u].type: DISP = 0x%" PRIx64 "\n", i, op->imm); - break; - case HPPA_OP_MEM: - printf("\t\toperands[%u].type: MEM\n", i); - if (op->mem.space != HPPA_OP_INVALID) { - printf("\t\t\toperands[%u].mem.space: REG = %s\n", - i, cs_reg_name(handle, op->mem.space)); - } - printf("\t\t\toperands[%u].mem.base: REG = %s\n", - i, cs_reg_name(handle, op->mem.base)); - break; - case HPPA_OP_TARGET: - printf("\t\toperands[%u].type: ", i); - target_addr = ins->address + op->imm; - printf("TARGET = 0x%" PRIx64 "\n", target_addr); - break; - } - } + uint64_t target_addr; + switch (op->type) { + case HPPA_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, + cs_reg_name(handle, op->reg)); + break; + case HPPA_OP_IMM: + if (op->imm < 0) + printf("\t\toperands[%u].type: IMM = -0x%" PRIx64 + "\n", + i, -(op->imm)); + else + printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 + "\n", + i, op->imm); + break; + case HPPA_OP_IDX_REG: + printf("\t\toperands[%u].type: IDX_REG = %s\n", i, + cs_reg_name(handle, op->reg)); + break; + case HPPA_OP_DISP: + if (op->imm < 0) + printf("\t\toperands[%u].type: DISP = -0x%" PRIx64 + "\n", + i, -(op->imm)); + else + printf("\t\toperands[%u].type: DISP = 0x%" PRIx64 + "\n", + i, op->imm); + break; + case HPPA_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.space != HPPA_OP_INVALID) { + printf("\t\t\toperands[%u].mem.space: REG = %s\n", + i, cs_reg_name(handle, op->mem.space)); + } + printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, + cs_reg_name(handle, op->mem.base)); + break; + case HPPA_OP_TARGET: + printf("\t\toperands[%u].type: ", i); + target_addr = ins->address + op->imm; + printf("TARGET = 0x%" PRIx64 "\n", target_addr); + break; + } + } - if (!cs_regs_access(handle, ins, - regs_read, ®s_read_count, - regs_write, ®s_write_count)) { + if (!cs_regs_access(handle, ins, regs_read, ®s_read_count, + regs_write, ®s_write_count)) { if (regs_read_count) { printf("\tRegisters read:"); - for(unsigned i = 0; i < regs_read_count; i++) - printf(" %s", cs_reg_name(handle, regs_read[i])); + for (unsigned i = 0; i < regs_read_count; i++) + printf(" %s", + cs_reg_name(handle, regs_read[i])); printf("\n"); } if (regs_write_count) { printf("\tRegisters modified:"); - for(unsigned i = 0; i < regs_write_count; i++) - printf(" %s", cs_reg_name(handle, regs_write[i])); + for (unsigned i = 0; i < regs_write_count; i++) + printf(" %s", + cs_reg_name(handle, regs_write[i])); printf("\n"); } } diff --git a/include/capstone/hppa.h b/include/capstone/hppa.h index 85a7e9ec26..549ad85ceb 100644 --- a/include/capstone/hppa.h +++ b/include/capstone/hppa.h @@ -18,10 +18,10 @@ typedef enum hppa_op_type { HPPA_OP_REG, HPPA_OP_IMM, - HPPA_OP_IDX_REG, - HPPA_OP_DISP, - HPPA_OP_MEM, - HPPA_OP_TARGET, + HPPA_OP_IDX_REG, + HPPA_OP_DISP, + HPPA_OP_MEM, + HPPA_OP_TARGET, } hppa_op_type; @@ -29,461 +29,460 @@ typedef enum hppa_op_type { typedef enum hppa_reg { HPPA_REG_INVALID = 0, - ///> General registers - HPPA_REG_GR0, - HPPA_REG_GR1, - HPPA_REG_GR2, - HPPA_REG_GR3, - HPPA_REG_GR4, - HPPA_REG_GR5, - HPPA_REG_GR6, - HPPA_REG_GR7, - HPPA_REG_GR8, - HPPA_REG_GR9, - HPPA_REG_GR10, - HPPA_REG_GR11, - HPPA_REG_GR12, - HPPA_REG_GR13, - HPPA_REG_GR14, - HPPA_REG_GR15, - HPPA_REG_GR16, - HPPA_REG_GR17, - HPPA_REG_GR18, - HPPA_REG_GR19, - HPPA_REG_GR20, - HPPA_REG_GR21, - HPPA_REG_GR22, - HPPA_REG_GR23, - HPPA_REG_GR24, - HPPA_REG_GR25, - HPPA_REG_GR26, - HPPA_REG_GR27, - HPPA_REG_GR28, - HPPA_REG_GR29, - HPPA_REG_GR30, - HPPA_REG_GR31, + ///> General registers + HPPA_REG_GR0, + HPPA_REG_GR1, + HPPA_REG_GR2, + HPPA_REG_GR3, + HPPA_REG_GR4, + HPPA_REG_GR5, + HPPA_REG_GR6, + HPPA_REG_GR7, + HPPA_REG_GR8, + HPPA_REG_GR9, + HPPA_REG_GR10, + HPPA_REG_GR11, + HPPA_REG_GR12, + HPPA_REG_GR13, + HPPA_REG_GR14, + HPPA_REG_GR15, + HPPA_REG_GR16, + HPPA_REG_GR17, + HPPA_REG_GR18, + HPPA_REG_GR19, + HPPA_REG_GR20, + HPPA_REG_GR21, + HPPA_REG_GR22, + HPPA_REG_GR23, + HPPA_REG_GR24, + HPPA_REG_GR25, + HPPA_REG_GR26, + HPPA_REG_GR27, + HPPA_REG_GR28, + HPPA_REG_GR29, + HPPA_REG_GR30, + HPPA_REG_GR31, - ///> Floating-point registers - HPPA_REG_FPR0, - HPPA_REG_FPR1, - HPPA_REG_FPR2, - HPPA_REG_FPR3, - HPPA_REG_FPR4, - HPPA_REG_FPR5, - HPPA_REG_FPR6, - HPPA_REG_FPR7, - HPPA_REG_FPR8, - HPPA_REG_FPR9, - HPPA_REG_FPR10, - HPPA_REG_FPR11, - HPPA_REG_FPR12, - HPPA_REG_FPR13, - HPPA_REG_FPR14, - HPPA_REG_FPR15, - HPPA_REG_FPR16, - HPPA_REG_FPR17, - HPPA_REG_FPR18, - HPPA_REG_FPR19, - HPPA_REG_FPR20, - HPPA_REG_FPR21, - HPPA_REG_FPR22, - HPPA_REG_FPR23, - HPPA_REG_FPR24, - HPPA_REG_FPR25, - HPPA_REG_FPR26, - HPPA_REG_FPR27, - HPPA_REG_FPR28, - HPPA_REG_FPR29, - HPPA_REG_FPR30, - HPPA_REG_FPR31, + ///> Floating-point registers + HPPA_REG_FPR0, + HPPA_REG_FPR1, + HPPA_REG_FPR2, + HPPA_REG_FPR3, + HPPA_REG_FPR4, + HPPA_REG_FPR5, + HPPA_REG_FPR6, + HPPA_REG_FPR7, + HPPA_REG_FPR8, + HPPA_REG_FPR9, + HPPA_REG_FPR10, + HPPA_REG_FPR11, + HPPA_REG_FPR12, + HPPA_REG_FPR13, + HPPA_REG_FPR14, + HPPA_REG_FPR15, + HPPA_REG_FPR16, + HPPA_REG_FPR17, + HPPA_REG_FPR18, + HPPA_REG_FPR19, + HPPA_REG_FPR20, + HPPA_REG_FPR21, + HPPA_REG_FPR22, + HPPA_REG_FPR23, + HPPA_REG_FPR24, + HPPA_REG_FPR25, + HPPA_REG_FPR26, + HPPA_REG_FPR27, + HPPA_REG_FPR28, + HPPA_REG_FPR29, + HPPA_REG_FPR30, + HPPA_REG_FPR31, - ///> Space registers - HPPA_REG_SR0, - HPPA_REG_SR1, - HPPA_REG_SR2, - HPPA_REG_SR3, - HPPA_REG_SR4, - HPPA_REG_SR5, - HPPA_REG_SR6, - HPPA_REG_SR7, + ///> Space registers + HPPA_REG_SR0, + HPPA_REG_SR1, + HPPA_REG_SR2, + HPPA_REG_SR3, + HPPA_REG_SR4, + HPPA_REG_SR5, + HPPA_REG_SR6, + HPPA_REG_SR7, - ///> Control registers - HPPA_REG_CR0, - HPPA_REG_CR1, - HPPA_REG_CR2, - HPPA_REG_CR3, - HPPA_REG_CR4, - HPPA_REG_CR5, - HPPA_REG_CR6, - HPPA_REG_CR7, - HPPA_REG_CR8, - HPPA_REG_CR9, - HPPA_REG_CR10, - HPPA_REG_CR11, - HPPA_REG_CR12, - HPPA_REG_CR13, - HPPA_REG_CR14, - HPPA_REG_CR15, - HPPA_REG_CR16, - HPPA_REG_CR17, - HPPA_REG_CR18, - HPPA_REG_CR19, - HPPA_REG_CR20, - HPPA_REG_CR21, - HPPA_REG_CR22, - HPPA_REG_CR23, - HPPA_REG_CR24, - HPPA_REG_CR25, - HPPA_REG_CR26, - HPPA_REG_CR27, - HPPA_REG_CR28, - HPPA_REG_CR29, - HPPA_REG_CR30, - HPPA_REG_CR31, + ///> Control registers + HPPA_REG_CR0, + HPPA_REG_CR1, + HPPA_REG_CR2, + HPPA_REG_CR3, + HPPA_REG_CR4, + HPPA_REG_CR5, + HPPA_REG_CR6, + HPPA_REG_CR7, + HPPA_REG_CR8, + HPPA_REG_CR9, + HPPA_REG_CR10, + HPPA_REG_CR11, + HPPA_REG_CR12, + HPPA_REG_CR13, + HPPA_REG_CR14, + HPPA_REG_CR15, + HPPA_REG_CR16, + HPPA_REG_CR17, + HPPA_REG_CR18, + HPPA_REG_CR19, + HPPA_REG_CR20, + HPPA_REG_CR21, + HPPA_REG_CR22, + HPPA_REG_CR23, + HPPA_REG_CR24, + HPPA_REG_CR25, + HPPA_REG_CR26, + HPPA_REG_CR27, + HPPA_REG_CR28, + HPPA_REG_CR29, + HPPA_REG_CR30, + HPPA_REG_CR31, - ///> Special floating point exception registers - HPPA_REG_FPE0, - HPPA_REG_FPE1, - HPPA_REG_FPE2, - HPPA_REG_FPE3, - HPPA_REG_FPE4, - HPPA_REG_FPE5, - HPPA_REG_FPE6, - HPPA_REG_FPE7, - HPPA_REG_FPE8, - HPPA_REG_FPE9, - HPPA_REG_FPE10, - HPPA_REG_FPE11, - HPPA_REG_FPE12, - HPPA_REG_FPE13, - HPPA_REG_FPE14, - HPPA_REG_FPE15, - HPPA_REG_FPE16, - HPPA_REG_FPE17, - HPPA_REG_FPE18, - HPPA_REG_FPE19, - HPPA_REG_FPE20, - HPPA_REG_FPE21, - HPPA_REG_FPE22, - HPPA_REG_FPE23, - HPPA_REG_FPE24, - HPPA_REG_FPE25, - HPPA_REG_FPE26, - HPPA_REG_FPE27, - HPPA_REG_FPE28, - HPPA_REG_FPE29, - HPPA_REG_FPE30, - HPPA_REG_FPE31, + ///> Special floating point exception registers + HPPA_REG_FPE0, + HPPA_REG_FPE1, + HPPA_REG_FPE2, + HPPA_REG_FPE3, + HPPA_REG_FPE4, + HPPA_REG_FPE5, + HPPA_REG_FPE6, + HPPA_REG_FPE7, + HPPA_REG_FPE8, + HPPA_REG_FPE9, + HPPA_REG_FPE10, + HPPA_REG_FPE11, + HPPA_REG_FPE12, + HPPA_REG_FPE13, + HPPA_REG_FPE14, + HPPA_REG_FPE15, + HPPA_REG_FPE16, + HPPA_REG_FPE17, + HPPA_REG_FPE18, + HPPA_REG_FPE19, + HPPA_REG_FPE20, + HPPA_REG_FPE21, + HPPA_REG_FPE22, + HPPA_REG_FPE23, + HPPA_REG_FPE24, + HPPA_REG_FPE25, + HPPA_REG_FPE26, + HPPA_REG_FPE27, + HPPA_REG_FPE28, + HPPA_REG_FPE29, + HPPA_REG_FPE30, + HPPA_REG_FPE31, - ///> Single-precision floating point registers - HPPA_REG_SP_FPR0, - HPPA_REG_SP_FPR1, - HPPA_REG_SP_FPR2, - HPPA_REG_SP_FPR3, - HPPA_REG_SP_FPR4, - HPPA_REG_SP_FPR5, - HPPA_REG_SP_FPR6, - HPPA_REG_SP_FPR7, - HPPA_REG_SP_FPR8, - HPPA_REG_SP_FPR9, - HPPA_REG_SP_FPR10, - HPPA_REG_SP_FPR11, - HPPA_REG_SP_FPR12, - HPPA_REG_SP_FPR13, - HPPA_REG_SP_FPR14, - HPPA_REG_SP_FPR15, - HPPA_REG_SP_FPR16, - HPPA_REG_SP_FPR17, - HPPA_REG_SP_FPR18, - HPPA_REG_SP_FPR19, - HPPA_REG_SP_FPR20, - HPPA_REG_SP_FPR21, - HPPA_REG_SP_FPR22, - HPPA_REG_SP_FPR23, - HPPA_REG_SP_FPR24, - HPPA_REG_SP_FPR25, - HPPA_REG_SP_FPR26, - HPPA_REG_SP_FPR27, - HPPA_REG_SP_FPR28, - HPPA_REG_SP_FPR29, - HPPA_REG_SP_FPR30, - HPPA_REG_SP_FPR31, + ///> Single-precision floating point registers + HPPA_REG_SP_FPR0, + HPPA_REG_SP_FPR1, + HPPA_REG_SP_FPR2, + HPPA_REG_SP_FPR3, + HPPA_REG_SP_FPR4, + HPPA_REG_SP_FPR5, + HPPA_REG_SP_FPR6, + HPPA_REG_SP_FPR7, + HPPA_REG_SP_FPR8, + HPPA_REG_SP_FPR9, + HPPA_REG_SP_FPR10, + HPPA_REG_SP_FPR11, + HPPA_REG_SP_FPR12, + HPPA_REG_SP_FPR13, + HPPA_REG_SP_FPR14, + HPPA_REG_SP_FPR15, + HPPA_REG_SP_FPR16, + HPPA_REG_SP_FPR17, + HPPA_REG_SP_FPR18, + HPPA_REG_SP_FPR19, + HPPA_REG_SP_FPR20, + HPPA_REG_SP_FPR21, + HPPA_REG_SP_FPR22, + HPPA_REG_SP_FPR23, + HPPA_REG_SP_FPR24, + HPPA_REG_SP_FPR25, + HPPA_REG_SP_FPR26, + HPPA_REG_SP_FPR27, + HPPA_REG_SP_FPR28, + HPPA_REG_SP_FPR29, + HPPA_REG_SP_FPR30, + HPPA_REG_SP_FPR31, - HPPA_REG_ENDING, + HPPA_REG_ENDING, } hppa_reg; /// HPPA instruction typedef enum hppa_insn { HPPA_INS_INVALID = 0, - HPPA_INS_ADD, - HPPA_INS_ADDI, - HPPA_INS_ADDIO, - HPPA_INS_ADDIT, - HPPA_INS_ADDITO, - HPPA_INS_ADDB, - HPPA_INS_ADDBT, - HPPA_INS_ADDBF, - HPPA_INS_ADDIB, - HPPA_INS_ADDIBT, - HPPA_INS_ADDIBF, - HPPA_INS_ADDIL, - HPPA_INS_ADDC, - HPPA_INS_ADDCO, - HPPA_INS_ADDL, - HPPA_INS_ADDO, - HPPA_INS_AND, - HPPA_INS_ANDCM, - HPPA_INS_B, - HPPA_INS_BB, - HPPA_INS_BE, - HPPA_INS_BL, - HPPA_INS_BLE, - HPPA_INS_BLR, - HPPA_INS_BREAK, - HPPA_INS_BV, - HPPA_INS_BVB, - HPPA_INS_BVE, - HPPA_INS_CALL, - HPPA_INS_CLDD, - HPPA_INS_CLDDS, - HPPA_INS_CLDDX, - HPPA_INS_CLDW, - HPPA_INS_CLDWS, - HPPA_INS_CLDWX, - HPPA_INS_CLRBTS, - HPPA_INS_CMPB, - HPPA_INS_CMPCLR, - HPPA_INS_CMPIB, - HPPA_INS_CMPICLR, - HPPA_INS_COMB, - HPPA_INS_COMBT, - HPPA_INS_COMBF, - HPPA_INS_COMCLR, - HPPA_INS_COMIB, - HPPA_INS_COMIBT, - HPPA_INS_COMIBF, - HPPA_INS_COMICLR, - HPPA_INS_COPR, - HPPA_INS_COPY, - HPPA_INS_CSTD, - HPPA_INS_CSTDS, - HPPA_INS_CSTDX, - HPPA_INS_CSTW, - HPPA_INS_CSTWS, - HPPA_INS_CSTWX, - HPPA_INS_DCOR, - HPPA_INS_DEP, - HPPA_INS_DEPI, - HPPA_INS_DEPD, - HPPA_INS_DEPDI, - HPPA_INS_DEPW, - HPPA_INS_DEPWI, - HPPA_INS_DIAG, - HPPA_INS_DS, - HPPA_INS_EXTRD, - HPPA_INS_EXTRS, - HPPA_INS_EXTRU, - HPPA_INS_EXTRW, - HPPA_INS_FABS, - HPPA_INS_FADD, - HPPA_INS_FCMP, - HPPA_INS_FCNV, - HPPA_INS_FCNVFF, - HPPA_INS_FCNVFX, - HPPA_INS_FCNVFXT, - HPPA_INS_FCNVXF, - HPPA_INS_FCPY, - HPPA_INS_FDC, - HPPA_INS_FDCE, - HPPA_INS_FDIV, - HPPA_INS_FIC, - HPPA_INS_FICE, - HPPA_INS_FID, - HPPA_INS_FLDD, - HPPA_INS_FLDDS, - HPPA_INS_FLDDX, - HPPA_INS_FLDW, - HPPA_INS_FLDWS, - HPPA_INS_FLDWX, - HPPA_INS_FMPY, - HPPA_INS_FMPYADD, - HPPA_INS_FMPYFADD, - HPPA_INS_FMPYNFADD, - HPPA_INS_FMPYSUB, - HPPA_INS_FNEG, - HPPA_INS_FNEGABS, - HPPA_INS_FREM, - HPPA_INS_FRND, - HPPA_INS_FSQRT, - HPPA_INS_FSTD, - HPPA_INS_FSTDS, - HPPA_INS_FSTDX, - HPPA_INS_FSTW, - HPPA_INS_FSTWS, - HPPA_INS_FSTWX, - HPPA_INS_FSTQS, - HPPA_INS_FSTQX, - HPPA_INS_FSUB, - HPPA_INS_FTEST, - HPPA_INS_GATE, - HPPA_INS_GFR, - HPPA_INS_GFW, - HPPA_INS_GRSHDW, - HPPA_INS_HADD, - HPPA_INS_HAVG, - HPPA_INS_HSHL, - HPPA_INS_HSHLADD, - HPPA_INS_HSHR, - HPPA_INS_HSHRADD, - HPPA_INS_HSUB, - HPPA_INS_IDTLBA, - HPPA_INS_IDTLBP, - HPPA_INS_IDTLBT, - HPPA_INS_IDCOR, - HPPA_INS_IITLBA, - HPPA_INS_IITLBP, - HPPA_INS_IITLBT, - HPPA_INS_LCI, - HPPA_INS_LDB, - HPPA_INS_LDBS, - HPPA_INS_LDBX, - HPPA_INS_LDCD, - HPPA_INS_LDCW, - HPPA_INS_LDCWS, - HPPA_INS_LDCWX, - HPPA_INS_LDD, - HPPA_INS_LDDA, - HPPA_INS_LDH, - HPPA_INS_LDHS, - HPPA_INS_LDHX, - HPPA_INS_LDI, - HPPA_INS_LDIL, - HPPA_INS_LDO, - HPPA_INS_LDSID, - HPPA_INS_LDW, - HPPA_INS_LDWA, - HPPA_INS_LDWAS, - HPPA_INS_LDWAX, - HPPA_INS_LDWM, - HPPA_INS_LDWS, - HPPA_INS_LDWX, - HPPA_INS_LPA, - HPPA_INS_MFCPU, - HPPA_INS_MFCTL, - HPPA_INS_MFIA, - HPPA_INS_MFSP, - HPPA_INS_MIXH, - HPPA_INS_MIXW, - HPPA_INS_MOVB, - HPPA_INS_MOVIB, - HPPA_INS_MTCPU, - HPPA_INS_MTCTL, - HPPA_INS_MTSAR, - HPPA_INS_MTSARCM, - HPPA_INS_MTSM, - HPPA_INS_MTSP, - HPPA_INS_NOP, - HPPA_INS_OR, - HPPA_INS_PDC, - HPPA_INS_PDTLB, - HPPA_INS_PDTLBE, - HPPA_INS_PERMH, - HPPA_INS_PITLB, - HPPA_INS_PITLBE, - HPPA_INS_PMDIS, - HPPA_INS_PMENB, - HPPA_INS_POPBTS, - HPPA_INS_PROBE, - HPPA_INS_PROBEI, - HPPA_INS_PROBER, - HPPA_INS_PROBERI, - HPPA_INS_PROBEW, - HPPA_INS_PROBEWI, - HPPA_INS_PUSHBTS, - HPPA_INS_PUSHNOM, - HPPA_INS_RET, - HPPA_INS_RFI, - HPPA_INS_RFIR, - HPPA_INS_RSM, - HPPA_INS_SHDWGR, - HPPA_INS_SHLADD, - HPPA_INS_SH1ADD, - HPPA_INS_SH1ADDL, - HPPA_INS_SH1ADDO, - HPPA_INS_SH2ADD, - HPPA_INS_SH2ADDL, - HPPA_INS_SH2ADDO, - HPPA_INS_SH3ADD, - HPPA_INS_SH3ADDL, - HPPA_INS_SH3ADDO, - HPPA_INS_SHD, - HPPA_INS_SHRPD, - HPPA_INS_SHRPW, - HPPA_INS_SPOP0, - HPPA_INS_SPOP1, - HPPA_INS_SPOP2, - HPPA_INS_SPOP3, - HPPA_INS_SSM, - HPPA_INS_STB, - HPPA_INS_STBS, - HPPA_INS_STBY, - HPPA_INS_STBYS, - HPPA_INS_STD, - HPPA_INS_STDA, - HPPA_INS_STDBY, - HPPA_INS_STH, - HPPA_INS_STHS, - HPPA_INS_STW, - HPPA_INS_STWA, - HPPA_INS_STWAS, - HPPA_INS_STWS, - HPPA_INS_STWM, - HPPA_INS_SUB, - HPPA_INS_SUBB, - HPPA_INS_SUBBO, - HPPA_INS_SUBI, - HPPA_INS_SUBIO, - HPPA_INS_SUBO, - HPPA_INS_SUBT, - HPPA_INS_SUBTO, - HPPA_INS_SYNC, - HPPA_INS_SYNCDMA, - HPPA_INS_TOCDIS, - HPPA_INS_TOCEN, - HPPA_INS_UADDCM, - HPPA_INS_UADDCMT, - HPPA_INS_UXOR, - HPPA_INS_VDEP, - HPPA_INS_VDEPI, - HPPA_INS_VEXTRS, - HPPA_INS_VEXTRU, - HPPA_INS_VSHD, - HPPA_INS_XMPYU, - HPPA_INS_XOR, - HPPA_INS_ZDEP, - HPPA_INS_ZDEPI, - HPPA_INS_ZVDEP, - HPPA_INS_ZVDEPI, - - HPPA_INS_ENDING -} hppa_insn; + HPPA_INS_ADD, + HPPA_INS_ADDI, + HPPA_INS_ADDIO, + HPPA_INS_ADDIT, + HPPA_INS_ADDITO, + HPPA_INS_ADDB, + HPPA_INS_ADDBT, + HPPA_INS_ADDBF, + HPPA_INS_ADDIB, + HPPA_INS_ADDIBT, + HPPA_INS_ADDIBF, + HPPA_INS_ADDIL, + HPPA_INS_ADDC, + HPPA_INS_ADDCO, + HPPA_INS_ADDL, + HPPA_INS_ADDO, + HPPA_INS_AND, + HPPA_INS_ANDCM, + HPPA_INS_B, + HPPA_INS_BB, + HPPA_INS_BE, + HPPA_INS_BL, + HPPA_INS_BLE, + HPPA_INS_BLR, + HPPA_INS_BREAK, + HPPA_INS_BV, + HPPA_INS_BVB, + HPPA_INS_BVE, + HPPA_INS_CALL, + HPPA_INS_CLDD, + HPPA_INS_CLDDS, + HPPA_INS_CLDDX, + HPPA_INS_CLDW, + HPPA_INS_CLDWS, + HPPA_INS_CLDWX, + HPPA_INS_CLRBTS, + HPPA_INS_CMPB, + HPPA_INS_CMPCLR, + HPPA_INS_CMPIB, + HPPA_INS_CMPICLR, + HPPA_INS_COMB, + HPPA_INS_COMBT, + HPPA_INS_COMBF, + HPPA_INS_COMCLR, + HPPA_INS_COMIB, + HPPA_INS_COMIBT, + HPPA_INS_COMIBF, + HPPA_INS_COMICLR, + HPPA_INS_COPR, + HPPA_INS_COPY, + HPPA_INS_CSTD, + HPPA_INS_CSTDS, + HPPA_INS_CSTDX, + HPPA_INS_CSTW, + HPPA_INS_CSTWS, + HPPA_INS_CSTWX, + HPPA_INS_DCOR, + HPPA_INS_DEP, + HPPA_INS_DEPI, + HPPA_INS_DEPD, + HPPA_INS_DEPDI, + HPPA_INS_DEPW, + HPPA_INS_DEPWI, + HPPA_INS_DIAG, + HPPA_INS_DS, + HPPA_INS_EXTRD, + HPPA_INS_EXTRS, + HPPA_INS_EXTRU, + HPPA_INS_EXTRW, + HPPA_INS_FABS, + HPPA_INS_FADD, + HPPA_INS_FCMP, + HPPA_INS_FCNV, + HPPA_INS_FCNVFF, + HPPA_INS_FCNVFX, + HPPA_INS_FCNVFXT, + HPPA_INS_FCNVXF, + HPPA_INS_FCPY, + HPPA_INS_FDC, + HPPA_INS_FDCE, + HPPA_INS_FDIV, + HPPA_INS_FIC, + HPPA_INS_FICE, + HPPA_INS_FID, + HPPA_INS_FLDD, + HPPA_INS_FLDDS, + HPPA_INS_FLDDX, + HPPA_INS_FLDW, + HPPA_INS_FLDWS, + HPPA_INS_FLDWX, + HPPA_INS_FMPY, + HPPA_INS_FMPYADD, + HPPA_INS_FMPYFADD, + HPPA_INS_FMPYNFADD, + HPPA_INS_FMPYSUB, + HPPA_INS_FNEG, + HPPA_INS_FNEGABS, + HPPA_INS_FREM, + HPPA_INS_FRND, + HPPA_INS_FSQRT, + HPPA_INS_FSTD, + HPPA_INS_FSTDS, + HPPA_INS_FSTDX, + HPPA_INS_FSTW, + HPPA_INS_FSTWS, + HPPA_INS_FSTWX, + HPPA_INS_FSTQS, + HPPA_INS_FSTQX, + HPPA_INS_FSUB, + HPPA_INS_FTEST, + HPPA_INS_GATE, + HPPA_INS_GFR, + HPPA_INS_GFW, + HPPA_INS_GRSHDW, + HPPA_INS_HADD, + HPPA_INS_HAVG, + HPPA_INS_HSHL, + HPPA_INS_HSHLADD, + HPPA_INS_HSHR, + HPPA_INS_HSHRADD, + HPPA_INS_HSUB, + HPPA_INS_IDTLBA, + HPPA_INS_IDTLBP, + HPPA_INS_IDTLBT, + HPPA_INS_IDCOR, + HPPA_INS_IITLBA, + HPPA_INS_IITLBP, + HPPA_INS_IITLBT, + HPPA_INS_LCI, + HPPA_INS_LDB, + HPPA_INS_LDBS, + HPPA_INS_LDBX, + HPPA_INS_LDCD, + HPPA_INS_LDCW, + HPPA_INS_LDCWS, + HPPA_INS_LDCWX, + HPPA_INS_LDD, + HPPA_INS_LDDA, + HPPA_INS_LDH, + HPPA_INS_LDHS, + HPPA_INS_LDHX, + HPPA_INS_LDI, + HPPA_INS_LDIL, + HPPA_INS_LDO, + HPPA_INS_LDSID, + HPPA_INS_LDW, + HPPA_INS_LDWA, + HPPA_INS_LDWAS, + HPPA_INS_LDWAX, + HPPA_INS_LDWM, + HPPA_INS_LDWS, + HPPA_INS_LDWX, + HPPA_INS_LPA, + HPPA_INS_MFCPU, + HPPA_INS_MFCTL, + HPPA_INS_MFIA, + HPPA_INS_MFSP, + HPPA_INS_MIXH, + HPPA_INS_MIXW, + HPPA_INS_MOVB, + HPPA_INS_MOVIB, + HPPA_INS_MTCPU, + HPPA_INS_MTCTL, + HPPA_INS_MTSAR, + HPPA_INS_MTSARCM, + HPPA_INS_MTSM, + HPPA_INS_MTSP, + HPPA_INS_NOP, + HPPA_INS_OR, + HPPA_INS_PDC, + HPPA_INS_PDTLB, + HPPA_INS_PDTLBE, + HPPA_INS_PERMH, + HPPA_INS_PITLB, + HPPA_INS_PITLBE, + HPPA_INS_PMDIS, + HPPA_INS_PMENB, + HPPA_INS_POPBTS, + HPPA_INS_PROBE, + HPPA_INS_PROBEI, + HPPA_INS_PROBER, + HPPA_INS_PROBERI, + HPPA_INS_PROBEW, + HPPA_INS_PROBEWI, + HPPA_INS_PUSHBTS, + HPPA_INS_PUSHNOM, + HPPA_INS_RET, + HPPA_INS_RFI, + HPPA_INS_RFIR, + HPPA_INS_RSM, + HPPA_INS_SHDWGR, + HPPA_INS_SHLADD, + HPPA_INS_SH1ADD, + HPPA_INS_SH1ADDL, + HPPA_INS_SH1ADDO, + HPPA_INS_SH2ADD, + HPPA_INS_SH2ADDL, + HPPA_INS_SH2ADDO, + HPPA_INS_SH3ADD, + HPPA_INS_SH3ADDL, + HPPA_INS_SH3ADDO, + HPPA_INS_SHD, + HPPA_INS_SHRPD, + HPPA_INS_SHRPW, + HPPA_INS_SPOP0, + HPPA_INS_SPOP1, + HPPA_INS_SPOP2, + HPPA_INS_SPOP3, + HPPA_INS_SSM, + HPPA_INS_STB, + HPPA_INS_STBS, + HPPA_INS_STBY, + HPPA_INS_STBYS, + HPPA_INS_STD, + HPPA_INS_STDA, + HPPA_INS_STDBY, + HPPA_INS_STH, + HPPA_INS_STHS, + HPPA_INS_STW, + HPPA_INS_STWA, + HPPA_INS_STWAS, + HPPA_INS_STWS, + HPPA_INS_STWM, + HPPA_INS_SUB, + HPPA_INS_SUBB, + HPPA_INS_SUBBO, + HPPA_INS_SUBI, + HPPA_INS_SUBIO, + HPPA_INS_SUBO, + HPPA_INS_SUBT, + HPPA_INS_SUBTO, + HPPA_INS_SYNC, + HPPA_INS_SYNCDMA, + HPPA_INS_TOCDIS, + HPPA_INS_TOCEN, + HPPA_INS_UADDCM, + HPPA_INS_UADDCMT, + HPPA_INS_UXOR, + HPPA_INS_VDEP, + HPPA_INS_VDEPI, + HPPA_INS_VEXTRS, + HPPA_INS_VEXTRU, + HPPA_INS_VSHD, + HPPA_INS_XMPYU, + HPPA_INS_XOR, + HPPA_INS_ZDEP, + HPPA_INS_ZDEPI, + HPPA_INS_ZVDEP, + HPPA_INS_ZVDEPI, + HPPA_INS_ENDING +} hppa_insn; /// HPPA space select operand typedef struct hppa_mem { - hppa_reg base; - hppa_reg space; - cs_ac_type base_access; + hppa_reg base; + hppa_reg space; + cs_ac_type base_access; } hppa_mem; // Instruction operand typedef struct cs_hppa_op { - hppa_op_type type; ///< operand type + hppa_op_type type; ///< operand type union { - hppa_reg reg; ///< register value for REG operand - int64_t imm; ///< immediate value for IMM operand - hppa_mem mem; + hppa_reg reg; ///< register value for REG operand + int64_t imm; ///< immediate value for IMM operand + hppa_mem mem; }; cs_ac_type access; } cs_hppa_op; @@ -497,45 +496,41 @@ typedef struct cs_hppa { } cs_hppa; typedef enum hppa_modifier_type { - HPPA_MOD_STR = 0, - HPPA_MOD_INT = 1 + HPPA_MOD_STR = 0, + HPPA_MOD_INT = 1 } hppa_modifier_type; /// hppa string/integer modifier typedef struct hppa_modifier { - hppa_modifier_type type; - union - { - char str_mod[HPPA_STR_MODIFIER_LEN]; - uint32_t int_mod; - }; - + hppa_modifier_type type; + union { + char str_mod[HPPA_STR_MODIFIER_LEN]; + uint32_t int_mod; + }; + } hppa_modifier; // Additional instruction info typedef struct hppa_ext { - hppa_modifier modifiers[HPPA_MAX_MODIFIERS_LEN]; - uint8_t mod_num; - bool b_writeble; - bool is_alternative; + hppa_modifier modifiers[HPPA_MAX_MODIFIERS_LEN]; + uint8_t mod_num; + bool b_writeble; + bool is_alternative; } hppa_ext; - - - // Group of HPPA instructions typedef enum hppa_insn_group { HPPA_GRP_INVALID = 0, ///< = CS_GRP_INVALID HPPA_GRP_COMPUTATION = 128, - HPPA_GRP_MULTIMEDIA, - HPPA_GRP_MEM_REF, - HPPA_GRP_LONG_IMM, - HPPA_GRP_BRANCH, - HPPA_GRP_SYSCTRL, - HPPA_GRP_ASSIST, - HPPA_GRP_FLOAT, - HPPA_GRP_PERFMON, + HPPA_GRP_MULTIMEDIA, + HPPA_GRP_MEM_REF, + HPPA_GRP_LONG_IMM, + HPPA_GRP_BRANCH, + HPPA_GRP_SYSCTRL, + HPPA_GRP_ASSIST, + HPPA_GRP_FLOAT, + HPPA_GRP_PERFMON, HPPA_GRP_ENDING, } hppa_insn_group; diff --git a/suite/cstest/src/hppa_detail.c b/suite/cstest/src/hppa_detail.c index 5c6184739b..38bc762c08 100644 --- a/suite/cstest/src/hppa_detail.c +++ b/suite/cstest/src/hppa_detail.c @@ -37,30 +37,33 @@ char *get_detail_hppa(csh *p_handle, cs_mode mode, cs_insn *ins) add_str(&result, "\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); break; - case HPPA_OP_IDX_REG: - add_str(&result, "\t\toperands[%u].type: IDX_REG = %s\n", i, - cs_reg_name(handle, op->reg)); - break; - case HPPA_OP_DISP: - add_str(&result, "\t\toperands[%u].type: DISP = 0x%x\n", i, - op->imm); - break; - case HPPA_OP_MEM: - add_str(&result, "\t\toperands[%u].type: MEM\n", i); - if (op->mem.space != HPPA_OP_INVALID) { - add_str(&result, "\t\t\toperands[%u].mem.space: REG = %s\n", - i, cs_reg_name(handle, op->mem.space)); - } - add_str(&result, "\t\t\toperands[%u].mem.base: REG = %s\n", - i, cs_reg_name(handle, op->mem.base)); - break; - case HPPA_OP_TARGET: - add_str(&result, "\t\toperands[%u].type: ", i); - if (op->imm >= 0x8000000000000000) - add_str(&result, "TARGET = -0x%lx\n", -op->imm); - else - add_str(&result, "TARGET = 0x%lx\n", op->imm); - break; + case HPPA_OP_IDX_REG: + add_str(&result, + "\t\toperands[%u].type: IDX_REG = %s\n", i, + cs_reg_name(handle, op->reg)); + break; + case HPPA_OP_DISP: + add_str(&result, "\t\toperands[%u].type: DISP = 0x%x\n", + i, op->imm); + break; + case HPPA_OP_MEM: + add_str(&result, "\t\toperands[%u].type: MEM\n", i); + if (op->mem.space != HPPA_OP_INVALID) { + add_str(&result, + "\t\t\toperands[%u].mem.space: REG = %s\n", + i, cs_reg_name(handle, op->mem.space)); + } + add_str(&result, + "\t\t\toperands[%u].mem.base: REG = %s\n", i, + cs_reg_name(handle, op->mem.base)); + break; + case HPPA_OP_TARGET: + add_str(&result, "\t\toperands[%u].type: ", i); + if (op->imm >= 0x8000000000000000) + add_str(&result, "TARGET = -0x%lx\n", -op->imm); + else + add_str(&result, "TARGET = 0x%lx\n", op->imm); + break; } // Print out all registers accessed by this instruction (either implicit or diff --git a/tests/test_hppa.c b/tests/test_hppa.c index e9b9b4df97..15a0179043 100644 --- a/tests/test_hppa.c +++ b/tests/test_hppa.c @@ -46,34 +46,38 @@ static void print_insn_detail(cs_insn *ins) switch ((int)op->type) { default: break; - case HPPA_OP_REG: - printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); - break; - case HPPA_OP_IMM: - printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); - break; - case HPPA_OP_IDX_REG: - printf("\t\toperands[%u].type: IDX_REG = %s\n", i, cs_reg_name(handle, op->reg)); - break; - case HPPA_OP_DISP: - printf("\t\toperands[%u].type: DISP = 0x%" PRIx64 "\n", i, op->imm); - break; - case HPPA_OP_MEM: - printf("\t\toperands[%u].type: MEM\n", i); - if (op->mem.space != HPPA_OP_INVALID) { - printf("\t\t\toperands[%u].mem.space: REG = %s\n", - i, cs_reg_name(handle, op->mem.space)); - } - printf("\t\t\toperands[%u].mem.base: REG = %s\n", - i, cs_reg_name(handle, op->mem.base)); - break; - case HPPA_OP_TARGET: - printf("\t\toperands[%u].type: ", i); - if (op->imm >= 0x8000000000000000) - printf("TARGET = -0x%" PRIx64 "\n", -op->imm); - else - printf("TARGET = 0x%" PRIx64 "\n", op->imm); - break; + case HPPA_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, + cs_reg_name(handle, op->reg)); + break; + case HPPA_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", + i, op->imm); + break; + case HPPA_OP_IDX_REG: + printf("\t\toperands[%u].type: IDX_REG = %s\n", i, + cs_reg_name(handle, op->reg)); + break; + case HPPA_OP_DISP: + printf("\t\toperands[%u].type: DISP = 0x%" PRIx64 "\n", + i, op->imm); + break; + case HPPA_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.space != HPPA_OP_INVALID) { + printf("\t\t\toperands[%u].mem.space: REG = %s\n", + i, cs_reg_name(handle, op->mem.space)); + } + printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, + cs_reg_name(handle, op->mem.base)); + break; + case HPPA_OP_TARGET: + printf("\t\toperands[%u].type: ", i); + if (op->imm >= 0x8000000000000000) + printf("TARGET = -0x%" PRIx64 "\n", -op->imm); + else + printf("TARGET = 0x%" PRIx64 "\n", op->imm); + break; } } @@ -82,11 +86,14 @@ static void print_insn_detail(cs_insn *ins) static void test() { -#define HPPA_20_CODE_BE "\x00\x20\x50\xa2\x00\x01\x58\x20\x00\x00\x44\xa1\x00\x41\x18\x40\x00\x20\x08\xa2\x01\x60\x48\xa1\x01\x61\x18\xc0\x00\x00\x14\xa1\x00\x0f\x0d\x61\x00\x0f\x0e\x61\x00\x01\x18\x60\x00\x00\x0c\x00\x00\x00\x0c\xa0\x03\xff\xc0\x1f\x00\x00\x04\x00\x00\x10\x04\x00\x04\x22\x51\x83\x04\x22\x51\xc3\x04\x22\x51\x83\x04\x2f\x71\x83\x04\x2f\x71\xc3\x04\x2f\x71\x83\x04\x41\x53\x43\x04\x41\x53\x63\x04\x41\x53\x03\x04\x41\x12\x00\x04\x41\x16\x00\x04\x41\x16\x20\x04\x41\x42\x00\x04\x41\x46\x00\x04\x41\x46\x20\x04\x41\x12\x40\x04\x41\x12\x60\x04\x41\x42\x40\x04\x41\x42\x60\x04\x41\x18\x00\x04\x41\x08\x00\x04\x41\x13\x80\x04\x41\x13\xa0\x04\x41\x52\x80\x04\x41\x52\xa0\x04\x5e\x72\x80\x04\x41\x42\x80\x04\x41\x52\xc0\x04\x41\x52\xe0\x04\x41\x42\xc0\x04\x41\x42\xe0\x14\x00\xde\xad" -#define HPPA_20_CODE "\xa2\x50\x20\x00\x20\x58\x01\x00\xa1\x44\x00\x00\x40\x18\x41\x00\xa2\x08\x20\x00\xa1\x48\x60\x01\xc0\x18\x61\x01\xa1\x14\x00\x00\x61\x0d\x0f\x00\x61\x0e\x0f\x00\x60\x18\x01\x00\x00\x0c\x00\x00\xa0\x0c\x00\x00\x1f\xc0\xff\x03\x00\x04\x00\x00\x00\x04\x10\x00\x83\x51\x22\x04\xc3\x51\x22\x04\x83\x51\x22\x04\x83\x71\x2f\x04\xc3\x71\x2f\x04\x83\x71\x2f\x04\x43\x53\x41\x04\x63\x53\x41\x04\x03\x53\x41\x04\x00\x12\x41\x04\x00\x16\x41\x04\x20\x16\x41\x04\x00\x42\x41\x04\x00\x46\x41\x04\x20\x46\x41\x04\x40\x12\x41\x04\x60\x12\x41\x04\x40\x42\x41\x04\x60\x42\x41\x04\x00\x18\x41\x04\x00\x08\x41\x04\x80\x13\x41\x04\xa0\x13\x41\x04\x80\x52\x41\x04\xa0\x52\x41\x04\x80\x72\x5e\x04\x80\x42\x41\x04\xc0\x52\x41\x04\xe0\x52\x41\x04\xc0\x42\x41\x04\xe0\x42\x41\x04\xad\xde\x00\x14" -#define HPPA_11_CODE_BE "\x24\x41\x40\xc3\x24\x41\x60\xc3\x24\x41\x40\xe3\x24\x41\x60\xe3\x24\x41\x68\xe3\x2c\x41\x40\xc3\x2c\x41\x60\xc3\x2c\x41\x40\xe3\x2c\x41\x60\xe3\x2c\x41\x68\xe3\x24\x62\x42\xc1\x24\x62\x62\xc1\x24\x62\x42\xe1\x24\x62\x46\xe1\x24\x62\x62\xe1\x24\x62\x6a\xe1\x2c\x62\x42\xc1\x2c\x62\x62\xc1\x2c\x62\x42\xe1\x2c\x62\x46\xe1\x2c\x62\x62\xe1\x2c\x62\x6a\xe1\x24\x3e\x50\xc2\x24\x3e\x50\xe2\x24\x3e\x70\xe2\x24\x3e\x78\xe2\x2c\x3e\x50\xc2\x2c\x3e\x50\xe2\x2c\x3e\x70\xe2\x2c\x3e\x78\xe2\x24\x5e\x52\xc1\x24\x5e\x52\xe1\x24\x5e\x56\xe1\x24\x5e\x72\xe1\x24\x5e\x7a\xe1\x2c\x5e\x52\xc1\x2c\x5e\x52\xe1\x2c\x5e\x56\xe1\x2c\x5e\x72\xe1\x2c\x5e\x7a\xe1" -#define HPPA_11_CODE "\xc3\x40\x41\x24\xc3\x60\x41\x24\xe3\x40\x41\x24\xe3\x60\x41\x24\xe3\x68\x41\x24\xc3\x40\x41\x2c\xc3\x60\x41\x2c\xe3\x40\x41\x2c\xe3\x60\x41\x2c\xe3\x68\x41\x2c\xc1\x42\x62\x24\xc1\x62\x62\x24\xe1\x42\x62\x24\xe1\x46\x62\x24\xe1\x62\x62\x24\xe1\x6a\x62\x24\xc1\x42\x62\x2c\xc1\x62\x62\x2c\xe1\x42\x62\x2c\xe1\x46\x62\x2c\xe1\x62\x62\x2c\xe1\x6a\x62\x2c\xc2\x50\x3e\x24\xe2\x50\x3e\x24\xe2\x70\x3e\x24\xe2\x78\x3e\x24\xc2\x50\x3e\x2c\xe2\x50\x3e\x2c\xe2\x70\x3e\x2c\xe2\x78\x3e\x2c\xc1\x52\x5e\x24\xe1\x52\x5e\x24\xe1\x56\x5e\x24\xe1\x72\x5e\x24\xe1\x7a\x5e\x24\xc1\x52\x5e\x2c\xe1\x52\x5e\x2c\xe1\x56\x5e\x2c\xe1\x72\x5e\x2c\xe1\x7a\x5e\x2c" - +#define HPPA_20_CODE_BE \ + "\x00\x20\x50\xa2\x00\x01\x58\x20\x00\x00\x44\xa1\x00\x41\x18\x40\x00\x20\x08\xa2\x01\x60\x48\xa1\x01\x61\x18\xc0\x00\x00\x14\xa1\x00\x0f\x0d\x61\x00\x0f\x0e\x61\x00\x01\x18\x60\x00\x00\x0c\x00\x00\x00\x0c\xa0\x03\xff\xc0\x1f\x00\x00\x04\x00\x00\x10\x04\x00\x04\x22\x51\x83\x04\x22\x51\xc3\x04\x22\x51\x83\x04\x2f\x71\x83\x04\x2f\x71\xc3\x04\x2f\x71\x83\x04\x41\x53\x43\x04\x41\x53\x63\x04\x41\x53\x03\x04\x41\x12\x00\x04\x41\x16\x00\x04\x41\x16\x20\x04\x41\x42\x00\x04\x41\x46\x00\x04\x41\x46\x20\x04\x41\x12\x40\x04\x41\x12\x60\x04\x41\x42\x40\x04\x41\x42\x60\x04\x41\x18\x00\x04\x41\x08\x00\x04\x41\x13\x80\x04\x41\x13\xa0\x04\x41\x52\x80\x04\x41\x52\xa0\x04\x5e\x72\x80\x04\x41\x42\x80\x04\x41\x52\xc0\x04\x41\x52\xe0\x04\x41\x42\xc0\x04\x41\x42\xe0\x14\x00\xde\xad" +#define HPPA_20_CODE \ + "\xa2\x50\x20\x00\x20\x58\x01\x00\xa1\x44\x00\x00\x40\x18\x41\x00\xa2\x08\x20\x00\xa1\x48\x60\x01\xc0\x18\x61\x01\xa1\x14\x00\x00\x61\x0d\x0f\x00\x61\x0e\x0f\x00\x60\x18\x01\x00\x00\x0c\x00\x00\xa0\x0c\x00\x00\x1f\xc0\xff\x03\x00\x04\x00\x00\x00\x04\x10\x00\x83\x51\x22\x04\xc3\x51\x22\x04\x83\x51\x22\x04\x83\x71\x2f\x04\xc3\x71\x2f\x04\x83\x71\x2f\x04\x43\x53\x41\x04\x63\x53\x41\x04\x03\x53\x41\x04\x00\x12\x41\x04\x00\x16\x41\x04\x20\x16\x41\x04\x00\x42\x41\x04\x00\x46\x41\x04\x20\x46\x41\x04\x40\x12\x41\x04\x60\x12\x41\x04\x40\x42\x41\x04\x60\x42\x41\x04\x00\x18\x41\x04\x00\x08\x41\x04\x80\x13\x41\x04\xa0\x13\x41\x04\x80\x52\x41\x04\xa0\x52\x41\x04\x80\x72\x5e\x04\x80\x42\x41\x04\xc0\x52\x41\x04\xe0\x52\x41\x04\xc0\x42\x41\x04\xe0\x42\x41\x04\xad\xde\x00\x14" +#define HPPA_11_CODE_BE \ + "\x24\x41\x40\xc3\x24\x41\x60\xc3\x24\x41\x40\xe3\x24\x41\x60\xe3\x24\x41\x68\xe3\x2c\x41\x40\xc3\x2c\x41\x60\xc3\x2c\x41\x40\xe3\x2c\x41\x60\xe3\x2c\x41\x68\xe3\x24\x62\x42\xc1\x24\x62\x62\xc1\x24\x62\x42\xe1\x24\x62\x46\xe1\x24\x62\x62\xe1\x24\x62\x6a\xe1\x2c\x62\x42\xc1\x2c\x62\x62\xc1\x2c\x62\x42\xe1\x2c\x62\x46\xe1\x2c\x62\x62\xe1\x2c\x62\x6a\xe1\x24\x3e\x50\xc2\x24\x3e\x50\xe2\x24\x3e\x70\xe2\x24\x3e\x78\xe2\x2c\x3e\x50\xc2\x2c\x3e\x50\xe2\x2c\x3e\x70\xe2\x2c\x3e\x78\xe2\x24\x5e\x52\xc1\x24\x5e\x52\xe1\x24\x5e\x56\xe1\x24\x5e\x72\xe1\x24\x5e\x7a\xe1\x2c\x5e\x52\xc1\x2c\x5e\x52\xe1\x2c\x5e\x56\xe1\x2c\x5e\x72\xe1\x2c\x5e\x7a\xe1" +#define HPPA_11_CODE \ + "\xc3\x40\x41\x24\xc3\x60\x41\x24\xe3\x40\x41\x24\xe3\x60\x41\x24\xe3\x68\x41\x24\xc3\x40\x41\x2c\xc3\x60\x41\x2c\xe3\x40\x41\x2c\xe3\x60\x41\x2c\xe3\x68\x41\x2c\xc1\x42\x62\x24\xc1\x62\x62\x24\xe1\x42\x62\x24\xe1\x46\x62\x24\xe1\x62\x62\x24\xe1\x6a\x62\x24\xc1\x42\x62\x2c\xc1\x62\x62\x2c\xe1\x42\x62\x2c\xe1\x46\x62\x2c\xe1\x62\x62\x2c\xe1\x6a\x62\x2c\xc2\x50\x3e\x24\xe2\x50\x3e\x24\xe2\x70\x3e\x24\xe2\x78\x3e\x24\xc2\x50\x3e\x2c\xe2\x50\x3e\x2c\xe2\x70\x3e\x2c\xe2\x78\x3e\x2c\xc1\x52\x5e\x24\xe1\x52\x5e\x24\xe1\x56\x5e\x24\xe1\x72\x5e\x24\xe1\x7a\x5e\x24\xc1\x52\x5e\x2c\xe1\x52\x5e\x2c\xe1\x56\x5e\x2c\xe1\x72\x5e\x2c\xe1\x7a\x5e\x2c" struct platform platforms[] = { { @@ -96,7 +103,7 @@ static void test() sizeof(HPPA_20_CODE_BE) - 1, "HPPA 2.0 (Big-endian)", }, - { + { CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_20, (unsigned char *)HPPA_20_CODE, @@ -110,7 +117,7 @@ static void test() sizeof(HPPA_11_CODE_BE) - 1, "HPPA 1.1 (Big-endian)", }, - { + { CS_ARCH_HPPA, CS_MODE_LITTLE_ENDIAN | CS_MODE_HPPA_11, (unsigned char *)HPPA_11_CODE,